Support positional arguments as search keywords

1. All search options are now boolean
2. -s is the default search option
This commit is contained in:
Arun Prakash Jana 2017-01-29 19:19:47 +05:30
parent ab49a7242a
commit bb8e683f93
No known key found for this signature in database
GPG Key ID: A75979F35C080412
3 changed files with 49 additions and 44 deletions

View File

@ -132,6 +132,9 @@ usage: buku [OPTIONS] [KEYWORD [KEYWORD ...]]
Powerful command-line bookmark manager. Your mini web! Powerful command-line bookmark manager. Your mini web!
POSITIONAL ARGUMENTS:
KEYWORD search keywords
GENERAL OPTIONS: GENERAL OPTIONS:
-a, --add URL [tag, ...] -a, --add URL [tag, ...]
bookmark URL with comma-separated tags bookmark URL with comma-separated tags
@ -168,17 +171,16 @@ EDIT OPTIONS:
N=0: mutable (default), N=1: immutable N=0: mutable (default), N=1: immutable
SEARCH OPTIONS: SEARCH OPTIONS:
-s, --sany keyword [...] -s, --sany find records with ANY search keyword
find records with ANY search keyword this is the default search option
-S, --sall keyword [...] -S, --sall find records with ALL search keywords
find records with ALL search keywords
special keywords - special keywords -
"blank": entries with empty title/tag "blank": entries with empty title/tag
"immutable": entries with locked title "immutable": entries with locked title
--deep match substrings ('pen' matches 'opens') --deep match substrings ('pen' matches 'opens')
--sreg expression run a regex search --sreg run a regex search
--stag [...] search bookmarks by a tag --stag search bookmarks by a tag
list all tags, if no arguments list all tags, if no search keywords
ENCRYPTION OPTIONS: ENCRYPTION OPTIONS:
-l, --lock [N] encrypt DB file with N (> 0, default 8) -l, --lock [N] encrypt DB file with N (> 0, default 8)
@ -198,7 +200,7 @@ POWER TOYS:
accepts indices and ranges accepts indices and ranges
show all bookmarks, if no arguments show all bookmarks, if no arguments
-f, --format N limit fields in -p or Json search output -f, --format N limit fields in -p or Json search output
1: URL, 2: URL and tag, 3: title N=1: URL, N=2: URL and tag, N=3: title
-r, --replace oldtag [newtag ...] -r, --replace oldtag [newtag ...]
replace oldtag with newtag everywhere replace oldtag with newtag everywhere
delete oldtag, if no newtag delete oldtag, if no newtag
@ -213,7 +215,7 @@ POWER TOYS:
--expand N/URL expand a tny.im shortened url --expand N/URL expand a tny.im shortened url
--tacit reduce verbosity --tacit reduce verbosity
--threads N max network connections in full refresh --threads N max network connections in full refresh
default 4, min 1, max 10 default N=4, min N=1, max N=10
--upstream check latest upstream version available --upstream check latest upstream version available
-z, --debug show debug information and verbose logs -z, --debug show debug information and verbose logs
@ -247,7 +249,7 @@ SYMBOLS:
- **Search** works in mysterious ways: - **Search** works in mysterious ways:
- Case-insensitive. - Case-insensitive.
- Matches words in URL, title and tags. - Matches words in URL, title and tags.
- --sany : match any of the keywords in URL, title or tags. - --sany : match any of the keywords in URL, title or tags. Default search option.
- --sall : match all the keywords in URL, title or tags. - --sall : match all the keywords in URL, title or tags.
- --deep : match **substrings** (`match` matches `rematched`) in URL, title and tags. - --deep : match **substrings** (`match` matches `rematched`) in URL, title and tags.
- --sreg : match a regular expression (ignores --deep). - --sreg : match a regular expression (ignores --deep).

4
buku.1
View File

