Example #1
0
    def start(self, force=False):
        def loop(*args):
            self.log += "%s\n" % args[0]

        if force or not self.information['status'] in [
                DownloadStatus.RUNNING, DownloadStatus.SEEDING
        ]:
            self.__task = GeneratorTask(self._download, loop)
            self.__task.start()
Example #2
0
    def on_button_search_clicked(self, widget, data=None):
        text = self.builder.get_object('entry_search').get_text()
        if len(text) < 3:
            self.builder.get_object('label_status').set_markup(
                "<b>Die Suche muss mindesten 3 Zeichen haben!</b>")
            return
        else:
            for char in text:
                if not char.lower(
                ) in 'abcdefghijklmnopqrstuvwxyz0123456789.-_ *':
                    self.builder.get_object('label_status').set_markup(
                        "<b>Erlaubt sind nur Groß- und Kleinbuchstaben, die Ziffern 0 bis 9, der Punkt, das Minus, der Unterstrich und der Stern/Leerzeichen als Platzhalter!</b>"
                    )
                    return

            self.builder.get_object('label_status').set_markup("")

        model = self.builder.get_object('liststore_programs')
        model.clear()
        self.builder.get_object('scrolledwindow_programs').hide()
        self.builder.get_object('vbox_searching').show()
        self.builder.get_object('button_search').set_sensitive(False)

        self.error = ""

        GeneratorTask(self.search, self.search_callback,
                      self.search_stop).start(text)
Example #3
0
    def on_entry_link_changed(self, widget, data=None):
        download_link = widget.get_text()
        result = re.findall("([a-z._\-0-9]*_TVOON_DE[a-z0-9.]*\.otrkey)",
                            download_link, re.IGNORECASE)
        if result:
            self.filename = result[0]

            GeneratorTask(self.gather_information,
                          self.gather_information_callback,
                          self.gather_information_stop).start()
        else:
            pass
Example #4
0
    def download_generator(self, get_all_qualities):
        # start looking for downloadable cutlists
        self.treeview_download_cutlists.get_model().clear()
        self.builder.get_object('label_status').set_markup(
            "<b>Cutlisten werden heruntergeladen...</b>")
        self.download_error = False

        # Empty the list for reuse
        self.cutlists_list = []
        GeneratorTask(cutlists_management.download_cutlists, None, self._completed).\
                            start(self.filename, self.app.config.get('general', 'server'),
                                  self.app.config.get('general', 'choose_cutlists_by'),
                                  self.app.config.get('general', 'cutlist_mp4_as_hq'),
                                  self._error_cb, self._cutlist_found_cb, get_all_qualities)
Example #5
0
    def setup(self, video_file):
        self.filename = video_file
        self.builder.get_object('label_file').set_markup(
            "<b>%s</b>" % os.path.basename(video_file))

        # looking for local cutlists
        p, filename = os.path.split(video_file)
        cutregex = re.compile("^" + filename + "\.?(.*).cutlist$")
        files = os.listdir(p)
        local_cutlists = []
        for f in files:
            match = cutregex.match(f)
            if match:
                # print "Found local cutlist"
                local_cutlists.append(p + '/' + match.group())
            else:
                # print f + " is no cutlist"
                pass

        # print "%d cutlists found" % len(local_cutlists)
        if len(local_cutlists) > 0:
            self.treeview_local_cutlists.get_model().clear()
            self.builder.get_object('scrolledwindow_local').set_sensitive(True)
            self.builder.get_object('button_local').set_sensitive(True)
            for c in local_cutlists:
                cutlist = cutlists_management.Cutlist()
                cutlist.local_filename = c
                cutlist.read_from_file()
                self.treeview_local_cutlists.add_cutlist(cutlist)

        else:
            self.builder.get_object('scrolledwindow_local').set_sensitive(
                False)
            self.builder.get_object('button_local').set_active(False)
            self.builder.get_object('button_local').set_sensitive(False)

        # start looking for downloadable cutlists
        self.treeview_download_cutlists.get_model().clear()
        self.builder.get_object('label_status').set_markup(
            "<b>Cutlisten werden heruntergeladen...</b>")
        self.download_error = False

        GeneratorTask(cutlists_management.download_cutlists, None,
                      self._completed).start(
                          video_file, self.app.config.get('general', 'server'),
                          self.app.config.get('general', 'choose_cutlists_by'),
                          self.app.config.get('general', 'cutlist_mp4_as_hq'),
                          self._error_cb, self._cutlist_found_cb)
Example #6
0
 def change_status(self, message_type, message, permanent=False):
     """ Zeigt ein Bild und einen Text in der Statusleiste an.
           message_type 0 = Information-Icon, -1  = kein Icon
           message Anzuzeigender Text
           permanent: wenn \e False, verschwindet die Nachricht nach 10s wieder."""
         
     self.builder.get_object('label_statusbar').set_text(message)           
         
     if message_type == 0:            
         self.builder.get_object('image_status').set_from_file(path.get_image_path("information.png"))
     
     if not permanent:                
         def wait():
             yield 0 # fake generator
             time.sleep(10)
                
         def completed():
             self.builder.get_object('label_statusbar').set_text("")     
             self.builder.get_object('image_status').clear()
                
         GeneratorTask(wait, None, completed).start()         
Example #7
0
    def forward(self, iter=None, link=None):
        """ iter==None --> programs search was skipped 
            iter!=None --> iter is the selected program 
            link!=None --> executable was called with 'link' argument """

        self.mode = 1  # download

        self.builder.get_object('vbox_search').hide()
        self.builder.get_object('vbox_download').show()
        self.builder.get_object('button_ok').set_label("_Download")
        self.builder.get_object('button_ok').set_sensitive(True)

        if iter:
            self.filename, mirrors = self.builder.get_object(
                'liststore_programs').get(iter, 0, 7)

            if mirrors == 1:
                self.builder.get_object('button_mirror_search').set_label(
                    "Auf einem Mirror suchen")
            else:
                self.builder.get_object('button_mirror_search').set_label(
                    "Auf %i Mirrors suchen" % mirrors)

            GeneratorTask(self.gather_information,
                          self.gather_information_callback,
                          self.gather_information_stop).start()
        else:
            self.builder.get_object('image_spinner_download').hide()
            self.builder.get_object('button_mirror_search').hide()
            self.builder.get_object('label_torrent').set_markup(
                "Download via Torrent")
            self.builder.get_object('label_error').set_markup('')

            if link:
                self.builder.get_object('entry_link').set_text(link)
            else:
                self.builder.get_object('label_download_status').set_markup(
                    "Füge einen Downloadlink in das Feld ein!")
