Hello community,

here is the log from the commit of package python-buku for openSUSE:Factory 
checked in at 2017-09-20 17:12:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-buku (Old)
 and      /work/SRC/openSUSE:Factory/.python-buku.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-buku"

Wed Sep 20 17:12:30 2017 rev:4 rq:527319 version:3.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-buku/python-buku.changes  2017-09-12 
19:55:32.225877562 +0200
+++ /work/SRC/openSUSE:Factory/.python-buku.new/python-buku.changes     
2017-09-20 17:12:31.418968337 +0200
@@ -1,0 +2,11 @@
+Mon Sep 18 08:05:12 UTC 2017 - [email protected]
+
+- Update to version 3.4
+  * Export bookmarks (including specific tags) to Buku DB file
+    using --export
+  * Option --import can merge Buku DB files now, option --merge is
+    retired
+  * Option --suggest now works at prompt as well
+  * Auto-import issue when Firefox is not installed fixed
+
+-------------------------------------------------------------------

Old:
----
  buku-3.3.1.tar.gz

New:
----
  buku-3.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-buku.spec ++++++
--- /var/tmp/diff_new_pack.AhKjv0/_old  2017-09-20 17:12:31.970890644 +0200
+++ /var/tmp/diff_new_pack.AhKjv0/_new  2017-09-20 17:12:31.970890644 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-buku
-Version:        3.3.1
+Version:        3.4
 Release:        0
 Summary:        Command-line bookmark manager
 License:        GPL-3.0+

++++++ buku-3.3.1.tar.gz -> buku-3.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/CHANGELOG new/buku-3.4/CHANGELOG
--- old/buku-3.3.1/CHANGELOG    2017-09-11 07:36:37.000000000 +0200
+++ new/buku-3.4/CHANGELOG      2017-09-18 09:53:49.000000000 +0200
@@ -1,3 +1,14 @@
+Buku 3.4
+2017-09-18
+
+What's in?
+- Export bookmarks (including specific tags) to Buku DB file using `--export`
+- Option `--import` can merge Buku DB files now, option `--merge` is retired
+- Option `--suggest` now works at prompt as well
+- Auto-import issue when Firefox is not installed fixed
+
+-------------------------------------------------------------------------------
+
 Buku 3.3.1
 2017-09-11
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/PKG-INFO new/buku-3.4/PKG-INFO
--- old/buku-3.3.1/PKG-INFO     2017-09-11 07:37:02.000000000 +0200
+++ new/buku-3.4/PKG-INFO       2017-09-18 09:54:17.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: buku
-Version: 3.3.1
+Version: 3.4
 Summary: Powerful command-line bookmark manager.
 Home-page: https://github.com/jarun/Buku
 Author: Arun Prakash Jana
 Author-email: [email protected]
 License: GPLv3
+Description-Content-Type: UNKNOWN
 Description: <h1 align="center">Buku</h1>
         
         <p align="center">
@@ -21,7 +22,7 @@
         </p>
         
         <p align="center">
-        <a href="https://asciinema.org/a/137065";><img 
src="https://asciinema.org/a/137065.png"; alt="Buku in action!" width="734"/></a>
+        <a href="https://asciinema.org/a/137065";><img 
src="https://s26.postimg.org/o6lka0dw9/buku_demo.png"; alt="Buku in action!" 
width="734"/></a>
         </p>
         
         <p align="center"><i>Buku in action!</i></p>
@@ -196,24 +197,23 @@
                                    search bookmarks by tags
                                    use ',' to find entries matching ANY tag
                                    use '+' to find entries matching ALL tags
-                                   excludes entries matching tags following ' 
- '
+                                   excludes entries with tags after ' - '
                                    list all tags, if no search keywords
         
         ENCRYPTION OPTIONS:
-              -l, --lock [N]       encrypt DB file with N (> 0, default 8)
-                                   hash iterations to generate key
-              -k, --unlock [N]     decrypt DB file with N (> 0, default 8)
-                                   hash iterations to generate key
+              -l, --lock [N]       encrypt DB in N (default 8) # iterations
+              -k, --unlock [N]     decrypt DB in N (default 8) # iterations
         
         POWER TOYS:
               --ai                 auto-import from Firefox and Chrome
               -e, --export file    export bookmarks in Firefox format html
                                    export markdown, if file ends with '.md'
                                    format: [title](url), 1 entry per line
-                                   use --tag to export only specific tags
+                                   export buku DB, if file ends with '.db'
+                                   use --tag to export specific tags
               -i, --import file    import Firefox or Chrome bookmarks html
                                    import markdown, if file ends with '.md'
-              -m, --merge file     add bookmarks from another buku DB file
+                                   import buku DB, if file ends with '.db'
               -p, --print [...]    show record details by indices, ranges
                                    print all bookmarks, if no arguments
                                    -n shows the last n results (like tail)
@@ -308,11 +308,13 @@
         
                 $ buku -e bookmarks.html --tag tag 1, tag 2
                 $ buku -e bookmarks.md --tag tag 1, tag 2
+                $ buku -e bookmarks.db --tag tag 1, tag 2
             All bookmarks are exported if --tag is not specified.
         10. **Import** bookmarks from HTML and markdown:
         
                 $ buku -i bookmarks.html
                 $ buku -i bookmarks.md
+                $ buku -i bookmarks.db
         11. **Delete only comment** for bookmark at 15012014:
         
                 $ buku -u 15012014 -c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/README.md new/buku-3.4/README.md
--- old/buku-3.3.1/README.md    2017-09-11 07:36:37.000000000 +0200
+++ new/buku-3.4/README.md      2017-09-18 09:53:49.000000000 +0200
@@ -13,7 +13,7 @@
 </p>
 
 <p align="center">
