forked from sigmavirus24/github3.py
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontents.py
More file actions
214 lines (168 loc) · 7.04 KB
/
Copy pathcontents.py
File metadata and controls
214 lines (168 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# -*- coding: utf-8 -*-
"""This module contains the Contents object."""
from __future__ import unicode_literals
from base64 import b64decode, b64encode
from json import dumps
from .. import models
from ..decorators import requires_auth
from ..git import Commit
class Contents(models.GitHubCore):
"""A representation of file contents returned via the API.
See also: http://developer.github.com/v3/repos/contents/
This object has the following attributes:
.. attribute:: content
The body of the file. If this is present, it may be base64 encoded.
.. attribute:: encoding
The encoding used on the :attr:`content` when returning the data from
the API, e.g., ``base64``. If :attr:`content` is not present this will
not be present either.
.. attribute:: decoded
.. note:: This is a computed attribute which isn't returned by the API.
.. versionchanged:: 0.5.2
Decoded content of the file as a bytes object. If we try to decode
to character set for you, we might encounter an exception which
will prevent the object from being created. On python2 this is the
same as a string, but on python3 you should call the decode method
with the character set you wish to use, e.g.,
``content.decoded.decode('utf-8')``.
.. attribute:: git_url
The URL for the Git API pertaining to this file.
.. attribute:: html_url
The URL to open this file in a browser.
.. attribute:: links
A dictionary of links returned about the contents and related
resources.
.. attribute:: name
The name of the file.
.. attribute:: path
The path to this file.
.. attribute:: sha
The SHA1 of the contents of this file.
.. attribute:: size
The size of file in bytes.
.. attribute:: submodule_git_url
The URL of the git submodule (if this is a git submodule).
.. attribute:: target
If the file is a symlink, this will be present and provides the type
of file that the symlink points to.
.. attribute:: type
Type of content, e.g., ``'file'``, ``'symlink'``, or ``'submodule'``.
"""
def _update_attributes(self, content):
self._api = content["url"]
self.content = content.get("content")
self.encoding = content.get("encoding")
self.decoded = self.content
if self.encoding == "base64" and self.content:
self.decoded = b64decode(self.content.encode())
self.download_url = content["download_url"]
self.git_url = content["git_url"]
self.html_url = content["html_url"]
self.links = content["_links"]
self.name = content["name"]
self.path = content["path"]
self._uniq = self.sha = content["sha"]
self.size = content["size"]
self.submodule_git_url = content.get("submodule_git_url")
self.target = content.get("target")
self.type = content["type"]
def _repr(self):
return "<Contents [{0}]>".format(self.path)
def __eq__(self, other):
return self.decoded == other
def __ne__(self, other):
return self.sha != other
@requires_auth
def delete(self, message, branch=None, committer=None, author=None):
"""Delete this file.
:param str message:
(required), commit message to describe the removal
:param str branch:
(optional), branch where the file exists.
Defaults to the default branch of the repository.
:param dict committer:
(optional), if no information is given the authenticated user's
information will be used. You must specify both a name and email.
:param dict author:
(optional), if omitted this will be filled in with committer
information. If passed, you must specify both a name and email.
:returns:
dictionary of new content and associated commit
:rtype:
:class:`~github3.repos.contents.Contents` and
:class:`~github3.git.Commit`
"""
json = {}
if message:
data = {
"message": message,
"sha": self.sha,
"branch": branch,
"committer": validate_commmitter(committer),
"author": validate_commmitter(author),
}
self._remove_none(data)
json = self._json(self._delete(self._api, data=dumps(data)), 200)
if json and "commit" in json:
json["commit"] = Commit(json["commit"], self)
if json and "content" in json:
json["content"] = self._instance_or_null(
Contents, json["content"]
)
return json
@requires_auth
def update(
self, message, content, branch=None, committer=None, author=None
):
"""Update this file.
:param str message:
(required), commit message to describe the update
:param str content:
(required), content to update the file with
:param str branch:
(optional), branch where the file exists.
Defaults to the default branch of the repository.
:param dict committer:
(optional), if no information is given the authenticated user's
information will be used. You must specify both a name and email.
:param dict author:
(optional), if omitted this will be filled in with committer
information. If passed, you must specify both a name and email.
:returns:
dictionary containing the updated contents object and the
commit in which it was changed.
:rtype:
dictionary of :class:`~github3.repos.contents.Contents` and
:class:`~github3.git.Commit`
"""
if content and not isinstance(content, bytes):
raise ValueError( # (No coverage)
"content must be a bytes object"
) # (No coverage)
json = None
if message and content:
content = b64encode(content).decode("utf-8")
data = {
"message": message,
"content": content,
"branch": branch,
"sha": self.sha,
"committer": validate_commmitter(committer),
"author": validate_commmitter(author),
}
self._remove_none(data)
json = self._json(self._put(self._api, data=dumps(data)), 200)
if json and "content" in json:
self._update_attributes(json["content"])
json["content"] = self
if json and "commit" in json:
json["commit"] = Commit(json["commit"], self)
return json
def validate_commmitter(d):
"""Validate that there are enough details in the dictionary.
When sending data to GitHub, we need to ensure we're sending the name and
email for committer and author data.
"""
if d and d.get("name") and d.get("email"):
return d
return None