__main__.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. from Commands import Commands
  2. from Globals import Globals
  3. from Kobo import Kobo, KoboException
  4. from LogFormatter import LogFormatter
  5. from Settings import Settings
  6. import colorama
  7. import requests
  8. import argparse
  9. import logging
  10. def InitializeGlobals() -> None:
  11. streamHandler = logging.StreamHandler()
  12. streamHandler.setFormatter( LogFormatter() )
  13. Globals.Logger = logging.getLogger()
  14. Globals.Logger.addHandler( streamHandler )
  15. Globals.Kobo = Kobo()
  16. Globals.Settings = Settings()
  17. def InitializeKoboApi() -> None:
  18. if not Globals.Settings.AreAuthenticationSettingsSet():
  19. Globals.Kobo.AuthenticateDevice()
  20. Globals.Kobo.LoadInitializationSettings()
  21. if not Globals.Settings.IsLoggedIn():
  22. email = input( "Waiting for your input. You can use Shift+Insert to paste from the clipboard. Ctrl+C aborts the program.\n\nKobo e-mail: " )
  23. password = input( "Kobo password: " )
  24. print( """
  25. Open https://authorize.kobo.com/signin in a private/incognito window in your browser, wait till the page
  26. loads (do not login!) then open the developer tools (use F12 in Firefox/Chrome), select the console tab,
  27. and paste the following code there and then press Enter there in the browser.
  28. var newCaptchaDiv = document.createElement( "div" );
  29. newCaptchaDiv.id = "new-hcaptcha-container";
  30. document.getElementById( "hcaptcha-container" ).insertAdjacentElement( "afterend", newCaptchaDiv );
  31. hcaptcha.render( newCaptchaDiv.id, {
  32. sitekey: "51a1773a-a9ae-4992-a768-e3b8d87355e8",
  33. callback: function( response ) { console.log( "Captcha response:" ); console.log( response ); }
  34. } );
  35. A captcha should show up below the Sign-in form. Once you solve the captcha its response will be written
  36. below the pasted code in the browser's console. Copy the response (the line below "Captcha response:")
  37. and paste it here.
  38. """ )
  39. captcha = input( "Captcha response: " ).strip()
  40. print( "" )
  41. Globals.Kobo.Login( email, password, captcha )
  42. def Main() -> None:
  43. InitializeGlobals()
  44. colorama.init()
  45. argumentParser = argparse.ArgumentParser( add_help = False )
  46. argumentParser.add_argument( "--help", "-h", default = False, action = "store_true" )
  47. argumentParser.add_argument( "--verbose", default = False, action = "store_true", dest = "VerboseLogging" )
  48. subparsers = argumentParser.add_subparsers( dest = "Command", title = "commands", metavar = "command" )
  49. getParser = subparsers.add_parser( "get", help = "Download book" )
  50. getParser.add_argument( "OutputPath", metavar = "output-path", help = "If the output path is a directory then the file will be named automatically." )
  51. getParser.add_argument( "RevisionId", metavar = "book-id", nargs = "?", help = "The identifier of the book" )
  52. getParser.add_argument( "--all", default = False, action = "store_true", help = "Download all my books" )
  53. infoParser = subparsers.add_parser( "info", help = "Show the location of the program's configuration file" )
  54. listParser = subparsers.add_parser( "list", help = "List unread books" )
  55. listParser.add_argument( "--all", default = False, action = "store_true", help = "List read books too" )
  56. pickParser = subparsers.add_parser( "pick", help = "Download books using interactive selection" )
  57. pickParser.add_argument( "OutputPath", metavar = "output-path", help = "Output path must be an existing directory" )
  58. pickParser.add_argument( "--all", default = False, action = "store_true", help = "List read books too" )
  59. wishListParser = subparsers.add_parser( "wishlist", help = "List your wish listed books" )
  60. arguments = argumentParser.parse_args()
  61. if arguments.VerboseLogging:
  62. Globals.Logger.setLevel( logging.DEBUG )
  63. if arguments.Command is None:
  64. Commands.ShowUsage()
  65. elif arguments.Command == "info":
  66. Commands.Info()
  67. else:
  68. InitializeKoboApi()
  69. if arguments.Command == "get":
  70. Commands.GetBookOrBooks( arguments.RevisionId, arguments.OutputPath, arguments.all )
  71. elif arguments.Command == "list":
  72. Commands.ListBooks( arguments.all )
  73. elif arguments.Command == "pick":
  74. Commands.PickBooks( arguments.OutputPath, arguments.all )
  75. elif arguments.Command == "wishlist":
  76. Commands.ListWishListedBooks()
  77. if __name__ == '__main__':
  78. try:
  79. Main()
  80. except KoboException as e:
  81. Globals.Logger.error( e )
  82. except requests.exceptions.Timeout as e:
  83. Globals.Logger.error( "The request has timed out." )