Skip to content

Commit 5aa47f1

Browse files
committed
Update github3.repos.contents for consistency
1 parent fca45b0 commit 5aa47f1

File tree

6 files changed

+154
-105
lines changed

6 files changed

+154
-105
lines changed

github3/pulls.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
from . import models
1010
from . import users
1111
from .repos import commit as rcommit
12+
from .repos import contents
1213
from .decorators import requires_auth
1314
from .issues import Issue
1415
from .issues.comment import IssueComment
15-
from .repos.contents import Contents
1616

1717

1818
class PullDestination(models.GitHubCore):
@@ -170,10 +170,10 @@ def contents(self):
170170
:returns:
171171
An object representing the contents of this file
172172
:rtype:
173-
:class:`Contents <github3.repos.contents.Contents>`
173+
:class:`~github3.repos.contents.Contents`
174174
"""
175175
json = self._json(self._get(self.contents_url), 200)
176-
return self._instance_or_null(Contents, json)
176+
return self._instance_or_null(contents.Contents, json)
177177

178178

179179
class _PullRequest(models.GitHubCore):

github3/repos/contents.py

Lines changed: 118 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,109 @@
11
# -*- coding: utf-8 -*-
2-
"""
3-
github3.repos.contents
4-
======================
5-
6-
This module contains the Contents object pertaining to READMEs and other files
7-
that can be accessed via the GitHub API.
8-
9-
"""
2+
"""This module contains the Contents object."""
103
from __future__ import unicode_literals
114

125
from base64 import b64decode, b64encode
136
from json import dumps
147

8+
from .. import models
9+
1510
from ..decorators import requires_auth
1611
from ..git import Commit
17-
from ..models import GitHubCore
1812

1913

20-
class Contents(GitHubCore):
21-
"""The :class:`Contents <Contents>` object. It holds the information
22-
concerning any content in a repository requested via the API.
14+
class Contents(models.GitHubCore):
15+
"""A representation of file contents returned via the API.
16+
17+
See also: http://developer.github.com/v3/repos/contents/
2318
24-
Two content instances can be checked like so::
19+
This object has the following attributes:
2520
26-
c1 == c2
27-
c1 != c2
21+
.. attribute:: content
2822
29-
And is equivalent to::
23+
The body of the file. If this is present, it may be base64 encoded.
3024
31-
c1.sha == c2.sha
32-
c1.sha != c2.sha
25+
.. attribute:: encoding
3326
34-
See also: http://developer.github.com/v3/repos/contents/
27+
The encoding used on the :attr:`content` when returning the data from
28+
the API, e.g., ``base64``. If :attr:`content` is not present this will
29+
not be present either.
30+
31+
.. attribute:: decoded
32+
33+
.. note:: This is a computed attribute which isn't returned by the API.
34+
.. versionchanged:: 0.5.2
35+
36+
Decoded content of the file as a bytes object. If we try to decode
37+
to character set for you, we might encounter an exception which
38+
will prevent the object from being created. On python2 this is the
39+
same as a string, but on python3 you should call the decode method
40+
with the character set you wish to use, e.g.,
41+
``content.decoded.decode('utf-8')``.
42+
43+
.. attribute:: git_url
44+
45+
The URL for the Git API pertaining to this file.
46+
47+
.. attribute:: html_url
48+
49+
The URL to open this file in a browser.
50+
51+
.. attribute:: links
52+
53+
A dictionary of links returned about the contents and related
54+
resources.
55+
56+
.. attribute:: name
57+
58+
The name of the file.
59+
60+
.. attribute:: path
61+
62+
The path to this file.
63+
64+
.. attribute:: sha
65+
66+
The SHA1 of the contents of this file.
67+
68+
.. attribute:: size
69+
70+
The size of file in bytes.
71+
72+
.. attribute:: submodule_git_url
73+
74+
The URL of the git submodule (if this is a git submodule).
75+
76+
.. attribute:: target
77+
78+
If the file is a symlink, this will be present and provides the type
79+
of file that the symlink points to.
80+
81+
.. attribute:: type
82+
83+
Type of content, e.g., ``'file'``, ``'symlink'``, or ``'submodule'``.
3584
"""
3685

