Index: hgreview.py |
=================================================================== |
--- a/hgreview.py |
+++ b/hgreview.py |
@@ -1,16 +1,20 @@ |
+import BaseHTTPServer |
import os |
+import random |
import re |
-import subprocess |
import sys |
import urllib |
from mercurial import cmdutil, error |
+SERVER = 'https://codereview.adblockplus.org' |
+UPLOADTOOL_URL = SERVER + '/static/upload.py' |
+ |
cmdtable = {} |
command = cmdutil.command(cmdtable) |
@command('review', |
[ |
('i', 'issue', '', 'If given, adds a patch set to this review, otherwise create a new one.', 'ISSUE'), |
('r', 'revision', '', 'Revision to diff against or a revision range to upload.', 'REV'), |
('c', 'change', '', 'A single revision to upload.', 'REV'), |
@@ -23,17 +27,17 @@ command = cmdutil.command(cmdtable) |
('', 'print_diffs', None, 'Print full diffs.'), |
], '[options] [path...]') |
def review(ui, repo, *paths, **opts): |
''' |
Uploads a review to https://codereview.adblockplus.org/ or updates an |
existing review request. This will always send mails for new reviews, when |
updating a review mails will only be sent if a message is given. |
''' |
- args = ['--oauth2'] |
+ args = ['--oauth2', '--server', SERVER] |
if ui.debugflag: |
args.append('--noisy') |
elif ui.verbose: |
args.append('--verbose') |
elif ui.quiet: |
args.append('--quiet') |
if opts.get('issue') or opts.get('message'): |
@@ -68,13 +72,55 @@ def review(ui, repo, *paths, **opts): |
args.append('--' + opt) |
args.extend(paths) |
upload_path = ui.config('review', 'uploadtool_path', |
os.path.join('~', '.hgreview_upload.py')) |
upload_path = os.path.expanduser(upload_path) |
if not os.path.exists(upload_path): |
- url = 'https://codereview.adblockplus.org/static/upload.py' |
- ui.status('Downloading {0} to {1}.\n'.format(url, upload_path)) |
- urllib.urlretrieve(url, upload_path) |
+ ui.status('Downloading {0} to {1}.\n'.format(UPLOADTOOL_URL, upload_path)) |
+ urllib.urlretrieve(UPLOADTOOL_URL, upload_path) |
- subprocess.call([sys.executable, upload_path] + args) |
+ # Modify upload tool's auth response in order to redirect to the issue |
+ port = random.randrange(2000, 60000) |
+ scope = dict(globals()) |
+ execfile(upload_path, scope) |
Wladimir Palant
2016/03/10 14:17:19
Side-effect of using execfile rather than subproce
Sebastian Noack
2016/03/10 14:30:20
Wow, downloading and executing code from the web t
Wladimir Palant
2016/03/10 14:52:18
Oh, you only noticed now? :)
On the bright side,
|
+ scope['AUTH_HANDLER_RESPONSE'] = '''\ |
+<html> |
+ <head> |
+ <title>Authentication Status</title> |
+ <script> |
+ window.onload = function() |
+ { |
+ setInterval(function() |
+ { |
+ var script = document.createElement("script"); |
+ script.src = "http://localhost:%s/?" + (new Date().getTime()); |
+ document.body.appendChild(script); |
+ }, 1000) |
+ } |
+ </script> |
+ </head> |
+ <body> |
+ <p> |
+ The authentication flow has completed. This page will redirect to your |
+ review shortly. |
+ </p> |
+ </body> |
+</html> |
+''' % port |
+ |
+ # Run the upload tool |
+ issue, patchset = scope['RealMain']([upload_path] + args) |
+ |
+ # Wait for the page to check in and retrieve issue URL |
+ class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
+ def do_GET(self): |
+ self.send_response(200) |
+ self.send_header('Content-type', 'text/javascript') |
+ self.end_headers() |
+ self.wfile.write('location.href = "{0}";'.format(SERVER + '/' + issue)) |
+ def log_message(*args, **kwargs): |
+ pass |
+ |
+ server = BaseHTTPServer.HTTPServer(('localhost', port), RequestHandler) |
+ server.handle_request() |