-<a href="https://asciinema.org/a/137065";><img 
src="https://asciinema.org/a/137065.png"; alt="Buku in action!" width="734"/></a>
+<a href="https://asciinema.org/a/137065";><img 
src="https://s26.postimg.org/o6lka0dw9/buku_demo.png"; alt="Buku in action!" 
width="734"/></a>
 </p>
 
 <p align="center"><i>Buku in action!</i></p>
@@ -188,24 +188,23 @@
                            search bookmarks by tags
                            use ',' to find entries matching ANY tag
                            use '+' to find entries matching ALL tags
-                           excludes entries matching tags following ' - '
+                           excludes entries with tags after ' - '
                            list all tags, if no search keywords
 
 ENCRYPTION OPTIONS:
-      -l, --lock [N]       encrypt DB file with N (> 0, default 8)
-                           hash iterations to generate key
-      -k, --unlock [N]     decrypt DB file with N (> 0, default 8)
-                           hash iterations to generate key
+      -l, --lock [N]       encrypt DB in N (default 8) # iterations
+      -k, --unlock [N]     decrypt DB in N (default 8) # iterations
 
 POWER TOYS:
       --ai                 auto-import from Firefox and Chrome
       -e, --export file    export bookmarks in Firefox format html
                            export markdown, if file ends with '.md'
                            format: [title](url), 1 entry per line
-                           use --tag to export only specific tags
+                           export buku DB, if file ends with '.db'
+                           use --tag to export specific tags
       -i, --import file    import Firefox or Chrome bookmarks html
                            import markdown, if file ends with '.md'
-      -m, --merge file     add bookmarks from another buku DB file
+                           import buku DB, if file ends with '.db'
       -p, --print [...]    show record details by indices, ranges
                            print all bookmarks, if no arguments
                            -n shows the last n results (like tail)
@@ -300,11 +299,13 @@
 
         $ buku -e bookmarks.html --tag tag 1, tag 2
         $ buku -e bookmarks.md --tag tag 1, tag 2
+        $ buku -e bookmarks.db --tag tag 1, tag 2
     All bookmarks are exported if --tag is not specified.
 10. **Import** bookmarks from HTML and markdown:
 
         $ buku -i bookmarks.html
         $ buku -i bookmarks.md
+        $ buku -i bookmarks.db
 11. **Delete only comment** for bookmark at 15012014:
 
         $ buku -u 15012014 -c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/auto-completion/bash/buku-completion.bash 
new/buku-3.4/auto-completion/bash/buku-completion.bash
--- old/buku-3.3.1/auto-completion/bash/buku-completion.bash    2017-09-11 
07:36:37.000000000 +0200
+++ new/buku-3.4/auto-completion/bash/buku-completion.bash      2017-09-18 
09:53:49.000000000 +0200
@@ -26,7 +26,6 @@
         -j --json
         -k --unlock
         -l --lock
-        -m --merge
         --nc
         --np
         -o --open
@@ -58,7 +57,6 @@
         -f --format
         -i --import
         --immutable
-        -m --merge
         -r --sreg
         --replace
         -s --sany
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/auto-completion/fish/buku.fish 
new/buku-3.4/auto-completion/fish/buku.fish
--- old/buku-3.3.1/auto-completion/fish/buku.fish       2017-09-11 
07:36:37.000000000 +0200
+++ new/buku-3.4/auto-completion/fish/buku.fish 2017-09-18 09:53:49.000000000 
+0200
@@ -19,7 +19,6 @@
 complete -c buku -s j -l json       --description 'show Json output for print 
and search'
 complete -c buku -s k -l unlock     --description 'decrypt database'
 complete -c buku -s l -l lock       --description 'encrypt database'
-complete -c buku -s m -l merge   -r --description 'merge another buku database'
 complete -c buku -l nc              --description 'disable color output'
 complete -c buku -l np              --description 'non-interactive mode'
 complete -c buku -s o -l open       --description 'open bookmarks in browser'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/auto-completion/zsh/_buku 
new/buku-3.4/auto-completion/zsh/_buku
--- old/buku-3.3.1/auto-completion/zsh/_buku    2017-09-11 07:36:37.000000000 
+0200
+++ new/buku-3.4/auto-completion/zsh/_buku      2017-09-18 09:53:49.000000000 
+0200
@@ -15,16 +15,15 @@
     '(--colors)--colors[set output colors in 5-letter string]:color string'
     '(-d --delete)'{-d,--delete}'[delete bookmark]'
     '(--deep)--deep[search matching substrings]'
-    '(-e --export)'{-e,--export}'[export bookmarks]:html output file'
+    '(-e --export)'{-e,--export}'[export bookmarks]:html/md/db output file'
     '(--expand)--expand[expand a tny.im shortened URL]:index/shorturl'
     '(-f --format)'{-f,--format}'[limit fields in print and Json output]:value'
     '(-h --help)'{-h,--help}'[show help]'
-    '(-i --import)'{-i,--import}'[import bookmarks]:html imput file'
+    '(-i --import)'{-i,--import}'[import bookmarks]:html/md/db input file'
     '(--immutable)--immutable[disable title update from web]:value'
     '(-j --json)'{-j,--json}'[show Json output for print and search]'
     '(-k --unlock)'{-k,--unlock}'[decrypt database]'
     '(-l --lock)'{-l,--lock}'[encrypt database]'
-    '(-m --merge)'{-m,--merge}'[merge another buku database]:buku db file'
     '(--nc)--nc[disable color output]'
     '(--np)--np[noninteractive mode]'
     '(-o --open)'{-o,--open}'[open bookmarks in browser]'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/buku.1 new/buku-3.4/buku.1
--- old/buku-3.3.1/buku.1       2017-09-11 07:36:37.000000000 +0200
+++ new/buku-3.4/buku.1 2017-09-18 09:53:49.000000000 +0200
@@ -1,4 +1,4 @@
-.TH "BUKU" "1" "Sep 2017" "Version 3.3.1" "User Commands"
+.TH "BUKU" "1" "Sep 2017" "Version 3.4" "User Commands"
 .SH NAME
 buku \- Powerful command-line bookmark manager.
 .SH SYNOPSIS
