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