Support searching by URL
Support copy/pasting a URL into the search box, if it matches the hostname of the Gerrit server, parse it and extract the change number and open that change. Change-Id: I0b74b4783742e909db4a2d8d3317061a67201ee8
This commit is contained in:
parent
110ee234d0
commit
86866f4b32
@ -23,6 +23,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
import threading
|
import threading
|
||||||
|
import urlparse
|
||||||
import warnings
|
import warnings
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
@ -172,7 +173,8 @@ class BackgroundBrowser(webbrowser.GenericBrowser):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
class App(object):
|
class App(object):
|
||||||
simple_change_search= re.compile('^(\d+|I[a-fA-F0-9]{40})$')
|
simple_change_search = re.compile('^(\d+|I[a-fA-F0-9]{40})$')
|
||||||
|
url_change_search = re.compile('^https?://.*$')
|
||||||
|
|
||||||
def __init__(self, server=None, palette='default', keymap='default',
|
def __init__(self, server=None, palette='default', keymap='default',
|
||||||
debug=False, verbose=False, disable_sync=False,
|
debug=False, verbose=False, disable_sync=False,
|
||||||
@ -440,8 +442,47 @@ class App(object):
|
|||||||
query = dialog.entry.edit_text.strip()
|
query = dialog.entry.edit_text.strip()
|
||||||
if self.simple_change_search.match(query):
|
if self.simple_change_search.match(query):
|
||||||
query = 'change:%s' % query
|
query = 'change:%s' % query
|
||||||
|
else:
|
||||||
|
result = self.parseInternalURL(query)
|
||||||
|
if result is not None:
|
||||||
|
return self.openInternalURL(result)
|
||||||
self.doSearch(query)
|
self.doSearch(query)
|
||||||
|
|
||||||
|
trailing_filename_re = re.compile('.*(,[a-z]+)')
|
||||||
|
def parseInternalURL(self, url):
|
||||||
|
if not self.url_change_search.match(url):
|
||||||
|
return None
|
||||||
|
result = urlparse.urlparse(url)
|
||||||
|
if result.netloc != self.config.hostname:
|
||||||
|
return None
|
||||||
|
change = patchset = filename = None
|
||||||
|
path = [x for x in result.path.split('/') if x]
|
||||||
|
if path:
|
||||||
|
change = path[0]
|
||||||
|
else:
|
||||||
|
path = [x for x in result.fragment.split('/') if x]
|
||||||
|
if path[0] == 'c':
|
||||||
|
path.pop(0)
|
||||||
|
while path:
|
||||||
|
if not change:
|
||||||
|
change = path.pop(0)
|
||||||
|
continue
|
||||||
|
if not patchset:
|
||||||
|
patchset = path.pop(0)
|
||||||
|
continue
|
||||||
|
if not filename:
|
||||||
|
filename = '/'.join(path)
|
||||||
|
m = trailing_filename_re.match(filename)
|
||||||
|
if m:
|
||||||
|
filename = filename[:0-len(m.group(1))]
|
||||||
|
path = None
|
||||||
|
return (change, patchset, filename)
|
||||||
|
|
||||||
|
def openInternalURL(self, result):
|
||||||
|
(change, patchset, filename) = result
|
||||||
|
# TODO: support deep-linking to a filename
|
||||||
|
self.doSearch('change:%s' % change)
|
||||||
|
|
||||||
def error(self, message, title='Error'):
|
def error(self, message, title='Error'):
|
||||||
dialog = mywid.MessageDialog(title, message)
|
dialog = mywid.MessageDialog(title, message)
|
||||||
urwid.connect_signal(dialog, 'close',
|
urwid.connect_signal(dialog, 'close',
|
||||||
|
@ -21,6 +21,7 @@ try:
|
|||||||
import ordereddict
|
import ordereddict
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
import urlparse
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
import voluptuous as v
|
import voluptuous as v
|
||||||
@ -137,6 +138,8 @@ class Config(object):
|
|||||||
if not url.endswith('/'):
|
if not url.endswith('/'):
|
||||||
url += '/'
|
url += '/'
|
||||||
self.url = url
|
self.url = url
|
||||||
|
result = urlparse.urlparse(url)
|
||||||
|
self.hostname = result.netloc
|
||||||
self.username = server['username']
|
self.username = server['username']
|
||||||
self.password = server.get('password')
|
self.password = server.get('password')
|
||||||
if self.password is None:
|
if self.password is None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user