8000 Merge pull request #540 from itsmemattchung/issue/497 · pythonthings/github3.py@b79a174 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit b79a174

Browse files
committed
Merge pull request sigmavirus24#540 from itsmemattchung/issue/497
Initial commit for implementing ImportIssue Beta API
2 parents b250397 + ffd11d1 commit b79a174

File tree

9 files changed

+248
-2
lines changed

9 files changed

+248
-2
lines changed

docs/examples/issue.r 8000 st

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,32 @@ Or how to do the same by wrapping the lines in your terminal.
4949

5050
.. literalinclude:: source/wrap_text.py
5151
:language: python
52+
53+
Importing an issue
54+
------------------
55+
56+
Not only can you create new issues, but you can import existing ones. When importing, you preserve the timestamp creation date; you can preserve the timestamp(s) for comment(s) too.
57+
58+
::
59+
60+
import github3
61+
gh = github3.login(token=token)
62+
issue = {
63+
'title': 'Documentation issue',
64+
'body': 'Missing links in index.html',
65+
'created_at': '2011-03-11T17:00:40Z'
66+
}
67+
68+
repository = gh.repository(user, repo)
69+
repository.import_issue(**issue)
70+
71+
Status of imported issue
72+
~~~~~~~~~~~~~~~~~~~~~~~~
73+
74+
Here's how to check the status of the imported issue.
75+
76+
::
77+
78+
import github3
79+
issue = repository.imported_issue(issue_num)
80+
print issue.status

docs/repos.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This part of the documentation covers:
1212
- :class:`Deployment <github3.repos.deployment.Deployment>`
1313
- :class:`DeploymentStatus <github3.repos.deployment.DeploymentStatus>`
1414
- :class:`Hook <github3.repos.hook.Hook>`
15+
- :class:`ImportedIssue <github3.repos.issue_import.ImportedIssue>`
1516
- :class:`PagesInfo <github3.repos.pages.PagesInfo>`
1617
- :class:`PagesBuild <github3.repos.pages.PagesBuild>`
1718
- :class:`Release <github3.repos.release.Release>`
@@ -89,6 +90,13 @@ Repository Objects
8990

9091
---------
9192

93+
.. module:: github3.repos.imported_issue
94+
95+
.. autoclass:: github3.repos.issue_import.ImportedIssue
96+
:members:
97+
98+
---------
99+
92100
.. module:: github3.repos.pages
93101

94102
.. autoclass:: github3.repos.pages.PagesInfo

github3/repos/issue_import.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff 67E6 line change
@@ -0,0 +1,35 @@
1+
# -*- coding: utf-8 -*-
2+
from ..models import GitHubCore
3+
"""
4+
github3.repos.issue_import
5+
==========================
6+
7+
This module contains the ImportedIssue object for Github's import issue API
8+
9+
"""
10+
11+
12+
class ImportedIssue(GitHubCore):
13+
"""
14+
The :class:`ImportedIssue <ImportedIssue>` object. This represents
15+
information from the Import Issue API.
16+
17+
See also: https://gist.github.com/jonmagic/5282384165e0f86ef105
18+
"""
19+
20+
IMPORT_CUSTOM_HEADERS = {
21+
'Accept': 'application/vnd.github.golden-comet-preview+json'
22+
}
23+
24+
def _update_attributes(self, json):
25+
self.id = json.get('id', None)
26+
self.status = json.get('status', None)
27+
self.url = json.get('url', None)
28+
# Since created_at and updated_at returns slightly different format
29+
# we can't use self._strptime
30+
# For example, repo correctly returns '2015-04-15T03:40:51Z'
31+
# For ImportedIssue, the format is '2016-01-14T10:57:56-08:00'
32+
self.created_at = json.get('created_at', None)
33+
self.updated_at = json.get('updated_at', None)
34+
self.import_issues_url = json.get('import_issues_url')
35+
self.repository_url = json.get('repository_url', None)