3786
def _update_attributes(self, content):
38-
# links
39-
self._api = self._get_attribute(content, 'url')
40-
41-
#: Dictionary of links
42-
self.links = self._get_attribute(content, '_links')
43-
44-
#: URL of the README on github.com
45-
self.html_url = self._get_attribute(content, 'html_url')
46-
47-
#: URL for the git api pertaining to the README
48-
self.git_url = self._get_attribute(content, 'git_url')
49-
50-
#: git:// URL of the content if it is a submodule
51-
self.submodule_git_url = self._get_attribute(
52-
content, 'submodule_git_url'
53-
)
54-
55-
# should always be 'base64'
56-
#: Returns encoding used on the content.
57-
self.encoding = self._get_attribute(content, 'encoding')
58-
59-
# content, base64 encoded and decoded
60-
#: Base64-encoded content of the file.
61-
self.content = self._get_attribute(content, 'content')
62-
63-
#: Decoded content of the file as a bytes object. If we try to decode
64-
#: to character set for you, we might encounter an exception which
65-
#: will prevent the object from being created. On python2 this is the
66-
#: same as a string, but on python3 you should call the decode method
67-
#: with the character set you wish to use, e.g.,
68-
#: ``content.decoded.decode('utf-8')``.
69-
#: .. versionchanged:: 0.5.2
87+
self._api = content['url']
88+
self.content = content.get('content')
89+
self.encoding = content.get('encoding')
7090
self.decoded = self.content
7191
if self.encoding == 'base64' and self.content:
7292
self.decoded = b64decode(self.content.encode())
73-
74-
# file name, path, and size
75-
#: Name of the content.
76-
self.name = self._get_attribute(content, 'name')
77-
#: Path to the content.
78-
self.path = self._get_attribute(content, 'path')
79-
#: Size of the content
80-
self.size = self._get_attribute(content, 'size')
81-
#: SHA string.
82-
self.sha = self._get_attribute(content, 'sha')
83-
#: Type of content. ('file', 'symlink', 'submodule')
84-
self.type = self._get_attribute(content, 'type')
85-
#: Target will only be set of type is a symlink. This is what the link
86-
#: points to
87-
self.target = self._get_attribute(content, 'target')
88-
89-
self._uniq = self.sha
93+
self.download_url = content['download_url']
94+
self.git_url = content['git_url']
95+
self.html_url = content['html_url']
96+
self.links = content['_links']
97+
self.name = content['name']
98+
self.path = content['path']
99+
self._uniq = self.sha = content['sha']
100+
self.size = content['size']
101+
self.submodule_git_url = content.get('submodule_git_url')
102+
self.target = content.get('target')
103+
self.type = content['type']
90104

91105
def _repr(self):
92-
return '<Content [{0}]>'.format(self.path)
106+
return '<Contents [{0}]>'.format(self.path)
93107