@@ -77,7 +77,7 @@
   - Auto-import looks in the default installation path and default user 
profile.
   - URLs starting with `place:`, `file://` and `apt:` are ignored during 
import.
   - Folder names are automatically imported as tags if --tacit is used.
-  - An auto-generated tag in the format 'YYYYMonDD' is added if --tacit is not 
used.
+  - An auto-generated tag in the format 'YYYYMonDD' is added if --tacit is not 
used in html or markdown import.
 .PP
 .IP 10. 4
 \fBEncryption\fR is optional and manual. AES256 algorithm is used. To use 
encryption, the database file should be unlocked (-k) before using \fBbuku\fR 
and locked (-l) afterwards. Between these 2 operations, the database file lies 
unencrypted on the disk, and NOT in memory. Also, note that the database file 
is \fBunencrypted on creation\fR.
@@ -188,15 +188,14 @@
 .I file
 has extension '.md'.
 .br
-Markdown format: [title](url), 1 entry per line.
+Markdown format: [title](url), 1 entry per line. A buku database is generated 
if
+.I file
+has extension '.db'.
 .TP
 .BI \-i " " \--import " file"
 Import bookmarks exported from Firefox or Google Chrome as HTML.
 .I file
-is considered Markdown (compliant with --export format) if it has '.md' 
extension.
-.TP
-.BI \-m " " \--merge " file"
-Add bookmarks from another buku database file.
+is considered Markdown (compliant with --export format) if it has '.md' 
extension or another buku database if the extension is '.db'.
 .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. A negative value 
(introduced for convenience) behaves like the tail utility, e.g., -n shows the 
details of the last n bookmarks.
@@ -504,6 +503,8 @@
 .B buku -e bookmarks.html --tag tag 1, tag 2
 .br
 .B buku -e bookmarks.md --tag tag 1, tag 2
+.br
+.B buku -e bookmarks.db --tag tag 1, tag 2
 .EE
 .PP
 .IP "" 4
@@ -517,6 +518,8 @@
 .B buku -i bookmarks.html
 .br
 .B buku -i bookmarks.md
+.br
+.B buku -i bookmarks.db
 .EE
 .PP
 .IP 11. 4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/buku.egg-info/PKG-INFO 
new/buku-3.4/buku.egg-info/PKG-INFO
--- old/buku-3.3.1/buku.egg-info/PKG-INFO       2017-09-11 07:37:02.000000000 
+0200
+++ new/buku-3.4/buku.egg-info/PKG-INFO 2017-09-18 09:54:17.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: buku
-Version: 3.3.1
+Version: 3.4
 Summary: Powerful command-line bookmark manager.
 Home-page: https://github.com/jarun/Buku
 Author: Arun Prakash Jana
 Author-email: [email protected]
 License: GPLv3
+Description-Content-Type: UNKNOWN
 Description: <h1 align="center">Buku</h1>
         
         <p align="center">
@@ -21,7 +22,7 @@
         </p>
         
         <p align="center">
-        <a href="https://asciinema.org/a/137065";><img 
src="https://asciinema.org/a/137065.png"; alt="Buku in action!" width="734"/></a>
+        <a href="https://asciinema.org/a/137065";><img 
src="https://s26.postimg.org/o6lka0dw9/buku_demo.png"; alt="Buku in action!" 
width="734"/></a>
         </p>
         
         <p align="center"><i>Buku in action!</i></p>
@@ -196,24 +197,23 @@
                                    search bookmarks by tags
                                    use ',' to find entries matching ANY tag
                                    use '+' to find entries matching ALL tags
-                                   excludes entries matching tags following ' 
- '
+                                   excludes entries with tags after ' - '
                                    list all tags, if no search keywords
         
         ENCRYPTION OPTIONS:
-              -l, --lock [N]       encrypt DB file with N (> 0, default 8)
-                                   hash iterations to generate key
-              -k, --unlock [N]     decrypt DB file with N (> 0, default 8)
-                                   hash iterations to generate key
+              -l, --lock [N]       encrypt DB in N (default 8) # iterations
+              -k, --unlock [N]     decrypt DB in N (default 8) # iterations
         
         POWER TOYS:
               --ai                 auto-import from Firefox and Chrome
               -e, --export file    export bookmarks in Firefox format html
                                    export markdown, if file ends with '.md'
                                    format: [title](url), 1 entry per line
-                                   use --tag to export only specific tags
+                                   export buku DB, if file ends with '.db'
+                                   use --tag to export specific tags
               -i, --import file    import Firefox or Chrome bookmarks html
                                    import markdown, if file ends with '.md'
-              -m, --merge file     add bookmarks from another buku DB file
+                                   import buku DB, if file ends with '.db'
               -p, --print [...]    show record details by indices, ranges
                                    print all bookmarks, if no arguments
                                    -n shows the last n results (like tail)
@@ -308,11 +308,13 @@
         
                 $ buku -e bookmarks.html --tag tag 1, tag 2
                 $ buku -e bookmarks.md --tag tag 1, tag 2
+                $ buku -e bookmarks.db --tag tag 1, tag 2
             All bookmarks are exported if --tag is not specified.
         10. **Import** bookmarks from HTML and markdown:
         
                 $ buku -i bookmarks.html
                 $ buku -i bookmarks.md
+                $ buku -i bookmarks.db
         11. **Delete only comment** for bookmark at 15012014:
         
                 $ buku -u 15012014 -c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buku-3.3.1/buku.py new/buku-3.4/buku.py
--- old/buku-3.3.1/buku.py      2017-09-11 07:36:37.000000000 +0200
+++ new/buku-3.4/buku.py        2017-09-18 09:53:49.000000000 +0200
@@ -39,7 +39,7 @@
 from urllib3.util import parse_url, make_headers
 import webbrowser
 