@ -60,7 +60,7 @@ Bookmarks with immutable titles are listed with bold '(L)' after the URL.
\fBSearch\fR works in mysterious ways: \fBSearch\fR works in mysterious ways:
- Case-insensitive. - Case-insensitive.
- Matches words in URL, title and tags. - Matches words in URL, title and tags.
- --sany : match any of the keywords in URL, title or tags. - --sany : match any of the keywords in URL, title or tags. Default search option.
- --sall : match all the keywords in URL, title or tags. - --sall : match all the keywords in URL, title or tags.
- --deep : match \fBsubstrings\fR (`match` matches `rematched`) in URL, title and tags. - --deep : match \fBsubstrings\fR (`match` matches `rematched`) in URL, title and tags.
- --sreg : match a regular expression (ignores --deep). - --sreg : match a regular expression (ignores --deep).
@ -110,6 +110,8 @@ Set the title of a bookmark immutable during updates. Works with --add, --update
.TP .TP
.BI \-s " " \--sany " keyword [...]" .BI \-s " " \--sany " keyword [...]"
Search bookmarks with ANY of the keyword(s) in URL, title or tags and show the results. Prompts to enter result number to open in browser. Note that the sequential result index is not the DB index. The DB index is shown in bold within '[]' after the URL. Search bookmarks with ANY of the keyword(s) in URL, title or tags and show the results. Prompts to enter result number to open in browser. Note that the sequential result index is not the DB index. The DB index is shown in bold within '[]' after the URL.
.br
This is the default search option for positional arguments if no other search option is specified.
.TP .TP
.BI \-S " " \--sall " keyword [...]" .BI \-S " " \--sall " keyword [...]"
Search bookmarks with ALL keywords in URL, title or tags and show the results. Behaviour same as --sany. Search bookmarks with ALL keywords in URL, title or tags and show the results. Behaviour same as --sany.

67
buku.py
View File

