Просмотр исходного кода

[added] Handle archived books.

TnS-hun 8 лет назад
Родитель
Сommit
a03e821208
2 измененных файлов с 41 добавлено и 6 удалено
  1. 35 5
      kobo-book-downloader/Commands.py
  2. 6 1
      kobo-book-downloader/Kobo.py

+ 35 - 5
kobo-book-downloader/Commands.py

@@ -85,6 +85,18 @@ Examples:
 
 		return fileName
 
+	@staticmethod
+	def __IsBookArchived( newEntitlement: dict ) -> bool:
+		bookEntitlement = newEntitlement.get( "BookEntitlement" )
+		if bookEntitlement is None:
+			return False
+
+		isRemoved = bookEntitlement.get( "IsRemoved" )
+		if isRemoved is None:
+			return False
+
+		return isRemoved
+
 	@staticmethod
 	def __GetBook( revisionId: str, outputPath: str ) -> None:
 		if os.path.isdir( outputPath ):
@@ -115,6 +127,16 @@ Examples:
 			fileName = Commands.__MakeFileNameForBook( bookMetadata )
 			outputFilePath = os.path.join( outputPath, fileName )
 
+			# Skip archived books.
+			if Commands.__IsBookArchived( newEntitlement ):
+				title = bookMetadata[ "Title" ]
+				author = Commands.__GetBookAuthor( bookMetadata )
+				if len( author ) > 0:
+					title += " by " + author
+
+				print( colorama.Fore.LIGHTYELLOW_EX + ( "Skipping archived book %s." % title ) + colorama.Fore.RESET )
+				continue
+
 			print( "Downloading book to '%s'." % outputFilePath )
 			Globals.Kobo.Download( bookMetadata[ "RevisionId" ], Kobo.DisplayProfile, outputFilePath )
 
@@ -162,18 +184,26 @@ Examples:
 				continue
 
 			bookMetadata = newEntitlement[ "BookMetadata" ]
-			rows.append( [ bookMetadata[ "RevisionId" ], bookMetadata[ "Title" ], Commands.__GetBookAuthor( bookMetadata ) ] )
+			book = [ bookMetadata[ "RevisionId" ],
+				bookMetadata[ "Title" ],
+				Commands.__GetBookAuthor( bookMetadata ),
+				Commands.__IsBookArchived( newEntitlement ) ]
+			rows.append( book )
 
 		rows = sorted( rows, key = lambda columns: columns[ 1 ] )
 		for columns in rows:
 			revisionId = colorama.Style.DIM + columns[ 0 ] + colorama.Style.RESET_ALL
 			title = colorama.Style.BRIGHT + columns[ 1 ] + colorama.Style.RESET_ALL
-			author = columns[ 2 ]
 
+			author = columns[ 2 ]
 			if len( author ) > 0:
-				print( "%s \t %s by %s" % ( revisionId, title, author ) )
-			else:
-				print( "%s \t %s" % ( revisionId, title ) )
+				title += " by " + author
+
+			archived = columns[ 3 ]
+			if archived:
+				title += colorama.Fore.LIGHTYELLOW_EX + " (archived)" + colorama.Fore.RESET
+
+			print( "%s \t %s" % ( revisionId, title ) )
 
 	@staticmethod
 	def Info():

+ 6 - 1
kobo-book-downloader/Kobo.py

@@ -237,7 +237,10 @@ class Kobo:
 	def __GetDownloadInfo( productId: str, contentAccessBookResponse: dict ) -> Tuple[ str, bool ]:
 		jsonContentUrls = contentAccessBookResponse.get( "ContentUrls" )
 		if jsonContentUrls is None:
-			raise KoboException( "Content URL can't be found for product '%s'." % productId )
+			raise KoboException( "Download URL can't be found for product '%s'." % productId )
+
+		if len( jsonContentUrls ) == 0:
+			raise KoboException( "Download URL list is empty for product '%s'. If this is an archived book then it must be unarchived first on the Kobo website (https://www.kobo.com/help/en-US/article/1799/restoring-deleted-books-or-magazines)." % productId )
 
 		for jsonContentUrl in jsonContentUrls:
 			if ( jsonContentUrl[ "DRMType" ] == "KDRM" or jsonContentUrl[ "DRMType" ] == "SignedNoDrm" ) and \
@@ -254,6 +257,8 @@ class Kobo:
 			for chunk in response.iter_content( chunk_size = 1024 * 256 ):
 				f.write( chunk )
 
+	# Downloading archived books is not possible, the "content_access_book" API endpoint returns with empty ContentKeys
+	# and ContentUrls for them.
 	def Download( self, productId: str, displayProfile: str, outputPath: str ) -> None:
 		jsonResponse = self.__GetContentAccessBook( productId, displayProfile )
 		contentKeys = Kobo.__GetContentKeys( jsonResponse )