-__version__ = '3.3.1'
+__version__ = '3.4'
 __author__ = 'Arun Prakash Jana <[email protected]>'
 __license__ = 'GPLv3'
 
@@ -147,17 +147,17 @@
 
     @staticmethod
     def get_filehash(filepath):
-        """Get the SHA256 hash of a file
+        """Get the SHA256 hash of a file.
 
         Parameters
         ----------
         filepath : str
-            Path to the file
+            Path to the file.
 
         Returns
         -------
         hash : bytes
-            Hash digest of file
+            Hash digest of file.
         """
 
         from hashlib import sha256
@@ -173,14 +173,14 @@
 
     @staticmethod
     def encrypt_file(iterations, dbfile=None):
-        """Encrypt the bookmarks database file
+        """Encrypt the bookmarks database file.
 
         Parameters
         ----------
         iterations : int
-            Number of iterations for key generation
+            Number of iterations for key generation.
         dbfile : str, optional
-            Custom database file path (including filename)
+            Custom database file path (including filename).
         """
 
         try:
@@ -271,14 +271,14 @@
 
     @staticmethod
     def decrypt_file(iterations, dbfile=None):
-        """Decrypt the bookmarks database file
+        """Decrypt the bookmarks database file.
 
         Parameters
         ----------
         iterations : int
-            Number of iterations for key generation
+            Number of iterations for key generation.
         dbfile : str, optional
-            Custom database file path (including filename)
+            Custom database file path (including filename).
             The '.enc' suffix must be omitted.
         """
 
@@ -370,19 +370,19 @@
 
 
 def import_md(filepath, newtag):
-    """Parse bookmark markdown file
+    """Parse bookmark markdown file.
 
     Parameters
     ----------
     filepath : str
-        Path to markdown file
+        Path to markdown file.
     newtag : str
-        New tag for bookmarks in markdown file
+        New tag for bookmarks in markdown file.
 
     Returns
     -------
     tuple
-        Parsed result
+        Parsed result.
     """
     with open(filepath, mode='r', encoding='utf-8') as infp:
         for line in infp:
@@ -410,21 +410,21 @@
 
 
 def import_html(html_soup, add_parent_folder_as_tag, newtag):
-    """Parse bookmark html
+    """Parse bookmark html.
 
     Parameters
     ----------
     html_soup : BeautifulSoup object
-        BeautifulSoup representation of bookmark html
+        BeautifulSoup representation of bookmark html.
     add_parent_folder_as_tag : bool
-        True if bookmark parent folders should be added as tags else False
+        True if bookmark parent folders should be added as tags else False.
     newtag : str
-        A new unique tag to add to imported bookmarks
+        A new unique tag to add to imported bookmarks.
 
     Returns
     -------
     tuple
-        Parsed result
+        Parsed result.
     """
 
     # compatibility
@@ -472,14 +472,14 @@
 
 
 class BukuDb:
-    """Abstracts all database operations
+    """Abstracts all database operations.
 
     Attributes
     ----------
-    conn : sqlite database connection
-    cur : sqlite database cursor
+    conn : sqlite database connection.
+    cur : sqlite database cursor.
     json : bool
-        True if results should be printed in json format else False
+        True if results should be printed in json format else False.
     field_filter : int
         Indicates format for displaying bookmarks. Default is 0.
     chatty : bool
@@ -487,12 +487,12 @@
     """
 
     def __init__(self, json=False, field_filter=0, chatty=False, dbfile=None, 
colorize=True):
-        """Database initialization API
+        """Database initialization API.
 
         Parameters
         ----------
         json : bool, optional
-            True if results should be printed in json format else False
+            True if results should be printed in json format else False.
         field_filter : int, optional
             Indicates format for displaying bookmarks. Default is 0.
         chatty : bool, optional
@@ -501,25 +501,25 @@
             Indicates whether color should be used in output. Default is True.
         """
 
-        self.conn, self.cur = BukuDb.initdb(dbfile)
         self.json = json
         self.field_filter = field_filter
         self.chatty = chatty
         self.colorize = colorize
+        self.conn, self.cur = BukuDb.initdb(dbfile, self.chatty)
 
     @staticmethod
     def get_default_dbdir():
-        """Determine the directory path where dbfile will be stored
+        """Determine the directory path where dbfile will be stored.
 
         If the platform is Windows, use %APPDATA%
         else if $XDG_DATA_HOME is defined, use it
         else if $HOME exists, use it
-        else use the current directory
+        else use the current directory.
 
         Returns
         -------
         str
-            Path to database file
+            Path to database file.
         """
 
         data_home = os.environ.get('XDG_DATA_HOME')
@@ -537,7 +537,7 @@
         return os.path.join(data_home, 'buku')
 
     @staticmethod
-    def initdb(dbfile=None):
+    def initdb(dbfile=None, chatty=False):
         """Initialize the database connection.
 
         Create DB file and/or bookmarks table if they don't exist.
@@ -546,12 +546,14 @@
         Parameters
         ----------
         dbfile : str, optional
-            Custom database file path (including filename)
+            Custom database file path (including filename).
+        chatty : bool
+            If True, shows informative message on DB creation.
 
         Returns
         -------
         tuple
-            (connection, cursor)
+            (connection, cursor).
         """
 
         if not dbfile:
@@ -580,7 +582,7 @@
         elif db_exists and enc_exists:
             logerr('Both encrypted and flat DB files exist!')
             sys.exit(1)
-        else:
+        elif chatty:
             # not db_exists and not enc_exists
             print('DB file is being created at %s.\nYou should encrypt it.' % 
dbfile)
 
@@ -609,12 +611,12 @@
         return (conn, cur)
 
     def get_rec_all(self):
-        """Get all the bookmarks in the database
+        """Get all the bookmarks in the database.
 
         Returns
         -------
         list