@ -887,6 +887,9 @@ class BukuDb:
:return: search results, or None, if no matches :return: search results, or None, if no matches
''' '''
if not keywords:
return None
qry = 'SELECT id, url, metadata, tags, desc FROM bookmarks WHERE' qry = 'SELECT id, url, metadata, tags, desc FROM bookmarks WHERE'
# Deep query string # Deep query string
q1 = "(tags LIKE ('%' || ? || '%') OR URL LIKE ('%' || ? || '%') OR \ q1 = "(tags LIKE ('%' || ? || '%') OR URL LIKE ('%' || ? || '%') OR \
@ -941,11 +944,7 @@ class BukuDb:
logerr(e) logerr(e)
return None return None
results = self.cur.fetchall() return self.cur.fetchall()
if len(results) == 0:
return None
return results
def search_by_tag(self, tag): def search_by_tag(self, tag):
'''Search and list bookmarks with a tag '''Search and list bookmarks with a tag
@ -960,11 +959,7 @@ class BukuDb:
logdbg('query: "%s", args: %s', query, tag) logdbg('query: "%s", args: %s', query, tag)
self.cur.execute(query, (tag,)) self.cur.execute(query, (tag,))
results = self.cur.fetchall() return self.cur.fetchall()
if len(results) == 0:
return None
return results
def compactdb(self, index, delay_commit=False): def compactdb(self, index, delay_commit=False):
'''When an entry at index is deleted, move the '''When an entry at index is deleted, move the
@ -2207,13 +2202,18 @@ def main():
# Setup custom argument parser # Setup custom argument parser
argparser = ExtendedArgumentParser( argparser = ExtendedArgumentParser(
description='Powerful command-line bookmark manager. Your mini web!', description='''Powerful command-line bookmark manager. Your mini web!
POSITIONAL ARGUMENTS:
KEYWORD search keywords''',
formatter_class=argparse.RawTextHelpFormatter, formatter_class=argparse.RawTextHelpFormatter,
usage='''buku [OPTIONS] [KEYWORD [KEYWORD ...]]''', usage='''buku [OPTIONS] [KEYWORD [KEYWORD ...]]''',
add_help=False add_help=False
) )
HIDE = argparse.SUPPRESS HIDE = argparse.SUPPRESS
argparser.add_argument('keywords', nargs='*', metavar='KEYWORD', help=HIDE)
# --------------------- # ---------------------
# GENERAL OPTIONS GROUP # GENERAL OPTIONS GROUP
# --------------------- # ---------------------
@ -2277,23 +2277,22 @@ def main():
search_grp = argparser.add_argument_group( search_grp = argparser.add_argument_group(
title='SEARCH OPTIONS', title='SEARCH OPTIONS',
description=''' -s, --sany keyword [...] description=''' -s, --sany find records with ANY search keyword
find records with ANY search keyword this is the default search option
-S, --sall keyword [...] -S, --sall find records with ALL search keywords
find records with ALL search keywords
special keywords - special keywords -
"blank": entries with empty title/tag "blank": entries with empty title/tag
"immutable": entries with locked title "immutable": entries with locked title
--deep match substrings ('pen' matches 'opens') --deep match substrings ('pen' matches 'opens')
--sreg expression run a regex search --sreg run a regex search
--stag [...] search bookmarks by a tag --stag search bookmarks by a tag
list all tags, if no arguments''') list all tags, if no search keywords''')
addarg = search_grp.add_argument addarg = search_grp.add_argument
addarg('-s', '--sany', nargs='+', help=HIDE) addarg('-s', '--sany', action='store_true', help=HIDE)
addarg('-S', '--sall', nargs='+', help=HIDE) addarg('-S', '--sall', action='store_true', help=HIDE)
addarg('--sreg', nargs=1, help=HIDE) addarg('--sreg', action='store_true', help=HIDE)
addarg('--deep', action='store_true', help=HIDE) addarg('--deep', action='store_true', help=HIDE)
addarg('--stag', nargs='*', help=HIDE) addarg('--stag', action='store_true', help=HIDE)
# ------------------------ # ------------------------
# ENCRYPTION OPTIONS GROUP # ENCRYPTION OPTIONS GROUP
@ -2326,7 +2325,7 @@ def main():
accepts indices and ranges accepts indices and ranges
show all bookmarks, if no arguments show all bookmarks, if no arguments
-f, --format N limit fields in -p or Json search output -f, --format N limit fields in -p or Json search output
1: URL, 2: URL and tag, 3: title N=1: URL, N=2: URL and tag, N=3: title
-r, --replace oldtag [newtag ...] -r, --replace oldtag [newtag ...]
replace oldtag with newtag everywhere replace oldtag with newtag everywhere
delete oldtag, if no newtag delete oldtag, if no newtag
@ -2341,7 +2340,7 @@ def main():
--expand N/URL expand a tny.im shortened url --expand N/URL expand a tny.im shortened url
--tacit reduce verbosity --tacit reduce verbosity
--threads N max network connections in full refresh --threads N max network connections in full refresh
default 4, min 1, max 10 default N=4, min N=1, max N=10
--upstream check latest upstream version available --upstream check latest upstream version available
-z, --debug show debug information and verbose logs''') -z, --debug show debug information and verbose logs''')
addarg = power_grp.add_argument addarg = power_grp.add_argument
@ -2455,22 +2454,24 @@ def main():
search_opted = True search_opted = True
update_search_results = False update_search_results = False
if args.sany is not None: if args.sany:
# Search URLs, titles, tags for any keyword # Search URLs, titles, tags for any keyword
search_results = bdb.searchdb(args.sany, False, args.deep) search_results = bdb.searchdb(args.keywords, False, args.deep)
elif args.sall is not None: elif args.sall:
# Search URLs, titles, tags with all keywords # Search URLs, titles, tags with all keywords
search_results = bdb.searchdb(args.sall, True, args.deep) search_results = bdb.searchdb(args.keywords, True, args.deep)
elif args.sreg is not None: elif args.sreg:
# Run a regular expression search # Run a regular expression search
search_results = bdb.searchdb(args.sreg, regex=True) search_results = bdb.searchdb(args.keywords, regex=True)
elif args.stag is not None: elif args.stag:
# Search bookmarks by tag # Search bookmarks by tag
if len(args.stag): if args.keywords:
search_results = bdb.search_by_tag(' '.join(args.stag)) search_results = bdb.search_by_tag(' '.join(args.keywords))
else: else:
# Use sub prompt to list all tags # Use sub prompt to list all tags
prompt(bdb, None, args.noprompt, subprompt=True) prompt(bdb, None, args.noprompt, subprompt=True)
elif args.keywords:
search_results = bdb.searchdb(args.keywords, False, args.deep)
else: else:
search_opted = False search_opted = False