Emphasis on --url option works with -u only.
This commit is contained in:
parent
5f0f372b8c
commit
8ca31e6ce8
@ -123,7 +123,7 @@ Shell completion scripts for Bash, Fish and Zsh can be found in respective subdi
|
|||||||
to change url, tag or comment
|
to change url, tag or comment
|
||||||
-d, --delete [N] delete bookmark at DB index N
|
-d, --delete [N] delete bookmark at DB index N
|
||||||
delete all bookmarks, if no arguments
|
delete all bookmarks, if no arguments
|
||||||
--url keyword specify url, works with -u
|
--url keyword specify url, works with -u only
|
||||||
--tag [...] set comma-separated tags, works with -a, -u
|
--tag [...] set comma-separated tags, works with -a, -u
|
||||||
clears tag, if no arguments
|
clears tag, if no arguments
|
||||||
-t, --title [...] manually set title, works with -a, -u
|
-t, --title [...] manually set title, works with -a, -u
|
||||||
|
204
buku
204
buku
@ -105,72 +105,72 @@ class BukuDb:
|
|||||||
else if $HOME exists, use it
|
else if $HOME exists, use it
|
||||||
else use the current directory
|
else use the current directory
|
||||||
"""
|
"""
|
||||||
|
|
||||||
data_home = os.environ.get('XDG_DATA_HOME')
|
data_home = os.environ.get('XDG_DATA_HOME')
|
||||||
if data_home is None:
|
if data_home is None:
|
||||||
if os.environ.get('HOME') is None:
|
if os.environ.get('HOME') is None:
|
||||||
data_home = '.'
|
data_home = '.'
|
||||||
else:
|
else:
|
||||||
data_home = os.path.join(os.environ.get('HOME'), '.local', 'share')
|
data_home = os.path.join(os.environ.get('HOME'), '.local', 'share')
|
||||||
|
|
||||||
return os.path.join(data_home, 'buku')
|
return os.path.join(data_home, 'buku')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def moveOldDatabase():
|
def moveOldDatabase():
|
||||||
"""Move database file from earlier path used in versions <= 1.8
|
"""Move database file from earlier path used in versions <= 1.8
|
||||||
to new path. Errors out if both the old and new DB files exist.
|
to new path. Errors out if both the old and new DB files exist.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
olddbpath = os.path.join(os.environ.get('HOME'), '.cache', 'buku')
|
olddbpath = os.path.join(os.environ.get('HOME'), '.cache', 'buku')
|
||||||
olddbfile = os.path.join(olddbpath, 'bookmarks.db')
|
olddbfile = os.path.join(olddbpath, 'bookmarks.db')
|
||||||
|
|
||||||
if not os.path.exists(olddbfile):
|
if not os.path.exists(olddbfile):
|
||||||
return
|
return
|
||||||
|
|
||||||
newdbpath = BukuDb.getDataPath()
|
newdbpath = BukuDb.getDataPath()
|
||||||
newdbfile = os.path.join(newdbpath, 'bookmarks.db')
|
newdbfile = os.path.join(newdbpath, 'bookmarks.db')
|
||||||
|
|
||||||
if os.path.exists(newdbfile):
|
if os.path.exists(newdbfile):
|
||||||
print("Both old (%s) and new (%s) databases exist, need manual action" % (olddbfile, newdbfile))
|
print("Both old (%s) and new (%s) databases exist, need manual action" % (olddbfile, newdbfile))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not os.path.exists(newdbpath):
|
if not os.path.exists(newdbpath):
|
||||||
os.makedirs(newdbpath)
|
os.makedirs(newdbpath)
|
||||||
|
|
||||||
os.rename(olddbfile, newdbfile)
|
os.rename(olddbfile, newdbfile)
|
||||||
print("Database was moved from old (%s) to new (%s) location.\n" % (olddbfile, newdbfile))
|
print("Database was moved from old (%s) to new (%s) location.\n" % (olddbfile, newdbfile))
|
||||||
|
|
||||||
os.rmdir(olddbpath)
|
os.rmdir(olddbpath)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def initdb():
|
def initdb():
|
||||||
"""Initialize the database connection. Create DB file and/or bookmarks table
|
"""Initialize the database connection. Create DB file and/or bookmarks table
|
||||||
if they don't exist. Alert on encryption options on first execution.
|
if they don't exist. Alert on encryption options on first execution.
|
||||||
|
|
||||||
Returns: connection, cursor
|
Returns: connection, cursor
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dbpath = BukuDb.getDataPath()
|
dbpath = BukuDb.getDataPath()
|
||||||
if not os.path.exists(dbpath):
|
if not os.path.exists(dbpath):
|
||||||
os.makedirs(dbpath)
|
os.makedirs(dbpath)
|
||||||
|
|
||||||
dbfile = os.path.join(dbpath, 'bookmarks.db')
|
dbfile = os.path.join(dbpath, 'bookmarks.db')
|
||||||
|
|
||||||
encpath = os.path.join(dbpath, 'bookmarks.db.enc')
|
encpath = os.path.join(dbpath, 'bookmarks.db.enc')
|
||||||
# Notify if DB file needs to be decrypted first
|
# Notify if DB file needs to be decrypted first
|
||||||
if os.path.exists(encpath) and not os.path.exists(dbfile):
|
if os.path.exists(encpath) and not os.path.exists(dbfile):
|
||||||
print("Unlock database first")
|
print("Unlock database first")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Show info on first creation
|
# Show info on first creation
|
||||||
if no_crypto == False and not os.path.exists(dbfile):
|
if no_crypto == False and not os.path.exists(dbfile):
|
||||||
print("DB file is being created. You may want to encrypt it later.")
|
print("DB file is being created. You may want to encrypt it later.")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Create a connection
|
# Create a connection
|
||||||
conn = sqlite3.connect(dbfile)
|
conn = sqlite3.connect(dbfile)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
|
|
||||||
# Create table if it doesn't exist
|
# Create table if it doesn't exist
|
||||||
cur.execute('''CREATE TABLE if not exists bookmarks \
|
cur.execute('''CREATE TABLE if not exists bookmarks \
|
||||||
(id integer PRIMARY KEY, URL text NOT NULL UNIQUE, metadata text default \'\', tags text default \',\', desc text default \'\')''')
|
(id integer PRIMARY KEY, URL text NOT NULL UNIQUE, metadata text default \'\', tags text default \',\', desc text default \'\')''')
|
||||||
@ -178,50 +178,50 @@ class BukuDb:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("\x1b[1mEXCEPTION\x1b[21m [initdb]: (%s) %s" % (type(e).__name__, e))
|
print("\x1b[1mEXCEPTION\x1b[21m [initdb]: (%s) %s" % (type(e).__name__, e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Add description column in existing DB (from version 2.1)
|
# Add description column in existing DB (from version 2.1)
|
||||||
try:
|
try:
|
||||||
cur.execute("""ALTER TABLE bookmarks ADD COLUMN desc text default \'\'""")
|
cur.execute("""ALTER TABLE bookmarks ADD COLUMN desc text default \'\'""")
|
||||||
conn.commit()
|
conn.commit()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return (conn, cur)
|
return (conn, cur)
|
||||||
|
|
||||||
def isBookmarkAdded(self, url):
|
def isBookmarkAdded(self, url):
|
||||||
"""Check if URL already exists in DB
|
"""Check if URL already exists in DB
|
||||||
|
|
||||||
Params: URL to search
|
Params: URL to search
|
||||||
Returns: DB index if URL found, else -1
|
Returns: DB index if URL found, else -1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.cur.execute("SELECT id FROM bookmarks WHERE URL = ?", (url,))
|
self.cur.execute("SELECT id FROM bookmarks WHERE URL = ?", (url,))
|
||||||
resultset = self.cur.fetchall()
|
resultset = self.cur.fetchall()
|
||||||
if len(resultset) == 0:
|
if len(resultset) == 0:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
return resultset[0][0]
|
return resultset[0][0]
|
||||||
|
|
||||||
def AddInsertEntry(self, keywords, insertindex=0):
|
def AddInsertEntry(self, keywords, insertindex=0):
|
||||||
"""Add a new bookmark or insert a
|
"""Add a new bookmark or insert a
|
||||||
new record at insertindex (if empty)
|
new record at insertindex (if empty)
|
||||||
|
|
||||||
Params: keywords, index to update, index to insert at
|
Params: keywords, index to update, index to insert at
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global tagManual
|
global tagManual
|
||||||
global titleManual
|
global titleManual
|
||||||
global description
|
global description
|
||||||
tags = ','
|
tags = ','
|
||||||
meta = ''
|
meta = ''
|
||||||
url = keywords[0]
|
url = keywords[0]
|
||||||
|
|
||||||
# Ensure that the URL does not exist in DB already
|
# Ensure that the URL does not exist in DB already
|
||||||
id = self.isBookmarkAdded(url)
|
id = self.isBookmarkAdded(url)
|
||||||
if id != -1:
|
if id != -1:
|
||||||
print("URL already exists at index %d" % id)
|
print("URL already exists at index %d" % id)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Process title
|
# Process title
|
||||||
if titleManual is not None:
|
if titleManual is not None:
|
||||||
meta = titleManual
|
meta = titleManual
|
||||||
@ -231,24 +231,24 @@ class BukuDb:
|
|||||||
print("\x1B[91mTitle: []\x1B[0m")
|
print("\x1B[91mTitle: []\x1B[0m")
|
||||||
else:
|
else:
|
||||||
print("Title: [%s]" % meta)
|
print("Title: [%s]" % meta)
|
||||||
|
|
||||||
# Process tags
|
# Process tags
|
||||||
if tagManual is not None and False == (tagManual[0] == ',' and len(tagManual) == 1):
|
if tagManual is not None and False == (tagManual[0] == ',' and len(tagManual) == 1):
|
||||||
keywords = keywords + [','] + tagManual
|
keywords = keywords + [','] + tagManual
|
||||||
|
|
||||||
if len(keywords) > 1:
|
if len(keywords) > 1:
|
||||||
tags = getTags(keywords[1:])
|
tags = getTags(keywords[1:])
|
||||||
|
|
||||||
# Process description
|
# Process description
|
||||||
if description is None:
|
if description is None:
|
||||||
description = ''
|
description = ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if insertindex == 0: # insertindex is index number to insert record at
|
if insertindex == 0: # insertindex is index number to insert record at
|
||||||
self.cur.execute('INSERT INTO bookmarks(URL, metadata, tags, desc) VALUES (?, ?, ?, ?)', (url, meta, tags, description))
|
self.cur.execute('INSERT INTO bookmarks(URL, metadata, tags, desc) VALUES (?, ?, ?, ?)', (url, meta, tags, description))
|
||||||
else:
|
else:
|
||||||
self.cur.execute('INSERT INTO bookmarks(id, URL, metadata, tags, desc) VALUES (?, ?, ?, ?, ?)', (insertindex, url, meta, tags, description))
|
self.cur.execute('INSERT INTO bookmarks(id, URL, metadata, tags, desc) VALUES (?, ?, ?, ?, ?)', (insertindex, url, meta, tags, description))
|
||||||
|
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
print("Added at index %d\n" % self.cur.lastrowid)
|
print("Added at index %d\n" % self.cur.lastrowid)
|
||||||
self.printdb(self.cur.lastrowid)
|
self.printdb(self.cur.lastrowid)
|
||||||
@ -256,14 +256,14 @@ class BukuDb:
|
|||||||
for row in self.cur.execute("SELECT id from bookmarks where URL LIKE ?", (url,)):
|
for row in self.cur.execute("SELECT id from bookmarks where URL LIKE ?", (url,)):
|
||||||
print("URL already exists at index %s" % row[0])
|
print("URL already exists at index %s" % row[0])
|
||||||
return
|
return
|
||||||
|
|
||||||
# Print error for index existing case
|
# Print error for index existing case
|
||||||
print("Index %d exists" % insertindex)
|
print("Index %d exists" % insertindex)
|
||||||
|
|
||||||
|
|
||||||
def UpdateEntry(self, index, url='', tag_manual=None, title_manual=None, desc=None):
|
def UpdateEntry(self, index, url='', tag_manual=None, title_manual=None, desc=None):
|
||||||
""" Update an existing record at index
|
""" Update an existing record at index
|
||||||
|
|
||||||
:param index: int position to update
|
:param index: int position to update
|
||||||
:param url: address
|
:param url: address
|
||||||
:param tag_manual: list of tags to add manually
|
:param tag_manual: list of tags to add manually
|
||||||
@ -271,17 +271,17 @@ class BukuDb:
|
|||||||
:param desc: string description
|
:param desc: string description
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
arguments = []
|
arguments = []
|
||||||
query = "UPDATE bookmarks SET"
|
query = "UPDATE bookmarks SET"
|
||||||
to_update = False
|
to_update = False
|
||||||
|
|
||||||
# Update URL if passed as argument
|
# Update URL if passed as argument
|
||||||
if url != '':
|
if url != '':
|
||||||
query += " URL = ?,"
|
query += " URL = ?,"
|
||||||
arguments.append(url)
|
arguments.append(url)
|
||||||
to_update = True
|
to_update = True
|
||||||
|
|
||||||
# Update tags if passed as argument
|
# Update tags if passed as argument
|
||||||
if tag_manual is not None:
|
if tag_manual is not None:
|
||||||
tags = ','
|
tags = ','
|
||||||
@ -290,13 +290,13 @@ class BukuDb:
|
|||||||
query += " tags = ?,"
|
query += " tags = ?,"
|
||||||
arguments.append(tags)
|
arguments.append(tags)
|
||||||
to_update = True
|
to_update = True
|
||||||
|
|
||||||
# Update description if passed as an argument
|
# Update description if passed as an argument
|
||||||
if desc is not None:
|
if desc is not None:
|
||||||
query += " desc = ?,"
|
query += " desc = ?,"
|
||||||
arguments.append(desc)
|
arguments.append(desc)
|
||||||
to_update = True
|
to_update = True
|
||||||
|
|
||||||
# Update title
|
# Update title
|
||||||
#
|
#
|
||||||
# 1. if -t has no arguments, delete existing title
|
# 1. if -t has no arguments, delete existing title
|
||||||
@ -316,20 +316,20 @@ class BukuDb:
|
|||||||
elif not to_update:
|
elif not to_update:
|
||||||
self.dbRefresh(index)
|
self.dbRefresh(index)
|
||||||
self.printdb(index)
|
self.printdb(index)
|
||||||
|
|
||||||
if meta is not None:
|
if meta is not None:
|
||||||
query += " metadata = ?,"
|
query += " metadata = ?,"
|
||||||
arguments.append(meta)
|
arguments.append(meta)
|
||||||
to_update = True
|
to_update = True
|
||||||
|
|
||||||
if not to_update: # Nothing to update
|
if not to_update: # Nothing to update
|
||||||
return
|
return
|
||||||
|
|
||||||
query = query[:-1] + " WHERE id = ?"
|
query = query[:-1] + " WHERE id = ?"
|
||||||
arguments.append(index)
|
arguments.append(index)
|
||||||
if debug:
|
if debug:
|
||||||
print("query: [%s], args: [%s]" % (query, arguments))
|
print("query: [%s], args: [%s]" % (query, arguments))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.cur.execute(query, arguments)
|
self.cur.execute(query, arguments)
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
@ -340,24 +340,24 @@ class BukuDb:
|
|||||||
print("No matching index")
|
print("No matching index")
|
||||||
except sqlite3.IntegrityError:
|
except sqlite3.IntegrityError:
|
||||||
print("URL already exists")
|
print("URL already exists")
|
||||||
|
|
||||||
|
|
||||||
def dbRefresh(self, index):
|
def dbRefresh(self, index):
|
||||||
"""Refresh ALL records in the database. Fetch title for each
|
"""Refresh ALL records in the database. Fetch title for each
|
||||||
bookmark from the web and update the records. Doesn't udpate
|
bookmark from the web and update the records. Doesn't udpate
|
||||||
the record if title is empty.
|
the record if title is empty.
|
||||||
This API doesn't change DB index, URL or tags of a bookmark.
|
This API doesn't change DB index, URL or tags of a bookmark.
|
||||||
|
|
||||||
Params: index of record to update, or 0 for all records
|
Params: index of record to update, or 0 for all records
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global titleManual
|
global titleManual
|
||||||
|
|
||||||
if index == 0:
|
if index == 0:
|
||||||
self.cur.execute("SELECT id, url FROM bookmarks ORDER BY id ASC")
|
self.cur.execute("SELECT id, url FROM bookmarks ORDER BY id ASC")
|
||||||
else:
|
else:
|
||||||
self.cur.execute("SELECT id, url FROM bookmarks WHERE id = ?", (index,))
|
self.cur.execute("SELECT id, url FROM bookmarks WHERE id = ?", (index,))
|
||||||
|
|
||||||
resultset = self.cur.fetchall()
|
resultset = self.cur.fetchall()
|
||||||
if titleManual is None:
|
if titleManual is None:
|
||||||
for row in resultset:
|
for row in resultset:
|
||||||
@ -368,31 +368,31 @@ class BukuDb:
|
|||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
print("Title: [%s]" % title)
|
print("Title: [%s]" % title)
|
||||||
|
|
||||||
self.cur.execute("UPDATE bookmarks SET metadata = ? WHERE id = ?", (title, row[0],))
|
self.cur.execute("UPDATE bookmarks SET metadata = ? WHERE id = ?", (title, row[0],))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
print("Updated index %d\n" % row[0])
|
print("Updated index %d\n" % row[0])
|
||||||
else:
|
else:
|
||||||
title = titleManual
|
title = titleManual
|
||||||
|
|
||||||
for row in resultset:
|
for row in resultset:
|
||||||
self.cur.execute("UPDATE bookmarks SET metadata = ? WHERE id = ?", (title, row[0],))
|
self.cur.execute("UPDATE bookmarks SET metadata = ? WHERE id = ?", (title, row[0],))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
print("Updated index %d\n" % row[0])
|
print("Updated index %d\n" % row[0])
|
||||||
|
|
||||||
|
|
||||||
def searchdb(self, keywords, all_keywords=False):
|
def searchdb(self, keywords, all_keywords=False):
|
||||||
"""Search the database for an entries with tags or URL
|
"""Search the database for an entries with tags or URL
|
||||||
or title info matching keywords and list those.
|
or title info matching keywords and list those.
|
||||||
|
|
||||||
Params: keywords to search, search any or all keywords
|
Params: keywords to search, search any or all keywords
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global jsonOutput
|
global jsonOutput
|
||||||
arguments = []
|
arguments = []
|
||||||
placeholder = "'%' || ? || '%'"
|
placeholder = "'%' || ? || '%'"
|
||||||
query = "SELECT id, url, metadata, tags, desc FROM bookmarks WHERE"
|
query = "SELECT id, url, metadata, tags, desc FROM bookmarks WHERE"
|
||||||
|
|
||||||
if all_keywords == True: # Match all keywords in URL or Title
|
if all_keywords == True: # Match all keywords in URL or Title
|
||||||
for token in keywords:
|
for token in keywords:
|
||||||
query += " (tags LIKE (%s) OR URL LIKE (%s) OR metadata LIKE (%s) OR desc LIKE (%s)) AND" % (placeholder, placeholder, placeholder, placeholder)
|
query += " (tags LIKE (%s) OR URL LIKE (%s) OR metadata LIKE (%s) OR desc LIKE (%s)) AND" % (placeholder, placeholder, placeholder, placeholder)
|
||||||
@ -409,50 +409,50 @@ class BukuDb:
|
|||||||
arguments.append(token)
|
arguments.append(token)
|
||||||
arguments.append(token)
|
arguments.append(token)
|
||||||
query = query[:-3]
|
query = query[:-3]
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
print("\"%s\", (%s)" % (query, arguments))
|
print("\"%s\", (%s)" % (query, arguments))
|
||||||
|
|
||||||
self.cur.execute(query, arguments)
|
self.cur.execute(query, arguments)
|
||||||
results = self.cur.fetchall()
|
results = self.cur.fetchall()
|
||||||
if len(results) == 0:
|
if len(results) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if jsonOutput == False:
|
if jsonOutput == False:
|
||||||
showPrompt(results)
|
showPrompt(results)
|
||||||
else:
|
else:
|
||||||
print(formatJson(results))
|
print(formatJson(results))
|
||||||
|
|
||||||
|
|
||||||
def searchTag(self, tag):
|
def searchTag(self, tag):
|
||||||
"""Search and list bookmarks with a tag
|
"""Search and list bookmarks with a tag
|
||||||
|
|
||||||
Params: tag to search
|
Params: tag to search
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global jsonOutput
|
global jsonOutput
|
||||||
self.cur.execute("SELECT id, url, metadata, tags, desc FROM bookmarks WHERE tags LIKE '%' || ? || '%'", (tag,))
|
self.cur.execute("SELECT id, url, metadata, tags, desc FROM bookmarks WHERE tags LIKE '%' || ? || '%'", (tag,))
|
||||||
results = self.cur.fetchall()
|
results = self.cur.fetchall()
|
||||||
if len(results) == 0:
|
if len(results) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if jsonOutput == False:
|
if jsonOutput == False:
|
||||||
showPrompt(results)
|
showPrompt(results)
|
||||||
else:
|
else:
|
||||||
print(formatJson(results))
|
print(formatJson(results))
|
||||||
|
|
||||||
def compactDB(self, index):
|
def compactDB(self, index):
|
||||||
"""When an entry at index is deleted, move the last
|
"""When an entry at index is deleted, move the last
|
||||||
entry in DB to index, if index is lesser.
|
entry in DB to index, if index is lesser.
|
||||||
|
|
||||||
Params: index of deleted entry
|
Params: index of deleted entry
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.cur.execute('SELECT MAX(id) from bookmarks')
|
self.cur.execute('SELECT MAX(id) from bookmarks')
|
||||||
results = self.cur.fetchall()
|
results = self.cur.fetchall()
|
||||||
if len(results) == 1 and results[0][0] is None: # Return if the last index was just deleted
|
if len(results) == 1 and results[0][0] is None: # Return if the last index was just deleted
|
||||||
return
|
return
|
||||||
|
|
||||||
for row in results:
|
for row in results:
|
||||||
if row[0] > index:
|
if row[0] > index:
|
||||||
self.cur.execute('SELECT id, URL, metadata, tags, desc FROM bookmarks WHERE id = ?', (row[0],))
|
self.cur.execute('SELECT id, URL, metadata, tags, desc FROM bookmarks WHERE id = ?', (row[0],))
|
||||||
@ -463,20 +463,20 @@ class BukuDb:
|
|||||||
self.cur.execute('INSERT INTO bookmarks(id, URL, metadata, tags, desc) VALUES (?, ?, ?, ?, ?)', (index, row[1], row[2], row[3], row[4],))
|
self.cur.execute('INSERT INTO bookmarks(id, URL, metadata, tags, desc) VALUES (?, ?, ?, ?, ?)', (index, row[1], row[2], row[3], row[4],))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
print("Index %d moved to %d" % (row[0], index))
|
print("Index %d moved to %d" % (row[0], index))
|
||||||
|
|
||||||
|
|
||||||
def cleardb(self, index):
|
def cleardb(self, index):
|
||||||
"""Delete a single record or remove the table if index is None
|
"""Delete a single record or remove the table if index is None
|
||||||
|
|
||||||
Params: index to delete
|
Params: index to delete
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if index == 0: # Remove the table
|
if index == 0: # Remove the table
|
||||||
resp = input("ALL bookmarks will be removed. Enter \x1b[1my\x1b[21m to confirm: ")
|
resp = input("ALL bookmarks will be removed. Enter \x1b[1my\x1b[21m to confirm: ")
|
||||||
if resp != 'y':
|
if resp != 'y':
|
||||||
print("No bookmarks deleted")
|
print("No bookmarks deleted")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.cur.execute('DROP TABLE if exists bookmarks')
|
self.cur.execute('DROP TABLE if exists bookmarks')
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
print("All bookmarks deleted")
|
print("All bookmarks deleted")
|
||||||
@ -491,18 +491,18 @@ class BukuDb:
|
|||||||
print("No matching index")
|
print("No matching index")
|
||||||
except IndexError:
|
except IndexError:
|
||||||
print("Index out of bound")
|
print("Index out of bound")
|
||||||
|
|
||||||
def printdb(self, index, empty=False):
|
def printdb(self, index, empty=False):
|
||||||
"""Print bookmark details at index or all bookmarks if index is None
|
"""Print bookmark details at index or all bookmarks if index is None
|
||||||
Print only bookmarks with blank title or tag if empty is True
|
Print only bookmarks with blank title or tag if empty is True
|
||||||
Note: URL is printed on top because title may be blank
|
Note: URL is printed on top because title may be blank
|
||||||
|
|
||||||
Params: index to print, flag to show only bookmarks with no title or tags
|
Params: index to print, flag to show only bookmarks with no title or tags
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global showOpt
|
global showOpt
|
||||||
global jsonOutput
|
global jsonOutput
|
||||||
|
|
||||||
resultset = None
|
resultset = None
|
||||||
if index == 0: # Show all entries
|
if index == 0: # Show all entries
|
||||||
if empty == False:
|
if empty == False:
|
||||||
@ -512,7 +512,7 @@ class BukuDb:
|
|||||||
self.cur.execute("SELECT * FROM bookmarks WHERE metadata = '' OR tags = ','")
|
self.cur.execute("SELECT * FROM bookmarks WHERE metadata = '' OR tags = ','")
|
||||||
resultset = self.cur.fetchall()
|
resultset = self.cur.fetchall()
|
||||||
print("\x1b[1m%d records found\x1b[21m\n" % len(resultset))
|
print("\x1b[1m%d records found\x1b[21m\n" % len(resultset))
|
||||||
|
|
||||||
if jsonOutput == False:
|
if jsonOutput == False:
|
||||||
if showOpt == 0:
|
if showOpt == 0:
|
||||||
for row in resultset:
|
for row in resultset:
|
||||||
@ -523,7 +523,7 @@ class BukuDb:
|
|||||||
elif showOpt == 2:
|
elif showOpt == 2:
|
||||||
for row in resultset:
|
for row in resultset:
|
||||||
print("%s %s %s" % (row[0], row[1], row[3][1:-1]))
|
print("%s %s %s" % (row[0], row[1], row[3][1:-1]))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print(formatJson(resultset))
|
print(formatJson(resultset))
|
||||||
else: # Show record at index
|
else: # Show record at index
|
||||||
@ -532,7 +532,7 @@ class BukuDb:
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
print("Index out of bound")
|
print("Index out of bound")
|
||||||
return
|
return
|
||||||
|
|
||||||
if jsonOutput == False:
|
if jsonOutput == False:
|
||||||
for row in resultset:
|
for row in resultset:
|
||||||
printRecord(row)
|
printRecord(row)
|
||||||
@ -544,37 +544,37 @@ class BukuDb:
|
|||||||
def showUniqueTags(self):
|
def showUniqueTags(self):
|
||||||
"""Print all unique tags ordered alphabetically
|
"""Print all unique tags ordered alphabetically
|
||||||
"""
|
"""
|
||||||
|
|
||||||
count = 1
|
count = 1
|
||||||
Tags = []
|
Tags = []
|
||||||
uniqueTags = []
|
uniqueTags = []
|
||||||
for row in self.cur.execute('SELECT DISTINCT tags FROM bookmarks'):
|
for row in self.cur.execute('SELECT DISTINCT tags FROM bookmarks'):
|
||||||
if row[0] == ',':
|
if row[0] == ',':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
Tags.extend(row[0].strip(',').split(','))
|
Tags.extend(row[0].strip(',').split(','))
|
||||||
|
|
||||||
for tag in Tags:
|
for tag in Tags:
|
||||||
if tag not in uniqueTags:
|
if tag not in uniqueTags:
|
||||||
uniqueTags.append(tag)
|
uniqueTags.append(tag)
|
||||||
|
|
||||||
Tags = sorted(uniqueTags, key=str.lower)
|
Tags = sorted(uniqueTags, key=str.lower)
|
||||||
for tag in Tags:
|
for tag in Tags:
|
||||||
print("%6d. %s" % (count, tag))
|
print("%6d. %s" % (count, tag))
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
|
|
||||||
def replaceTag(self, orig, new=None):
|
def replaceTag(self, orig, new=None):
|
||||||
"""Replace orig tags with new tags in DB for all records.
|
"""Replace orig tags with new tags in DB for all records.
|
||||||
Remove orig tag is new tag is empty.
|
Remove orig tag is new tag is empty.
|
||||||
|
|
||||||
Params: original and new tags
|
Params: original and new tags
|
||||||
"""
|
"""
|
||||||
|
|
||||||
update = False
|
update = False
|
||||||
delete = False
|
delete = False
|
||||||
newtags = ','
|
newtags = ','
|
||||||
|
|
||||||
orig = ',' + orig + ','
|
orig = ',' + orig + ','
|
||||||
if new is None:
|
if new is None:
|
||||||
delete = True
|
delete = True
|
||||||
@ -584,39 +584,39 @@ class BukuDb:
|
|||||||
tag = tag.strip(',') + ',' # if delimiter is present, maintain it
|
tag = tag.strip(',') + ',' # if delimiter is present, maintain it
|
||||||
else:
|
else:
|
||||||
tag = tag.strip(',') # a token in a multi-word tag
|
tag = tag.strip(',') # a token in a multi-word tag
|
||||||
|
|
||||||
if tag == ',':
|
if tag == ',':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if newtags[-1] == ',':
|
if newtags[-1] == ',':
|
||||||
newtags += tag
|
newtags += tag
|
||||||
else:
|
else:
|
||||||
newtags += ' ' + tag
|
newtags += ' ' + tag
|
||||||
|
|
||||||
if newtags[-1] != ',':
|
if newtags[-1] != ',':
|
||||||
newtags += ','
|
newtags += ','
|
||||||
|
|
||||||
if newtags == ',':
|
if newtags == ',':
|
||||||
delete = True
|
delete = True
|
||||||
|
|
||||||
if orig == newtags:
|
if orig == newtags:
|
||||||
print("Tags are same.")
|
print("Tags are same.")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.cur.execute("SELECT id, tags FROM bookmarks WHERE tags LIKE ?", ('%' + orig + '%',))
|
self.cur.execute("SELECT id, tags FROM bookmarks WHERE tags LIKE ?", ('%' + orig + '%',))
|
||||||
results = self.cur.fetchall()
|
results = self.cur.fetchall()
|
||||||
|
|
||||||
for row in results:
|
for row in results:
|
||||||
if delete == False:
|
if delete == False:
|
||||||
# Check if tag newtags is already added
|
# Check if tag newtags is already added
|
||||||
if row[1].find(newtags) >= 0:
|
if row[1].find(newtags) >= 0:
|
||||||
newtags = ','
|
newtags = ','
|
||||||
|
|
||||||
newtags = row[1].replace(orig, newtags)
|
newtags = row[1].replace(orig, newtags)
|
||||||
self.cur.execute("UPDATE bookmarks SET tags = ? WHERE id = ?", (newtags, row[0],))
|
self.cur.execute("UPDATE bookmarks SET tags = ? WHERE id = ?", (newtags, row[0],))
|
||||||
print("Updated index %d" % row[0])
|
print("Updated index %d" % row[0])
|
||||||
update = True
|
update = True
|
||||||
|
|
||||||
if update:
|
if update:
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
|
||||||
@ -1274,7 +1274,7 @@ general_group = argparser.add_argument_group(title="general options",
|
|||||||
to change url, tag or comment
|
to change url, tag or comment
|
||||||
-d, --delete [N] delete bookmark at DB index N
|
-d, --delete [N] delete bookmark at DB index N
|
||||||
delete all bookmarks, if no arguments
|
delete all bookmarks, if no arguments
|
||||||
--url keyword specify url, works with -u
|
--url keyword specify url, works with -u only
|
||||||
--tag [...] set comma-separated tags, works with -a, -u
|
--tag [...] set comma-separated tags, works with -a, -u
|
||||||
clears tag, if no arguments
|
clears tag, if no arguments
|
||||||
-t, --title [...] manually set title, works with -a, -u
|
-t, --title [...] manually set title, works with -a, -u
|
||||||
|
2
buku.1
2
buku.1
@ -71,7 +71,7 @@ in DB (from -p output). The last record is moved to the removed index. If
|
|||||||
is omitted, all records are deleted from the DB.
|
is omitted, all records are deleted from the DB.
|
||||||
.TP
|
.TP
|
||||||
.BI \--url " [...]"
|
.BI \--url " [...]"
|
||||||
Specify the URL, works with -u. Fetches and updates title if --title is not used.
|
Specify the URL, works with -u only. Fetches and updates title if --title is not used.
|
||||||
.TP
|
.TP
|
||||||
.BI \--tag " [...]"
|
.BI \--tag " [...]"
|
||||||
Specify comma separated tags, works with -a, -u. Clears the tags, if no arguments passed.
|
Specify comma separated tags, works with -a, -u. Clears the tags, if no arguments passed.
|
||||||
|
Loading…
Reference in New Issue
Block a user