-            A list of tuples representing bookmark records
+            A list of tuples representing bookmark records.
         """
 
         self.cur.execute('SELECT * FROM bookmarks')
@@ -626,12 +628,12 @@
         Parameters
         ----------
         index : int
-            DB index of bookmark record
+            DB index of bookmark record.
 
         Returns
         -------
         tuple or None
-            Bookmark data, or None if index is not found
+            Bookmark data, or None if index is not found.
         """
 
         self.cur.execute('SELECT * FROM bookmarks WHERE id = ? LIMIT 1', 
(index,))
@@ -639,17 +641,17 @@
         return resultset[0] if resultset else None
 
     def get_rec_id(self, url):
-        """Check if URL already exists in DB
+        """Check if URL already exists in DB.
 
         Parameters
         ----------
         url : str
-            A URL to search for in the DB
+            A URL to search for in the DB.
 
         Returns
         -------
         int
-            DB index, or -1 if URL not found in DB
+            DB index, or -1 if URL not found in DB.
         """
 
         self.cur.execute('SELECT id FROM bookmarks WHERE URL = ? LIMIT 1', 
(url,))
@@ -657,12 +659,12 @@
         return resultset[0][0] if resultset else -1
 
     def get_max_id(self):
-        """Fetch the ID of the last record
+        """Fetch the ID of the last record.
 
         Returns
         -------
         int
-            ID of the record if any record exists, else -1
+            ID of the record if any record exists, else -1.
         """
 
         self.cur.execute('SELECT MAX(id) from bookmarks')
@@ -670,12 +672,12 @@
         return -1 if resultset[0][0] is None else resultset[0][0]
 
     def add_rec(self, url, title_in=None, tags_in=None, desc=None, 
immutable=0, delay_commit=False):
-        """Add a new bookmark
+        """Add a new bookmark.
 
         Parameters
         ----------
         url : str
-            URL to bookmark
+            URL to bookmark.
         title_in :str, optional
             Title to add manually. Default is None.
         tags_in : str, optional
@@ -693,7 +695,7 @@
         Returns
         -------
         int
-            DB index of new bookmark on success, -1 on failure
+            DB index of new bookmark on success, -1 on failure.
         """
 
         # Return error for empty URL
@@ -750,14 +752,14 @@
             return -1
 
     def append_tag_at_index(self, index, tags_in, delay_commit=False):
-        """Append tags to bookmark tagset at index
+        """Append tags to bookmark tagset at index.
 
         Parameters
         ----------
         index : int
             DB index of the record. 0 indicates all records.
         tags_in : str
-            Comma-separated tags to add manually
+            Comma-separated tags to add manually.
         delay_commit : bool, optional
             True if record should not be committed to the DB,
             leaving commit responsibility to caller. Default is False.
@@ -765,7 +767,7 @@
         Returns
         -------
         bool
-            True on success, False on failuree
+            True on success, False on failure.
         """
 
         if index == 0:
@@ -795,14 +797,14 @@
         return True
 
     def delete_tag_at_index(self, index, tags_in, delay_commit=False):
-        """Delete tags from bookmark tagset at index
+        """Delete tags from bookmark tagset at index.
 
         Parameters
         ----------
         index : int
             DB index of bookmark record. 0 indicates all records.
         tags_in : str
-            Comma-separated tags to delete manually
+            Comma-separated tags to delete manually.
         delay_commit : bool, optional
             True if record should not be committed to the DB,
             leaving commit responsibility to caller. Default is False.
@@ -810,7 +812,7 @@
         Returns
         -------
         bool
-            True on success, False on failure
+            True on success, False on failure.
         """
 
         tags_to_delete = tags_in.strip(DELIM).split(DELIM)
@@ -860,7 +862,7 @@
         return True
 
     def update_rec(self, index, url=None, title_in=None, tags_in=None, 
desc=None, immutable=-1, threads=4):
-        """Update an existing record at index
+        """Update an existing record at index.
 
         Update all records if index is 0 and url is not specified.
         URL is an exception because URLs are unique in DB.
@@ -870,15 +872,15 @@
         index : int
             DB index of record. 0 indicates all records.
         url : str, optional
-            Bookmark address
+            Bookmark address.
         title_in : str, optional
             Title to add manually.
         tags_in : str, optional
             Comma-separated tags to add manually. Must start and end with 
comma.
             Prefix with '+,' to append to current tags.
-            Prefix with '-,' to delete from current tags
+            Prefix with '-,' to delete from current tags.
         desc : str, optional
-            Description of bookmark
+            Description of bookmark.
         immutable : int, optional
             Diable title fetch from web if 1. Default is -1.
         threads : int, optional
@@ -887,7 +889,7 @@
         Returns
         -------
         bool
-            True on success, False on Failure
+            True on success, False on Failure.
         """
 
         arguments = []
@@ -1077,13 +1079,13 @@
         cond.acquire()
 
         def refresh(count, cond):
-            """Inner function to fetch titles and update records
+            """Inner function to fetch titles and update records.
 
             Parameters
             ----------
             count : int
                 Dummy input to adhere to convention.
-            cond : threading condition object
+            cond : threading condition object.
             """
 
             count = 0
@@ -1153,19 +1155,19 @@
         return True
 
     def edit_update_rec(self, index, immutable=-1):
-        """Edit in editor and update a record
+        """Edit in editor and update a record.
 
         Parameters
         ----------
         index : int
-            DB index of the record
+            DB index of the record.
         immutable : int, optional
             Diable title fetch from web if 1. Default is -1.
 
         Returns
         -------
         bool
-            True if updated, else False
+            True if updated, else False.
         """
 
         editor = get_system_editor()
@@ -1189,12 +1191,12 @@
         return False
 
     def searchdb(self, keywords, all_keywords=False, deep=False, regex=False):
-        """Search DB for entries where tags, URL, or title fields match 
keywords
+        """Search DB for entries where tags, URL, or title fields match 
keywords.
 
         Parameters
         ----------
         keywords : list of str