github3/repos/repo.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from .contents import Contents, validate_commmitter
2929
from .deployment import Deployment
3030
from .hook import Hook
31+
from .issue_import import ImportedIssue
3132
from ..licenses import License
3233
from .pages import PagesBuild, PagesInfo
3334
from .status import Status
@@ -1264,6 +1265,63 @@ def ignore(self):
12641265
json = self._json(self._put(url, data=dumps({'ignored': True})), 200)
12651266
return self._instance_or_null(Subscription, json)
12661267

1268+
@requires_auth
1269+
def imported_issue(self, imported_issue_id):
1270+
"""Retrieve imported issue specified by imported issue id.
1271+
1272+
:param int imported_issue_id: (required) id of imported issue
1273+
:returns: :class:`Imported Issue <github3.repos.
1274+
issue_import.ImportedIssue>`
1275+
"""
1276+
url = self._build_url('import/issues', imported_issue_id,
1277+
base_url=self._api)
1278+
data = self._get(url, headers=ImportedIssue.IMPORT_CUSTOM_HEADERS)
1279+
json = self._json(data, 200)
1280+
return self._instance_or_null(ImportedIssue, json)
1281+
1282+
@requires_auth
1283+
def import_issue(self, title, body, created_at, assignee=None,
1284+
milestone=None, closed=None, labels=None, comments=None):
1285+
"""Import an issue into the repository.
1286+
1287+
See also: https://gist.github.com/jonmagic/5282384165e0f86ef105
1288+
1289+
:param string title: (required) Title of issue
1290+
:param string body: (required) Body of issue
1291+
:param timestamp created_at: (required) Creation timestamp
1292+
:param string assignee: (optional) Username to assign issue to
1293+
:param int milestone: (optional) Milestone ID
1294+
:param boolean closed: (optional) Status of issue is Closed if True
1295+
:param list labels: (optional) List of labels containing string names
1296+
:param list comments: (optional) List of dictionaries which contain
1297+
created_at and body attributes
1298+
:returns: :class:`ImportedIssue <github3.repos.
1299+
issue_import.ImportedIssue>`
1300+
"""
1301+
1302+
issue = {
1303+
'issue': {
1304+
'title': title,
1305+
'body': body,
1306+
'created_at': created_at,
1307+
'assignee': assignee,
1308+
'milestone': milestone,
1309+
'closed': closed,
1310+
'labels': labels,
1311+
},
1312+
'comments': comments
1313+
}
1314+
1315+
self._remove_none(issue)
1316+
self._remove_none(issue['issue'])
1317+
url = self._build_url('import/issues', base_url=self._api)
1318+
1319+
data = self._post(url, data=issue,
1320+
headers=ImportedIssue.IMPORT_CUSTOM_HEADERS)
1321+
1322+
json = self._json(data, 200)
1323+
return self._instance_or_null(ImportedIssue, json)
1324+
12671325
def is_assignee(self, username):
12681326
"""Check if the user can be assigned an issue on this repository.
12691327
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "token <AUTH_TOKEN>"}, "method": "GET", "uri": "https://api.github.com/repos/github3py/test_rename1"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA+2Yz27jNhDG30XXumYcb7a7BortG/TSUy8GLdESEYkUSMpGIuTd+w2p/yhkO7wGCAJJ1vz0cThDzrBNZJYc9vtvu93T95+bRPFKJIfECeuORtDdLtkk56Ysj91PuXRFc9rXb2zxkr4qYZJDm5Q6lwqQ4U0Q6Cu7P348716+bxJ+4Y6bY2NKvFU4V9sDY+Gh3QarxgqTauWEcttUV6xhnfWvy5978HLTQQic4MECVssOFKxBs2yqp3BVuRAQfvbvT98867LUV9gv9a5+gg1m5D6PkCr/DAJmLdOuEHAYhvFBg5fWPSjHm7QYGOZVZgSxmAIjssckdUYQRJP90TIjau1pzcmmRtZOavWgtJkpUNrkXMl3/gkUTC0IJOpBEd4EpuKCiHvQNti0rDbywtM3cocRqZAXePczvIUxcO6tpqz8e+IZ8rl04sizipLtzEsrPjaJ1+Dwsn+wQXbdFefLXM7EMJshvc7avA7Q1VzznhwzaEkm0A3/rhGQV7DH4F/FWwyGzFuG/102pEhRftKGO30r01flzTgtm95SXDjBqxjZ3h6cQusoL3p7cKS1jbgrSFdH7TGW9YmgmuoUVqp7wn+VHABQyq2VuRIixnsDo2X9UnoyXKVFFLVHtCxc+XnmeYxQMgflVOpTDAbbGPOMltmCh53DHSO1EZQQM6YR51ihhBiYzsTNtBdJjIGIncth0mNU9gjWdt4sucobnkdBBwYt6NiSc/5+s9ZYzZgRAiKVUEaemuhVbcSQzrDZI8ej3DlSRqYvINZrkvXRT+oQP/6qkrf281VgR5hFezyV4nNJpvvbxcdNsYRo2bgEhyW+g0d4tlvje5XTT3SFekww9AjW/lZzV9BahS/V3IgIyR2BtSeO4mi73baF4L74rYSJS9sAAImbtEClF6Gy7REobSrufFF9JpEZiuxS8yzGrwMDvDCDEUoDYDrzNRrDGHnefgqsZInWU6uoNXWETNFKO3mW6T19xWqSzTjtLytVKja8LDeIVidTifhFz0YTiIpSRLknADAI9OGhrSgFQjnG40YERMtCG5gagX4hO3KHQv/5affy+9M3/P2zezm8/Djsn//FOJo6W3nnZUfv1I0tbmCw6HXBhyt0/P/XcM/aBWrhgba2GO3+Gq0O4XJ5FNFZpSWiaBHsd3/xstyDblpCZ6ErUaMcSA4KYU392Tuun2b7eqobBU/j4ZU7FJ7YQcdHfS3QAwpujyHnkoMzDbVzeDKm9OThVb7K6Uukww4NW2i6xg9V0hjdHcAErboWqvvWRFBotkjt5PeZen+TiTNvSncM9S/iqOLW4SwIUSFMhRHQoQCdDHXNahgLRUwvmdaBcI0ednoA8HWe1B22fZ0njSeF6ydvX+dJ89NOlBOzwyik5f3nSUq4K05cJmvCtPjvVpTdx39kO0E5RxYAAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "x-github-media-type": "github.v3; param=full; format=json", "x-oauth-scopes": "admin:public_key, gist, repo, user", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "x-accepted-oauth-scopes": "repo", "etag": "W/\"c68f5ce7b37c113680b45bf278d8a0e8\"", "cache-control": "private, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "4998", "x-served-by": "2811da37fbdda4367181b328b22b2499", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "3F91CA23:B792:8B05480:5697FC33", "access-control-allow-credentials": "true", "last-modified": "Sat, 04 Apr 2015 15:58:51 GMT", "date": "Thu, 14 Jan 2016 19:51:21 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1452804639"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/github3py/test_rename1"}, "recorded_at": "2016-01-14T19:51:21"}, {"request": {"body": {"string": "{\"issue\": {\"body\": \"bar\", \"title\": \"foo\", \"created_at\": \"2014-03-16T17:15:42Z\"}}", "encoding": "utf-8"}, "headers": {"Content-Length": "80", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.golden-comet-preview+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "token <AUTH_TOKEN>"}, "method": "POST", "uri": "https://api.github.com/repos/github3py/test_rename1/import/issues"}, "response": {"body": {"string": "{\"id\":399790,\"status\":\"pending\",\"url\":\"https://api.github.com/repos/github3py/test_rename1/import/issues/399790\",\"import_issues_url\":\"https://api.github.com/repos/github3py/test_rename1/import/issues\",\"repository_url\":\"https://api.github.com/repos/github3py/test_rename1\",\"created_at\":\"2016-01-14T11:51:21-08:00\",\"updated_at\":\"2016-01-14T11:51:21-08:00\"}", "encoding": "utf-8"}, "headers": {"status": "202 Accepted", "x-accepted-oauth-scopes": "", "content-length": "354", "x-github-media-type": "github.golden-comet-preview; format=json", "x-content-type-options": "nosniff", "content-security-policy": "default-src 'none'", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "x-github-request-id": "3F91CA23:B792:8B05A4D:5697FC39", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "x-ratelimit-remaining": "4997", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-oauth-scopes": "admin:public_key, gist, repo, user", "access-control-allow-credentials": "true", "date": "Thu, 14 Jan 2016 19:51:21 GMT", "x-frame-options": "deny", "access-control-allow-origin": "*", "content-type": "application/json; charset=utf-8", "x-xss-protection": "1; mode=block", "x-ratelimit-reset": "1452804639"}, "status": {"message": "Accepted", "code": 202}, "url": "https://api.github.com/repos/github3py/test_rename1/import/issues"}, "recorded_at": "2016-01-14T19:51:23"}], "recorded_with": "betamax/0.5.0"}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "token <AUTH_TOKEN>"}, "method": "GET", "uri": "https://api.github.com/repos/github3py/test_rename1"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA+2YzW7jNhDH30XXumYUb7a7BortG/TSUy8GLdESEUkUSMpGIuTd+x+S+rBQyHZ4DRAEssT5cTicIWemT2Se7He7b2n69P3nJml4LZJ9YoWxBy3oV5psklNXVYfwqZC27I679o0tBqlLI3Sy75NKFbIBZBwJAs2S/vHjOX35vkn4mVuuD52uMKq0tjV7xvxLs/VSnRE6U40Vjd1mqmYdC9K/zn/uwCt0gBA4wYsFrJUB5KVBM2yuT2nraqGA/+zGz0eeVFWpC+SX+q5OwUYxMp9DyKb4DAJiPVO2FDAYlvFBi5fGPqiOE+mxMOyrzAlisAVa5I+pFISgEG32R8+0aJWjdUeTadlaqZoHVbsSBUrpgjfynX8CBVEDAin1oBJOBKLiDI97UNbL9KzV8syzNzKHFpmQZ1j3M7yFMHD2raWo/HtmGbK5tOLA85qC7cQrIz42idPBYrB7sUF03eXny1jOxbibPrxOSr+O0NVYc5acImhJJtAN+64REFeQx+JfxVsMhsR7hv8hGjKEKD8qza26Femr6l1xejb/SX5hBa9j1Hby4JRKRVnRyYMjjenEXU66umqHMWwIhKarj/6kusf9V8keAE25MbJohIix3sjo2XCUHjVvsjKKOiB65p/cPvMiRlESB+VYqWMMBtcYc4yemZL7m8MeInUjKCGumFqcYhUlxMi0Om6nnZLEGIm4uSw2PUbLAcH6YM2KN0XHiyjoyKADHVdywd9v5hqrETNBQKQUSstjF32qTRjS01/2iPEoc06UiekSiPWcZH31szzErb+u5a37fBUYCFfeHk8l/1yS6fft5OOmsoTo2XQE+yM+wCMsG874Qcv5FCFRj3GGAcH631puSzqrMFPLtYhQORBYf+RIjrbbbV8K7pLfWui4sPUAkLjOSmR6EVr2AwKpTc2tS6pPpGSOJLtSPI+x68gAz+9ghKYeMN/5FoVhjHpOfg6sZYXSUzVRZ+oEmaMbZeVJZvfUFatBdsXpfxnZZGLDq2oDb7Uyk/Bf1Gy0gcgoRZR5PACLQB3uy4pKwJVjLK6FR/TMl4GZFqgX8gO3SPSfn9KX35++4e+f9GX/8mO/e/4X6+jafGXMS0pj2s6UNzA49ILz4QkV//8V3FflApXwQBtTTnJ/TVJ7/7hsRQSprIIXLZz97hnPyzvopiT0LFUtWqQDyb6BW1N99o7np6t7PVNdA0vj5YVbJJ64QadXQy4wAEpuDj7mkr3VHZVzeDOF9OzlRb7K+SDSw4wFmy+6polqqbUKDRivq2pFE+YaFEqpcUHFFmk7+45GzqS9+5iLE+8qe/D5L/yo5saiFwSvELrGCqgpQJ2hUKz6tZDHDCrTOeCfUcPOGwBf/aTQbPvqJ02dwvXO21c/6brbiXTiqhmFsLy/n9QIe8EhMDuk5sl/OFHSj/8AY3HIZUcWAAA=", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "x-github-media-type": "github.v3; param=full; format=json", "x-oauth-scopes": "admin:public_key, gist, repo, user", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "x-accepted-oauth-scopes": "repo", "etag": "W/\"e619b5d14c30e3dcd78e53e65820ff71\"", "cache-control": "private, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "4991", "x-served-by": "2d7a5e35115884240089368322196939", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "5693B1BF:B791:A5B6F5A:569CF6B6", "access-control-allow-credentials": "true", "last-modified": "Sat, 04 Apr 2015 15:58:51 GMT", "date": "Mon, 18 Jan 2016 14:29:10 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1453130309"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/github3py/test_rename1"}, "recorded_at": "2016-01-18T14:29:10"}, {"request": {"body": {"string": "{\"issue\": {\"body\": \"bar\", \"title\": \"foo\", \"created_at\": \"2014-03-16T17:15:42Z\"}, \"comments\": [{\"body\": \"fake comments\"}]}", "encoding": "utf-8"}, "headers": {"Content-Length": "121", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.golden-comet-preview+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "token <AUTH_TOKEN>"}, "method": "POST", "uri": "https://api.github.com/repos/github3py/test_rename1/import/issues"}, "response": {"body": {"string": "{\"id\":400916,\"status\":\"pending\",\"url\":\"https://api.github.com/repos/github3py/test_rename1/import/issues/400916\",\"import_issues_url\":\"https://api.github.com/repos/github3py/test_rename1/import/issues\",\"repository_url\":\"https://api.github.com/repos/github3py/test_rename1\",\"created_at\":\"2016-01-18T14:29:10+00:00\",\"updated_at\":\"2016-01-18T14:29:10+00:00\"}", "encoding": "utf-8"}, "headers": {"status": "202 Accepted", "x-accepted-oauth-scopes": "", "content-length": "354", "x-github-media-type": "github.golden-comet-preview; format=json", "x-content-type-options": "nosniff", "content-security-policy": "default-src 'none'", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "x-github-request-id": "5693B1BF:B791:A5B6F9E:569CF6B6", "strict-transport-security": "max-ag 3857 e=31536000; includeSubdomains; preload", "x-ratelimit-remaining": "4990", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-oauth-scopes": "admin:public_key, gist, repo, user", "access-control-allow-credentials": "true", "date": "Mon, 18 Jan 2016 14:29:10 GMT", "x-frame-options": "deny", "access-control-allow-origin": "*", "content-type": "application/json; charset=utf-8", "x-xss-protection": "1; mode=block", "x-ratelimit-reset": "1453130309"}, "status": {"message": "Accepted", "code": 202}, "url": "https://api.github.com/repos/github3py/test_rename1/import/issues"}, "recorded_at": "2016-01-18T14:29:10"}], "recorded_with": "betamax/0.5.0"}

0 commit comments

Comments
 (0)
0