diff --git a/buku b/buku
index 21a52e93..7f639615 100755
--- a/buku
+++ b/buku
@@ -44,7 +44,7 @@ import webbrowser
from enum import Enum
from itertools import chain
from subprocess import DEVNULL, PIPE, Popen
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any, Dict, List, Optional, Tuple, NamedTuple
import urllib3
from bs4 import BeautifulSoup
@@ -95,6 +95,8 @@ COLORMAP = {k: '\x1b[%sm' % v for k, v in {
'x': '0', 'X': '1', 'y': '7', 'Y': '7;1', 'z': '2',
}.items()}
+[FLAG_NONE, FLAG_IMMUTABLE] = [0x00, 0x01]
+
USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:101.0) Gecko/20100101 Firefox/101.0'
MYHEADERS = None # Default dictionary of headers
MYPROXY = None # Default proxy
@@ -362,9 +364,16 @@ class BukuCrypt:
sys.exit(1)
-BookmarkVar = Tuple[int, str, Optional[str], str, str, int]
-# example:
-# (1, 'http://example.com', 'example title', ',tags1,', 'randomdesc', 0))
+class BookmarkVar(NamedTuple):
+ """Bookmark data named tuple"""
+ id: int
+ url: str
+ title: Optional[str] = None
+ tags: str = ''
+ desc: str = ''
+ flags: int = FLAG_NONE
+
+bookmark_vars = lambda xs: (BookmarkVar(*x) for x in xs)
class BukuDb:
@@ -385,8 +394,8 @@ class BukuDb:
"""
def __init__(
- self, json: Optional[str] = None, field_filter: Optional[int] = 0, chatty: Optional[bool] = False,
- dbfile: Optional[str] = None, colorize: Optional[bool] = True) -> None:
+ self, json: Optional[str] = None, field_filter: int = 0, chatty: bool = False,
+ dbfile: Optional[str] = None, colorize: bool = True) -> None:
"""Database initialization API.
Parameters
@@ -395,11 +404,11 @@ class BukuDb:
Empty string if results should be printed in JSON format to stdout.
Nonempty string if results should be printed in JSON format to file. The string has to be a valid path.
None if the results should be printed as human-readable plaintext.
- field_filter : int, optional
+ field_filter : int
Indicates format for displaying bookmarks. Default is 0.
- chatty : bool, optional
+ chatty : bool
Sets the verbosity of the APIs. Default is False.
- colorize : bool, optional
+ colorize : bool
Indicates whether color should be used in output. Default is True.
"""
@@ -439,7 +448,7 @@ class BukuDb:
return os.path.join(data_home, 'buku')
@staticmethod
- def initdb(dbfile: Optional[str] = None, chatty: Optional[bool] = False) -> Tuple[sqlite3.Connection, sqlite3.Cursor]:
+ def initdb(dbfile: Optional[str] = None, chatty: bool = False) -> Tuple[sqlite3.Connection, sqlite3.Cursor]:
"""Initialize the database connection.
Create DB file and/or bookmarks table if they don't exist.
@@ -514,7 +523,7 @@ class BukuDb:
def _fetch(self, query: str, *args) -> List[BookmarkVar]:
self.cur.execute(query, args)
- return self.cur.fetchall()
+ return [BookmarkVar(*x) for x in self.cur.fetchall()]
def _fetch_first(self, query: str, *args) -> Optional[BookmarkVar]:
rows = self._fetch(query + ' LIMIT 1', *args)
@@ -562,7 +571,7 @@ class BukuDb:
"""
row = self._fetch_first('SELECT * FROM bookmarks WHERE url = ?', url)
- return row and row[0]
+ return row and row.id
def get_max_id(self) -> int:
"""Fetch the ID of the last record.
@@ -582,9 +591,9 @@ class BukuDb:
title_in: Optional[str] = None,
tags_in: Optional[str] = None,
desc: Optional[str] = None,
- immutable: Optional[int] = 0,
- delay_commit: Optional[bool] = False,
- fetch: Optional[bool] = True) -> int:
+ immutable: int = FLAG_NONE,
+ delay_commit: bool = False,
+ fetch: bool = True) -> int:
"""Add a new bookmark.
Parameters
@@ -598,13 +607,13 @@ class BukuDb:
Must start and end with comma. Default is None.
desc : str, optional
Description of the bookmark. Default is None.
- immutable : int, optional
+ immutable : int
Indicates whether to disable title fetch from web.
- Default is 0.
- delay_commit : bool, optional
+ Default is 0 ("no"); the "yes" value is 1.
+ delay_commit : bool
True if record should not be committed to the DB,
leaving commit responsibility to caller. Default is False.
- fetch : bool, optional
+ fetch : bool
Fetch page from web and parse for data
Returns
@@ -614,7 +623,7 @@ class BukuDb:
"""
# Return error for empty URL
- if not url or url == '':
+ if not url:
LOGERR('Invalid URL')
return None
@@ -650,8 +659,8 @@ class BukuDb:
desc = '' if pdesc is None else pdesc
try:
- flagset = 0
- if immutable == 1:
+ flagset = FLAG_NONE
+ if immutable == FLAG_IMMUTABLE:
flagset |= immutable
qry = 'INSERT INTO bookmarks(URL, metadata, tags, desc, flags) VALUES (?, ?, ?, ?, ?)'
@@ -674,7 +683,7 @@ class BukuDb:
DB index of the record. 0 indicates all records.
tags_in : str
Comma-separated tags to add manually.
- delay_commit : bool, optional
+ delay_commit : bool
True if record should not be committed to the DB,
leaving commit responsibility to caller. Default is False.
@@ -722,10 +731,10 @@ class BukuDb:
DB index of bookmark record. 0 indicates all records.
tags_in : str
Comma-separated tags to delete manually.
- delay_commit : bool, optional
+ delay_commit : bool
True if record should not be committed to the DB,
leaving commit responsibility to caller. Default is False.
- chatty: bool, optional
+ chatty: bool
Skip confirmation when set to False.
Returns
@@ -792,7 +801,7 @@ class BukuDb:
title_in: Optional[str] = None,
tags_in: Optional[str] = None,
desc: Optional[str] = None,
- immutable: Optional[int] = -1,
+ immutable: int = -1,
threads: int = 4) -> bool:
"""Update an existing record at index.
@@ -813,9 +822,10 @@ class BukuDb:
Prefix with '-,' to delete from current tags.
desc : str, optional
Description of bookmark.
- immutable : int, optional
- Disable title fetch from web if 1. Default is -1.
- threads : int, optional
+ immutable : int
+ Disable title fetch from web if 1 (or enable if 0).
+ Default is -1 ("no change").
+ threads : int
Number of threads to use to refresh full DB. Default is 4.
Returns
@@ -871,15 +881,13 @@ class BukuDb:
to_update = True
# Update immutable flag if passed as argument
- if immutable != -1:
- flagset = 1
- if immutable == 1:
+ if immutable in {FLAG_NONE, FLAG_IMMUTABLE}:
+ if immutable == FLAG_IMMUTABLE:
query += ' flags = flags | ?,'
- elif immutable == 0:
+ arguments += (FLAG_IMMUTABLE,)
+ else:
query += ' flags = flags & ?,'
- flagset = ~flagset
-
- arguments += (flagset,)
+ arguments += (~FLAG_IMMUTABLE,)
to_update = True
# Update title
@@ -1123,8 +1131,9 @@ class BukuDb:
index : int
DB index of the record.
Last record, if index is -1.
- immutable : int, optional
- Diable title fetch from web if 1. Default is -1.
+ immutable : int
+ Diable title fetch from web if 1 (or enable if 0).
+ Default is -1 ("no change").
Returns
-------
@@ -1151,14 +1160,13 @@ class BukuDb:
# If reading from DB, show empty title and desc as empty lines. We have to convert because
# even in case of add with a blank title or desc, '' is used as initializer to show '-'.
- result = edit_rec(editor, rec[1], rec[2] if rec[2] != '' else None,
- rec[3], rec[4] if rec[4] != '' else None)
+ result = edit_rec(editor, rec.url, rec.title or None, rec.tags, rec.desc or None)
if result is not None:
url, title, tags, desc = result
return self.update_rec(index, url, title, tags, desc, immutable)
- if immutable != -1:
- return self.update_rec(index, immutable)
+ if immutable in {FLAG_NONE, FLAG_IMMUTABLE}:
+ return self.update_rec(index, immutable=immutable)
return False
@@ -1203,9 +1211,9 @@ class BukuDb:
def searchdb(
self,
keywords: List[str],
- all_keywords: Optional[bool] = False,
- deep: Optional[bool] = False,
- regex: Optional[bool] = False
+ all_keywords: bool = False,
+ deep: bool = False,
+ regex: bool = False
) -> List[BookmarkVar]:
"""Search DB for entries where tags, URL, or title fields match keywords.
@@ -1213,12 +1221,12 @@ class BukuDb:
----------
keywords : list of str
Keywords to search.
- all_keywords : bool, optional
+ all_keywords : bool
True to return records matching ALL keywords.
False (default value) to return records matching ANY keyword.
- deep : bool, optional
+ deep : bool
True to search for matching substrings. Default is False.
- regex : bool, optional
+ regex : bool
Match a regular expression if True. Default is False.
Returns
@@ -1395,12 +1403,12 @@ class BukuDb:
----------
keywords : list of str
Keywords to search.
- all_keywords : bool, optional
+ all_keywords : bool
True to return records matching ALL keywords.
False to return records matching ANY keyword.
- deep : bool, optional
+ deep : bool
True to search for matching substrings.
- regex : bool, optional
+ regex : bool
Match a regular expression if True.
stag : str
String of tags to search for.
@@ -1428,7 +1436,7 @@ class BukuDb:
List of search results
without : list of str
Keywords to search.
- deep : bool, optional
+ deep : bool
True to search for matching substrings.
Returns
@@ -1447,7 +1455,7 @@ class BukuDb:
----------
index : int
DB index of deleted entry.
- delay_commit : bool, optional
+ delay_commit : bool
True if record should not be committed to the DB,
leaving commit responsibility to caller. Default is False.
"""
@@ -1465,12 +1473,12 @@ class BukuDb:
if max_id > index:
results = self._fetch(query1, max_id)
for row in results:
- self.cur.execute(query2, (row[0],))
- self.cur.execute(query3, (index, row[1], row[2], row[3], row[4], row[5]))
+ self.cur.execute(query2, (row.id,))
+ self.cur.execute(query3, (index, row.url, row.title, row.tags, row.desc, row.flags))
if not delay_commit:
self.conn.commit()
if self.chatty:
- print('Index %d moved to %d' % (row[0], index))
+ print('Index %d moved to %d' % (row.id, index))
def delete_rec(
self,
@@ -1486,14 +1494,14 @@ class BukuDb:
----------
index : int, optional
DB index of deleted entry.
- low : int, optional
+ low : int
Actual lower index of range.
- high : int, optional
+ high : int
Actual higher index of range.
- is_range : bool, optional
+ is_range : bool
A range is passed using low and high arguments.
An index is ignored if is_range is True.
- delay_commit : bool, optional
+ delay_commit : bool
True if record should not be committed to the DB,
leaving commit responsibility to caller. Default is False.
@@ -1681,7 +1689,7 @@ class BukuDb:
Parameters
----------
- delay_commit : bool, optional
+ delay_commit : bool
True if record should not be committed to the DB,
leaving commit responsibility to caller. Default is False.
@@ -1731,13 +1739,13 @@ class BukuDb:
Parameters
-----------
- index : int, optional
+ index : int
DB index of record to print. 0 prints all records.
- low : int, optional
+ low : int
Actual lower index of range.
- high : int, optional
+ high : int
Actual higher index of range.
- is_range : bool, optional
+ is_range : bool
A range is passed using low and high arguments.
An index is ignored if is_range is True.
@@ -1932,7 +1940,7 @@ class BukuDb:
return parse_tags(tags)
- def replace_tag(self, orig: str, new: Optional[List[str]] = None) -> bool:
+ def replace_tag(self, orig: str, new: List[str] = []) -> bool:
"""Replace original tag by new tags in all records.
Remove original tag if new tag is empty.
@@ -1950,11 +1958,8 @@ class BukuDb:
True on success, False on failure.
"""
- newtags = DELIM
-
orig = delim_wrap(orig)
- if new is not None:
- newtags = parse_tags(new)
+ newtags = parse_tags(new) if new else DELIM
if orig == newtags:
print('Tags are same.')
@@ -2226,7 +2231,7 @@ class BukuDb:
outdb = BukuDb(dbfile=filepath)
qry = 'INSERT INTO bookmarks(URL, metadata, tags, desc, flags) VALUES (?, ?, ?, ?, ?)'
for row in resultset:
- outdb.cur.execute(qry, (row[1], row[2], row[3], row[4], row[5]))
+ outdb.cur.execute(qry, (row.url, row.title, row.tags, row.desc, row.flags))
count += 1
outdb.conn.commit()
outdb.close()
@@ -2381,10 +2386,7 @@ class BukuDb:
tags = parse_tags(formatted_tags)
# get the title
- if row[2]:
- title = row[2]
- else:
- title = ''
+ title = row[2] or ''
self.add_rec(url, title, tags, None, 0, True, False)
try:
@@ -2569,7 +2571,7 @@ class BukuDb:
----------
filepath : str
Path to file to import.
- tacit : bool, optional
+ tacit : bool
If True, no questions asked and folder names are automatically
imported as tags from bookmarks HTML.
If True, automatic timestamp tag is NOT added.
@@ -2709,8 +2711,8 @@ n: don't add parent folder as tag
resultset = indb_cur.fetchall()
if resultset:
- for row in resultset:
- self.add_rec(row[1], row[2], row[3], row[4], row[5], True, False)
+ for row in bookmark_vars(resultset):
+ self.add_rec(row.url, row.title, row.tags, row.desc, row.flags, True, False)
self.conn.commit()
@@ -2726,7 +2728,7 @@ n: don't add parent folder as tag
self,
index: Optional[int] = None,
url: Optional[str] = None,
- shorten: Optional[bool] = True) -> Optional[str]:
+ shorten: bool = True) -> Optional[str]:
"""Shorten a URL using Google URL shortener.
Parameters
@@ -2735,7 +2737,7 @@ n: don't add parent folder as tag
DB index of the bookmark with the URL to shorten. Default is None.
url : str, optional (if index is provided)
URL to shorten.
- shorten : bool, optional
+ shorten : bool
True to shorten, False to expand. Default is False.
Returns
@@ -2894,7 +2896,7 @@ n: don't add parent folder as tag
Parameters
----------
- exitval : int, optional
+ exitval : int
Program exit value.
"""
@@ -2917,7 +2919,7 @@ class ExtendedArgumentParser(argparse.ArgumentParser):
Parameters
----------
- file : file, optional
+ file : file
File to write program info to. Default is sys.stdout.
"""
if sys.platform == 'win32' and file == sys.stdout:
@@ -2941,7 +2943,7 @@ Webpage: https://github.com/jarun/buku
Parameters
----------
- file : file, optional
+ file : file
File to write program info to. Default is sys.stdout.
"""
file.write('''
@@ -3001,7 +3003,7 @@ PROMPT KEYS:
Parameters
----------
- file : file, optional
+ file : file
File to write program info to. Default is sys.stdout.
"""
super().print_help(file)
@@ -3046,30 +3048,24 @@ def convert_bookmark_set(
import html
assert export_type in ['markdown', 'html', 'org', 'xbel']
# compatibility
- resultset = bookmark_set
+ resultset = bookmark_vars(bookmark_set)
count = 0
out = ''
if export_type == 'markdown':
for row in resultset:
- if not row[2] or row[2] is None:
- out += '- [Untitled](' + row[1] + ')'
- else:
- out += '- [' + row[2] + '](' + row[1] + ')'
+ out += '- [' + (row.title or 'Untitled') + '](' + row.url + ')'
- if row[3] != DELIM:
- out += ' \n'.format(row[3][1:-1])
+ if row.tags != DELIM:
+ out += ' \n'.format(row.tags[1:-1])
else:
out += '\n'
count += 1
elif export_type == 'org':
for row in resultset:
- if not row[2]:
- out += '* [[{}][Untitled]]'.format(row[1])
- else:
- out += '* [[{}][{}]]'.format(row[1], row[2])
- out += convert_tags_to_org_mode_tags(row[3])
+ out += '* [[{}][{}]]'.format(row.url, row.title or 'Untitled')
+ out += convert_tags_to_org_mode_tags(row.tags)
count += 1
elif export_type == 'xbel':
timestamp = str(int(time.time()))
@@ -3081,11 +3077,11 @@ def convert_bookmark_set(
'
\n'.format(timestamp)) for row in resultset: - out += '
\n
' @@ -3897,7 +3893,7 @@ def get_PoolManager(): def network_handler( url: str, - http_head: Optional[bool] = False + http_head: bool = False ) -> Tuple[Optional[str], Optional[str], Optional[str], int, int]: """Handle server connection and redirections. @@ -3978,7 +3974,7 @@ def parse_tags(keywords=[]): Parameters ---------- - keywords : list, optional + keywords : list List of tags to parse. Default is empty list. Returns @@ -3994,7 +3990,7 @@ def parse_tags(keywords=[]): if keywords is None: return None - if not keywords or len(keywords) < 1 or not keywords[0]: + if not keywords or not keywords[0]: return DELIM tags = DELIM @@ -4114,7 +4110,7 @@ def edit_at_prompt(obj, nav, suggest=False): A valid instance of BukuDb class. nav : str Navigation command argument passed at prompt by user. - suggest : bool, optional + suggest : bool If True, suggest similar tags on new bookmark addition. """ @@ -4166,15 +4162,15 @@ def prompt(obj, results, noninteractive=False, deep=False, listtags=False, sugge A valid instance of BukuDb class. results : list Search result set from a DB query. - noninteractive : bool, optional + noninteractive : bool If True, does not seek user input. Shows all results. Default is False. - deep : bool, optional + deep : bool Use deep search. Default is False. - listtags : bool, optional + listtags : bool If True, list all tags. - suggest : bool, optional + suggest : bool If True, suggest similar tags on edit and add bookmark. - num : int, optional + num : int Number of results to show per page. Default is 10. """ @@ -4481,10 +4477,11 @@ def print_rec_with_filter(records, field_filter=0): records : list or sqlite3.Cursor object List of bookmark records to print field_filter : int - Integer indicating which fields to print. + Integer indicating which fields to print. Default is 0 ("all fields"). """ try: + records = bookmark_vars(records) if field_filter == 0: for row in records: try: @@ -4494,40 +4491,40 @@ def print_rec_with_filter(records, field_filter=0): print_single_rec(row, columns=columns) elif field_filter == 1: for row in records: - print('%s\t%s' % (row[0], row[1])) + print('%s\t%s' % (row.id, row.url)) elif field_filter == 2: for row in records: - print('%s\t%s\t%s' % (row[0], row[1], row[3][1:-1])) + print('%s\t%s\t%s' % (row.id, row.url, row.tags[1:-1])) elif field_filter == 3: for row in records: - print('%s\t%s' % (row[0], row[2])) + print('%s\t%s' % (row.id, row.title)) elif field_filter == 4: for row in records: - print('%s\t%s\t%s\t%s' % (row[0], row[1], row[2], row[3][1:-1])) + print('%s\t%s\t%s\t%s' % (row.id, row.url, row.title, row.tags[1:-1])) elif field_filter == 5: for row in records: - print('%s\t%s\t%s' % (row[0], row[2], row[3][1:-1])) + print('%s\t%s\t%s' % (row.id, row.title, row.tags[1:-1])) elif field_filter == 10: for row in records: - print(row[1]) + print(row.url) elif field_filter == 20: for row in records: - print('%s\t%s' % (row[1], row[3][1:-1])) + print('%s\t%s' % (row.url, row.tags[1:-1])) elif field_filter == 30: for row in records: - print(row[2]) + print(row.title) elif field_filter == 40: for row in records: - print('%s\t%s\t%s' % (row[1], row[2], row[3][1:-1])) + print('%s\t%s\t%s' % (row.url, row.title, row.tags[1:-1])) elif field_filter == 50: for row in records: - print('%s\t%s' % (row[2], row[3][1:-1])) + print('%s\t%s' % (row.title, row.tags[1:-1])) except BrokenPipeError: sys.stdout = os.fdopen(1) sys.exit(1) -def print_single_rec(row: BookmarkVar, idx: Optional[int]=0, columns: Optional[int]=0): # NOQA +def print_single_rec(row: BookmarkVar, idx: int=0, columns: int=0): # NOQA """Print a single DB record. Handles both search results and individual record. @@ -4536,35 +4533,36 @@ def print_single_rec(row: BookmarkVar, idx: Optional[int]=0, columns: Optional[i ---------- row : tuple Tuple representing bookmark record data. - idx : int, optional + idx : int Search result index. If 0, print with DB index. Default is 0. - columns : int, optional + columns : int Number of columns to wrap comments to. Default is 0. """ str_list = [] + row = BookmarkVar(*row) # ensuring named tuple # Start with index and title if idx != 0: - id_title_res = ID_STR % (idx, row[2] if row[2] else 'Untitled', row[0]) + id_title_res = ID_STR % (idx, row.title or 'Untitled', row.id) else: - id_title_res = ID_DB_STR % (row[0], row[2] if row[2] else 'Untitled') + id_title_res = ID_DB_STR % (row.id, row.title or 'Untitled') # Indicate if record is immutable - if row[5] & 1: + if row.flags & FLAG_IMMUTABLE: id_title_res = MUTE_STR % (id_title_res) else: id_title_res += '\n' try: print(id_title_res, end='') - print(URL_STR % (row[1]), end='') + print(URL_STR % (row.url), end='') if columns == 0: - if row[4]: - print(DESC_STR % (row[4]), end='') - if row[3] != DELIM: - print(TAG_STR % (row[3][1:-1]), end='') + if row.desc: + print(DESC_STR % (row.desc), end='') + if row.tags != DELIM: + print(TAG_STR % (row.tags[1:-1]), end='') print() return @@ -4572,7 +4570,7 @@ def print_single_rec(row: BookmarkVar, idx: Optional[int]=0, columns: Optional[i ln_num = 1 fillwidth = columns - INDENT - for line in textwrap.wrap(row[4].replace('\n', ''), width=fillwidth): + for line in textwrap.wrap(row.desc.replace('\n', ''), width=fillwidth): if ln_num == 1: print(DESC_STR % line, end='') ln_num += 1 @@ -4580,7 +4578,7 @@ def print_single_rec(row: BookmarkVar, idx: Optional[int]=0, columns: Optional[i print(DESC_WRAP % (' ' * INDENT, line)) ln_num = 1 - for line in textwrap.wrap(row[3][1:-1].replace('\n', ''), width=fillwidth): + for line in textwrap.wrap(row.tags[1:-1].replace('\n', ''), width=fillwidth): if ln_num == 1: print(TAG_STR % line, end='') ln_num += 1 @@ -4590,11 +4588,11 @@ def print_single_rec(row: BookmarkVar, idx: Optional[int]=0, columns: Optional[i except UnicodeEncodeError: str_list = [] str_list.append(id_title_res) - str_list.append(URL_STR % (row[1])) - if row[4]: - str_list.append(DESC_STR % (row[4])) - if row[3] != DELIM: - str_list.append(TAG_STR % (row[3][1:-1])) + str_list.append(URL_STR % (row.url)) + if row.desc: + str_list.append(DESC_STR % (row.desc)) + if row.tags != DELIM: + str_list.append(TAG_STR % (row.tags[1:-1])) sys.stdout.buffer.write((''.join(str_list) + '\n').encode('utf-8')) except BrokenPipeError: sys.stdout = os.fdopen(1) @@ -4627,10 +4625,10 @@ def format_json(resultset, single_record=False, field_filter=0): ---------- resultset : list Search results from DB query. - single_record : bool, optional + single_record : bool If True, indicates only one record. Default is False. - field_filter : int, optional - Indicates format for displaying bookmarks. Default is 0. + field_filter : int + Indicates format for displaying bookmarks. Default is 0 ("all fields"). Returns ------- @@ -4638,44 +4636,45 @@ def format_json(resultset, single_record=False, field_filter=0): Record(s) in JSON format. """ + resultset = bookmark_vars(resultset) if single_record: marks = {} for row in resultset: if field_filter == 1: - marks['uri'] = row[1] + marks['uri'] = row.url elif field_filter == 2: - marks['uri'] = row[1] - marks['tags'] = row[3][1:-1] + marks['uri'] = row.url + marks['tags'] = row.tags[1:-1] elif field_filter == 3: - marks['title'] = row[2] + marks['title'] = row.title elif field_filter == 4: - marks['uri'] = row[1] - marks['tags'] = row[3][1:-1] - marks['title'] = row[2] + marks['uri'] = row.url + marks['tags'] = row.tags[1:-1] + marks['title'] = row.title else: - marks['index'] = row[0] - marks['uri'] = row[1] - marks['title'] = row[2] - marks['description'] = row[4] - marks['tags'] = row[3][1:-1] + marks['index'] = row.id + marks['uri'] = row.url + marks['title'] = row.title + marks['description'] = row.desc + marks['tags'] = row.tags[1:-1] else: marks = [] for row in resultset: if field_filter == 1: - record = {'uri': row[1]} + record = {'uri': row.url} elif field_filter == 2: - record = {'uri': row[1], 'tags': row[3][1:-1]} + record = {'uri': row.url, 'tags': row.tags[1:-1]} elif field_filter == 3: - record = {'title': row[2]} + record = {'title': row.title} elif field_filter == 4: - record = {'uri': row[1], 'title': row[2], 'tags': row[3][1:-1]} + record = {'uri': row.url, 'title': row.title, 'tags': row.tags[1:-1]} else: record = { - 'index': row[0], - 'uri': row[1], - 'title': row[2], - 'description': row[4], - 'tags': row[3][1:-1] + 'index': row.id, + 'uri': row.url, + 'title': row.title, + 'description': row.desc, + 'tags': row.tags[1:-1] } marks.append(record) @@ -4690,10 +4689,10 @@ def print_json_safe(resultset, single_record=False, field_filter=0): ---------- resultset : list Search results from DB query. - single_record : bool, optional + single_record : bool If True, indicates only one record. Default is False. - field_filter : int, optional - Indicates format for displaying bookmarks. Default is 0. + field_filter : int + Indicates format for displaying bookmarks. Default is 0 ("all fields"). Returns ------- diff --git a/bukuserver/api.py b/bukuserver/api.py index 5ab984ab..49fe8c15 100644 --- a/bukuserver/api.py +++ b/bukuserver/api.py @@ -111,13 +111,13 @@ def get(self, rec_id: Union[int, None]): result = {'bookmarks': []} # type: Dict[str, Any] for bookmark in all_bookmarks: result_bookmark = { - 'url': bookmark[1], - 'title': bookmark[2], - 'tags': [x for x in bookmark[3].split(',') if x], - 'description': bookmark[4] + 'url': bookmark.url, + 'title': bookmark.title, + 'tags': [x for x in bookmark.tags.split(',') if x], + 'description': bookmark.desc } if not request.path.startswith('/api/'): - result_bookmark['id'] = bookmark[0] + result_bookmark['id'] = bookmark.id result['bookmarks'].append(result_bookmark) res = jsonify(result) else: @@ -127,10 +127,10 @@ def get(self, rec_id: Union[int, None]): res = response_bad() else: res = jsonify({ - 'url': bookmark[1], - 'title': bookmark[2], - 'tags': [x for x in bookmark[3].split(',') if x], - 'description': bookmark[4] + 'url': bookmark.url, + 'title': bookmark.title, + 'tags': [x for x in bookmark.tags.split(',') if x], + 'description': bookmark.desc, }) return res @@ -178,10 +178,10 @@ def get(self, starting_id: int, ending_id: int): for i in range(starting_id, ending_id + 1, 1): bookmark = bukudb.get_rec_by_id(i) result['bookmarks'][i] = { - 'url': bookmark[1], - 'title': bookmark[2], - 'tags': [x for x in bookmark[3].split(',') if x], - 'description': bookmark[4] + 'url': bookmark.url, + 'title': bookmark.title, + 'tags': [x for x in bookmark.tags.split(',') if x], + 'description': bookmark.desc, } return jsonify(result) @@ -236,11 +236,11 @@ def get(self): res = None for bookmark in bukudb.searchdb(keywords, all_keywords, deep, regex): result_bookmark = { - 'id': bookmark[0], - 'url': bookmark[1], - 'title': bookmark[2], - 'tags': list(filter(lambda x: x, bookmark[3].split(','))), - 'description': bookmark[4] + 'id': bookmark.id, + 'url': bookmark.url, + 'title': bookmark.title, + 'tags': [x for x in bookmark.tags.split(',') if x], + 'description': bookmark.desc, } result['bookmarks'].append(result_bookmark) current_app.logger.debug('total bookmarks:{}'.format(len(result['bookmarks']))) @@ -266,7 +266,7 @@ def delete(self): bukudb = getattr(flask.g, 'bukudb', get_bukudb()) res = None for bookmark in bukudb.searchdb(keywords, all_keywords, deep, regex): - if not bukudb.delete_rec(bookmark[0]): + if not bukudb.delete_rec(bookmark.id): res = response_bad() return res or response_ok()