-            Keywords to search
+            Keywords to search.
         all_keywords : bool, optional
             True to return records matching ALL keywords.
             False (default value) to return records matching ANY keyword.
@@ -1206,7 +1208,7 @@
         Returns
         -------
         list or None
-            List of search results, or None if no matches
+            List of search results, or None if no matches.
         """
         if not keywords:
             return None
@@ -1271,7 +1273,7 @@
         return self.cur.fetchall()
 
     def search_by_tag(self, tags):
-        """Search bookmarks for entries with given tags
+        """Search bookmarks for entries with given tags.
 
         Parameters
         ----------
@@ -1285,7 +1287,7 @@
         Returns
         -------
         list or None
-            List of search results, or None if no matches
+            List of search results, or None if no matches.
         """
 
         # do not allow combination of search logics
@@ -1316,7 +1318,7 @@
         Parameters
         ----------
         index : int
-            DB index of deleted entry
+            DB index of deleted entry.
         delay_commit : bool, optional
             True if record should not be committed to the DB,
             leaving commit responsibility to caller. Default is False.
@@ -1343,7 +1345,7 @@
                     print('Index %d moved to %d' % (row[0], index))
 
     def delete_rec(self, index, low=0, high=0, is_range=False, 
delay_commit=False):
-        """Delete a single record or remove the table if index is None
+        """Delete a single record or remove the table if index is None.
 
         Parameters
         ----------
@@ -1434,7 +1436,7 @@
         Returns
         -------
         bool
-            True on success, False on failure
+            True on success, False on failure.
         """
         resp = read_in('Delete the search results? (y/n): ')
         if resp != 'y':
@@ -1455,7 +1457,7 @@
         return True
 
     def delete_rec_all(self, delay_commit=False):
-        """Removes all records in the Bookmarks table
+        """Removes all records in the Bookmarks table.
 
         Parameters
         ----------
@@ -1466,7 +1468,7 @@
         Returns
         -------
         bool
-            True on success, False on failure
+            True on success, False on failure.
         """
 
         try:
@@ -1479,12 +1481,12 @@
             return False
 
     def cleardb(self):
-        """Drops the bookmark table if it exists
+        """Drops the bookmark table if it exists.
 
         Returns
         -------
         bool
-            True on success, False on failure
+            True on success, False on failure.
         """
 
         resp = read_in('Remove ALL bookmarks? (y/n): ')
@@ -1498,9 +1500,9 @@
         return True
 
     def print_rec(self, index=0, low=0, high=0, is_range=False):
-        """Print bookmark details at index or all bookmarks if index is 0
+        """Print bookmark details at index or all bookmarks if index is 0.
 
-        A negative index behaves like tail, if title is blank show "Untitled"
+        A negative index behaves like tail, if title is blank show "Untitled".
 
         Parameters
         -----------
@@ -1602,13 +1604,13 @@
             print(format_json(resultset, field_filter=self.field_filter))
 
     def get_tag_all(self):
-        """Get list of tags in DB
+        """Get list of tags in DB.
 
         Returns
         -------
         tuple
             (list of unique tags sorted alphabetically,
-             dictionary of {tag: usage_count})
+             dictionary of {tag: usage_count}).
         """
 
         tags = []
@@ -1635,7 +1637,7 @@
         return unique_tags, dic
 
     def suggest_similar_tag(self, tagstr):
-        """Show list of tags those go together in DB
+        """Show list of tags those go together in DB.
 
         Parameters
         ----------
@@ -1645,7 +1647,7 @@
         Returns
         -------
         str
-            DELIM separated string of tags
+            DELIM separated string of tags.
         """
 
         tags = tagstr.split(',')
@@ -1846,7 +1848,7 @@
         return update_count
 
     def browse_by_index(self, index=0, low=0, high=0, is_range=False):
-        """Open URL at index or range of indies in browser
+        """Open URL at index or range of indies in browser.
 
         Parameters
         ----------
@@ -1918,6 +1920,8 @@
     def exportdb(self, filepath, taglist=None):
         """Export DB bookmarks to file.
 
+        If destination file name ends with '.db', bookmarks are
+        exported to a Buku database file.
         If destination file name ends with '.md', bookmarks are
         exported to a markdown file. Otherwise, bookmarks are
         exported to a Firefox bookmarks.html formatted file.
@@ -1966,7 +1970,7 @@
         self.cur.execute(query, arguments)
         resultset = self.cur.fetchall()
         if not resultset:
-            print('No bookmarks exported')
+            print('No records found')
             return False
 
         if os.path.exists(filepath):
@@ -1974,6 +1978,19 @@
             if resp != 'y':
                 return False
 
+            if filepath.endswith('.db'):
+                os.remove(filepath)
+
+        if filepath.endswith('.db'):
+            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.conn.commit()
+            outdb.close()
+            return True
+
         try:
             outfp = open(filepath, mode='w', encoding='utf-8')
         except Exception as e:
@@ -1981,7 +1998,6 @@
             return False
 
         if filepath.endswith('.md'):
-            outfp.write('List of buku bookmarks:\n\n')
             for row in resultset:
                 if row[2] == '':
                     out = '- [Untitled](' + row[1] + ')\n'
