diff --git a/doc/examples/Repository.rst b/doc/examples/Repository.rst index b8649a19..bfc3b4fa 100644 --- a/doc/examples/Repository.rst +++ b/doc/examples/Repository.rst @@ -138,3 +138,12 @@ Delete a file in the repository >>> repo.delete_file(contents.path, "remove test", contents.sha, branch="test") {'commit': Commit(sha="0f40b0b4f31f62454f1758d7e6b384795e48fd96"), 'content': NotSet} +======= +====== +Mark the notifications of the repository as read +------------------------------------------------ + +.. code-block:: python + + >>> repo = g.get_repo("PyGithub/PyGithub") + >>> repo.mark_notifications_as_read() diff --git a/github/AuthenticatedUser.py b/github/AuthenticatedUser.py index e230a0ee..604eb0c8 100644 --- a/github/AuthenticatedUser.py +++ b/github/AuthenticatedUser.py @@ -1044,6 +1044,22 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): ) return status == 200 + def mark_notifications_as_read(self, last_read_at=datetime.datetime.utcnow()): + """ + :calls: `PUT /notifications `_ + :param last_read_at: datetime + """ + assert isinstance(last_read_at, datetime.datetime) + put_parameters = { + "last_read_at": last_read_at.strftime('%Y-%m-%dT%H:%M:%SZ') + } + + headers, data = self._requester.requestJsonAndCheck( + "PUT", + "/notifications", + input=put_parameters + ) + def remove_from_emails(self, *emails): """ :calls: `DELETE /user/emails `_ diff --git a/github/Notification.py b/github/Notification.py index f38f845b..b62d75f6 100644 --- a/github/Notification.py +++ b/github/Notification.py @@ -115,6 +115,15 @@ class Notification(github.GithubObject.CompletableGithubObject): self._completeIfNotSet(self._url) return self._url.value + def mark_as_read(self): + """ + :calls: `PATCH /notifications/threads/:id `_ + """ + headers, data = self._requester.requestJsonAndCheck( + "PATCH", + self.url, + ) + def _initAttributes(self): self._id = github.GithubObject.NotSet self._last_read_at = github.GithubObject.NotSet diff --git a/github/Repository.py b/github/Repository.py index e8412222..92e1a459 100644 --- a/github/Repository.py +++ b/github/Repository.py @@ -2473,6 +2473,22 @@ class Repository(github.GithubObject.CompletableGithubObject): for element in data["issues"] ] + def mark_notifications_as_read(self, last_read_at=datetime.datetime.utcnow()): + """ + :calls: `PUT /repos/:owner/:repo/notifications `_ + :param last_read_at: datetime + """ + assert isinstance(last_read_at, datetime.datetime) + put_parameters = { + "last_read_at": last_read_at.strftime('%Y-%m-%dT%H:%M:%SZ') + } + + headers, data = self._requester.requestJsonAndCheck( + "PUT", + self.url + "/notifications", + input=put_parameters + ) + def merge(self, base, head, commit_message=github.GithubObject.NotSet): """ :calls: `POST /repos/:owner/:repo/merges `_ diff --git a/github/tests/AllTests.py b/github/tests/AllTests.py index 9d79fc71..d43a592e 100644 --- a/github/tests/AllTests.py +++ b/github/tests/AllTests.py @@ -71,6 +71,7 @@ from Label import * from Milestone import * from NamedUser import * from Markdown import * +from Notification import * from OrganizationHasInMembers import * from Organization import * from Project import * diff --git a/github/tests/AuthenticatedUser.py b/github/tests/AuthenticatedUser.py index c498b16e..43cbd410 100644 --- a/github/tests/AuthenticatedUser.py +++ b/github/tests/AuthenticatedUser.py @@ -243,6 +243,9 @@ class AuthenticatedUser(Framework.TestCase): def testGetNotificationsWithOtherArguments(self): self.assertListKeyEqual(self.user.get_notifications(all=True), lambda n: n.id, []) + def testMarkNotificationsAsRead(self): + self.user.mark_notifications_as_read(datetime.datetime(2018, 10, 18, 18, 20, 01, 0)) + def testGetTeams(self): self.assertListKeyEqual(self.user.get_teams(), lambda t: t.name, ["Owners", "Honoraries", "Honoraries", "Honoraries", "Honoraries", "Honoraries", "Honoraries", "Honoraries", "Honoraries", "Honoraries"]) diff --git a/github/tests/Notification.py b/github/tests/Notification.py new file mode 100644 index 00000000..04543094 --- /dev/null +++ b/github/tests/Notification.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +############################ Copyrights and license ############################ +# # +# Copyright 2012 Vincent Jacques # +# Copyright 2012 Zearin # +# Copyright 2013 Vincent Jacques # +# Copyright 2014 Vincent Jacques # +# Copyright 2016 Jannis Gebauer # +# Copyright 2016 Peter Buckley # +# Copyright 2018 sfdye # +# # +# This file is part of PyGithub. # +# http://pygithub.readthedocs.io/ # +# # +# PyGithub is free software: you can redistribute it and/or modify it under # +# the terms of the GNU Lesser General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # +# details. # +# # +# You should have received a copy of the GNU Lesser General Public License # +# along with PyGithub. If not, see . # +# # +################################################################################ + +import Framework + +import datetime + + +class Notification(Framework.TestCase): + def setUp(self): + Framework.TestCase.setUp(self) + self.notification = self.g.get_user().get_notifications()[0] + + def testMarkAsRead(self): + self.notification.mark_as_read() diff --git a/github/tests/ReplayData/AuthenticatedUser.testMarkNotificationsAsRead.txt b/github/tests/ReplayData/AuthenticatedUser.testMarkNotificationsAsRead.txt new file mode 100644 index 00000000..109e882e --- /dev/null +++ b/github/tests/ReplayData/AuthenticatedUser.testMarkNotificationsAsRead.txt @@ -0,0 +1,11 @@ +https +PUT +api.github.com +None +/notifications +{'Content-Type': 'application/json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +{"last_read_at": "2018-10-18T18:20:01Z"} +205 +[('Server', 'GitHub.com'), ('Date', 'Thu, 18 Oct 2018 18:41:54 GMT'), ('Content-Type', 'text/plain;charset=utf-8'), ('Content-Length', '0'), ('Status', '205 Reset Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4989'), ('X-RateLimit-Reset', '1539890344'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', 'notifications, repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'B236:4C25:2ABE5CA:58BE030:5BC8D3F2')] + + diff --git a/github/tests/ReplayData/Notification.setUp.txt b/github/tests/ReplayData/Notification.setUp.txt new file mode 100644 index 00000000..d3dc082c --- /dev/null +++ b/github/tests/ReplayData/Notification.setUp.txt @@ -0,0 +1,11 @@ +https +GET +api.github.com +None +/notifications +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Server', 'GitHub.com'), ('Date', 'Thu, 18 Oct 2018 18:46:58 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4984'), ('X-RateLimit-Reset', '1539890344'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/""'), ('Last-Modified', 'Thu, 18 Oct 2018 18:29:47 GMT'), ('X-Poll-Interval', '60'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', 'notifications, repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'B148:4C25:2AC480C:58CB140:5BC8D522')] +[{"id":"397777914","unread":true,"reason":"subscribed","updated_at":"2018-10-18T18:29:47Z","last_read_at":"2018-10-18T13:20:08Z","subject":{"title":"chore: Add more repos migrated on Quay","url":"https://api.github.com/repos/dailymotion/jarvis/pulls/103","latest_comment_url":"https://api.github.com/repos/dailymotion/jarvis/pulls/103","type":"PullRequest"},"repository":{"id":117231874,"node_id":"MDEwOlJlcG9zaXRvcnkxMTcyMzE4NzQ=","name":"jarvis","full_name":"dailymotion/jarvis","private":true,"owner":{"login":"dailymotion","id":115313,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNTMxMw==","avatar_url":"https://avatars2.githubusercontent.com/u/115313?v=4","gravatar_id":"","url":"https://api.github.com/users/dailymotion","html_url":"https://github.com/dailymotion","followers_url":"https://api.github.com/users/dailymotion/followers","following_url":"https://api.github.com/users/dailymotion/following{/other_user}","gists_url":"https://api.github.com/users/dailymotion/gists{/gist_id}","starred_url":"https://api.github.com/users/dailymotion/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dailymotion/subscriptions","organizations_url":"https://api.github.com/users/dailymotion/orgs","repos_url":"https://api.github.com/users/dailymotion/repos","events_url":"https://api.github.com/users/dailymotion/events{/privacy}","received_events_url":"https://api.github.com/users/dailymotion/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/dailymotion/jarvis","description":"A shared library containing Jenkins pipeline steps and utilities","fork":false,"url":"https://api.github.com/repos/dailymotion/jarvis","forks_url":"https://api.github.com/repos/dailymotion/jarvis/forks","keys_url":"https://api.github.com/repos/dailymotion/jarvis/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dailymotion/jarvis/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dailymotion/jarvis/teams","hooks_url":"https://api.github.com/repos/dailymotion/jarvis/hooks","issue_events_url":"https://api.github.com/repos/dailymotion/jarvis/issues/events{/number}","events_url":"https://api.github.com/repos/dailymotion/jarvis/events","assignees_url":"https://api.github.com/repos/dailymotion/jarvis/assignees{/user}","branches_url":"https://api.github.com/repos/dailymotion/jarvis/branches{/branch}","tags_url":"https://api.github.com/repos/dailymotion/jarvis/tags","blobs_url":"https://api.github.com/repos/dailymotion/jarvis/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dailymotion/jarvis/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dailymotion/jarvis/git/refs{/sha}","trees_url":"https://api.github.com/repos/dailymotion/jarvis/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dailymotion/jarvis/statuses/{sha}","languages_url":"https://api.github.com/repos/dailymotion/jarvis/languages","stargazers_url":"https://api.github.com/repos/dailymotion/jarvis/stargazers","contributors_url":"https://api.github.com/repos/dailymotion/jarvis/contributors","subscribers_url":"https://api.github.com/repos/dailymotion/jarvis/subscribers","subscription_url":"https://api.github.com/repos/dailymotion/jarvis/subscription","commits_url":"https://api.github.com/repos/dailymotion/jarvis/commits{/sha}","git_commits_url":"https://api.github.com/repos/dailymotion/jarvis/git/commits{/sha}","comments_url":"https://api.github.com/repos/dailymotion/jarvis/comments{/number}","issue_comment_url":"https://api.github.com/repos/dailymotion/jarvis/issues/comments{/number}","contents_url":"https://api.github.com/repos/dailymotion/jarvis/contents/{+path}","compare_url":"https://api.github.com/repos/dailymotion/jarvis/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dailymotion/jarvis/merges","archive_url":"https://api.github.com/repos/dailymotion/jarvis/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dailymotion/jarvis/downloads","issues_url":"https://api.github.com/repos/dailymotion/jarvis/issues{/number}","pulls_url":"https://api.github.com/repos/dailymotion/jarvis/pulls{/number}","milestones_url":"https://api.github.com/repos/dailymotion/jarvis/milestones{/number}","notifications_url":"https://api.github.com/repos/dailymotion/jarvis/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dailymotion/jarvis/labels{/name}","releases_url":"https://api.github.com/repos/dailymotion/jarvis/releases{/id}","deployments_url":"https://api.github.com/repos/dailymotion/jarvis/deployments"},"url":"https://api.github.com/notifications/threads/397777914","subscription_url":"https://api.github.com/notifications/threads/397777914/subscription"}] + diff --git a/github/tests/ReplayData/Notification.testMarkAsRead.txt b/github/tests/ReplayData/Notification.testMarkAsRead.txt new file mode 100644 index 00000000..a243ee9c --- /dev/null +++ b/github/tests/ReplayData/Notification.testMarkAsRead.txt @@ -0,0 +1,11 @@ +https +PATCH +api.github.com +None +/notifications/threads/397777914 +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +205 +[('Server', 'GitHub.com'), ('Date', 'Thu, 18 Oct 2018 18:46:59 GMT'), ('Content-Type', 'text/plain;charset=utf-8'), ('Content-Length', '0'), ('Status', '205 Reset Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4983'), ('X-RateLimit-Reset', '1539890344'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', 'notifications, repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'B14A:4C25:2AC483C:58CB194:5BC8D523')] + + diff --git a/github/tests/ReplayData/Repository.testMarkNotificationsAsRead.txt b/github/tests/ReplayData/Repository.testMarkNotificationsAsRead.txt new file mode 100644 index 00000000..fa409578 --- /dev/null +++ b/github/tests/ReplayData/Repository.testMarkNotificationsAsRead.txt @@ -0,0 +1,33 @@ +https +GET +api.github.com +None +/user +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Server', 'GitHub.com'), ('Date', 'Thu, 18 Oct 2018 18:19:45 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4993'), ('X-RateLimit-Reset', '1539890344'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/"4c0d57696297d443d17a214011b1cc0b"'), ('Last-Modified', 'Mon, 08 Oct 2018 14:54:47 GMT'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'B188:4C25:2AA2DF3:58852FF:5BC8CEC0')] +{"login":"zer0tonin","id":7149690,"node_id":"MDQ6VXNlcjcxNDk2OTA=","avatar_url":"https://avatars3.githubusercontent.com/u/7149690?v=4","gravatar_id":"","url":"https://api.github.com/users/zer0tonin","html_url":"https://github.com/zer0tonin","followers_url":"https://api.github.com/users/zer0tonin/followers","following_url":"https://api.github.com/users/zer0tonin/following{/other_user}","gists_url":"https://api.github.com/users/zer0tonin/gists{/gist_id}","starred_url":"https://api.github.com/users/zer0tonin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zer0tonin/subscriptions","organizations_url":"https://api.github.com/users/zer0tonin/orgs","repos_url":"https://api.github.com/users/zer0tonin/repos","events_url":"https://api.github.com/users/zer0tonin/events{/privacy}","received_events_url":"https://api.github.com/users/zer0tonin/received_events","type":"User","site_admin":false,"name":"Alice GIRARD","company":null,"blog":"","location":null,"email":null,"hireable":null,"bio":null,"public_repos":20,"public_gists":12,"followers":2,"following":2,"created_at":"2014-04-03T11:51:25Z","updated_at":"2018-10-08T14:54:47Z","private_gists":1,"total_private_repos":0,"owned_private_repos":0,"disk_usage":71917,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/repos/zer0tonin/PyGithub +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Server', 'GitHub.com'), ('Date', 'Thu, 18 Oct 2018 18:19:45 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4992'), ('X-RateLimit-Reset', '1539890344'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/"4a950e02588f33f0012cc792923cb1d1"'), ('Last-Modified', 'Mon, 15 Oct 2018 16:50:55 GMT'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'B18A:4C23:14C9D54:32A299E:5BC8CEC1')] +{"id":153149352,"node_id":"MDEwOlJlcG9zaXRvcnkxNTMxNDkzNTI=","name":"PyGithub","full_name":"zer0tonin/PyGithub","private":false,"owner":{"login":"zer0tonin","id":7149690,"node_id":"MDQ6VXNlcjcxNDk2OTA=","avatar_url":"https://avatars3.githubusercontent.com/u/7149690?v=4","gravatar_id":"","url":"https://api.github.com/users/zer0tonin","html_url":"https://github.com/zer0tonin","followers_url":"https://api.github.com/users/zer0tonin/followers","following_url":"https://api.github.com/users/zer0tonin/following{/other_user}","gists_url":"https://api.github.com/users/zer0tonin/gists{/gist_id}","starred_url":"https://api.github.com/users/zer0tonin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zer0tonin/subscriptions","organizations_url":"https://api.github.com/users/zer0tonin/orgs","repos_url":"https://api.github.com/users/zer0tonin/repos","events_url":"https://api.github.com/users/zer0tonin/events{/privacy}","received_events_url":"https://api.github.com/users/zer0tonin/received_events","type":"User","site_admin":false},"html_url":"https://github.com/zer0tonin/PyGithub","description":"Typed interactions with the GitHub API v3","fork":true,"url":"https://api.github.com/repos/zer0tonin/PyGithub","forks_url":"https://api.github.com/repos/zer0tonin/PyGithub/forks","keys_url":"https://api.github.com/repos/zer0tonin/PyGithub/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zer0tonin/PyGithub/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zer0tonin/PyGithub/teams","hooks_url":"https://api.github.com/repos/zer0tonin/PyGithub/hooks","issue_events_url":"https://api.github.com/repos/zer0tonin/PyGithub/issues/events{/number}","events_url":"https://api.github.com/repos/zer0tonin/PyGithub/events","assignees_url":"https://api.github.com/repos/zer0tonin/PyGithub/assignees{/user}","branches_url":"https://api.github.com/repos/zer0tonin/PyGithub/branches{/branch}","tags_url":"https://api.github.com/repos/zer0tonin/PyGithub/tags","blobs_url":"https://api.github.com/repos/zer0tonin/PyGithub/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zer0tonin/PyGithub/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zer0tonin/PyGithub/git/refs{/sha}","trees_url":"https://api.github.com/repos/zer0tonin/PyGithub/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zer0tonin/PyGithub/statuses/{sha}","languages_url":"https://api.github.com/repos/zer0tonin/PyGithub/languages","stargazers_url":"https://api.github.com/repos/zer0tonin/PyGithub/stargazers","contributors_url":"https://api.github.com/repos/zer0tonin/PyGithub/contributors","subscribers_url":"https://api.github.com/repos/zer0tonin/PyGithub/subscribers","subscription_url":"https://api.github.com/repos/zer0tonin/PyGithub/subscription","commits_url":"https://api.github.com/repos/zer0tonin/PyGithub/commits{/sha}","git_commits_url":"https://api.github.com/repos/zer0tonin/PyGithub/git/commits{/sha}","comments_url":"https://api.github.com/repos/zer0tonin/PyGithub/comments{/number}","issue_comment_url":"https://api.github.com/repos/zer0tonin/PyGithub/issues/comments{/number}","contents_url":"https://api.github.com/repos/zer0tonin/PyGithub/contents/{+path}","compare_url":"https://api.github.com/repos/zer0tonin/PyGithub/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zer0tonin/PyGithub/merges","archive_url":"https://api.github.com/repos/zer0tonin/PyGithub/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zer0tonin/PyGithub/downloads","issues_url":"https://api.github.com/repos/zer0tonin/PyGithub/issues{/number}","pulls_url":"https://api.github.com/repos/zer0tonin/PyGithub/pulls{/number}","milestones_url":"https://api.github.com/repos/zer0tonin/PyGithub/milestones{/number}","notifications_url":"https://api.github.com/repos/zer0tonin/PyGithub/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zer0tonin/PyGithub/labels{/name}","releases_url":"https://api.github.com/repos/zer0tonin/PyGithub/releases{/id}","deployments_url":"https://api.github.com/repos/zer0tonin/PyGithub/deployments","created_at":"2018-10-15T16:50:51Z","updated_at":"2018-10-15T16:50:55Z","pushed_at":"2018-10-18T18:05:03Z","git_url":"git://github.com/zer0tonin/PyGithub.git","ssh_url":"git@github.com:zer0tonin/PyGithub.git","clone_url":"https://github.com/zer0tonin/PyGithub.git","svn_url":"https://github.com/zer0tonin/PyGithub","homepage":"https://pygithub.readthedocs.io/","size":11451,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","spdx_id":"LGPL-3.0","url":"https://api.github.com/licenses/lgpl-3.0","node_id":"MDc6TGljZW5zZTEy"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"parent":{"id":3544490,"node_id":"MDEwOlJlcG9zaXRvcnkzNTQ0NDkw","name":"PyGithub","full_name":"PyGithub/PyGithub","private":false,"owner":{"login":"PyGithub","id":11288996,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExMjg4OTk2","avatar_url":"https://avatars0.githubusercontent.com/u/11288996?v=4","gravatar_id":"","url":"https://api.github.com/users/PyGithub","html_url":"https://github.com/PyGithub","followers_url":"https://api.github.com/users/PyGithub/followers","following_url":"https://api.github.com/users/PyGithub/following{/other_user}","gists_url":"https://api.github.com/users/PyGithub/gists{/gist_id}","starred_url":"https://api.github.com/users/PyGithub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PyGithub/subscriptions","organizations_url":"https://api.github.com/users/PyGithub/orgs","repos_url":"https://api.github.com/users/PyGithub/repos","events_url":"https://api.github.com/users/PyGithub/events{/privacy}","received_events_url":"https://api.github.com/users/PyGithub/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/PyGithub/PyGithub","description":"Typed interactions with the GitHub API v3","fork":false,"url":"https://api.github.com/repos/PyGithub/PyGithub","forks_url":"https://api.github.com/repos/PyGithub/PyGithub/forks","keys_url":"https://api.github.com/repos/PyGithub/PyGithub/keys{/key_id}","collaborators_url":"https://api.github.com/repos/PyGithub/PyGithub/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/PyGithub/PyGithub/teams","hooks_url":"https://api.github.com/repos/PyGithub/PyGithub/hooks","issue_events_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/events{/number}","events_url":"https://api.github.com/repos/PyGithub/PyGithub/events","assignees_url":"https://api.github.com/repos/PyGithub/PyGithub/assignees{/user}","branches_url":"https://api.github.com/repos/PyGithub/PyGithub/branches{/branch}","tags_url":"https://api.github.com/repos/PyGithub/PyGithub/tags","blobs_url":"https://api.github.com/repos/PyGithub/PyGithub/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/PyGithub/PyGithub/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/PyGithub/PyGithub/git/refs{/sha}","trees_url":"https://api.github.com/repos/PyGithub/PyGithub/git/trees{/sha}","statuses_url":"https://api.github.com/repos/PyGithub/PyGithub/statuses/{sha}","languages_url":"https://api.github.com/repos/PyGithub/PyGithub/languages","stargazers_url":"https://api.github.com/repos/PyGithub/PyGithub/stargazers","contributors_url":"https://api.github.com/repos/PyGithub/PyGithub/contributors","subscribers_url":"https://api.github.com/repos/PyGithub/PyGithub/subscribers","subscription_url":"https://api.github.com/repos/PyGithub/PyGithub/subscription","commits_url":"https://api.github.com/repos/PyGithub/PyGithub/commits{/sha}","git_commits_url":"https://api.github.com/repos/PyGithub/PyGithub/git/commits{/sha}","comments_url":"https://api.github.com/repos/PyGithub/PyGithub/comments{/number}","issue_comment_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/comments{/number}","contents_url":"https://api.github.com/repos/PyGithub/PyGithub/contents/{+path}","compare_url":"https://api.github.com/repos/PyGithub/PyGithub/compare/{base}...{head}","merges_url":"https://api.github.com/repos/PyGithub/PyGithub/merges","archive_url":"https://api.github.com/repos/PyGithub/PyGithub/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/PyGithub/PyGithub/downloads","issues_url":"https://api.github.com/repos/PyGithub/PyGithub/issues{/number}","pulls_url":"https://api.github.com/repos/PyGithub/PyGithub/pulls{/number}","milestones_url":"https://api.github.com/repos/PyGithub/PyGithub/milestones{/number}","notifications_url":"https://api.github.com/repos/PyGithub/PyGithub/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/PyGithub/PyGithub/labels{/name}","releases_url":"https://api.github.com/repos/PyGithub/PyGithub/releases{/id}","deployments_url":"https://api.github.com/repos/PyGithub/PyGithub/deployments","created_at":"2012-02-25T12:53:47Z","updated_at":"2018-10-18T11:41:36Z","pushed_at":"2018-10-18T18:05:05Z","git_url":"git://github.com/PyGithub/PyGithub.git","ssh_url":"git@github.com:PyGithub/PyGithub.git","clone_url":"https://github.com/PyGithub/PyGithub.git","svn_url":"https://github.com/PyGithub/PyGithub","homepage":"https://pygithub.readthedocs.io/","size":11426,"stargazers_count":2136,"watchers_count":2136,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":736,"mirror_url":null,"archived":false,"open_issues_count":50,"license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","spdx_id":"LGPL-3.0","url":"https://api.github.com/licenses/lgpl-3.0","node_id":"MDc6TGljZW5zZTEy"},"forks":736,"open_issues":50,"watchers":2136,"default_branch":"master"},"source":{"id":3544490,"node_id":"MDEwOlJlcG9zaXRvcnkzNTQ0NDkw","name":"PyGithub","full_name":"PyGithub/PyGithub","private":false,"owner":{"login":"PyGithub","id":11288996,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExMjg4OTk2","avatar_url":"https://avatars0.githubusercontent.com/u/11288996?v=4","gravatar_id":"","url":"https://api.github.com/users/PyGithub","html_url":"https://github.com/PyGithub","followers_url":"https://api.github.com/users/PyGithub/followers","following_url":"https://api.github.com/users/PyGithub/following{/other_user}","gists_url":"https://api.github.com/users/PyGithub/gists{/gist_id}","starred_url":"https://api.github.com/users/PyGithub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PyGithub/subscriptions","organizations_url":"https://api.github.com/users/PyGithub/orgs","repos_url":"https://api.github.com/users/PyGithub/repos","events_url":"https://api.github.com/users/PyGithub/events{/privacy}","received_events_url":"https://api.github.com/users/PyGithub/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/PyGithub/PyGithub","description":"Typed interactions with the GitHub API v3","fork":false,"url":"https://api.github.com/repos/PyGithub/PyGithub","forks_url":"https://api.github.com/repos/PyGithub/PyGithub/forks","keys_url":"https://api.github.com/repos/PyGithub/PyGithub/keys{/key_id}","collaborators_url":"https://api.github.com/repos/PyGithub/PyGithub/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/PyGithub/PyGithub/teams","hooks_url":"https://api.github.com/repos/PyGithub/PyGithub/hooks","issue_events_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/events{/number}","events_url":"https://api.github.com/repos/PyGithub/PyGithub/events","assignees_url":"https://api.github.com/repos/PyGithub/PyGithub/assignees{/user}","branches_url":"https://api.github.com/repos/PyGithub/PyGithub/branches{/branch}","tags_url":"https://api.github.com/repos/PyGithub/PyGithub/tags","blobs_url":"https://api.github.com/repos/PyGithub/PyGithub/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/PyGithub/PyGithub/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/PyGithub/PyGithub/git/refs{/sha}","trees_url":"https://api.github.com/repos/PyGithub/PyGithub/git/trees{/sha}","statuses_url":"https://api.github.com/repos/PyGithub/PyGithub/statuses/{sha}","languages_url":"https://api.github.com/repos/PyGithub/PyGithub/languages","stargazers_url":"https://api.github.com/repos/PyGithub/PyGithub/stargazers","contributors_url":"https://api.github.com/repos/PyGithub/PyGithub/contributors","subscribers_url":"https://api.github.com/repos/PyGithub/PyGithub/subscribers","subscription_url":"https://api.github.com/repos/PyGithub/PyGithub/subscription","commits_url":"https://api.github.com/repos/PyGithub/PyGithub/commits{/sha}","git_commits_url":"https://api.github.com/repos/PyGithub/PyGithub/git/commits{/sha}","comments_url":"https://api.github.com/repos/PyGithub/PyGithub/comments{/number}","issue_comment_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/comments{/number}","contents_url":"https://api.github.com/repos/PyGithub/PyGithub/contents/{+path}","compare_url":"https://api.github.com/repos/PyGithub/PyGithub/compare/{base}...{head}","merges_url":"https://api.github.com/repos/PyGithub/PyGithub/merges","archive_url":"https://api.github.com/repos/PyGithub/PyGithub/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/PyGithub/PyGithub/downloads","issues_url":"https://api.github.com/repos/PyGithub/PyGithub/issues{/number}","pulls_url":"https://api.github.com/repos/PyGithub/PyGithub/pulls{/number}","milestones_url":"https://api.github.com/repos/PyGithub/PyGithub/milestones{/number}","notifications_url":"https://api.github.com/repos/PyGithub/PyGithub/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/PyGithub/PyGithub/labels{/name}","releases_url":"https://api.github.com/repos/PyGithub/PyGithub/releases{/id}","deployments_url":"https://api.github.com/repos/PyGithub/PyGithub/deployments","created_at":"2012-02-25T12:53:47Z","updated_at":"2018-10-18T11:41:36Z","pushed_at":"2018-10-18T18:05:05Z","git_url":"git://github.com/PyGithub/PyGithub.git","ssh_url":"git@github.com:PyGithub/PyGithub.git","clone_url":"https://github.com/PyGithub/PyGithub.git","svn_url":"https://github.com/PyGithub/PyGithub","homepage":"https://pygithub.readthedocs.io/","size":11426,"stargazers_count":2136,"watchers_count":2136,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":736,"mirror_url":null,"archived":false,"open_issues_count":50,"license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","spdx_id":"LGPL-3.0","url":"https://api.github.com/licenses/lgpl-3.0","node_id":"MDc6TGljZW5zZTEy"},"forks":736,"open_issues":50,"watchers":2136,"default_branch":"master"},"network_count":736,"subscribers_count":1} + +https +PUT +api.github.com +None +/repos/zer0tonin/PyGithub/notifications +{'Content-Type': 'application/json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +{"last_read_at": "2018-10-18T18:19:43Z"} +205 +[('Server', 'GitHub.com'), ('Date', 'Thu, 18 Oct 2018 18:19:46 GMT'), ('Content-Type', 'text/plain;charset=utf-8'), ('Content-Length', '0'), ('Status', '205 Reset Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4991'), ('X-RateLimit-Reset', '1539890344'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', 'notifications, repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'B18C:4C25:2AA2E23:5885386:5BC8CEC1')] + + diff --git a/github/tests/Repository.py b/github/tests/Repository.py index 7fe24767..27b71c62 100644 --- a/github/tests/Repository.py +++ b/github/tests/Repository.py @@ -500,6 +500,10 @@ class Repository(Framework.TestCase): self.assertListKeyEqual(issues[0].labels, lambda l: l.name, ["Functionalities", "RequestedByUser"]) self.assertEqual(issues[0].state, "open") + def testMarkNotificationsAsRead(self): + repo = self.g.get_user().get_repo("PyGithub") + repo.mark_notifications_as_read(datetime.datetime(2018, 10, 18, 18, 19, 43, 0)) + def testAssignees(self): lyloa = self.g.get_user("Lyloa") jacquev6 = self.g.get_user("jacquev6")