1
1
# -*- 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."""
10
3
from __future__ import unicode_literals
11
4
12
5
from base64 import b64decode, b64encode
13
6
from json import dumps
14
7
8
+ from .. import models
9
+
15
10
from ..decorators import requires_auth
16
11
from ..git import Commit
17
- from ..models import GitHubCore
18
12
19
13
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/
23
18
24
- Two content instances can be checked like so: :
19
+ This object has the following attributes :
25
20
26
- c1 == c2
27
- c1 != c2
21
+ .. attribute:: content
28
22
29
- And is equivalent to::
23
+ The body of the file. If this is present, it may be base64 encoded.
30
24
31
- c1.sha == c2.sha
32
- c1.sha != c2.sha
25
+ .. attribute:: encoding
33
26
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'``.
35
84
"""
36
85
37
86
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')
70
90
self.decoded = self.content
71
91
if self.encoding == 'base64' and self.content:
72
92
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']
90
104
91
105
def _repr(self):
92
- return '<Content [{0}]>'.format(self.path)
106
+ return '<Contents [{0}]>'.format(self.path)
93
107
94
108
def __eq__(self, other):
95
109
return self.decoded == other
@@ -101,17 +115,21 @@ def __ne__(self, other):
101
115
def delete(self, message, branch=None, committer=None, author=None):
102
116
"""Delete this file.
103
117
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.
106
122
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
115
133
:class:`~github3.git.Commit`
116
134
"""
117
135
json = {}
@@ -133,19 +151,24 @@ def update(self, message, content, branch=None, committer=None,
133
151
author=None):
134
152
"""Update this file.
135
153
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.
139
160
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
147
169
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
149
172
:class:`~github3.git.Commit`
150
173
"""
151
174
if content and not isinstance(content, bytes):
@@ -170,6 +193,11 @@ def update(self, message, content, branch=None, committer=None,
170
193
171
194
172
195
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
+ """
173
201
if d and d.get('name') and d.get('email'):
174
202
return d
175
203
return None
0 commit comments