@@ -2150,25 +2166,30 @@
             True on success, False on failure.
         """
 
+        FF_BM_DB_PATH = None
+
         if sys.platform.startswith('linux'):
             GC_BM_DB_PATH = '~/.config/google-chrome/Default/Bookmarks'
 
             DEFAULT_FF_FOLDER = os.path.expanduser('~/.mozilla/firefox')
             profile = get_firefox_profile_name(DEFAULT_FF_FOLDER)
-            FF_BM_DB_PATH = 
'~/.mozilla/firefox/{}.default/places.sqlite'.format(profile)
+            if profile:
+                FF_BM_DB_PATH = 
'~/.mozilla/firefox/{}.default/places.sqlite'.format(profile)
         elif sys.platform == 'darwin':
             GC_BM_DB_PATH = '~/Library/Application 
Support/Google/Chrome/Default/Bookmarks'
 
             DEFAULT_FF_FOLDER = os.path.expanduser('~/Library/Application 
Support/Firefox')
             profile = get_firefox_profile_name(DEFAULT_FF_FOLDER)
-            FF_BM_DB_PATH = '~/Library/Application 
Support/Firefox/{}.default/places.sqlite'.format(profile)
+            if profile:
+                FF_BM_DB_PATH = '~/Library/Application 
Support/Firefox/{}.default/places.sqlite'.format(profile)
         elif sys.platform == 'win32':
             username = os.getlogin()
             GC_BM_DB_PATH = 'C:/Users/{}/AppData/Local/Google/Chrome/User 
Data/Default/Bookmarks'.format(username)
 
             DEFAULT_FF_FOLDER = 
'C:/Users/{}/AppData/Roaming/Mozilla/Firefox/Profiles'.format(username)
             profile = get_firefox_profile_name(DEFAULT_FF_FOLDER)
-            FF_BM_DB_PATH = os.path.join(DEFAULT_FF_FOLDER, 
'{}.default/places.sqlite'.format(profile))
+            if profile:
+                FF_BM_DB_PATH = os.path.join(DEFAULT_FF_FOLDER, 
'{}.default/places.sqlite'.format(profile))
         else:
             logerr('Buku does not support {} yet'.format(sys.platform))
             self.close_quit(1)
@@ -2215,6 +2236,7 @@
 
         Supports Firefox, Google Chrome, and IE exported html bookmarks.
         Supports markdown files with extension '.md'.
+        Supports importing bookmarks from another Buku database file.
 
         Parameters
         ----------
@@ -2232,6 +2254,9 @@
             True on success, False on failure.
         """
 
+        if filepath.endswith('.db'):
+            return self.mergedb(filepath)
+
         if not tacit:
             newtag = gen_auto_tag()
         else:
@@ -2322,7 +2347,7 @@
         index : int, optional (if URL is provided)
             DB index of the bookmark with the URL to shorten. Default is 0.
         url : str, optional (if index is provided)
-            URL to shorten
+            URL to shorten.
         shorten : bool, optional
             True to shorten, False to expand. Default is False.
 
@@ -2402,6 +2427,17 @@
         if to_commit:
             self.conn.commit()
 
+    def close(self):
+        """Close a DB connection."""
+
+        if self.conn is not None:
+            try:
+                self.cur.close()
+                self.conn.close()
+            except Exception:
+                # ignore errors here, we're closing down
+                pass
+
     def close_quit(self, exitval=0):
         """Close a DB connection and exit.
 
@@ -2422,7 +2458,7 @@
 
 
 class ExtendedArgumentParser(argparse.ArgumentParser):
-    """Extend classic argument parser"""
+    """Extend classic argument parser."""
 
     @staticmethod
     def program_info(file=sys.stdout):
@@ -2530,8 +2566,12 @@
         Firefox profile name.
     """
 
-    names = os.listdir(path)
-    profile = [name[:-8] for name in names if name.endswith('.default')][0]
+    try:
+        names = os.listdir(path)
+        profile = [name[:-8] for name in names if name.endswith('.default')][0]
+    except FileNotFoundError:
+        profile = None
+
     return profile
 
 
@@ -2601,7 +2641,7 @@
     Returns
     -------
     bool
-        True if URL is a nongeneric URL, False otherwise.
+        True if URL is a non-generic URL, False otherwise.
     """
 
     ignored_prefix = ['place:', 'file://', 'apt:']
@@ -2721,7 +2761,7 @@
     Returns
     -------
     tuple
-        (title, recognized mime, bad url)
+        (title, recognized mime, bad url).
     """
 
     page_title = None
@@ -2855,7 +2895,7 @@
     tuple
         (list of formatted tags to search,
          a string indicating query search operator (either OR or AND),
-         a regex string of tags or None if ' - ' delimiter not in tags)
+         a regex string of tags or None if ' - ' delimiter not in tags).
     """
 
     excluded_tags = None
@@ -2883,7 +2923,7 @@
     Returns
     -------
     str
-        New tag as YYYYMonDD
+        New tag as YYYYMonDD.
     """
 
     import calendar as cal
@@ -2892,7 +2932,7 @@
     return ('%d%s%02d' % (t.tm_year, cal.month_abbr[t.tm_mon], t.tm_mday))
 
 
-def edit_at_prompt(obj, nav):
+def edit_at_prompt(obj, nav, suggest=False):
     """Edit and add or update a bookmark.
 
     Parameters
@@ -2901,6 +2941,8 @@
         A valid instance of BukuDb class.
     nav : str
         Navigation command argument passed at prompt by user.
+    suggest : bool, optional
+        If True, suggest similar tags on new bookmark addition.
     """
 
     if nav == 'w':
@@ -2916,6 +2958,8 @@
     result = edit_rec(editor, '', None, DELIM, None)
     if result is not None:
         url, title, tags, desc = result
+        if suggest:
+            tags = obj.suggest_similar_tag(tags)
         obj.add_rec(url, title, tags, desc)
 
 
@@ -2973,17 +3017,15 @@
             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 ') or nav.startswith('o ') or 
nav.startswith('p ') or nav.startswith('g ')):
+              nav.startswith('t ') or nav.startswith('o ') or 
nav.startswith('p ') or
+              nav.startswith('g ')) or nav == 'w' or nav.startswith('w '):
             return nav
-        elif nav == 'w' or nav.startswith('w '):
-            edit_at_prompt(obj, nav)
-            new_results = False
         else:
             print('Invalid input')
             new_results = False
 
 
