Esempio n. 1
0
    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()
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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()
Esempio n. 5
0
    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
Esempio n. 6
0
    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()
Esempio n. 7
0
    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()
Esempio n. 8
0
    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()