94108
def __eq__(self, other):
95109
return self.decoded == other
@@ -101,17 +115,21 @@ def __ne__(self, other):
101115
def delete(self, message, branch=None, committer=None, author=None):
102116
"""Delete this file.
103117
104-
:param str message: (required), commit message to describe the removal
105-
:param str branch: (optional), branch where the file exists.
118+
:param str message:
119+
(required), commit message to describe the removal
120+
:param str branch:
121+
(optional), branch where the file exists.
106122
Defaults to the default branch of the repository.
107-
:param dict committer: (optional), if no information is given the
108-
authenticated user's information will be used. You must specify
109-
both a name and email.
110-
:param dict author: (optional), if omitted this will be filled in with
111-
committer information. If passed, you must specify both a name and
112-
email.
113-
:returns: dictionary of new content and associated commit
114-
:rtype: :class:`~github3.repos.contents.Contents` and
123+
:param dict committer:
124+
(optional), if no information is given the authenticated user's
125+
information will be used. You must specify both a name and email.
126+
:param dict author:
127+
(optional), if omitted this will be filled in with committer
128+
information. If passed, you must specify both a name and email.
129+
:returns:
130+
dictionary of new content and associated commit
131+
:rtype:
132+
:class:`~github3.repos.contents.Contents` and
115133
:class:`~github3.git.Commit`
116134
"""
117135
json = {}
@@ -133,19 +151,24 @@ def update(self, message, content, branch=None, committer=None,
133151
author=None):
134152
"""Update this file.
135153
136-
:param str message: (required), commit message to describe the update
137-
:param str content: (required), content to update the file with
138-
:param str branch: (optional), branch where the file exists.
154+
:param str message:
155+
(required), commit message to describe the update
156+
:param str content:
157+
(required), content to update the file with
158+
:param str branch:
159+
(optional), branch where the file exists.
139160
Defaults to the default branch of the repository.
140-
:param dict committer: (optional), if no information is given the
141-
authenticated user's information will be used. You must specify
142-
both a name and email.
143-
:param dict author: (optional), if omitted this will be filled in with
144-
committer information. If passed, you must specify both a name and
145-
email.
146-
:returns: dictionary containing the updated contents object and the
161+
:param dict committer:
162+
(optional), if no information is given the authenticated user's
163+
information will be used. You must specify both a name and email.
164+
:param dict author:
165+
(optional), if omitted this will be filled in with committer
166+
information. If passed, you must specify both a name and email.
167+
:returns:
168+
dictionary containing the updated contents object and the
147169
commit in which it was changed.
148-
:rtype: dictionary of :class:`~github3.repos.contents.Contents` and
170+
:rtype:
171+
dictionary of :class:`~github3.repos.contents.Contents` and
149172
:class:`~github3.git.Commit`
150173
"""
151174
if content and not isinstance(content, bytes):
@@ -170,6 +193,11 @@ def update(self, message, content, branch=None, committer=None,
170193

171194

172195
def validate_commmitter(d):
196+
"""Validate that there are enough details in the dictionary.
197+
198+
When sending data to GitHub, we need to ensure we're sending the name and
199+
email for committer and author data.
200+
"""
173201
if d and d.get('name') and d.get('email'):
174202
return d
175203
return None

github3/repos/repo.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
from ..utils import stream_response_to_file, timestamp_parameter
3030
from . import branch
3131
from . import commit
32+
from . import contents
3233
from .comment import RepoComment
3334
from .comparison import Comparison
34-
from .contents import Contents, validate_commmitter
3535
from .deployment import Deployment
3636
from .hook import Hook
3737
from .issue_import import ImportedIssue
@@ -530,7 +530,7 @@ def create_file(self, path, message, content, branch=None,
530530
committer information. If passed, you must specify both a name and
531531
email.
532532
:returns: {
533-
'content': :class:`Contents <github3.repos.contents.Contents>`:,
533+
'content': :class:`~github3.repos.contents.Contents`,
534534
'commit': :class:`Commit <github3.git.Commit>`}
535535
536536
"""
@@ -543,12 +543,14 @@ def create_file(self, path, message, content, branch=None,
543543
url = self._build_url('contents', path, base_url=self._api)
544544
content = b64encode(content).decode('utf-8')
545545
data = {'message': message, 'content': content, 'branch': branch,
546-
'committer': validate_commmitter(committer),
547-
'author': validate_commmitter(author)}
546+
'committer': contents.validate_commmitter(committer),
547+
'author': contents.validate_commmitter(author)}
548548
self._remove_none(data)
549549
json = self._json(self._put(url, data=dumps(data)), 201)
550550
if json and 'content' in json and 'commit' in json:
551-
json['content'] = Contents(json['content'], self)
551+
json['content'] = contents.Contents(
552+
json['content'], self
553+
)
552554
json['commit'] = Commit(json['commit'], self)
553555
return json
554556

@@ -952,7 +954,8 @@ def directory_contents(self, directory_path, ref=None, return_as=list):
952954
"""
953955
url = self._build_url('contents', directory_path, base_url=self._api)
954956
json = self._json(self._get(url, params={'ref': ref}), 200) or []
955-
return return_as((j.get('name'), Contents(j, self)) for j in json)
957+
return return_as((j.get('name'), contents.Contents(j, self))
958+
for j in json)
956959

957960
@requires_auth
958961
def edit(self, name, description=None, homepage=None, private=None,
@@ -1022,7 +1025,7 @@ def file_contents(self, path, ref=None):
10221025
"""
10231026
url = self._build_url('contents', path, base_url=self._api)
10241027
json = self._json(self._get(url, params={'ref': ref}), 200)
1025-
return self._instance_or_null(Contents, json)
1028+
return self._instance_or_null(contents.Contents, json)
10261029

10271030
def forks(self, sort='', number=-1, etag=None):
10281031
"""Iterate over forks of this repository.
@@ -1590,7 +1593,7 @@ def readme(self):
15901593
"""
15911594
url = self._build_url('readme', base_url=self._api)
15921595
json = self._json(self._get(url), 200)
1593-
return self._instance_or_null(Contents, json)
1596+
return self._instance_or_null(contents.Contents, json)
15941597

15951598
def ref(self, ref):
15961599
"""Get a reference pointed to by ``ref``.

tests/cassettes/PullFile_contents.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy