From ec8259d5a564905163b66b31a7a794395a8ba122 Mon Sep 17 00:00:00 2001 From: Arun Prakash Jana Date: Sun, 19 Mar 2017 00:45:26 +0530 Subject: [PATCH] Support tail-like behaviour with --print --- README.md | 23 +++++++++-------- buku.1 | 26 ++++++++++++------- buku.py | 77 +++++++++++++++++++++++++++++++++---------------------- 3 files changed, 77 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 7b4e430..1375d26 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,7 @@ POWER TOYS: -m, --merge file add bookmarks from another buku DB file -p, --print [...] show record details by indices, ranges print all bookmarks, if no arguments - -1 shows the bookmark with highest index + -n shows the last n results (like tail) -f, --format N limit fields in -p or Json search output N=1: URL, N=2: URL and tag, N=3: title -j, --json Json formatted output for -p and search @@ -451,34 +451,37 @@ NOTE: This flexibility is not exposed in the program. 23. **Show details** of bookmarks at index 15012014 and ranges 20-30, 40-50: $ buku -p 20-30 15012014 40-50 -24. **Show all** bookmarks with real index from database: +24. Show details of the **last 10 bookmarks**: + + $ buku -p -10 +25. **Show all** bookmarks with real index from database: $ buku -p $ buku -p | more -25. **Replace tag** 'old tag' with 'new tag': +26. **Replace tag** 'old tag' with 'new tag': $ buku --replace 'old tag' 'new tag' -26. **Delete tag** 'old tag' from DB: +27. **Delete tag** 'old tag' from DB: $ buku --replace 'old tag' -27. **Append (or delete) tags** 'tag 1', 'tag 2' to (or from) existing tags of bookmark at index 15012014: +28. **Append (or delete) tags** 'tag 1', 'tag 2' to (or from) existing tags of bookmark at index 15012014: $ buku -u 15012014 --tag + tag 1, tag 2 $ buku -u 15012014 --tag - tag 1, tag 2 -28. **Open URL** at index 15012014 in browser: +29. **Open URL** at index 15012014 in browser: $ buku -o 15012014 -29. List bookmarks with **no title or tags** for bookkeeping: +30. List bookmarks with **no title or tags** for bookkeeping: $ buku -S blank -30. List bookmarks with **immutable title**: +31. List bookmarks with **immutable title**: $ buku -S immutable -31. **Shorten URL** www.google.com and the URL at index 20: +32. **Shorten URL** www.google.com and the URL at index 20: $ buku --shorten www.google.com $ buku --shorten 20 -32. More **help**: +33. More **help**: $ buku -h $ man buku diff --git a/buku.1 b/buku.1 index b1dabfd..59b6519 100644 --- a/buku.1 +++ b/buku.1 @@ -171,10 +171,10 @@ Import bookmarks exported from Firefox or Google Chrome as HTML. is considered Markdown (compliant with --export format) if it has '.md' extension. .TP .BI \-m " " \--merge " file" -Add bookmarks from another Buku database file. +Add bookmarks from another buku database file. .TP .BI \-p " " \--print " [...]" -Show details (DB index, URL, title, tags and comment) of bookmark record by DB index. If no arguments, all records with actual index from DB are shown. Accepts hyphenated ranges and space-separated indices. Special index -1 (introduced for convenience) shows the details of the bookmark with the highest index. +Show details (DB index, URL, title, tags and comment) of bookmark record by DB index. If no arguments, all records with actual index from DB are shown. Accepts hyphenated ranges and space-separated indices. A negative value (introduced for convenience) behaves like the tail utility, e.g., -n shows the details of the last n bookmarks. .TP .BI \-f " " \--format " N" Show selective monochrome output with specific fields. Works with --print. Search results honour the option when used along with --json. Useful for creating batch scripts. @@ -522,6 +522,14 @@ The same number of iterations must be specified for one lock & unlock instance. .EE .PP .IP 24. 4 +Show details of the \fBlast 10 bookmarks\fR: +.PP +.EX +.IP +.B buku -p -10 +.EE +.PP +.IP 25. 4 \fBShow all\fR bookmarks with real index from database: .PP .EX @@ -530,7 +538,7 @@ The same number of iterations must be specified for one lock & unlock instance. .B buku -p | more .EE .PP -.IP 25. 4 +.IP 26. 4 \fBReplace tag\fR 'old tag' with 'new tag': .PP .EX @@ -538,7 +546,7 @@ The same number of iterations must be specified for one lock & unlock instance. .B buku --replace 'old tag' 'new tag' .EE .PP -.IP 26. 4 +.IP 27. 4 \fBDelete tag\fR 'old tag' from DB: .PP .EX @@ -546,7 +554,7 @@ The same number of iterations must be specified for one lock & unlock instance. .B buku --replace 'old tag' .EE .PP -.IP 27. 4 +.IP 28. 4 \fBAppend (or delete) tags\fR 'tag 1', 'tag 2' to (or from) existing tags of bookmark at index 15012014: .PP .EX @@ -555,7 +563,7 @@ The same number of iterations must be specified for one lock & unlock instance. .B buku -u 15012014 --tag - tag 1, tag 2 .EE .PP -.IP 28. 4 +.IP 29. 4 \fBOpen URL\fR at index 15012014 in browser: .PP .EX @@ -563,7 +571,7 @@ The same number of iterations must be specified for one lock & unlock instance. .B buku -o 15012014 .EE .PP -.IP 29. 4 +.IP 30. 4 List bookmarks with \fBno title or tags\fR for bookkeeping: .PP .EX @@ -571,7 +579,7 @@ List bookmarks with \fBno title or tags\fR for bookkeeping: .B buku -S blank .EE .PP -.IP 30. 4 +.IP 31. 4 List bookmarks with \fBimmutable title\fR: .PP .EX @@ -579,7 +587,7 @@ List bookmarks with \fBimmutable title\fR: .B buku -S immutable .EE .PP -.IP 31. 4 +.IP 32. 4 \fBShorten\fR the URL www.google.com and the URL at index 20: .PP .EX diff --git a/buku.py b/buku.py index 27cc787..fe6a2bb 100755 --- a/buku.py +++ b/buku.py @@ -1158,21 +1158,24 @@ class BukuDb: print('All bookmarks deleted') return True - def print_rec(self, index): + def print_rec(self, index, low=0, high=0, is_range=False): '''Print bookmark details at index or all bookmarks if index is 0 Note: URL is printed on top because title may be blank :param index: index to print, 0 prints all + :param low: actual lower index of range + :param high: actual higher index of range + :param is_range: a range is passed using low and high arguments ''' - if index != 0: # Show record at index - # Show the last record if -1 is passed - if index == -1: - index = self.get_max_id() - if index == -1: - logerr('Empty database') - return - + if is_range: + try: + query = 'SELECT * from bookmarks where id BETWEEN ? AND ?' + resultset = self.cur.execute(query, (low, high)) + except IndexError: + logerr('Index out of range') + return + elif index != 0: # Show record at index try: query = 'SELECT * FROM bookmarks WHERE id = ? LIMIT 1' self.cur.execute(query, (index,)) @@ -1196,25 +1199,31 @@ class BukuDb: print('%s\t%s' % (row[0], row[2])) else: print(format_json(results, True, self.field_filter)) + + return else: # Show all entries self.cur.execute('SELECT * FROM bookmarks') resultset = self.cur.fetchall() - if not self.json: - if self.field_filter == 0: - for row in resultset: - print_record(row) - elif self.field_filter == 1: - for row in resultset: - print('%s\t%s' % (row[0], row[1])) - elif self.field_filter == 2: - for row in resultset: - print('%s\t%s\t%s' % (row[0], row[1], row[3][1:-1])) - elif self.field_filter == 3: - for row in resultset: - print('%s\t%s' % (row[0], row[2])) - else: - print(format_json(resultset, field_filter=self.field_filter)) + if not resultset: + logerr('0 records') + return + + if not self.json: + if self.field_filter == 0: + for row in resultset: + print_record(row) + elif self.field_filter == 1: + for row in resultset: + print('%s\t%s' % (row[0], row[1])) + elif self.field_filter == 2: + for row in resultset: + print('%s\t%s\t%s' % (row[0], row[1], row[3][1:-1])) + elif self.field_filter == 3: + for row in resultset: + print('%s\t%s' % (row[0], row[2])) + else: + print(format_json(resultset, field_filter=self.field_filter)) def get_tag_all(self): '''Get list of tags in DB @@ -2633,7 +2642,7 @@ POSITIONAL ARGUMENTS: -m, --merge file add bookmarks from another buku DB file -p, --print [...] show record details by indices, ranges print all bookmarks, if no arguments - -1 shows the bookmark with highest index + -n shows the last n results (like tail) -f, --format N limit fields in -p or Json search output N=1: URL, N=2: URL and tag, N=3: title -j, --json Json formatted output for -p and search @@ -2959,17 +2968,25 @@ POSITIONAL ARGUMENTS: else: for idx in args.print: if is_int(idx): - bdb.print_rec(int(idx)) + id = int(idx) + if id >= 0: + bdb.print_rec(id) + else: + # Show the last n records + _id = bdb.get_max_id() + if _id == -1: + logerr('Empty database') + bdb.close_quit(1) + bdb.print_rec(0, 1 if _id <= -id else _id + id + 1, + _id, True) elif ('-' in idx and is_int(idx.split('-')[0]) and is_int(idx.split('-')[1])): lower = int(idx.split('-')[0]) upper = int(idx.split('-')[1]) if lower > upper: lower, upper = upper, lower - for _id in range(lower, upper + 1): - bdb.print_rec(_id) - elif idx == '-1': - bdb.print_rec(idx) + + bdb.print_rec(0, lower, upper, True) else: logerr('Invalid index or range to print') bdb.close_quit(1)