def do(self, filenames, cut_action=None): # widgets archive_directory = self.__app.config.get('general', 'folder_archive') dialog = self.__gui.dialog_archive result, renamed_filenames, archive_to = dialog.run( filenames, archive_directory) if result: self.update_list = True for original, new_name in renamed_filenames.items(): # add extension to renamed file if needed extension = splitext(original)[1] if not new_name.endswith(extension): new_name += extension new_name = join(dirname(original), new_name.replace('/', '_')) if new_name != original: fileoperations.rename_file(original, new_name) fileoperations.move_file(new_name, archive_to) dialog.hide()
def mux_ac3(self, filename, cut_video, ac3_file, cutlist): # cuts the ac3 and muxes it with the avi into an mkv mkvmerge = self.config.get_program('mkvmerge') root, extension = os.path.splitext(filename) mkv_file = os.path.splitext(cut_video)[0] + ".mkv" # env my_env = os.environ.copy() my_env["LANG"] = "C" # creates the timecodes string for splitting the .ac3 with mkvmerge timecodes = (','.join([self.get_timecode(start) + ',' + self.get_timecode(start+duration) for start, duration in cutlist.cuts_seconds])) # splitting .ac3. Every second fragment will be used. # return_value = subprocess.call([mkvmerge, "--split", "timecodes:" + timecodes, "-o", root + "-%03d.mka", ac3_file]) try: blocking_process = subprocess.Popen([mkvmerge, '--ui-language', 'en_US', "--split", "timecodes:" + timecodes, "-o", root + "-%03d.mka", ac3_file ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=my_env) except OSError as e: return None, e.strerror + ": " + mkvmerge return_value = blocking_process.wait() # return_value=0 is OK, return_value=1 means a warning. Most probably non-ac3-data that has been omitted. # TODO: Is there some way to pass this warning to the conclusion dialog? if return_value != 0 and return_value != 1: return None, None, str(return_value) if len(cutlist.cuts_seconds) == 1: # Only the second fragment is needed. Delete the rest. fileoperations.rename_file(root + "-002.mka", root + ".mka") fileoperations.remove_file(root + "-001.mka") if os.path.isfile(root + "-003.mka"): fileoperations.remove_file(root + "-003.mka") else: # Concatenating every second fragment. command = [mkvmerge, "-o", root + ".mka", root + "-002.mka"] command[len(command):] = ["+" + root + "-%03d.mka" % (2*n) for n in range(2,len(cutlist.cuts_seconds)+1)] # return_value = subprocess.call(command) try: blocking_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=my_env) except OSError as e: return None, e.strerror + ": " + mkvmerge return_value = blocking_process.wait() if return_value != 0: # There should be no warnings here return None, None, str(return_value) for n in range(1,2*len(cutlist.cuts_seconds)+2): # Delete all temporary audio fragments if os.path.isfile(root + "-%03d.mka" % n): fileoperations.remove_file(root + "-%03d.mka" % n) # Mux the cut .avi with the resulting audio-file into mkv_file # TODO: Is there some way to pass possible warnings to the conclusion dialog? # return_value = subprocess.call([mkvmerge, "-o", mkv_file, cut_video, root + ".mka"]) try: blocking_process = subprocess.Popen([mkvmerge, "-o", mkv_file, cut_video, root + ".mka"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=my_env) except OSError as e: return None, e.strerror + ": " + mkvmerge return_value = blocking_process.wait() if return_value != 0 and return_value != 1: return None, None, str(return_value) fileoperations.remove_file(root + ".mka") # Delete remaining temporary files fileoperations.remove_file(cut_video) return mkv_file, ac3_file, None
def do(self, filenames): response, new_names = self.__gui.dialog_rename.init_and_run("Umbenennen", filenames) if response: for f in filenames: extension = splitext(f)[1] new_name = new_names[f] new_name = join(dirname(f), new_name.replace('/', '_')) if f.endswith(extension) and not new_name.endswith(extension): new_name += extension fileoperations.rename_file(f, new_name) else: self.update_list = False
def do(self, filenames): # widgets archive_directory = self.__app.config.get('general', 'folder_archive') dialog = self.__gui.dialog_archive result, renamed_filenames, archive_to = dialog.run(filenames, archive_directory) if result: self.update_list = True for original, new_name in renamed_filenames.iteritems(): # add extension to renamed file if needed extension = splitext(original)[1] if not new_name.endswith(extension): new_name += extension new_name = join(dirname(original), new_name.replace('/', '_')) if new_name != original: fileoperations.rename_file(original, new_name) fileoperations.move_file(new_name, archive_to) dialog.hide()
def mux_ac3(self, filename, cut_video, ac3_file, cutlist): # cuts the ac3 and muxes it with the avi into an mkv mkvmerge = self.config.get_program('mkvmerge') root, extension = os.path.splitext(filename) mkv_file = os.path.splitext(cut_video)[0] + ".mkv" # env my_env = os.environ.copy() my_env["LANG"] = "C" # creates the timecodes string for splitting the .ac3 with mkvmerge timecodes = (','.join([ self.get_timecode(start) + ',' + self.get_timecode(start + duration) for start, duration in cutlist.cuts_seconds ])) # splitting .ac3. Every second fragment will be used. # return_value = subprocess.call([mkvmerge, "--split", "timecodes:" + timecodes, "-o", root + "-%03d.mka", ac3_file]) try: blocking_process = subprocess.Popen([ mkvmerge, '--ui-language', 'en_US', "--split", "timecodes:" + timecodes, "-o", root + "-%03d.mka", ac3_file ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=my_env) except OSError as e: return None, e.strerror + ": " + mkvmerge return_value = blocking_process.wait() # return_value=0 is OK, return_value=1 means a warning. Most probably non-ac3-data that has been omitted. # TODO: Is there some way to pass this warning to the conclusion dialog? if return_value != 0 and return_value != 1: return None, None, str(return_value) if len(cutlist.cuts_seconds ) == 1: # Only the second fragment is needed. Delete the rest. fileoperations.rename_file(root + "-002.mka", root + ".mka") fileoperations.remove_file(root + "-001.mka") if os.path.isfile(root + "-003.mka"): fileoperations.remove_file(root + "-003.mka") else: # Concatenating every second fragment. command = [mkvmerge, "-o", root + ".mka", root + "-002.mka"] command[len(command):] = [ "+" + root + "-%03d.mka" % (2 * n) for n in range(2, len(cutlist.cuts_seconds) + 1) ] # return_value = subprocess.call(command) try: blocking_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=my_env) except OSError as e: return None, e.strerror + ": " + mkvmerge return_value = blocking_process.wait() if return_value != 0: # There should be no warnings here return None, None, str(return_value) for n in range(1, 2 * len(cutlist.cuts_seconds) + 2): # Delete all temporary audio fragments if os.path.isfile(root + "-%03d.mka" % n): fileoperations.remove_file(root + "-%03d.mka" % n) # Mux the cut .avi with the resulting audio-file into mkv_file # TODO: Is there some way to pass possible warnings to the conclusion dialog? # return_value = subprocess.call([mkvmerge, "-o", mkv_file, cut_video, root + ".mka"]) try: blocking_process = subprocess.Popen( [mkvmerge, "-o", mkv_file, cut_video, root + ".mka"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=my_env) except OSError as e: return None, e.strerror + ": " + mkvmerge return_value = blocking_process.wait() if return_value != 0 and return_value != 1: return None, None, str(return_value) fileoperations.remove_file(root + ".mka") # Delete remaining temporary files fileoperations.remove_file(cut_video) return mkv_file, ac3_file, None
def show_conclusions(self): conclusions = self.app.gui.dialog_conclusion._run( self.conclusions, self.app.rename_by_schema, self.app.config.get('general', 'folder_archive')) self.app.gui.main_window.builder.get_object('box_conclusion').hide() self.conclusions = [] # create cutlists cutlists = [] for conclusion in conclusions: if conclusion.action == Action.DECODE: continue print "[Conclusion] for file ", conclusion.uncut_video # rename print "[Conclusion] Rename?" if conclusion.cut.rename: print "[Conclusion] true" extension = os.path.splitext(conclusion.cut_video)[1] if not conclusion.cut.rename.endswith(extension): conclusion.cut.rename += extension new_filename = os.path.join( self.app.config.get('general', 'folder_cut_avis'), conclusion.cut.rename.replace('/', '_')) new_filename = fileoperations.make_unique_filename( new_filename) if conclusion.cut_video != new_filename: conclusion.cut_video = fileoperations.rename_file( conclusion.cut_video, new_filename) # move cut video to archive print "[Conclusion] Move to archive?" if conclusion.cut.archive_to: print "[Conclusion] true" fileoperations.move_file(conclusion.cut_video, conclusion.cut.archive_to) # move uncut video to trash if it's ok print "[Conclusion] Move to trash?" if conclusion.cut.status == Status.OK and conclusion.cut.delete_uncut: print "[Conclusion] true" if os.path.exists(conclusion.uncut_video): # move to trash target = self.app.config.get('general', 'folder_trash_avis') conclusion.uncut_video = fileoperations.move_file( conclusion.uncut_video, target) if os.path.exists(conclusion.ac3_file): target = self.app.config.get('general', 'folder_trash_avis') fileoperations.move_file(conclusion.ac3_file, target) # remove local cutlists print "[Conclusion] Remove local cutlist?" if self.app.config.get('general', 'delete_cutlists'): print "[Conclusion] true" if conclusion.cut.cutlist.local_filename: if os.path.exists( conclusion.cut.cutlist.local_filename): fileoperations.remove_file( conclusion.cut.cutlist.local_filename) print "[Conclusion] Create cutlist?" if conclusion.cut.create_cutlist: print "[Conclusion] true" if "VirtualDub" in conclusion.cut.cutlist.intended_app: intended_app_name = "VirtualDub" else: intended_app_name = "Avidemux" if not conclusion.cut.cutlist.local_filename: conclusion.cut.cutlist.local_filename = self.app.config.get( 'general', 'folder_uncut_avis') + '/' + os.path.basename( conclusion.uncut_video) + ".cutlist" conclusion.cut.cutlist.author = self.app.config.get( 'general', 'cutlist_username') conclusion.cut.cutlist.intended_version = open( path.getdatapath("VERSION"), 'r').read().strip() conclusion.cut.cutlist.smart = self.app.config.get( 'general', 'smart') conclusion.cut.cutlist.write_local_cutlist( conclusion.uncut_video, intended_app_name, conclusion.cut.my_rating) if conclusion.cut.upload_cutlist: cutlists.append(conclusion.cut.cutlist) # upload cutlists: def upload(): error_messages = [] for cutlist in cutlists: error_message = cutlist.upload( self.app.config.get('general', 'server'), self.app.config.get('general', 'cutlist_hash')) if error_message: error_messages.append(error_message) else: if self.app.config.get('general', 'delete_cutlists'): fileoperations.remove_file(cutlist.local_filename) count = len(cutlists) message = "Es wurden %s/%s Cutlisten hochgeladen!" % ( str(count - len(error_messages)), str(count)) if len(error_messages) > 0: message += " (" + ", ".join(error_messages) + ")" yield message if len(cutlists) > 0: print "[Conclusion] Upload cutlists" if self.app.gui.question_box( "Soll(en) %s Cutlist(en) hochgeladen werden?" % len(cutlists)): def change_status(message): self.app.gui.main_window.change_status(0, message) GeneratorTask(upload, change_status).start() # rate cutlists def rate(): yield 0 # fake generator messages = [] count = 0 for conclusion in conclusions: if conclusion.action == Action.DECODE: continue if conclusion.cut.my_rating > -1: print "Rate with ", conclusion.cut.my_rating success, message = conclusion.cut.cutlist.rate( conclusion.cut.my_rating, self.app.config.get('general', 'server')) if success: count += 1 else: messages += [message] if count > 0 or len(messages) > 0: if count == 0: text = "Es wurde keine Cutlist bewertet!" if count == 1: text = "Es wurde 1 Cutlist bewertet!" else: text = "Es wurden %s Cutlisten bewertet!" % count if len(messages) > 0: text += " (Fehler: %s)" % ", ".join(messages) self.app.gui.main_window.change_status(0, text) print "[Conclusion] Rate cutlists" GeneratorTask(rate).start()
def show_conclusions(self): conclusions = self.app.gui.dialog_conclusion._run(self.conclusions, self.app.rename_by_schema, self.app.config.get('general', 'folder_archive')) self.app.gui.main_window.builder.get_object('box_conclusion').hide() self.conclusions = [] # create cutlists cutlists = [] for conclusion in conclusions: if conclusion.action == Action.DECODE: continue print "[Conclusion] for file ", conclusion.uncut_video # rename print "[Conclusion] Rename?" if conclusion.cut.rename: print "[Conclusion] true" extension = os.path.splitext(conclusion.cut_video)[1] if not conclusion.cut.rename.endswith(extension): conclusion.cut.rename += extension new_filename = os.path.join(self.app.config.get('general', 'folder_cut_avis'), conclusion.cut.rename.replace('/', '_')) #new_filename = fileoperations.make_unique_filename(new_filename) if conclusion.cut_video != new_filename: conclusion.cut_video = fileoperations.rename_file(conclusion.cut_video, new_filename) # move cut video to archive print "[Conclusion] Move to archive?" if conclusion.cut.archive_to: print "[Conclusion] true" fileoperations.move_file(conclusion.cut_video, conclusion.cut.archive_to) # move uncut video to trash if it's ok print "[Conclusion] Move to trash?" if conclusion.cut.status == Status.OK and conclusion.cut.delete_uncut: print "[Conclusion] true" if os.path.exists(conclusion.uncut_video): # move to trash target = self.app.config.get('general', 'folder_trash_avis') conclusion.uncut_video = fileoperations.move_file(conclusion.uncut_video, target) if os.path.exists(conclusion.ac3_file): target = self.app.config.get('general', 'folder_trash_avis') fileoperations.move_file(conclusion.ac3_file, target) # remove local cutlists print "[Conclusion] Remove local cutlist?" if self.app.config.get('general', 'delete_cutlists'): print "[Conclusion] true" if conclusion.cut.cutlist.local_filename: if os.path.exists(conclusion.cut.cutlist.local_filename): fileoperations.remove_file(conclusion.cut.cutlist.local_filename) print "[Conclusion] Create cutlist?" if conclusion.cut.create_cutlist: print "[Conclusion] true" if "VirtualDub" in conclusion.cut.cutlist.intended_app: intended_app_name = "VirtualDub" else: intended_app_name = "Avidemux" if not conclusion.cut.cutlist.local_filename: conclusion.cut.cutlist.local_filename = self.app.config.get('general', 'folder_uncut_avis') + '/' + os.path.basename(conclusion.uncut_video) + ".cutlist" conclusion.cut.cutlist.author = self.app.config.get('general', 'cutlist_username') conclusion.cut.cutlist.intended_version = open(path.getdatapath("VERSION"), 'r').read().strip() conclusion.cut.cutlist.smart = self.app.config.get('general', 'smart') conclusion.cut.cutlist.write_local_cutlist(conclusion.uncut_video, intended_app_name, conclusion.cut.my_rating) if conclusion.cut.upload_cutlist: cutlists.append(conclusion.cut.cutlist) # upload cutlists: def upload(): error_messages = [] for cutlist in cutlists: error_message = cutlist.upload(self.app.config.get('general', 'server'), self.app.config.get('general', 'cutlist_hash')) if error_message: error_messages.append(error_message) else: if self.app.config.get('general', 'delete_cutlists'): fileoperations.remove_file(cutlist.local_filename) count = len(cutlists) message = "Es wurden %s/%s Cutlisten hochgeladen!" % (str(count - len(error_messages)), str(count)) if len(error_messages) > 0: message += " (" + ", ".join(error_messages) + ")" yield message if len(cutlists) > 0: print "[Conclusion] Upload cutlists" if self.app.gui.question_box("Soll(en) %s Cutlist(en) hochgeladen werden?" % len(cutlists)): def change_status(message): self.app.gui.main_window.change_status(0, message) GeneratorTask(upload, change_status).start() # rate cutlists def rate(): yield 0 # fake generator messages = [] count = 0 for conclusion in conclusions: if conclusion.action == Action.DECODE: continue if conclusion.cut.my_rating > -1: print "Rate with ", conclusion.cut.my_rating success, message = conclusion.cut.cutlist.rate(conclusion.cut.my_rating, self.app.config.get('general', 'server')) if success: count += 1 else: messages += [message] if count > 0 or len(messages) > 0: if count == 0: text = "Es wurde keine Cutlist bewertet!" if count == 1: text = "Es wurde 1 Cutlist bewertet!" else: text = "Es wurden %s Cutlisten bewertet!" % count if len(messages) > 0: text += " (Fehler: %s)" % ", ".join(messages) self.app.gui.main_window.change_status(0, text) print "[Conclusion] Rate cutlists" GeneratorTask(rate).start()
def _download(self): self.log = '' self.information['message_short'] = '' self.information['status'] = DownloadStatus.RUNNING if self.information['download_type'] == DownloadTypes.TORRENT: # download torrent if necessary torrent_filename = os.path.join( self._config.get('general', 'folder_new_otrkeys'), self.filename + '.torrent') if not os.path.exists(torrent_filename): url = 'http://81.95.11.2/torrents/' + self.filename + '.torrent' try: request.urlretrieve(url, torrent_filename) # read filename f = open(torrent_filename, 'r') line = f.readlines()[0] except IOError as error: self.information['status'] = DownloadStatus.ERROR self.information[ 'message_short'] = 'Torrentdatei konnte nicht geladen werden.' yield "Torrentdatei konnte nicht heruntergeladen werden (%s)!" % error return if "Hash wrong" in line: os.remove(torrent_filename) self.information['status'] = DownloadStatus.ERROR self.information[ 'message_short'] = 'OTR-Daten nicht korrekt!' yield 'OTR-Daten nicht korrekt!' return self.information['output'] = self._config.get( 'general', 'folder_new_otrkeys') command = [self._config.get_program('aria2c')] + self._config.get( 'downloader', 'aria2c_opts_torrent') + [ "-d", self.information['output'], "-T", torrent_filename ] yield "Ausgeführt wird:\n%s\n" % " ".join(command) try: self.__process = subprocess.Popen(command, stdout=subprocess.PIPE) except OSError as error: self.information['status'] = DownloadStatus.ERROR self.information[ 'message_short'] = 'Aria2c ist nicht installiert.' yield "Ist aria2c installiert? Der Befehl konnte nicht ausgeführt werden:\nFehlermeldung: %s" % error return while self.__process.poll() == None: line = self.__process.stdout.readline().strip() if "Checksum" in line: result = re.findall('Checksum:.*\((.*%)\)', line) if result: self.information[ 'message_short'] = 'Überprüfen...%s' % result[0] elif "SEEDING" in line: self.information['message_short'] = 'Seeden...' self.information[ 'status'] = DownloadStatus.SEEDING # _NOT_ DownloadStatus.FINISHED self.information['progress'] = 100 self.information['est'] = '' self.information['speed'] = '' self.information['seeders'] = None result = re.findall('ratio:(.*)\) ', line) if result: self.information['ratio'] = result[0] result = re.findall('UP:(.*)\((.*)\)', line) if result: self.information['upspeed'] = result[0][0] self.information['uploaded'] = result[0][1] elif "%" in line: self.information['message_short'] = '' # get size if not self.information['size']: try: # aria2c gives size always in MiB (hopefully) size = re.findall('SIZE:.*/(.*)MiB\(', line)[0] size = size.replace(',', '') size = int(round(float(size))) * 1024 * 1024 self.information['size'] = size yield line except: pass # get progress result = re.findall('([0-9]{1,3})%', line) if result: self.information['progress'] = int(result[0]) # get speed, est if "UP" in line: result = re.findall( 'SPD:(.*) UP:(.*)\((.*)\) ETA:(.*)]', line) if result: self.information['speed'] = result[0][0] self.information['upspeed'] = result[0][1] self.information['uploaded'] = result[0][2] self.information['est'] = result[0][3] else: result = re.findall('SPD:(.*) .*ETA:(.*)]', line) if result: self.information['speed'] = result[0][0] self.information['est'] = result[0][1] # get seeder info result = re.findall('SEED:([0-9]*) ', line) if result: self.information['seeders'] = result[0] else: yield line self.update_view() ### Process is terminated stdout = self.__process.stdout.read().strip() yield stdout # A torrent download only stops: # a) when the user clicks 'stop' # b) when an error occured if self.information['status'] != DownloadStatus.STOPPED: self.information['status'] = DownloadStatus.ERROR elif self.information['download_type'] == DownloadTypes.BASIC: self.information['output'] = self._config.get( 'general', 'folder_new_otrkeys') if self.information['preferred_downloader'] == 'wget': command = [ self._config.get_program('wget') ] + self._config.get('downloader', 'wget') + [ "-c", "-P", self.information['output'], self.link ] yield "Ausgeführt wird:\n%s\n" % " ".join(command) try: self.__process = subprocess.Popen(command, stderr=subprocess.PIPE) except OSError as error: self.information['status'] = DownloadStatus.ERROR self.information[ 'message_short'] = 'Wget ist nicht installiert.' yield "Ist Wget installiert? Der Befehl konnte nicht ausgeführt werden:\n%s" % error return while True: exit_code = self.__process.poll() if exit_code != None: if self.information['status'] != DownloadStatus.STOPPED: if exit_code == 0: self._finished() else: self.information[ 'status'] = DownloadStatus.ERROR break line = self.__process.stderr.readline().strip() if line: if not self.information['size']: result = re.findall(': ([0-9]*) \(', line) if result: self.information['size'] = int(result[0]) if "%" in line: result = re.findall('([0-9]{1,3})% (.*)[ =](.*)', line) if result: progress = int(result[0][0]) if self.information['progress'] == progress: continue else: self.information['progress'] = progress self.information['speed'] = result[0][1] if progress == 100: self._finished() else: self.information['est'] = result[0][2] else: yield line self.update_view() ### Process is terminated yield self.__process.stderr.read().strip() else: # Download with aria2c self.information[ 'message_short'] = 'Überprüfung der bereits heruntergeladen Datei ...' self.update_view() if 'otrkey' in self.filename and os.path.exists( self.information['output'] + '/' + self.filename): torrent_check_return = self._check_file_with_torrent() if torrent_check_return == 0: self.information[ 'message_short'] = '(OK):Download vollständig.' self._finished() command = [ self._config.get_program('aria2c') ] + self._config.get('downloader', 'aria2c_opts') + [ "-d", self.information['output'], '--retry-wait=30', '--max-tries=0', '--summary-interval=5', '--log', '-', '--log-level', 'info', self.link ] yield "Ausgeführt wird:\n%s\n" % " ".join(command) if self.information['status'] == DownloadStatus.RUNNING: self.log = '' self.information[ 'message_short'] = 'Versuche Download zu starten ... eventuell erst Warteschlange durchlaufen ...' self.update_view() try: self.__process = subprocess.Popen( command, stdout=subprocess.PIPE) except OSError as error: self.information['status'] = DownloadStatus.ERROR self.information[ 'message_short'] = 'Aria2c ist nicht installiert.' yield "Ist aria2c installiert? Der Befehl konnte nicht ausgeführt werden:\n%s" % error return while self.__process.poll() == None: time.sleep(0.1) line = self.__process.stdout.readline() if 'X-OTR-Queueposition' in line or 'errorCode=29' in line: match = re.search( 'X-OTR-Queueposition:\ ([0-9]{1,})', line) if match: self.information[ 'message_short'] = 'OTR Warteschlange - %s' % match.group( 0) self.update_view() else: if not 'OTR' in self.information[ 'message_short']: self.information[ 'message_short'] = line.strip() elif 'X-OTR-Error-Message' in line: self.information['message_short'] = line.strip() self.update_view() elif 'errorCode=' in line: self.information['message_short'] = line.strip() self.update_view() elif "%" in line: if "FileAlloc" in line: result = re.findall( 'FileAlloc:.*\(([0-9]{1,3}%)', line) self.information[ 'message_short'] = 'Datei wird angelegt...%s' % result[ 0] else: self.information['message_short'] = '' if not self.information['size']: try: # aria2c gives size always in MiB (hopefully) size = re.findall('.*/(.*)\(', line.strip())[0] size = size.strip('MiB') size = size.replace(',', '') size = int(round( float(size))) * 1024 * 1024 self.information['size'] = size yield line except: pass result = re.findall( '\(([0-9]{1,3})%\).*CN:([0-9]{1,5}).*DL:(.*) ETA:(.*)]', line) if result: self.information['progress'] = int( result[0][0]) self.information[ 'message_short'] = 'Verbindungen: %s' % result[ 0][1] self.information['speed'] = result[0][2] self.information['est'] = result[0][3] self.update_view() else: yield line.strip() ### Process is terminated stdout = self.__process.stdout.read().strip() yield stdout if not self.information['status'] in [ DownloadStatus.STOPPED, DownloadStatus.ERROR ]: time.sleep(1) # wait for log being updated - very ugly if '(INPR):wird heruntergeladen.' in self.log: self.information[ 'message_short'] = '(INPR):Download unvollständig.' self.information['progress'] = 0 elif '(INPR):download in-progress.' in self.log: self.information[ 'message_short'] = '(INPR):Download unvollständig.' self.information['progress'] = 0 elif '(OK):Herunterladen abgeschlossen.' in self.log: self.information[ 'message_short'] = '(OK):Download vollständig.' self._finished() elif '(OK):download completed.' in self.log: self.information[ 'message_short'] = '(OK):Download vollständig.' self._finished() # Download Test self.information[ 'message_short'] = 'Abschliessende Überprüfung der heruntergeladen Datei ...' self.update_view() if 'otrkey' in self.filename: torrent_check_return = self._check_file_with_torrent() if torrent_check_return == 0: self.information[ 'message_short'] = '(OK):Download vollständig.' self._finished() elif torrent_check_return == 7: self.information['status'] = DownloadStatus.ERROR self.information[ 'message_short'] = '(INPR):Download unvollständig - Datei hat Torrent-Prüfung nicht bestanden. z.B. durch fehlerhaften oder nicht mehr gültiger Link. Downloadabbruch oder defekte Mirrordatei.' self.information['progress'] = 0 else: self.information['status'] = DownloadStatus.ERROR self.information[ 'message_short'] = '(EER):Fehler bei der abschliessenden Überprüfung aufgetreten. Eventuell OTR nicht erreichbar.' self.information['progress'] = 0 elif self.information['download_type'] in [ DownloadTypes.OTR_DECODE, DownloadTypes.OTR_CUT ]: decoder = self._config.get_program('decoder') email = self._config.get('general', 'email') password = self._config.get('general', 'password') cache_dir = self._config.get('general', 'folder_trash_otrkeys') command = [ decoder, "-b", "0", "-n", "-i", self.link, "-e", email, "-p", password, "-c", cache_dir ] if self.information['download_type'] == DownloadTypes.OTR_CUT: self.information['output'] = self._config.get( 'general', 'folder_cut_avis') if not self.information['cutlist']: cutlist = Cutlist() cutlist.id = self.information['cutlist_id'] error = cutlist.download( self._config.get('general', 'server'), os.path.join(self.information['output'], self.filename)) if error: self.information['status'] = DownloadStatus.ERROR self.information[ 'message_short'] = 'Cutlist konnte nicht geladen werden.' yield error return self.information['cutlist'] = cutlist command += [ "-o", self.information['output'], "-C", self.information['cutlist'].local_filename ] else: self.information['output'] = self._config.get( 'general', 'folder_uncut_avis') command += ["-o", self.information['output']] # write command to log, but strip out email and password log = list(command) log[log.index('-p') + 1] = '*******' log[log.index('-e') + 1] = '*******' yield "Ausgeführt wird:\n%s\n" % " ".join(log) try: self.__process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError as error: self.information['status'] = DownloadStatus.ERROR self.information['message_short'] = 'Dekoder nicht gefunden.' yield "Der Pfad zum Dekoder scheint nicht korrekt zu sein. Der folgende Befehl konnte nicht ausgeführt werden\nFehlermeldung: %s" % error return line = '' while self.__process.poll() == None: char = self.__process.stdout.read(1) if char == '\r' or char == '\n': line = line.strip() if not line: continue if not "%" in line: yield line result = re.findall("([0-9]{1,3})%", line) if result: self.information['progress'] = int(result[0]) result = re.findall("[0-9]{1,3}%.*: (.*)", line) if result: self.information['speed'] = result[0] self.update_view() line = '' else: line += char ### Process is terminated stderr = self.__process.stderr.read().strip() if stderr: self.information['status'] = DownloadStatus.ERROR if "invalid option" in stderr: self.information[ 'message_short'] = 'Der Dekoder ist veraltet.' yield "Es ist ein veralteter Dekoder angegeben!\n" elif "maximale Anzahl": self.information[ 'message_short'] = 'Maximale Anzahl der Dekodierungen erreicht.' yield str(stderr, 'iso-8859-1') else: self.information['message_short'] = stderr yield stderr if not self.information['status'] in [ DownloadStatus.ERROR, DownloadStatus.STOPPED ]: self._finished() # remove otrkey and .segments file otrkey = os.path.join(cache_dir, self.filename) fileoperations.remove_file(otrkey, None) fileoperations.remove_file( os.path.join(cache_dir, self.filename + '.segments'), None) if self.information['download_type'] == DownloadTypes.OTR_CUT: # rename file to "cut" filename filename = os.path.join(self.information['output'], self.filename.rstrip(".otrkey")) new_filename, extension = os.path.splitext(filename) new_filename += ".cut" + extension fileoperations.rename_file(filename, new_filename, None) conclusion = FileConclusion(Action.DECODEANDCUT, otrkey=otrkey, uncut_video=filename) conclusion.decode.status = Status.OK conclusion.cut_video = new_filename conclusion.cut.cutlist = self.information['cutlist'] conclusion.cut.cutlist.read_from_file() conclusion.cut.status = Status.OK conclusion.cut.cut_action = Cut_action.CHOOSE_CUTLIST if self._config.get('general', 'rename_cut'): conclusion.cut.rename = self._app.rename_by_schema( self.filename.rstrip(".otrkey")) else: conclusion.cut.rename = os.path.basename(new_filename) self._app.conclusions_manager.add_conclusions(conclusion) self.update_view()