From fcb0d43ea2dfbb1a4b54f571954de66949e15e5f Mon Sep 17 00:00:00 2001 From: TnS-hun Date: Sun, 28 Apr 2019 20:39:56 +0200 Subject: [PATCH] [added] New command: pick. Download books using interactive selection. --- README.md | 8 ++++ kobo-book-downloader/Commands.py | 81 ++++++++++++++++++++++++++++++-- kobo-book-downloader/__main__.py | 5 ++ 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cf23260..43957ad 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,14 @@ It has been tested on Linux but it should work on other platforms too. ## Usage +To interactively select from your unread books to download: +``` +python kobo-book-downloader pick /dir/ +``` +To interactively select from all of your books to download: +``` +python kobo-book-downloader pick /dir/ --all +``` To list your unread books: ``` python kobo-book-downloader list diff --git a/kobo-book-downloader/Commands.py b/kobo-book-downloader/Commands.py index e63884e..736892f 100644 --- a/kobo-book-downloader/Commands.py +++ b/kobo-book-downloader/Commands.py @@ -27,6 +27,7 @@ def ShowUsage(): get Download book info Show the location of the configuration file list List your books + pick Download books using interactive selection Optional arguments: -h, --help Show this help message and exit @@ -38,7 +39,9 @@ def ShowUsage(): kobo-book-downloader info Show the location of the program's configuration file kobo-book-downloader list List your unread books kobo-book-downloader list --all List all your books - kobo-book-downloader list --help Get additional help for the list command (it works for get too)""" + kobo-book-downloader list --help Get additional help for the list command (it works for get too) + kobo-book-downloader pick /dir/ Interactively select unread books to download + kobo-book-downloader pick /dir/ --all Interactively select books to download""" print( usage ) @@ -169,9 +172,7 @@ def __IsBookRead( newEntitlement: dict ) -> bool: return status == "Finished" @staticmethod - def ListBooks( listAll: bool ) -> None: - colorama.init() - + def __GetBookList( listAll: bool ) -> list: bookList = Globals.Kobo.GetMyBookList() rows = [] @@ -191,6 +192,13 @@ def ListBooks( listAll: bool ) -> None: rows.append( book ) rows = sorted( rows, key = lambda columns: columns[ 1 ].lower() ) + return rows + + @staticmethod + def ListBooks( listAll: bool ) -> None: + colorama.init() + + rows = Commands.__GetBookList( listAll ) for columns in rows: revisionId = colorama.Style.DIM + columns[ 0 ] + colorama.Style.RESET_ALL title = colorama.Style.BRIGHT + columns[ 1 ] + colorama.Style.RESET_ALL @@ -205,6 +213,71 @@ def ListBooks( listAll: bool ) -> None: print( "%s \t %s" % ( revisionId, title ) ) + @staticmethod + def __ListBooksToPickFrom( rows: list ) -> None: + longestIndex = len( "%d" % len( rows ) ) + + for index, columns in enumerate( rows ): + alignedIndexText = str( index + 1 ).rjust( longestIndex, ' ' ) + + title = colorama.Style.BRIGHT + columns[ 1 ] + colorama.Style.RESET_ALL + + author = columns[ 2 ] + if len( author ) > 0: + title += " by " + author + + archived = columns[ 3 ] + if archived: + title += colorama.Fore.LIGHTYELLOW_EX + " (archived)" + colorama.Fore.RESET + + print( "%s. %s" % ( alignedIndexText, title ) ) + + @staticmethod + def __GetPickedBookRows( rows: list ) -> list: + print( """\nEnter the number of the book(s) to download. Use comma or space to list multiple. Enter "all" to download all of them.""" ) + indexText = input( "Books: " ) + + if indexText == "all": + return rows + + indexList = indexText.replace( " ", "," ).split( "," ) + rowsToDownload = [] + + for indexText in indexList: + try: + index = int( indexText.strip() ) - 1 + if index >= 0 and index < len( rows ): + rowsToDownload.append( rows[ index ] ) + except Exception: + pass + + return rowsToDownload + + @staticmethod + def __DownloadPickedBooks( outputPath: str, rows: list ) -> None: + for columns in rows: + revisionId = columns[ 0 ] + title = columns[ 1 ] + author = columns[ 2 ] + archived = columns[ 3 ] + + if archived: + if len( author ) > 0: + title += " by " + author + + print( colorama.Fore.LIGHTYELLOW_EX + ( "Skipping archived book %s." % title ) + colorama.Fore.RESET ) + else: + Commands.GetBookOrBooks( revisionId, outputPath, False ) + + @staticmethod + def PickBooks( outputPath: str, listAll: bool ) -> None: + colorama.init() + + rows = Commands.__GetBookList( listAll ) + Commands.__ListBooksToPickFrom( rows ) + rowsToDownload = Commands.__GetPickedBookRows( rows ) + Commands.__DownloadPickedBooks( outputPath, rowsToDownload ) + @staticmethod def Info(): print( "The configuration file is located at:\n%s" % Globals.Settings.SettingsFilePath ) diff --git a/kobo-book-downloader/__main__.py b/kobo-book-downloader/__main__.py index 91f5fdb..ddcb693 100644 --- a/kobo-book-downloader/__main__.py +++ b/kobo-book-downloader/__main__.py @@ -53,6 +53,9 @@ def Main() -> None: infoParser = subparsers.add_parser( "info", help = "Show the location of the program's configuration file" ) listParser = subparsers.add_parser( "list", help = "List unread books" ) listParser.add_argument( "--all", default = False, action = "store_true", help = "List read books too" ) + pickParser = subparsers.add_parser( "pick", help = "Download books using interactive selection" ) + pickParser.add_argument( "OutputPath", metavar = "output-path", help = "Output path must be an existing directory" ) + pickParser.add_argument( "--all", default = False, action = "store_true", help = "List read books too" ) arguments = argumentParser.parse_args() if arguments.Command is None: @@ -67,6 +70,8 @@ def Main() -> None: Commands.Info() elif arguments.Command == "list": Commands.ListBooks( arguments.all ) + elif arguments.Command == "pick": + Commands.PickBooks( arguments.OutputPath, arguments.all ) if __name__ == '__main__':