def downloadManga(self): print("Parsing XML File...") if (self.verbose_FLAG): print("XML Path = %s" % self.xmlfile_path) dom = minidom.parse(self.xmlfile_path) threadPool = [] self.options.auto = True SetOutputPathToName_Flag = False # Default OutputDir is the ./MangaName if (self.options.outputDir == 'DEFAULT_VALUE'): SetOutputPathToName_Flag = True for node in dom.getElementsByTagName("MangaSeries"): seriesOptions = copy.copy(self.options) seriesOptions.manga = getText(node.getElementsByTagName('name')[0]) seriesOptions.site = getText( node.getElementsByTagName('HostSite')[0]) try: lastDownloaded = getText( node.getElementsByTagName('LastChapterDownloaded')[0]) except IndexError: lastDownloaded = "" try: download_path = getText( node.getElementsByTagName('downloadPath')[0]) except IndexError: download_path = ('./' + fixFormatting( seriesOptions.manga, seriesOptions.spaceToken)) if self.options.downloadPath != 'DEFAULT_VALUE' and not os.path.isabs( download_path): download_path = os.path.join(self.options.downloadPath, download_path) seriesOptions.downloadPath = download_path seriesOptions.lastDownloaded = lastDownloaded if SetOutputPathToName_Flag: seriesOptions.outputDir = download_path # Because the SiteParserThread constructor parses the site to retrieve which chapters to # download the following code would be faster # thread = SiteParserThread(self.options, dom, node) # thread.start() # threadPool.append(thread) # Need to remove the loop which starts the thread's downloading. The disadvantage is that the # the print statement would intermingle with the progress bar. It would be very difficult to # understand what was happening. Do not believe this change is worth it. threadPool.append(SiteParserThread(seriesOptions, dom, node)) for thread in threadPool: thread.start() thread.join() #Backs up file backupFileName = self.xmlfile_path + "_bak" os.rename(self.xmlfile_path, backupFileName) f = open(self.xmlfile_path, 'w') outputStr = '\n'.join( [line for line in dom.toprettyxml().split('\n') if line.strip()]) outputStr = outputStr.encode('utf-8') f.write(outputStr) # The file was succesfully saved and now remove backup os.remove(backupFileName)
def main(): printLicenseInfo() # for easier parsing, adds free --help and --version # optparse (v2.3-v2.7) was chosen over argparse (v2.7+) for compatibility (and relative similarity) reasons # and over getopt(v?) for additional functionality parser = optparse.OptionParser(usage='usage: %prog [options] <manga name>', version=('Manga Downloader %s' % VERSION)) parser.set_defaults(all_chapters_FLAG=False, auto=False, conversion_FLAG=False, convert_Directory=False, device='Kindle 3', downloadFormat='.cbz', downloadPath='DEFAULT_VALUE', inputDir=None, outputDir='DEFAULT_VALUE', overwrite_FLAG=False, verbose_FLAG=False, timeLogging_FLAG=False, maxChapterThreads=3, useShortName=False, spaceToken='.', proxy=None, siteSelect=0) parser.add_option('--all', action='store_true', dest='all_chapters_FLAG', help='Download all available chapters.') parser.add_option( '-d', '--directory', dest='downloadPath', help= 'The destination download directory. Defaults to the directory of the script.' ) parser.add_option( '--overwrite', action='store_true', dest='overwrite_FLAG', help='Overwrites previous copies of downloaded chapters.') parser.add_option('--verbose', action='store_true', dest='verbose_FLAG', help='Verbose Output.') parser.add_option( '-x', '--xml', dest='xmlfile_path', help= 'Parses the .xml file and downloads all chapters newer than the last chapter downloaded for the listed mangas.' ) parser.add_option( '-c', '--convertFiles', action='store_true', dest='conversion_FLAG', help= 'Converts downloaded files to a Format/Size acceptable to the device specified by the --device parameter.' ) parser.add_option( '--device', dest='device', help= 'Specifies the conversion device. Omitting this option default to %default.' ) parser.add_option( '--convertDirectory', action='store_true', dest='convert_Directory', help= 'Converts the image files stored in the directory specified by --inputDirectory. Stores the converted images in the directory specified by --outputDirectory' ) parser.add_option( '--inputDirectory', dest='inputDir', help= 'The directory containing the images to convert when --convertDirectory is specified.' ) parser.add_option( '--outputDirectory', dest='outputDir', help= 'The directory to store the images when --convertDirectory is specified.' ) parser.add_option( '-z', '--zip', action='store_const', dest='downloadFormat', const='.zip', help= 'Downloads using .zip compression. Omitting this option defaults to %default.' ) parser.add_option( '-t', '--threads', dest='maxChapterThreads', help='Limits the number of chapter threads to the value specified.') parser.add_option('--timeLogging', action='store_true', dest='timeLogging_FLAG', help='Output time logging.') parser.add_option( '--useShortName', action='store_true', dest='useShortName_FLAG', help= 'To support devices that limit the size of the filename, this parameter uses a short name' ) parser.add_option( '--spaceToken', dest='spaceToken', help='Specifies the character used to replace spaces in the manga name.' ) parser.add_option('--proxy', dest='proxy', help='Specifies the proxy.') parser.add_option('-s', '--site', dest='siteSelect', help='Specifies the site to download from.') (options, args) = parser.parse_args() try: options.siteSelect = int(options.siteSelect) except: options.siteSelect = 0 try: options.maxChapterThreads = int(options.maxChapterThreads) except: options.maxChapterThreads = 2 if (options.maxChapterThreads <= 0): options.maxChapterThreads = 2 if (len(args) == 0 and (not (options.convert_Directory or options.xmlfile_path != None))): parser.error('Manga not specified.') #if(len(args) > 1): # parser.error('Possible multiple mangas specified, please select one. (Did you forget to put quotes around a multi-word manga?)') SetDownloadPathToName_Flag = False SetOutputPathToDefault_Flag = False if (len(args) > 0): # Default Directory is the ./MangaName if (options.downloadPath == 'DEFAULT_VALUE'): SetDownloadPathToName_Flag = True # Default outputDir is the ./MangaName if (options.outputDir == 'DEFAULT_VALUE'): SetOutputPathToDefault_Flag = True PILAvailable = isImageLibAvailable() # Check if PIL Library is available if either of convert Flags are set if ((not PILAvailable) and (options.convert_Directory or options.conversion_FLAG)): print( "\nConversion Functionality Not available.\nMust install the PIL (Python Image Library)" ) sys.exit() else: if (PILAvailable): from ConvertPackage.ConvertFile import convertFile if (options.convert_Directory): options.inputDir = os.path.abspath(options.inputDir) # Changes the working directory to the script location if (os.path.dirname(sys.argv[0]) != ""): os.chdir(os.path.dirname(sys.argv[0])) options.outputMgr = progressBarManager() options.outputMgr.start() try: if (options.convert_Directory): if (options.outputDir == 'DEFAULT_VALUE'): options.outputDir = '.' print("Converting Files: %s" % options.inputDir) convertFile.convert(options.outputMgr, options.inputDir, options.outputDir, options.device, options.verbose_FLAG) elif options.xmlfile_path != None: xmlParser = MangaXmlParser(options) xmlParser.downloadManga() else: threadPool = [] for manga in args: print(manga) options.manga = manga if SetDownloadPathToName_Flag: options.downloadPath = ( './' + fixFormatting(options.manga, options.spaceToken)) if SetOutputPathToDefault_Flag: options.outputDir = options.downloadPath options.downloadPath = os.path.realpath( options.downloadPath) + os.sep # site selection if (options.siteSelect == 0): print('Which site?') for i in siteDict: print(siteDict[i][1]) # Python3 fix - removal of raw_input() try: options.siteSelect = raw_input() except NameError: options.siteSelect = input() try: options.site = siteDict[int(options.siteSelect)][0] except KeyError: raise InvalidSite('Site selection invalid.') threadPool.append(SiteParserThread(options, None, None)) for thread in threadPool: thread.start() thread.join() finally: # Must always stop the manager options.outputMgr.stop()