Example #8
0
    def on_mp4_clicked(self, widget, data=None):
        filenames = self.gui.main_window.get_selected_filenames()

        if len(filenames) == 0:
            self.gui.message_error_box("Es muss eine Datei markiert sein.")
            return

        self.toolbutton.set_sensitive(False)
        self.gui.main_window.set_tasks_visible(True)
        self.success = 0
        self.errors = {}

        def mp4():
            # env
            my_env = os.environ.copy()
            my_env["LANG"] = "C"

            for count, filename in enumerate(filenames):
                # analyse file
                cutter = Cut(self.app, self.gui)
                fps, dar, sar, max_frames, ac3_stream, error = cutter.analyse_mediafile(
                    filename)
                if fps == None:
                    self.errors[filename] = error
                    continue

                # mkvmerge pass
                yield 0, count
                self.progress = 0

                if os.path.splitext(filename)[1] != '.mkv':

                    mkvpass_file = fileoperations.make_unique_filename(
                        os.path.splitext(filename)[0] + "_remux.mkv")
                    try:
                        p = subprocess.Popen([
                            self.app.config.get_program('mkvmerge'),
                            '--ui-language', 'en_US', "-o", mkvpass_file,
                            filename
                        ],
                                             stdout=subprocess.PIPE,
                                             env=my_env)
                    except OSError:
                        self.errors[
                            filename] = "MKVmerge wurde nicht gefunden!"
                        continue

                    p.stdout.readline()
                    line = ""

                    while p.poll() == None:
                        # read progress from stdout
                        char = p.stdout.read(1)
                        line += char.decode('utf-8')
                        progress = ''
                        if char == ':':
                            if "Error" in line or "Warning" in line:
                                break

                            while char != '%':
                                char = p.stdout.read(1)
                                progress += char

                            try:
                                self.progress = int(progress.strip(' %'))
                                yield 4, self.progress
                            except ValueError:
                                pass

                    exit_code = p.poll()

                    if exit_code == 0 or exit_code == 1:
                        pass
                    else:
                        error = p.stdout.readline()
                        if os.path.exists(mkvpass_file):
                            fileoperations.remove_file(mkvpass_file)
                        try:
                            error = error.split(":")[1]
                        except IndexError:
                            pass

                        if "unknown type" in error:
                            error = "Datei konnte nicht gelesen werden."
                        self.errors[filename] = error
                        continue
                else:
                    mkvpass_file = filename

                # norm volume ausrechnen
                yield 5, count
                if self.Config['NormalizeAudio'] and self.Config[
                        'EncodeAudioToAAC']:
                    vol, error = self.get_norm_volume(filename)
                else:
                    vol = 1.0

                # ffmpeg pass
                yield 1, count
                self.progress = 0
                ffmpegpass_file = fileoperations.make_unique_filename(
                    os.path.splitext(filename)[0] + "_remux.mp4")

                if self.Config['EncodeAudioToAAC']:
                    if self.Config['EncodeOnlyFirstAudioToAAC']:
                        aacaudiostreams = '-c:a:0'
                    else:
                        aacaudiostreams = '-c:a'

                    # convert first audio stream to aac
                    ffmpeg = self.app.config.get_program('ffmpeg')
                    if 'nonfree' in ffmpeg:
                        # nonfree ffmpeg version with fdk support available
                        audiocodec = [
                            '-c:a', 'copy', aacaudiostreams, 'libfdk_aac',
                            '-flags', '+qscale', '-profile:a:0', 'aac_low',
                            '-global_quality', '5', '-afterburner', '1'
                        ]
                    else:
                        # only gpl version of ffmpeg available -> use standard aac codec
                        audiocodec = [
                            '-c:a', 'copy', aacaudiostreams, 'aac', '-strict',
                            '-2', '-profile:a:0', 'aac_low', '-ab', '192k',
                            '-cutoff', '18000'
                        ]
                else:
                    # only copy audio
                    ffmpeg = path.get_tools_path('intern-ffmpeg')
                    audiocodec = ['-c:a', 'copy']

                if self.Config['DownMixStereo'] and self.Config[
                        'EncodeAudioToAAC']:
                    audiocodec.extend(['-ac:0', '2'])

                if ac3_stream == None:
                    # no ac3 stream found - all streams are muxed
                    map = ['-map', '0']
                else:
                    if self.Config['RemoveOtherAudioStreamsThanAC3']:
                        # mux only video and ac3 stream
                        map = ['-map', '0:v', '-map', ac3_stream]
                    else:
                        map = ['-map', '0']

                args = [
                    ffmpeg, "-loglevel", "info", "-y", "-drc_scale", "1.0",
                    "-i", mkvpass_file, "-vcodec", "copy", '-af',
                    'volume=volume=' + str(vol), "-vsync", "1", '-async',
                    '1000', "-dts_delta_threshold", "100", "-vf",
                    "fps=" + str(fps), ffmpegpass_file
                ]
                map.extend(audiocodec)
                args[8:8] = map

                try:
                    p = subprocess.Popen(args,
                                         stderr=subprocess.PIPE,
                                         universal_newlines=True)
                except OSError:
                    self.errors[
                        filename] = "FFMPEG (intern) wurde nicht gefunden!"
                    if os.path.exists(
                            mkvpass_file) and filename != mkvpass_file:
                        fileoperations.remove_file(mkvpass_file)
                    continue

                yield 4, 0
                line = ""
                infos_match = re.compile(r"frame=\ {0,1}(\d{1,})")

                while p.poll() == None:
                    line = p.stderr.readline()
                    m = re.search(infos_match, line)
                    if m and max_frames != 0:
                        next = float(
                            float(m.group(1)) / float(max_frames)) * 100
                        if next > self.progress:
                            self.progress = next
                            yield 4, self.progress
                    else:
                        pass

                exit_code = p.poll()
                if os.path.exists(mkvpass_file) and filename != mkvpass_file:
                    fileoperations.remove_file(mkvpass_file)

                if exit_code == 0:
                    if self.Config['DumpAVIs']:
                        yield 3, self.success
                        new_filename = os.path.join(
                            self.app.config.get('general',
                                                'folder_trash_avis'),
                            os.path.basename(filename))
                        if os.path.exists(new_filename):
                            fileoperations.remove_file(new_filename)
                        fileoperations.move_file(
                            filename,
                            self.app.config.get('general',
                                                'folder_trash_avis'))
                else:
                    self.errors[
                        filename] = "Fehler beim Erzeugen der MP4 Datei durch FFMPEG"
                    if os.path.exists(ffmpegpass_file):
                        fileoperations.remove_file(ffmpegpass_file)
                    continue

                # mp4box - last turn
                self.progress = 0
                mp4boxpass_file = fileoperations.make_unique_filename(
                    os.path.splitext(filename)[0] + ".mp4")

                if self.Config['DontOptimizeMP4']:
                    os.rename(ffmpegpass_file, mp4boxpass_file)
                    self.success += 1
                    continue

                yield 2, count
                try:
                    p = subprocess.Popen([
                        self.app.config.get_program('mp4box'), "-keep-all",
                        "-new", "-packed", "-fps",
                        str(fps), "-add", ffmpegpass_file, mp4boxpass_file
                    ],
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.STDOUT)
                except OSError:
                    self.errors[
                        filename] = "MP4Box (intern) wurde nicht gefunden!"
                    if os.path.exists(ffmpegpass_file):
                        fileoperations.remove_file(ffmpegpass_file)
                    continue

                yield 4, 0
                infos_match = re.compile(r".*\((\d{2,})\/\d{2,}\).*")

                while p.poll() == None:
                    line = p.stdout.read(60)
                    line = line.decode('utf-8')
                    m = re.search(infos_match, line)
                    if m:
                        self.progress = int(m.group(1))
                        yield 4, self.progress

                        if 'Importing' in line:
                            yield 2, count
                        elif 'Writing' in line:
                            yield 6, count
                    else:
                        pass

                exit_code = p.poll()
                if os.path.exists(ffmpegpass_file):
                    fileoperations.remove_file(ffmpegpass_file)

                if exit_code == 0:
                    self.success += 1
                else:
                    self.errors[
                        filename] = "Fehler beim Erzeugen der MP4 Datei durch MP4Box"

        def loop(state, argument):
            if state == 0:
                self.gui.main_window.set_tasks_text(
                    "Extrahiere Streams aus Inputdatei ... %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            elif state == 1:
                self.gui.main_window.set_tasks_text(
                    "MP4 erzeugen ... %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            elif state == 2:
                self.gui.main_window.set_tasks_text(
                    "MP4 optimieren (importiere Stream) ...  %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            elif state == 3:
                self.gui.main_window.set_tasks_text(
                    "Originaldatei in Mülleimer verschieben ... %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            elif state == 5:
                self.gui.main_window.set_tasks_text(
                    "Normalisierungswert berechnen ... %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            elif state == 6:
                self.gui.main_window.set_tasks_text(
                    "MP4 optimieren (schreibe MP4) ... %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            else:
                self.gui.main_window.set_tasks_progress(argument)

        def complete():
            if len(self.errors) == 0:
                self.gui.main_window.change_status(
                    0, "Erfolgreich %s/%s Dateien umgewandelt." %
                    (str(self.success), str(len(filenames))))
            else:
                self.gui.main_window.change_status(
                    0, "Erfolgreich %s/%s Dateien umgewandelt. (Fehler: %s)" %
                    (str(self.success), str(len(filenames)), " ".join(
                        self.errors.values())))

            self.gui.main_window.set_tasks_visible(False)
            if self.success > 0:
                self.app.show_section(self.app.section)
            self.toolbutton.set_sensitive(True)

        GeneratorTask(mp4, loop, complete).start()
Example #9
0
    def on_mkv_clicked(self, widget, data=None):
        filenames = self.gui.main_window.get_selected_filenames()

        if len(filenames) == 0:
            self.gui.message_error_box("Es muss eine Datei markiert sein.")
            return

        self.toolbutton.set_sensitive(False)
        self.gui.main_window.set_tasks_visible(True)
        self.success = 0
        self.errors = {}

        def mkvmerge():
            # env
            my_env = os.environ.copy()
            my_env["LANG"] = "C"

            for count, filename in enumerate(filenames):
                yield 0, count
                yield 3, 0
                self.progress = 0

                #analyse file
                cutter = Cut(self.app, self.gui)
                fps, dar, sar, max_frames, ac3_stream, error = cutter.analyse_mediafile(
                    filename)
                if fps == None:
                    self.errors[filename] = error
                    continue

                # encode aac with ffmpeg
                if self.Config['EncodeAudioToAAC']:
                    #norm volume ausrechnen
                    yield 5, count
                    if self.Config['NormalizeAudio'] and self.Config[
                            'EncodeAudioToAAC']:
                        vol, error = self.get_norm_volume(filename)
                    else:
                        vol = 1.0

                    # ffmpeg pass
                    yield 1, count
                    self.progress = 0
                    ffmpegpass_file = fileoperations.make_unique_filename(
                        os.path.splitext(filename)[0] + "_remux.mkv")

                    # convert first audio stream to aac
                    if self.Config['EncodeOnlyFirstAudioToAAC']:
                        aacaudiostreams = '-c:a:0'
                    else:
                        aacaudiostreams = '-c:a'

                    # convert first audio stream to aac
                    ffmpeg = self.app.config.get_program('ffmpeg')
                    if 'nonfree' in ffmpeg:
                        # nonfree ffmpeg version with fdk support available
                        audiocodec = [
                            '-c:a', 'copy', aacaudiostreams, 'libfdk_aac',
                            '-flags', '+qscale', '-profile:a:0', 'aac_low',
                            '-global_quality', '5', '-afterburner', '1'
                        ]
                    else:
                        # only gpl version of ffmpeg available -> use standard aac codec
                        audiocodec = [
                            '-c:a', 'copy', aacaudiostreams, 'aac', '-strict',
                            '-2', '-profile:a:0', 'aac_low', '-ab', '192k',
                            '-cutoff', '18000'
                        ]

                    if self.Config['DownMixStereo'] and self.Config[
                            'EncodeAudioToAAC']:
                        audiocodec.extend(['-ac:0', '2'])

                    if ac3_stream == None:
                        # no ac3 stream found - all streams are muxed
                        map = ['-map', '0']
                    else:
                        if self.Config['RemoveOtherAudioStreamsThanAC3']:
                            # mux only video and ac3 stream
                            map = ['-map', '0:v', '-map', ac3_stream]
                        else:
                            map = ['-map', '0']

                    args = [
                        ffmpeg, "-loglevel", "info", "-y", "-drc_scale", "1.0",
                        "-i", filename, "-vn", '-af',
                        'volume=volume=' + str(vol), "-vsync", "1", '-async',
                        '1000', "-dts_delta_threshold", "100", "-vf",
                        "fps=" + str(fps), '-threads', '0', ffmpegpass_file
                    ]
                    map.extend(audiocodec)
                    args[8:8] = map

                    try:
                        p = subprocess.Popen(args,
                                             stderr=subprocess.PIPE,
                                             universal_newlines=True)
                    except OSError:
                        self.errors[
                            filename] = "FFMPEG (intern) wurde nicht gefunden!"
                        continue

                    yield 4, 0
                    line = ""
                    infos_match = re.compile(
                        r"time=(\d{2,}):(\d{2,}):(\d{2,}.\d{2,})")

                    while p.poll() == None:
                        line = p.stderr.readline()
                        m = re.search(infos_match, line)
                        if m and max_frames != 0:
                            frame = (float(m.group(1)) * 3600 +
                                     float(m.group(2)) * 60 +
                                     float(m.group(3))) * fps
                            next = float(frame / float(max_frames)) * 100
                            if next > self.progress:
                                self.progress = next
                                yield 4, self.progress
                        else:
                            pass

                    exit_code = p.poll()

                    if exit_code == 0:
                        pass
                    else:
                        self.errors[
                            filename] = "Fehler beim Erzeugen der MP4 Datei durch FFMPEG"
                        if os.path.exists(ffmpegpass_file):
                            fileoperations.remove_file(ffmpegpass_file)
                        continue

                # mkvmerge pass
                yield 2, count
                self.progress = 0

                mkvpass_file = fileoperations.make_unique_filename(
                    os.path.splitext(filename)[0] + ".mkv")

                if self.Config['EncodeAudioToAAC']:
                    args = [
                        self.app.config.get_program('mkvmerge'), '--engage',
                        'no_cue_duration', '--engage',
                        'no_cue_relative_position', '--ui-language', 'en_US',
                        "-o", mkvpass_file, '-A', filename, '-D',
                        ffmpegpass_file
                    ]
                else:
                    if self.Config[
                            'RemoveOtherAudioStreamsThanAC3'] and ac3_stream:
                        args = [
                            self.app.config.get_program('mkvmerge'),
                            '--engage', 'no_cue_duration', '--engage',
                            'no_cue_relative_position', '--ui-language',
                            'en_US', "-o", mkvpass_file, '-a', ac3_stream[2],
                            filename
                        ]
                    else:
                        args = [
                            self.app.config.get_program('mkvmerge'),
                            '--engage', 'no_cue_duration', '--engage',
                            'no_cue_relative_position', '--ui-language',
                            'en_US', "-o", mkvpass_file, filename
                        ]

                p = subprocess.Popen(args, stdout=subprocess.PIPE, env=my_env)
                p.stdout.readline()

                line = ""
                while p.poll() == None:
                    # read progress from stdout
                    char = p.stdout.read(1)
                    line += char
                    progress = ''
                    if char == ':':
                        if "Error" in line or "Warning" in line:
                            break

                        while char != '%':
                            char = p.stdout.read(1)
                            progress += char

                        try:
                            self.progress = int(progress.strip(' %'))
                            yield 3, self.progress
                        except ValueError:
                            pass

                exit_code = p.poll()

                if exit_code == 0 or exit_code == 1:
                    self.success += 1
                    if self.Config['EncodeAudioToAAC']:
                        fileoperations.remove_file(ffmpegpass_file)
                    if self.Config['DumpAVIs']:
                        if self.Config['DumpAVIs_delete']:
                            fileoperations.remove_file(filename)
                        else:
                            new_filename = os.path.join(
                                self.app.config.get('general',
                                                    'folder_trash_avis'),
                                os.path.basename(filename))
                            if os.path.exists(new_filename):
                                fileoperations.remove_file(new_filename)
                            fileoperations.move_file(
                                filename,
                                self.app.config.get('general',
                                                    'folder_trash_avis'))
                else:
                    error = p.stdout.readline()
                    try:
                        error = error.split(":")[1]
                    except IndexError:
                        pass

                    if "unknown type" in error:
                        error = "Datei konnte nicht gelesen werden."
                    self.errors[filename] = error

        def loop(state, argument):
            if state == 0:
                self.gui.main_window.set_tasks_text(
                    "Analysiere Datei ... %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            elif state == 1:
                self.gui.main_window.set_tasks_text(
                    "Audiospur in AAC wandeln ... %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            elif state == 2:
                self.gui.main_window.set_tasks_text(
                    "MKV erstellen ...  %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            elif state == 5:
                self.gui.main_window.set_tasks_text(
                    "Normalisierungswert berechnen ... %s/%s" %
                    (str(argument + 1), str(len(filenames))))
            else:
                self.gui.main_window.set_tasks_progress(argument)

        def complete():
            if len(self.errors) == 0:
                self.gui.main_window.change_status(
                    0, "Erfolgreich %s/%s Dateien umgewandelt." %
                    (str(self.success), str(len(filenames))))
            else:
                self.gui.main_window.change_status(
                    0, "Erfolgreich %s/%s Dateien umgewandelt. (Fehler: %s)" %
                    (str(self.success), str(len(filenames)), " ".join(
                        self.errors.values())))

            self.gui.main_window.set_tasks_visible(False)
            if self.success > 0:
                self.app.show_section(self.app.section)
            self.toolbutton.set_sensitive(True)

        GeneratorTask(mkvmerge, loop, complete).start()
Example #10
0
class Details(Plugin):
    Name = "Details"
    Desc = "Zeigt zu einer Video-Datei Details wie den verwendeten Codec und die Dauer an."
    Author = "Benjamin Elbers"
    Configurable = False
 
    def enable(self):
        treeselection = self.gui.main_window.builder.get_object('treeview_files').get_selection()
        self.on_treeselection_changed_id = treeselection.connect('changed', lambda callback: self.update_details())
                
        # Typ
        # Aspect-Ratio ...
        # Video-Format ...
        # Dauer        ...        
        padding = 3,3
        table = gtk.Table(4, 2)
        self.label_filetype = gtk.Label('')
        self.label_aspect = gtk.Label('...')
        self.label_video_format = gtk.Label('...')
        self.label_length = gtk.Label('...')
        
        table.attach(self.label_filetype, 0, 2, 0, 1, gtk.FILL, gtk.FILL, *padding)        
        table.attach(gtk.Label("Aspect-Ratio"), 0, 1, 1, 2, gtk.FILL, gtk.FILL, *padding)
        table.attach(self.label_aspect, 1, 2, 1, 2, gtk.FILL, gtk.FILL, *padding)
        table.attach(gtk.Label("Video-Format"), 0, 1, 2, 3, gtk.FILL, gtk.FILL, *padding)
        table.attach(self.label_video_format, 1, 2, 2, 3, gtk.FILL, gtk.FILL, *padding)
        table.attach(gtk.Label("Dauer"), 0, 1, 3, 4, gtk.FILL, gtk.FILL, *padding)
        table.attach(self.label_length, 1, 2, 3, 4, gtk.FILL, gtk.FILL, *padding)
        table.show_all()
        
        # add to bottom bar
        self.page_index = self.gui.main_window.builder.get_object('notebook_bottom').append_page(table, gtk.Label("Details"))
        
    def disable(self):                
        treeselection = self.gui.main_window.builder.get_object('treeview_files').get_selection()
        treeselection.disconnect(self.on_treeselection_changed_id)
    
        self.gui.main_window.builder.get_object('notebook_bottom').remove_page(self.page_index)
                      
    def update_details(self):       
        try:
            self.task.stop()
        except:
            pass
    
        if self.app.section == Section.PLANNING:
            self.reset_details("")
            return

        mplayer = self.app.config.get('general', 'mplayer')

        if not mplayer:
            self.reset_details("Der MPlayer ist nicht installiert!")
            return
      
        filenames = self.gui.main_window.get_selected_filenames()   
      
        if len(filenames) == 0:
            self.reset_details("<b>Keine Datei markiert.</b>")
        
        elif len(filenames) > 1:
            self.reset_details("<b>%s Dateien markiert.</b>" % len(filenames))
        
        else:
            filename = filenames[0]
           
            extension = os.path.splitext(filename)[1]
            
            self.label_filetype.set_markup("<b>%s-Datei</b>" % extension[1:])
            
            if extension != ".otrkey":

                def get_information():
                    yield
                                
                    # prettify the output!
                    def prettify_aspect(aspect):
                        if aspect == "1.7778":
                            return "16:9" 
                        elif aspect == "1.3333":
                            return "4:3"
                        else:
                            return aspect
                    
                    def prettify_length(seconds):                       
                        hrs = float(seconds) / 3600       
                        leftover = float(seconds) % 3600
                        mins = leftover / 60
                        secs = leftover % 60
                           
                        return "%02d:%02d:%02d" % (hrs, mins, secs)
                    
                    values = (
                        ("ID_VIDEO_ASPECT", self.label_aspect, prettify_aspect),
                        ("ID_VIDEO_FORMAT", self.label_video_format, None),
                        ("ID_LENGTH", self.label_length, prettify_length)
                        )
                  
                    process = subprocess.Popen([mplayer, "-identify", "-vo", "null", "-frames", "1", "-nosound", filename], stdout=subprocess.PIPE)
                          
                    while process.poll() == None:                                          
                        line = process.stdout.readline().strip()

                        for value, widget, callback in values:
                            
                            if line.startswith(value):
                                # mplayer gives an output like this: ID_VIDEO_ASPECT=1.3333
                                value = line.split("=")[1]
                                
                                if callback:
                                    value = callback(value)
                                
                                widget.set_text(value)   
                                
                self.task = GeneratorTask(get_information)
                self.task.start()
                            
    def reset_details(self, filetype=""):
        self.label_filetype.set_markup(filetype)
        self.label_aspect.set_text("...")
        self.label_video_format.set_text("...")
        self.label_length.set_text("...")                                    
Example #11
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()
Example #12
0
    def update_details(self):
        try:
            self.task.stop()
        except:
            pass

        if self.app.section == Section.PLANNING:
            self.reset_details("")
            return

        mplayer = self.app.config.get_program('mplayer')

        if not mplayer:
            self.reset_details("Der MPlayer ist nicht installiert!")
            return

        filenames = self.gui.main_window.get_selected_filenames()

        if len(filenames) == 0:
            self.reset_details("<b>Keine Datei markiert.</b>")

        elif len(filenames) > 1:
            self.reset_details("<b>%s Dateien markiert.</b>" % len(filenames))

        else:
            filename = filenames[0]

            extension = os.path.splitext(filename)[1]

            self.label_filetype.set_markup("<b>%s-Datei</b>" % extension[1:])

            if extension != ".otrkey":

                def get_information():
                    yield

                    # prettify the output!
                    def prettify_aspect(aspect):
                        if aspect == "1.7778":
                            return "16:9"
                        elif aspect == "1.3333":
                            return "4:3"
                        else:
                            return aspect

                    def prettify_length(seconds):
                        hrs = float(seconds) / 3600
                        leftover = float(seconds) % 3600
                        mins = leftover / 60
                        secs = leftover % 60

                        return "%02d:%02d:%02d" % (hrs, mins, secs)

                    values = (("ID_VIDEO_ASPECT", self.label_aspect,
                               prettify_aspect),
                              ("ID_VIDEO_FORMAT", self.label_video_format,
                               None), ("ID_LENGTH", self.label_length,
                                       prettify_length))

                    process = subprocess.Popen([
                        mplayer, "-identify", "-vo", "null", "-frames", "1",
                        "-nosound", filename
                    ],
                                               stdout=subprocess.PIPE)

                    while process.poll() == None:
                        line = process.stdout.readline().strip()

                        for value, widget, callback in values:

                            if line.startswith(value):
                                # mplayer gives an output like this: ID_VIDEO_ASPECT=1.3333
                                value = line.split("=")[1]

                                if callback:
                                    value = callback(value)

                                widget.set_text(value)

                self.task = GeneratorTask(get_information)
                self.task.start()
Example #13
0
class Details(Plugin):
    Name = "Details"
    Desc = "Zeigt zu einer Video-Datei Details wie den verwendeten Codec und die Dauer an."
    Author = "Benjamin Elbers"
    Configurable = False

    def enable(self):
        treeselection = self.gui.main_window.builder.get_object(
            'treeview_files').get_selection()
        self.on_treeselection_changed_id = treeselection.connect(
            'changed', lambda callback: self.update_details())

        # Typ
        # Aspect-Ratio ...
        # Video-Format ...
        # Dauer        ...
        padding = 3, 3
        table = Gtk.Table(4, 2)
        self.label_filetype = Gtk.Label('')
        self.label_aspect = Gtk.Label('...')
        self.label_video_format = Gtk.Label('...')
        self.label_length = Gtk.Label('...')

        table.attach(self.label_filetype, 0, 2, 0, 1, Gtk.Align.FILL,
                     Gtk.Align.FILL, *padding)
        table.attach(Gtk.Label("Aspect-Ratio"), 0, 1, 1, 2, Gtk.Align.FILL,
                     Gtk.Align.FILL, *padding)
        table.attach(self.label_aspect, 1, 2, 1, 2, Gtk.Align.FILL,
                     Gtk.Align.FILL, *padding)
        table.attach(Gtk.Label("Video-Format"), 0, 1, 2, 3, Gtk.Align.FILL,
                     Gtk.Align.FILL, *padding)
        table.attach(self.label_video_format, 1, 2, 2, 3, Gtk.Align.FILL,
                     Gtk.Align.FILL, *padding)
        table.attach(Gtk.Label("Dauer"), 0, 1, 3, 4, Gtk.Align.FILL,
                     Gtk.Align.FILL, *padding)
        table.attach(self.label_length, 1, 2, 3, 4, Gtk.Align.FILL,
                     Gtk.Align.FILL, *padding)
        table.show_all()

        # add to bottom bar
        self.page_index = self.gui.main_window.builder.get_object(
            'notebook_bottom').append_page(table, Gtk.Label("Details"))

    def disable(self):
        treeselection = self.gui.main_window.builder.get_object(
            'treeview_files').get_selection()
        treeselection.disconnect(self.on_treeselection_changed_id)

        self.gui.main_window.builder.get_object('notebook_bottom').remove_page(
            self.page_index)

    def update_details(self):
        try:
            self.task.stop()
        except:
            pass

        if self.app.section == Section.PLANNING:
            self.reset_details("")
            return

        mplayer = self.app.config.get_program('mplayer')

        if not mplayer:
            self.reset_details("Der MPlayer ist nicht installiert!")
            return

        filenames = self.gui.main_window.get_selected_filenames()

        if len(filenames) == 0:
            self.reset_details("<b>Keine Datei markiert.</b>")

        elif len(filenames) > 1:
            self.reset_details("<b>%s Dateien markiert.</b>" % len(filenames))

        else:
            filename = filenames[0]

            extension = os.path.splitext(filename)[1]

            self.label_filetype.set_markup("<b>%s-Datei</b>" % extension[1:])

            if extension != ".otrkey":

                def get_information():
                    yield

                    # prettify the output!
                    def prettify_aspect(aspect):
                        if aspect == "1.7778":
                            return "16:9"
                        elif aspect == "1.3333":
                            return "4:3"
                        else:
                            return aspect

                    def prettify_length(seconds):
                        hrs = float(seconds) / 3600
                        leftover = float(seconds) % 3600
                        mins = leftover / 60
                        secs = leftover % 60

                        return "%02d:%02d:%02d" % (hrs, mins, secs)

                    values = (("ID_VIDEO_ASPECT", self.label_aspect,
                               prettify_aspect),
                              ("ID_VIDEO_FORMAT", self.label_video_format,
                               None), ("ID_LENGTH", self.label_length,
                                       prettify_length))

                    process = subprocess.Popen([
                        mplayer, "-identify", "-vo", "null", "-frames", "1",
                        "-nosound", filename
                    ],
                                               stdout=subprocess.PIPE)

                    while process.poll() == None:
                        line = process.stdout.readline().strip()

                        for value, widget, callback in values:

                            if line.startswith(value):
                                # mplayer gives an output like this: ID_VIDEO_ASPECT=1.3333
                                value = line.split("=")[1]

                                if callback:
                                    value = callback(value)

                                widget.set_text(value)

                self.task = GeneratorTask(get_information)
                self.task.start()

    def reset_details(self, filetype=""):
        self.label_filetype.set_markup(filetype)
        self.label_aspect.set_text("...")
        self.label_video_format.set_text("...")
        self.label_length.set_text("...")
Example #14
0
class Download:
    def __init__(self, app, config, filename=None, link=None):
        """ Torrent: link=None """

        self._app = app
        self._config = config

        self.filename = filename
        self.link = link
        self.log = ""

        self.information = {
            'output': '',
            'status': -1,
            'size': None,
            'progress': 0,
            'speed': '',
            'est': '',
            'message_short': '',
            # Torrent
            'seeders': None,
            'upspeed': None,
            'uploaded': None,
            'ratio': None
        }

        self.__task = None
        self.__process = None

    #
    # Storage
    #

    def to_json(self):
        information = self.information.copy()
        if 'cutlist' in information.keys():
            information['cutlist'] = None

        return {
            'information': information,
            'filename': self.filename,
            'link': self.link
        }

    def from_json(self, json):
        self.information = json['information']
        self.filename = json['filename']
        self.link = json['link']

    #
    # Init methods for action
    #

    def download_torrent(self):
        self.information['download_type'] = DownloadTypes.TORRENT

    def download_basic(self, preferred_downloader):
        self.information['download_type'] = DownloadTypes.BASIC
        self.information['preferred_downloader'] = preferred_downloader

    def download_decode(self, cutlist_id=None):
        if cutlist_id:
            self.information['download_type'] = DownloadTypes.OTR_CUT
            self.information['cutlist_id'] = cutlist_id
            self.information['cutlist'] = None
        else:
            self.information['download_type'] = DownloadTypes.OTR_DECODE

    #
    # Convenience methods used only by this class
    #

    def _finished(self):
        self.information['status'] = DownloadStatus.FINISHED
        self.information['progress'] = 100
        self.information['est'] = ""

    # unused by now
    def _parse_time(time):
        """ Takes a string '5m' or '6h2m59s' and calculates seconds. """
        m = re.match(
            '((?P<h>[0-9]*)h)?((?P<m>[0-9]{1,2})m)?((?P<s>[0-9]{1,2})s)?',
            time)
        if m:
            d = m.groupdict()
            time = 60 * 60 * int(m.group('h')) if m.group('h') else 0
            time = (time + 60 * int(m.group('m'))) if m.group('m') else time
            time = (time + int(m.group('s'))) if m.group('s') else time
            return time
        else:
            return 0

    def _check_file_with_torrent(self):
        """ checks file with torrent """
        torrent_url = 'http://81.95.11.2/torrents/' + self.filename + '.torrent'
        torrent_command = [
            self._config.get_program('aria2c')
        ] + self._config.get('downloader', 'aria2c_opts_torrent') + [
            "-d", self.information['output'], '--check-integrity=true',
            '--continue', '--bt-enable-lpd=false', '--bt-exclude-tracker="*"',
            '--enable-dht=false', '--enable-dht6=false',
            '--enable-peer-exchange=false', '--bt-hash-check-seed=false',
            '--bt-stop-timeout=1', '--seed-time=0', '--follow-torrent=mem',
            torrent_url
        ]

        # Checking
        try:
            returncode = subprocess.call(torrent_command)
        except OSError:
            return -1

        return returncode

    #
    # Download
    #

    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()

    def start(self, force=False):
        def loop(*args):
            self.log += "%s\n" % args[0]

        if force or not self.information['status'] in [
                DownloadStatus.RUNNING, DownloadStatus.SEEDING
        ]:
            self.__task = GeneratorTask(self._download, loop)
            self.__task.start()

    def stop(self):
        if self.information['status'] in [
                DownloadStatus.RUNNING, DownloadStatus.SEEDING
        ]:
            self.information['status'] = DownloadStatus.STOPPED
            self.information['message_short'] = ""
            self.information['est'] = ""
            self.information['speed'] = ""
            self.update_view()

            if self.__process:
                try:
                    self.__process.kill()
                except OSError:
                    pass
Example #15
0
    def cut(self, file_conclusions, action, default_cut_action=None):
        # now this method may not return "False"
        self.__gui.main_window.set_tasks_visible(True)
        self.__gui.main_window.block_gui(True)

        if not default_cut_action:
            default_cut_action = self.config.get('general', 'cut_action')

        for count, file_conclusion in enumerate(file_conclusions):
            self.__gui.main_window.set_tasks_text("Cutlist %s/%s wählen" % (count + 1, len(file_conclusions)))
            self.__gui.main_window.set_tasks_progress((count + 1) / float(len(file_conclusions)) * 100)

            # file correctly decoded?
            if action == Action.DECODEANDCUT:
                if file_conclusion.decode.status != Status.OK:
                    file_conclusion.cut.status = Status.NOT_DONE
                    file_conclusion.cut.message = "Datei wurde nicht dekodiert."
                    continue

            file_conclusion.cut.cut_action = default_cut_action

            if default_cut_action in [Cut_action.ASK, Cut_action.CHOOSE_CUTLIST]:
                # show dialog
                self.__gui.dialog_cut.setup(
                    file_conclusion.uncut_video,
                    self.config.get('general', 'folder_cut_avis'),
                    default_cut_action == Cut_action.ASK)

                cutlists = []
                self.cutlists_error = False

                def error_cb(error):
                    self.__gui.dialog_cut.builder.get_object('label_status').set_markup("<b>%s</b>" % error)
                    self.cutlists_error = True

                def cutlist_found_cb(cutlist):
                    self.__gui.dialog_cut.add_cutlist(cutlist)
                    cutlists.append(cutlist)

                def completed():
                    if not self.cutlists_error:
                        self.__gui.dialog_cut.builder.get_object('label_status').set_markup("")

                GeneratorTask(cutlists_management.download_cutlists, None, completed).start(file_conclusion.uncut_video, self.config.get('general', 'server'), self.config.get('general', 'choose_cutlists_by'), self.config.get('general', 'cutlist_mp4_as_hq'), error_cb, cutlist_found_cb)

                response = self.__gui.dialog_cut.run()
                self.__gui.dialog_cut.hide()

                if response < 0:
                    file_conclusion.cut.status = Status.NOT_DONE
                    file_conclusion.cut.message = "Abgebrochen."
                else:  # change cut_action accordingly
                    file_conclusion.cut.cut_action = response

            if file_conclusion.cut.cut_action == Cut_action.MANUALLY: # MANUALLY
                error_message, cuts, executable = self.cut_file_manually(file_conclusion.uncut_video)

                if not error_message:
                    file_conclusion.cut.create_cutlist = True
                    file_conclusion.cut.cutlist.cuts_frames = cuts
                    file_conclusion.cut.cutlist.intended_app = basename(executable)
                    file_conclusion.cut.cutlist.usercomment = 'Mit OTR-Verwaltung geschnitten'

                    fps, error = self.__get_fps(file_conclusion.uncut_video)
                    if not error:
                        file_conclusion.cut.cutlist.fps = fps
                    else:
                        file_conclusion.cut.cutlist.fps = 25.
                        print "Achtung! Möglicherweise wurde eine falsche Fps-Anzahl eingetragen! (%s)" % error
                    # calculate seconds
                    for start_frame, duration_frames in cuts:
                        file_conclusion.cut.cutlist.cuts_seconds.append((start_frame / fps, duration_frames / fps))
                else:
                    file_conclusion.cut.status = Status.ERROR
                    file_conclusion.cut.message = error_message

            elif file_conclusion.cut.cut_action == Cut_action.BEST_CUTLIST:
                error, cutlists = cutlists_management.download_cutlists(file_conclusion.uncut_video, self.config.get('general', 'server'), self.config.get('general', 'choose_cutlists_by'), self.config.get('general', 'cutlist_mp4_as_hq'))

                if error:
                    file_conclusion.cut.status = Status.ERROR
                    file_conclusion.cut.message = error
                    continue

                if len(cutlists) == 0:
                    file_conclusion.cut.status = Status.NOT_DONE
                    file_conclusion.cut.message = "Keine Cutlist gefunden."
                    continue

                file_conclusion.cut.cutlist = cutlists_management.get_best_cutlist(cutlists)

            elif file_conclusion.cut.cut_action == Cut_action.CHOOSE_CUTLIST:
                file_conclusion.cut.cutlist = self.__gui.dialog_cut.chosen_cutlist

            elif file_conclusion.cut.cut_action == Cut_action.LOCAL_CUTLIST:
                file_conclusion.cut.cutlist.local_filename = file_conclusion.uncut_video + ".cutlist"

                if not exists(file_conclusion.cut.cutlist.local_filename):
                    file_conclusion.cut.status = Status.ERROR
                    file_conclusion.cut.message = "Keine lokale Cutlist gefunden."

        # and finally cut the file
        for count, file_conclusion in enumerate(file_conclusions):

            if file_conclusion.cut.status in [Status.NOT_DONE, Status.ERROR]:
                continue

            print "[Decodeandcut] Datei %s wird geschnitten" % file_conclusion.uncut_video
            self.__gui.main_window.set_tasks_text("Datei %s/%s schneiden" % (count + 1, len(file_conclusions)))
            self.__gui.main_window.set_tasks_progress(0.5)

            # download cutlist
            if file_conclusion.cut.cut_action in [Cut_action.BEST_CUTLIST, Cut_action.CHOOSE_CUTLIST]:
                file_conclusion.cut.cutlist.download(self.config.get('general', 'server'), file_conclusion.uncut_video)

            cut_video, error = self.cut_file_by_cutlist(file_conclusion.uncut_video, file_conclusion.cut.cutlist)

            if cut_video == None:
                file_conclusion.cut.status = Status.ERROR
                file_conclusion.cut.message = error
            else:
                file_conclusion.cut.status = Status.OK
                file_conclusion.cut_video = cut_video

                if self.config.get('general', 'rename_cut'):
                    file_conclusion.cut.rename = self.rename_by_schema(basename(file_conclusion.uncut_video))
                else:
                    file_conclusion.cut.rename = basename(cut_video)

        return True
Example #16
0
    def on_mkv_clicked(self, widget, data=None):
        self.toolbutton.set_sensitive(False)
        filenames = self.gui.main_window.get_selected_filenames()
        self.gui.main_window.set_tasks_visible(True)

        self.success = 0
        self.errors ={}
                
        def mkvmerge():
            for count, filename in enumerate(filenames):           
                yield 0, count
                self.progress = 0
                p = subprocess.Popen([self.Config['mkvmerge'], "-o", os.path.splitext(filename)[0] + ".mkv", filename], stdout=subprocess.PIPE)
                p.stdout.readline()

                line = ""                            
                while p.poll() == None:
                    # read progress from stdout 
                    char = p.stdout.read(1)
                    line += char
                    progress = ''
                    if char == ':':
                        if "Error" in line or "Warning" in line:                            
                            break
                    
                        while char != '%':
                            char = p.stdout.read(1)
                            progress += char
                      
                        try:
                            self.progress = int(progress.strip(' %'))
                            yield 1, self.progress                                
                        except ValueError:
                            pass
                
                exit_code = p.poll()

                if exit_code == 0:
                    self.success += 1
                else:
                    error = p.stdout.readline()
                    try:
                        error = error.split(":")[1]
                    except IndexError:
                        pass
                        
                    if "unknown type" in error:
                        error = "Datei konnte nicht gelesen werden."
                    self.errors[filename] = error
                  
        def loop(state, argument):            
            if state == 0:
                self.gui.main_window.set_tasks_text("In Mkv Umwandeln %s/%s" % (str(argument + 1), str(len(filenames))))
            else:                
                self.gui.main_window.set_tasks_progress(argument)
        
        def complete():
            if len(self.errors) == 0:
                self.gui.main_window.change_status(0, "Erfolgreich %s/%s Dateien umgewandelt." % (str(self.success), str(len(filenames))))
            else:
                self.gui.main_window.change_status(0, "Erfolgreich %s/%s Dateien umgewandelt. (Fehler: %s)" % (str(self.success), str(len(filenames)), " ".join(self.errors.values())))
            
            self.gui.main_window.set_tasks_visible(False)                
            if self.success > 0:
                self.app.show_section(self.app.section)
            self.toolbutton.set_sensitive(True)
                        
        GeneratorTask(mkvmerge, loop, complete).start() 
Example #17
0
    def cut(self, file_conclusions, action, default_cut_action=None):
        # now this method may not return "False"
        self.gui.main_window.set_tasks_visible(True)
        self.gui.main_window.block_gui(True)

        if not default_cut_action:
            default_cut_action = self.config.get('general', 'cut_action')

        for count, file_conclusion in enumerate(file_conclusions):
            self.gui.main_window.set_tasks_text(
                "Cutlist %s/%s wählen" % (count + 1, len(file_conclusions)))
            self.gui.main_window.set_tasks_progress(
                (count + 1) / float(len(file_conclusions)) * 100)

            # file correctly decoded?
            if action == Action.DECODEANDCUT:
                if file_conclusion.decode.status != Status.OK:
                    file_conclusion.cut.status = Status.NOT_DONE
                    file_conclusion.cut.message = "Datei wurde nicht dekodiert."
                    continue

            file_conclusion.cut.cut_action = default_cut_action

            if default_cut_action in [
                    Cut_action.ASK, Cut_action.CHOOSE_CUTLIST
            ]:
                # show dialog
                self.gui.dialog_cut.setup(
                    file_conclusion.uncut_video,
                    self.config.get('general', 'folder_cut_avis'),
                    default_cut_action == Cut_action.ASK)

                cutlists = []
                self.cutlists_error = False

                def error_cb(error):
                    self.gui.dialog_cut.builder.get_object(
                        'label_status').set_markup("<b>%s</b>" % error)
                    self.cutlists_error = True

                def cutlist_found_cb(cutlist):
                    self.gui.dialog_cut.add_cutlist(cutlist)
                    cutlists.append(cutlist)

                def completed():
                    if not self.cutlists_error:
                        self.gui.dialog_cut.builder.get_object(
                            'label_status').set_markup("")

                GeneratorTask(cutlists_management.download_cutlists, None,
                              completed).start(
                                  file_conclusion.uncut_video,
                                  self.config.get('general', 'server'),
                                  self.config.get('general',
                                                  'choose_cutlists_by'),
                                  self.config.get('general',
                                                  'cutlist_mp4_as_hq'),
                                  error_cb, cutlist_found_cb)

                response = self.gui.dialog_cut.run()
                self.gui.dialog_cut.hide()

                if response < 0:
                    file_conclusion.cut.status = Status.NOT_DONE
                    file_conclusion.cut.message = "Abgebrochen."
                else:  # change cut_action accordingly
                    file_conclusion.cut.cut_action = response

            if file_conclusion.cut.cut_action == Cut_action.MANUALLY:  # MANUALLY
                error_message, cutlist = self.cut_file_manually(
                    file_conclusion.uncut_video)

                if not error_message:
                    file_conclusion.cut.create_cutlist = True
                    file_conclusion.cut.upload_cutlist = True
                    file_conclusion.cut.cutlist = cutlist
                else:
                    file_conclusion.cut.status = Status.ERROR
                    file_conclusion.cut.message = error_message

            elif file_conclusion.cut.cut_action == Cut_action.BEST_CUTLIST:
                error, cutlists = cutlists_management.download_cutlists(
                    file_conclusion.uncut_video,
                    self.config.get('general', 'server'),
                    self.config.get('general', 'choose_cutlists_by'),
                    self.config.get('general', 'cutlist_mp4_as_hq'))

                if error:
                    file_conclusion.cut.status = Status.ERROR
                    file_conclusion.cut.message = error
                    continue

                if len(cutlists) == 0:
                    file_conclusion.cut.status = Status.NOT_DONE
                    file_conclusion.cut.message = "Keine Cutlist gefunden."
                    continue

                file_conclusion.cut.cutlist = cutlists_management.get_best_cutlist(
                    cutlists)

            elif file_conclusion.cut.cut_action == Cut_action.CHOOSE_CUTLIST:
                if self.gui.dialog_cut.chosen_cutlist is not None:
                    file_conclusion.cut.cutlist = self.gui.dialog_cut.chosen_cutlist
                else:
                    file_conclusion.cut.status = Status.NOT_DONE
                    file_conclusion.cut.message = "Keine Cutlist gefunden."

            elif file_conclusion.cut.cut_action == Cut_action.LOCAL_CUTLIST:
                file_conclusion.cut.cutlist.local_filename = file_conclusion.uncut_video + ".cutlist"

                if not exists(file_conclusion.cut.cutlist.local_filename):
                    file_conclusion.cut.status = Status.ERROR
                    file_conclusion.cut.message = "Keine lokale Cutlist gefunden."

            elif file_conclusion.cut.cut_action == Cut_action.ASK:
                file_conclusion.cut.status = Status.NOT_DONE
                file_conclusion.cut.message = "Keine Cutlist gefunden."

        # and finally cut the file
        for count, file_conclusion in enumerate(file_conclusions):

            if file_conclusion.cut.status in [Status.NOT_DONE, Status.ERROR]:
                continue

            self.log.info("[Decodeandcut] Datei %s wird geschnitten" %
                          file_conclusion.uncut_video)
            self.gui.main_window.set_tasks_text(
                "Datei %s/%s schneiden" % (count + 1, len(file_conclusions)))
            self.gui.main_window.set_tasks_progress(0)
            while Gtk.events_pending():
                Gtk.main_iteration()

            # download cutlist
            if file_conclusion.cut.cut_action in [
                    Cut_action.BEST_CUTLIST, Cut_action.CHOOSE_CUTLIST
            ]:
                file_conclusion.cut.cutlist.download(
                    self.config.get('general', 'server'),
                    file_conclusion.uncut_video)

            cut_video, ac3_file, error = self.cut_file_by_cutlist(
                file_conclusion.uncut_video, file_conclusion.cut.cutlist, None)

            if cut_video is None:
                file_conclusion.cut.status = Status.ERROR
                file_conclusion.cut.message = error
                file_conclusion.cut.upload_cutlist = False
            else:
                file_conclusion.cut.status = Status.OK
                file_conclusion.cut_video = cut_video
                file_conclusion.ac3_file = ac3_file

                if self.config.get('general', 'rename_cut'):
                    file_conclusion.cut.rename = self.rename_by_schema(
                        basename(file_conclusion.cut_video)
                    )  # rename after cut video, extension could have changed
                else:
                    file_conclusion.cut.rename = basename(cut_video)

                if os.path.isfile(file_conclusion.uncut_video +
                                  '.ffindex_track00.kf.txt'):
                    os.remove(file_conclusion.uncut_video +
                              '.ffindex_track00.kf.txt')

                if os.path.isfile(file_conclusion.uncut_video +
                                  '.ffindex_track00.tc.txt'):
                    os.remove(file_conclusion.uncut_video +
                              '.ffindex_track00.tc.txt')

        return True
Example #18
0
    def update_details(self):       
        try:
            self.task.stop()
        except:
            pass
    
        if self.app.section == Section.PLANNING:
            self.reset_details("")
            return

        mplayer = self.app.config.get('general', 'mplayer')

        if not mplayer:
            self.reset_details("Der MPlayer ist nicht installiert!")
            return
      
        filenames = self.gui.main_window.get_selected_filenames()   
      
        if len(filenames) == 0:
            self.reset_details("<b>Keine Datei markiert.</b>")
        
        elif len(filenames) > 1:
            self.reset_details("<b>%s Dateien markiert.</b>" % len(filenames))
        
        else:
            filename = filenames[0]
           
            extension = os.path.splitext(filename)[1]
            
            self.label_filetype.set_markup("<b>%s-Datei</b>" % extension[1:])
            
            if extension != ".otrkey":

                def get_information():
                    yield
                                
                    # prettify the output!
                    def prettify_aspect(aspect):
                        if aspect == "1.7778":
                            return "16:9" 
                        elif aspect == "1.3333":
                            return "4:3"
                        else:
                            return aspect
                    
                    def prettify_length(seconds):                       
                        hrs = float(seconds) / 3600       
                        leftover = float(seconds) % 3600
                        mins = leftover / 60
                        secs = leftover % 60
                           
                        return "%02d:%02d:%02d" % (hrs, mins, secs)
                    
                    values = (
                        ("ID_VIDEO_ASPECT", self.label_aspect, prettify_aspect),
                        ("ID_VIDEO_FORMAT", self.label_video_format, None),
                        ("ID_LENGTH", self.label_length, prettify_length)
                        )
                  
                    process = subprocess.Popen([mplayer, "-identify", "-vo", "null", "-frames", "1", "-nosound", filename], stdout=subprocess.PIPE)
                          
                    while process.poll() == None:                                          
                        line = process.stdout.readline().strip()

                        for value, widget, callback in values:
                            
                            if line.startswith(value):
                                # mplayer gives an output like this: ID_VIDEO_ASPECT=1.3333
                                value = line.split("=")[1]
                                
                                if callback:
                                    value = callback(value)
                                
                                widget.set_text(value)   
                                
                self.task = GeneratorTask(get_information)
                self.task.start()