]>
Commit | Line | Data |
---|---|---|
db56f281 S |
1 | #!/usr/bin/env python |
2 | from __future__ import unicode_literals | |
3 | ||
4 | import base64 | |
5 | import json | |
6 | import mimetypes | |
7 | import netrc | |
8 | import optparse | |
9 | import os | |
10 | import sys | |
11 | ||
12 | sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
13 | ||
14 | from youtube_dl.compat import ( | |
15 | compat_basestring, | |
16 | compat_input, | |
17 | compat_getpass, | |
18 | compat_print, | |
19 | compat_urllib_request, | |
20 | ) | |
21 | from youtube_dl.utils import ( | |
22 | make_HTTPS_handler, | |
23 | sanitized_Request, | |
24 | ) | |
25 | ||
26 | ||
27 | class GitHubReleaser(object): | |
28 | _API_URL = 'https://api.github.com/repos/rg3/youtube-dl/releases' | |
29 | _UPLOADS_URL = 'https://uploads.github.com/repos/rg3/youtube-dl/releases/%s/assets?name=%s' | |
30 | _NETRC_MACHINE = 'github.com' | |
31 | ||
32 | def __init__(self, debuglevel=0): | |
33 | self._init_github_account() | |
34 | https_handler = make_HTTPS_handler({}, debuglevel=debuglevel) | |
35 | self._opener = compat_urllib_request.build_opener(https_handler) | |
36 | ||
37 | def _init_github_account(self): | |
38 | try: | |
39 | info = netrc.netrc().authenticators(self._NETRC_MACHINE) | |
40 | if info is not None: | |
41 | self._username = info[0] | |
42 | self._password = info[2] | |
43 | compat_print('Using GitHub credentials found in .netrc...') | |
44 | return | |
45 | else: | |
46 | compat_print('No GitHub credentials found in .netrc') | |
47 | except (IOError, netrc.NetrcParseError): | |
48 | compat_print('Unable to parse .netrc') | |
49 | self._username = compat_input( | |
50 | 'Type your GitHub username or email address and press [Return]: ') | |
51 | self._password = compat_getpass( | |
52 | 'Type your GitHub password and press [Return]: ') | |
53 | ||
54 | def _call(self, req): | |
55 | if isinstance(req, compat_basestring): | |
56 | req = sanitized_Request(req) | |
57 | # Authorizing manually since GitHub does not response with 401 with | |
58 | # WWW-Authenticate header set (see | |
59 | # https://developer.github.com/v3/#basic-authentication) | |
60 | b64 = base64.b64encode( | |
61 | ('%s:%s' % (self._username, self._password)).encode('utf-8')).decode('ascii') | |
62 | req.add_header('Authorization', 'Basic %s' % b64) | |
63 | response = self._opener.open(req).read().decode('utf-8') | |
64 | return json.loads(response) | |
65 | ||
66 | def list_releases(self): | |
67 | return self._call(self._API_URL) | |
68 | ||
69 | def create_release(self, tag_name, name=None, body='', draft=False, prerelease=False): | |
70 | data = { | |
71 | 'tag_name': tag_name, | |
72 | 'target_commitish': 'master', | |
73 | 'name': name, | |
74 | 'body': body, | |
75 | 'draft': draft, | |
76 | 'prerelease': prerelease, | |
77 | } | |
78 | req = sanitized_Request(self._API_URL, json.dumps(data).encode('utf-8')) | |
79 | return self._call(req) | |
80 | ||
81 | def create_asset(self, release_id, asset): | |
82 | asset_name = os.path.basename(asset) | |
83 | url = self._UPLOADS_URL % (release_id, asset_name) | |
84 | # Our files are small enough to be loaded directly into memory. | |
85 | data = open(asset, 'rb').read() | |
86 | req = sanitized_Request(url, data) | |
87 | mime_type, _ = mimetypes.guess_type(asset_name) | |
88 | req.add_header('Content-Type', mime_type or 'application/octet-stream') | |
89 | return self._call(req) | |
90 | ||
91 | ||
92 | def main(): | |
93 | parser = optparse.OptionParser(usage='%prog VERSION BUILDPATH') | |
94 | options, args = parser.parse_args() | |
95 | if len(args) != 2: | |
96 | parser.error('Expected a version and a build directory') | |
97 | ||
98 | version, build_path = args | |
99 | ||
db59b37d | 100 | releaser = GitHubReleaser() |
db56f281 | 101 | |
db59b37d | 102 | new_release = releaser.create_release(version, name='youtube-dl %s' % version) |
db56f281 S |
103 | release_id = new_release['id'] |
104 | ||
105 | for asset in os.listdir(build_path): | |
106 | compat_print('Uploading %s...' % asset) | |
107 | releaser.create_asset(release_id, os.path.join(build_path, asset)) | |
108 | ||
109 | ||
110 | if __name__ == '__main__': | |
111 | main() |