aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykyta Holubakha <hilobakho@gmail.com>2017-08-27 19:40:47 +0300
committerMykyta Holubakha <hilobakho@gmail.com>2017-08-27 19:40:47 +0300
commit8a90813957b0f857e5f20285bd091b67da218f8e (patch)
tree991f2b2c9e939b265e5535c93b241c9b07bc75bf
parentFinished zugaina searcher and picker (diff)
downloadpomu-8a90813957b0f857e5f20285bd091b67da218f8e.tar.gz
pomu-8a90813957b0f857e5f20285bd091b67da218f8e.tar.bz2
pomu-8a90813957b0f857e5f20285bd091b67da218f8e.zip
Multiple fixes in:
zugaina searching, remote fetching, iquery command line interface, remotes
-rw-r--r--pomu/cli.py4
-rw-r--r--pomu/data/zugaina.py2
-rw-r--r--pomu/repo/remote/remote.py29
-rw-r--r--pomu/search.py58
-rw-r--r--pomu/util/iquery.py27
5 files changed, 82 insertions, 38 deletions
diff --git a/pomu/cli.py b/pomu/cli.py
index 8de900f..1d4ce39 100644
--- a/pomu/cli.py
+++ b/pomu/cli.py
@@ -3,9 +3,11 @@ import click
from os import path
+from pomu.data.zugaina import ZugainaDataSource
from pomu.patch.patch import process_changes
from pomu.repo.init import init_plain_repo, init_portage_repo
from pomu.repo.repo import portage_repo_path, portage_repos, pomu_active_repo
+from pomu.search import PSPrompt
from pomu.source import dispatcher
from pomu.util.pkg import cpv_split
from pomu.util.result import ResultException
@@ -149,7 +151,7 @@ def show(package):
@main.command()
@click.argument('query', required=True)
@click.option('--fetch-only', default=False, is_flag=True)
-def search(query):
+def search(query, fetch_only):
"""Search gpo.zugaina.org"""
ds = ZugainaDataSource(query)
p = PSPrompt(ds)
diff --git a/pomu/data/zugaina.py b/pomu/data/zugaina.py
index 14a3ddd..88f2fbc 100644
--- a/pomu/data/zugaina.py
+++ b/pomu/data/zugaina.py
@@ -41,7 +41,7 @@ class ZugainaDataSource(DataSource):
id_ = div.xpath('li/a')[0].get('href').split('/')[3]
pv = div.xpath('li/div/b')[0].text
v = cpv_split(pv, True)[2]
- overlay = div.xpath('@id')
+ overlay = div.xpath('@id')[0]
res.append((id_, v, overlay))
return res
diff --git a/pomu/repo/remote/remote.py b/pomu/repo/remote/remote.py
index d057e6f..133c645 100644
--- a/pomu/repo/remote/remote.py
+++ b/pomu/repo/remote/remote.py
@@ -1,11 +1,38 @@
"""A template class for remote repos"""
-
+from urllib.parse import urlparse
class RemoteRepo():
"""A class responsible for remotes"""
def __init__(self, url):
raise NotImplementedError()
+ @classmethod
+ def from_url(cls, uri, type_=None):
+ tp = RemoteRepo.type_for_name(type_)
+ if not tp:
+ try:
+ scheme, *_ = urlparse(uri)
+ except:
+ tp = RemoteGitRepo
+ if (scheme.startswith('http') or scheme.startswith('git')
+ scheme.startswith('ssh')):
+ tp = RemoteGitRepo
+ elif scheme.startswith('svn'):
+ tp = RemoteSvnRepo
+ elif scheme.startswith('rsync'):
+ tp = RemoteRsyncRepo
+ return tp(uri)
+
+ @classmethod
+ def type_for_name(type_):
+ from pomu.repo.remote.git import RemoteGitRepo
+ from pomu.repo.remote.hg import RemoteHgRepo
+ from pomu.repo.remote.rsync import RemoteRsyncRepo
+ from pomu.repo.remote.svn import RemoteSvnRepo
+ res = {'git': RemoteGitRepo, 'mercurial': RemoteHgRepo,
+ 'rsync': RemoteRsyncRepo, 'svn': RemoteSvnRepo}
+ return res.get(type_)
+
def fetch_package(self, name, category=None, version=None):
"""Fetches a package, determined by the parametres"""
cat, n, ver = get_full_cpv(self.fetch_tree(), name, category, version).unwrap()
diff --git a/pomu/search.py b/pomu/search.py
index e77ed1a..db8625c 100644
--- a/pomu/search.py
+++ b/pomu/search.py
@@ -1,7 +1,8 @@
from enum import Enum
from pydoc import pager
-from curtsies import FullscreenWindow, width, invert, fmtstr
+from curtsies import FullscreenWindow, fmtstr, fsarray
+from curtsies.fmtfuncs import invert
from pomu.util.iquery import Prompt, clamp
@@ -12,7 +13,7 @@ class Entry:
self.item = item
self.children = children
- def toggle(self, idx):
+ def toggle(self, idx=0):
if idx == 0:
self.expanded = not self.expanded
else:
@@ -28,7 +29,9 @@ class Entry:
return len(self.children) + 1 if self.expanded else 1
def selected(self):
- return [child[1] for child in self.children if child[0]]
+ if self.children:
+ return [child[1] for child in self.children if child[0]]
+ return []
class PromptState(Enum):
TOP_PREV=0
@@ -44,14 +47,14 @@ class PSPrompt(Prompt):
self.state = PromptState.LIST
self.set_page(1)
- def results():
+ def results(self):
# (cp, v, overlay, data)
res = []
- for k, v in self. itemitems():
+ for k, v in self.pages.items():
for entry in v:
cp = entry.item[0]
for child in entry.selected():
- cid, v, overlay = *child
+ cid, v, overlay = child
data = self.data.get_item(cid)
res.append((cp, v, overlay, data))
return res
@@ -67,7 +70,7 @@ class PSPrompt(Prompt):
self.pages[page] = self.entries
def render(self):
- title = str(self.page)
+ title = str(self.page) + '//' + str(self.state.value)
if self.page > 1:
title = ('[ ' +
(invert('Prev') if self.state == 0 else ('Prev')) +
@@ -76,28 +79,33 @@ class PSPrompt(Prompt):
title = (title + ' [ ' +
(invert('Next') if self.state == 1 else ('Next')) +
' ]')
- title = center(title)
- bottom = ('[ ' + invert('OK') if self.idx == len(self) else 'OK' + ' ]')
- bottom = center(bottom)
- items = [render_entry(e, idx) for idx, e in enumerate(self.lens())]
+ title = self.center(title)
+ bottom = '[ ' + (invert('OK') if self.idx == len(self) else 'OK') + ' ]'
+ bottom = self.center(bottom)
+ items = [self.render_entry(e, idx) for idx, e in enumerate(self.lens())]
output = fsarray([title] + items + [bottom])
self.window.render_to_terminal(output)
+ def _refresh(self):
+ w, h = self.window.width, self.window.height
+ output = fsarray([' ' * w] * h)
+ self.window.render_to_terminal(output)
+
def render_entry(self, entry, idx):
winw = self.window.width
if entry[1]:
- hld, data = *entry[1]
+ hld, data = entry[1]
stt = '*' if hld else ' '
- text = ' [' + invert(stt) if idx == 0 else stt + '] '
+ text = ' [' + (invert(stt) if idx == 0 else stt) + '] '
text += '{}::{}'.format(data[1], data[2])
elif entry[0]:
- data = entry[0]
- exp = 'v' if entry.expanded else '>'
- text = '[' + invert(exp) if idx == 0 else exp + '] '
+ data = entry[0].item
+ exp = 'v' if entry[0].expanded else '>'
+ text = '[' + (invert(exp) if idx == 0 else exp) + '] '
text += data[0] + ' '
strw = fmtstr(text).width
insw = fmtstr(data[1]).width
- text += data[1][:winw - strw - 2] + '..' if insw + strw > winw else data[1]
+ text += data[1][:winw - strw - 2] + ('..' if insw + strw > winw else data[1])
else:
text = ''
return text
@@ -107,9 +115,9 @@ class PSPrompt(Prompt):
if res:
return res
elif event == '<TAB>':
- self.state = (self.state + 1) % 2
+ self.state = PromptState((self.state.value + 1) % 2)
elif event in {'<Ctrl-j>', '<Ctrl-m>'}:
- if self.state < 2:
+ if self.state.value < 2:
return -1
else:
return False
@@ -117,7 +125,7 @@ class PSPrompt(Prompt):
def __len__(self):
- return sum(lun(y) for y in self.entries)
+ return sum(len(y) for y in self.entries)
def center(self, stri):
tw = fmtstr(stri).width
@@ -129,13 +137,15 @@ class PSPrompt(Prompt):
def toggle(self):
item, idx = self.get_idx(self.idx)
- item.toggle(idx)
+ item[0].toggle(idx)
def preview(self):
target = self.get_target()
if target[1]:
- data = self.data.get_item(target[1][0])
+ data = self.data.get_item(target[1][1][0])
pager(data)
+ self._refresh()
+ self.render()
def lens(self):
h = self.window.height - 2
@@ -144,10 +154,10 @@ class PSPrompt(Prompt):
return lst
def get_target(self):
- return get_idx(self.idx)[0]
+ return self.get_idx(self.idx)[0]
def get_idx(self, idx):
- for entry in self.entries():
+ for entry in self.entries:
if len(entry) > idx:
break
idx -= len(entry)
diff --git a/pomu/util/iquery.py b/pomu/util/iquery.py
index d0281a3..8f81e57 100644
--- a/pomu/util/iquery.py
+++ b/pomu/util/iquery.py
@@ -35,18 +35,23 @@ class Prompt:
def run(self, window_type=CursorAwareWindow, **args):
with open('/dev/tty', 'r') as tty_in, \
open('/dev/tty', 'w') as tty_out, \
- Input(in_stream=tty_in) as input_, \
- window_type(in_stream=tty_in,
- out_stream=tty_out,
- hide_cursor=False,
- extra_bytes_callback=input_.unget_bytes,
- **args) as window:
- self.window = window
+ Input(in_stream=tty_in) as input_:
+ if window_type == CursorAwareWindow:
+ iargs = {'in_stream':tty_in, 'out_stream':tty_out,
+ 'hide_cursor':False, 'extra_bytes_callback':input_.unget_bytes}
+ else:
+ iargs = {'out_stream':tty_out}
+ iargs.update(args)
+ with window_type(**args) as window:
+ return self.event_loop(window, input_)
+
+ def event_loop(self, window, input_):
+ self.window = window
+ self.render()
+ for event in input_:
+ if self.process_event(event) == -1:
+ break
self.render()
- for event in input_:
- if self.process_event(event) == -1:
- break
- self.render()
return self.results()
def clamp(self, x):