-def prompt(obj, results, noninteractive=False, deep=False, subprompt=False):
+def prompt(obj, results, noninteractive=False, deep=False, subprompt=False, 
suggest=False):
     """Show each matching result from a search and prompt.
 
     Parameters
@@ -2998,6 +3040,8 @@
         Use deep search. Default is False.
     subprompt : bool, optional
         If True, jump directly to subprompt.
+    suggest : bool, optional
+        If True, suggest similar tags on edit and add bookmark.
     """
 
     if not type(obj) is BukuDb:
@@ -3089,7 +3133,7 @@
 
         # Edit and add or update
         if nav == 'w' or nav.startswith('w '):
-            edit_at_prompt(obj, nav)
+            edit_at_prompt(obj, nav, suggest)
             continue
 
         # Append or overwrite tags
@@ -3175,7 +3219,7 @@
 def print_single_rec(row, idx=0):  # NOQA
     """Print a single DB record.
 
-    Handles both search results and individual record
+    Handles both search results and individual record.
 
     Parameters
     ----------
@@ -3284,7 +3328,7 @@
 
 
 def browse(url):
-    """Duplicate stdin, stdout and open URL in default browser
+    """Duplicate stdin, stdout and open URL in default browser.
 
     .. note:: Duplicates stdin and stdout in order to
               suppress showing errors on the terminal.
@@ -3298,6 +3342,7 @@
     ----------
     suppress_browser_output : bool
         True if a text based browser is detected.
+        Must be initialized (as applicable) to use the API.
     """
 
     if not parse_url(url).scheme:
@@ -3404,7 +3449,7 @@
     Parameters
     ----------
     msg : str
-        String to pass to to input()
+        String to pass to to input().
     """
 
     disable_sigint_handler()
@@ -3429,7 +3474,7 @@
     ----------
     signum : int
         Signal number.
-    frame : frame object or None
+    frame : frame object or None.
     """
 
     global interrupted
@@ -3458,13 +3503,13 @@
 
 
 def get_system_editor():
-    """Returns default system editor is $EDITOR is set"""
+    """Returns default system editor is $EDITOR is set."""
 
     return os.environ.get('EDITOR', 'none')
 
 
 def is_editor_valid(editor):
-    """Check if the editor string is valid
+    """Check if the editor string is valid.
 
     Parameters
     ----------
@@ -3489,7 +3534,7 @@
 
 
 def to_temp_file_content(url, title_in, tags_in, desc):
-    """Generate temporary file content string
+    """Generate temporary file content string.
 
     Parameters
     ----------
@@ -3542,7 +3587,7 @@
     Parameters
     ----------
     content : str
-        String of content
+        String of content.
 
     Returns
     -------
@@ -3594,7 +3639,7 @@
 
 
 def edit_rec(editor, url, title_in, tags_in, desc):
-    """Edit a bookmark record
+    """Edit a bookmark record.
 
     Parameters
     ----------
@@ -3823,7 +3868,7 @@
                          search bookmarks by tags
                          use ',' to find entries matching ANY tag
                          use '+' to find entries matching ALL tags
-                         excludes entries matching tags following ' - '
+                         excludes entries with tags after ' - '
                          list all tags, if no search keywords''')
     addarg = search_grp.add_argument
     addarg('-s', '--sany', action='store_true', help=HIDE)
@@ -3838,10 +3883,8 @@
 
     crypto_grp = argparser.add_argument_group(
         title='ENCRYPTION OPTIONS',
-        description='''    -l, --lock [N]       encrypt DB file with N (> 0, 
default 8)
-                         hash iterations to generate key
-    -k, --unlock [N]     decrypt DB file with N (> 0, default 8)
-                         hash iterations to generate key''')
+        description='''    -l, --lock [N]       encrypt DB in N (default 8) # 
iterations
+    -k, --unlock [N]     decrypt DB in N (default 8) # iterations''')
     addarg = crypto_grp.add_argument
     addarg('-k', '--unlock', nargs='?', type=int, const=8, help=HIDE)
     addarg('-l', '--lock', nargs='?', type=int, const=8, help=HIDE)
@@ -3856,10 +3899,11 @@
     -e, --export file    export bookmarks in Firefox format html
                          export markdown, if file ends with '.md'
                          format: [title](url), 1 entry per line
-                         use --tag to export only specific tags
+                         export buku DB, if file ends with '.db'
+                         use --tag to export specific tags
     -i, --import file    import Firefox or Chrome bookmarks html
                          import markdown, if file ends with '.md'
-    -m, --merge file     add bookmarks from another buku DB file
+                         import buku DB, if file ends with '.db'
     -p, --print [...]    show record details by indices, ranges
                          print all bookmarks, if no arguments
                          -n shows the last n results (like tail)
@@ -3887,7 +3931,6 @@
     addarg('--ai', action='store_true', help=HIDE)
     addarg('-e', '--export', nargs=1, help=HIDE)
     addarg('-i', '--import', nargs=1, dest='importfile', help=HIDE)
-    addarg('-m', '--merge', nargs=1, help=HIDE)
     addarg('-p', '--print', nargs='*', help=HIDE)
     addarg('-f', '--format', type=int, default=0, choices={1, 2, 3, 4}, 
help=HIDE)
     addarg('-j', '--json', action='store_true', help=HIDE)
@@ -4068,7 +4111,7 @@
             search_results = bdb.search_by_tag(' '.join(args.keywords))
         else:
             # Use sub prompt to list all tags
-            prompt(bdb, None, args.np, subprompt=True)
+            prompt(bdb, None, args.np, subprompt=True, suggest=args.suggest)
     elif args.keywords:
         search_results = bdb.searchdb(args.keywords, False, args.deep)
     else:
@@ -4244,10 +4287,6 @@
     if args.ai:
         bdb.auto_import_from_browser()
 
-    # Merge a database file and exit
-    if args.merge is not None:
-        bdb.mergedb(args.merge[0])
-
     # Open URL in browser
     if args.open is not None:
         if not args.open:


Reply via email to