Support append/overwrite/delete tags from prompt

This commit is contained in:
Arun Prakash Jana 2017-04-07 00:49:08 +05:30
parent 620f1944fb
commit 706f234989
No known key found for this signature in database
GPG Key ID: A75979F35C080412
4 changed files with 174 additions and 30 deletions

View File

@ -485,7 +485,17 @@ NOTE: This flexibility is not exposed in the program.
$ buku --shorten www.google.com
$ buku --shorten 20
33. More **help**:
33. **Append, remove tags at prompt** (taglist index to the left, bookmark index to the right):
// append tags at taglist indices 4 and 6-9 to existing tags in bookmarks at indices 5 and 2-3
buku (? for help) g 4 9-6 >> 5 3-2
// set tags at taglist indices 4 and 6-9 as tags in bookmarks at indices 5 and 2-3
buku (? for help) g 4 9-6 > 5 3-2
// remove all tags from bookmarks at indices 5 and 2-3
buku (? for help) g > 5 3-2
// remove tags at taglist indices 4 and 6-9 from tags in bookmarks at indices 5 and 2-3
buku (? for help) g 4 9-6 << 5 3-2
34. More **help**:
$ buku -h
$ man buku

18
buku.1
View File

@ -266,6 +266,9 @@ Run a regular expression search.
.BI "t" " [...]"
Search bookmarks by a tag. List all tags alphabetically, if no arguments. The index of a tag from the tag list can be used to search all bookmarks having the tag. Note that multiple indices and/or ranges do not work in this case.
.TP
.BI "g" " [...][>>|>|<<][...]"
Append, remove tags to/from indices and/or ranges.
.TP
.BI "w" " [editor|index]"
Edit and add or update a bookmark.
.TP
@ -597,6 +600,21 @@ List bookmarks with \fBimmutable title\fR:
.B buku --shorten www.google.com
.B buku --shorten 20
.EE
.PP
.IP 33. 4
\fBAppend, remove tags at prompt\fR (taglist index to the left, bookmark index to the right):
.PP
.EX
.IP
// append tags at taglist indices 4 and 6-9 to existing tags in bookmarks at indices 5 and 2-3
.B buku (? for help) g 4 9-6 >> 5 3-2
// set tags at taglist indices 4 and 6-9 as tags in bookmarks at indices 5 and 2-3
.B buku (? for help) g 4 9-6 > 5 3-2
// remove all tags from bookmarks at indices 5 and 2-3
.B buku (? for help) g > 5 3-2
// remove tags at taglist indices 4 and 6-9 from tags in bookmarks at indices 5 and 2-3
.B buku (? for help) g 4 9-6 << 5 3-2
.EE
.SH AUTHOR
Arun Prakash Jana <engineerarun@gmail.com>.
.SH HOME

151
buku.py
View File

@ -550,11 +550,12 @@ class BukuDb:
logerr('add_rec(): %s', e)
return -1
def append_tag_at_index(self, index, tags_in):
def append_tag_at_index(self, index, tags_in, delay_commit=False):
'''Append tags to bookmark tagset at index
:param index: int position of record, 0 for all
:param tags_in: string of comma-separated tags to add manually
:param delay_commit: do not commit to DB, caller's responsibility
:return: True on success, False on failure
'''
@ -575,18 +576,22 @@ class BukuDb:
tags = row[1] + tags_in[1:]
tags = parse_tags([tags])
self.cur.execute(query, (tags, row[0],))
if self.chatty:
if self.chatty and not delay_commit:
self.print_rec(row[0])
else:
return False
if not delay_commit:
self.conn.commit()
return True
def delete_tag_at_index(self, index, tags_in):
def delete_tag_at_index(self, index, tags_in, delay_commit=False):
'''Delete tags from bookmark tagset at index
:param index: int position of record, 0 for all
:param tags_in: string of comma-separated tags to delete manually
:param delay_commit: do not commit to DB, caller's responsibility
:return: True on success, False on failure
'''
@ -606,7 +611,7 @@ class BukuDb:
self.cur.execute(q, (tag,))
count += self.cur.rowcount
if count:
if count and not delay_commit:
self.conn.commit()
if self.chatty:
print('%d record(s) updated' % count)
@ -627,10 +632,13 @@ class BukuDb:
tags = tags.replace(delim_wrap(tag), DELIM)
self.cur.execute(query, (parse_tags([tags]), row[0],))
if self.chatty:
if self.chatty and not delay_commit:
self.print_rec(row[0])
self.conn.commit()
if not delay_commit:
self.conn.commit()
else:
return False
return True
@ -1321,6 +1329,101 @@ class BukuDb:
return True
def set_tag(self, cmdstr, taglist):
'''Append, overwrite, remove tags using the symbols
>>, > and << respectively.
:param cmdstr: command pattern
:param taglist: a list of tags
:return: number of indices updated on success, -1 on failure
'''
if not len(cmdstr) or not len(taglist):
return -1
flag = 0 # 0: invalid, 1: append, 2: overwrite, 3: remove
index = cmdstr.find('>>')
if index == -1:
index = cmdstr.find('>')
if index != -1:
flag = 2
else:
index = cmdstr.find('<<')
if index != -1:
flag = 3
else:
flag = 1
if not flag:
return -1
tags = DELIM
id_list = cmdstr[:index].split()
try:
for id in id_list:
if is_int(id) and int(id) > 0:
tags += taglist[int(id) - 1] + DELIM
elif '-' in id:
vals = [int(x) for x in id.split('-')]
if vals[0] > vals[-1]:
vals[0], vals[-1] = vals[-1], vals[0]
for _id in range(vals[0], vals[-1] + 1):
tags += taglist[_id - 1] + DELIM
else:
return -1
except ValueError:
return -1
if flag != 2:
index += 1
update_count = 0
query = 'UPDATE bookmarks SET tags = ? WHERE id = ?'
try:
db_id_list = cmdstr[index + 1:].split()
for id in db_id_list:
if is_int(id) and int(id) > 0:
if flag == 1:
if self.append_tag_at_index(id, tags, True):
update_count += 1
elif flag == 2:
tags = parse_tags([tags])
self.cur.execute(query, (tags, id,))
update_count += self.cur.rowcount
else:
self.delete_tag_at_index(id, tags, True)
update_count += 1
elif '-' in id:
vals = [int(x) for x in id.split('-')]
if vals[0] > vals[-1]:
vals[0], vals[-1] = vals[-1], vals[0]
for _id in range(vals[0], vals[-1] + 1):
if flag == 1:
if self.append_tag_at_index(_id, tags, True):
update_count += 1
elif flag == 2:
tags = parse_tags([tags])
self.cur.execute(query, (tags, _id,))
update_count += self.cur.rowcount
else:
if self.delete_tag_at_index(_id, tags, True):
update_count += 1
else:
return -1
except ValueError:
return -1
except sqlite3.IntegrityError:
return -1
try:
self.conn.commit()
except:
return -1
return update_count
def browse_by_index(self, index):
'''Open URL at index in browser
@ -1682,17 +1785,18 @@ Webpage: https://github.com/jarun/Buku
def prompt_help(file=sys.stdout):
file.write('''
keys:
1-N browse search result indices and/or ranges
a open all results in browser
s keyword [...] search for records with ANY keyword
S keyword [...] search for records with ALL keywords
d match substrings ('pen' matches 'opened')
r expression run a regex search
t [...] search bookmarks by a tag or show tag list
w [editor|index] edit and add or update a bookmark
(tag list index fetches bookmarks by tag)
? show this help
q, ^D, double Enter exit buku
1-N browse search result indices and/or ranges
a open all results in browser
s keyword [...] search for records with ANY keyword
S keyword [...] search for records with ALL keywords
d match substrings ('pen' matches 'opened')
r expression run a regex search
t [...] search bookmarks by a tag or show tag list
g [...][>>|>|<<][...] append, remove tags to/from indices and/or ranges
w [editor|index] edit and add or update a bookmark
(tag list index fetches bookmarks by tag)
? show this help
q, ^D, double Enter exit buku
''')
@ -1999,7 +2103,8 @@ def taglist_subprompt(obj, msg, noninteractive=False):
new_results = True
elif (nav == 'q' or nav == 'd' or nav == '?' or
nav.startswith('s ') or nav.startswith('S ') or
nav.startswith('r ') or nav.startswith('t ')):
nav.startswith('r ') or nav.startswith('t ') or
nav.startswith('g ')):
return nav
elif nav == 'w' or nav.startswith('w '):
edit_at_prompt(obj, nav)
@ -2115,6 +2220,16 @@ def prompt(obj, results, noninteractive=False, deep=False, subprompt=False):
edit_at_prompt(obj, nav)
continue
# append or overwrite tags
if nav.startswith('g '):
unique_tags, dic = obj.get_tag_all()
_count = obj.set_tag(nav[2:], unique_tags)
if _count == -1:
print('Invalid input')
else:
print('%d updated' % _count)
continue
# Nothing to browse if there are no results
if not results:
print('Not in a search context')

View File

@ -39,17 +39,18 @@ def test_prompt_help():
buku.ExtendedArgumentParser.prompt_help(file)
file.write.assert_called_once_with('''
keys:
1-N browse search result indices and/or ranges
a open all results in browser
s keyword [...] search for records with ANY keyword
S keyword [...] search for records with ALL keywords
d match substrings ('pen' matches 'opened')
r expression run a regex search
t [...] search bookmarks by a tag or show tag list
w [editor|index] edit and add or update a bookmark
(tag list index fetches bookmarks by tag)
? show this help
q, ^D, double Enter exit buku
1-N browse search result indices and/or ranges
a open all results in browser
s keyword [...] search for records with ANY keyword
S keyword [...] search for records with ALL keywords
d match substrings ('pen' matches 'opened')
r expression run a regex search
t [...] search bookmarks by a tag or show tag list
g [...][>>|>|<<][...] append, remove tags to/from indices and/or ranges
w [editor|index] edit and add or update a bookmark
(tag list index fetches bookmarks by tag)
? show this help
q, ^D, double Enter exit buku
''')