Beispiel #1
0
    def _configure_filebot_handler(settings, handler=None):
        """Configures a handler using the given settings dictionary.

        If no handler is given a new handler is created. Invalid settings
        will be skipped

        *settings*: a dictionary in format {"setting": value, ...}
        *handler*: the handler you want to use, defaults to new Handler

        *returns*: a configured handler.
        """
        if not handler:
            handler = pyfilebot.FilebotHandler()

        valid_handler_attributes = [
            "format_string", "database", "output", "episode_order",
            "rename_action", "recursive", "language_code", "encoding",
            "on_conflict", "query_override", "non_strict", "mode"
        ]
        for attribute in valid_handler_attributes:
            if attribute in settings:
                try:
                    handler.__setattr__(attribute, settings[attribute])
                except ValueError:
                    log.warning("{0} is not a valid value for {1}, "
                                "skipping...".format(settings[attribute],
                                                     attribute))
        return handler
Beispiel #2
0
    def do_revert(self, torrent_ids):
        """calls filebottool.revert() on files in a torrent. Will only allow
        one torrent at a time"""
        errors = {}
        if isinstance(torrent_ids, str):
            torrent_ids = [torrent_ids]
        for torrent_id in torrent_ids:
            self._mark_processing(torrent_id)
            targets = self._get_filebot_target(torrent_id)
            log.debug("reverting torrent {0} with targets {1}".format(
                torrent_id, targets))
            self.torrent_manager[torrent_id].pause()
            handler = pyfilebot.FilebotHandler()
            try:
                # noinspection PyUnresolvedReferences
                filebot_results = yield threads.deferToThread(
                    handler.revert, targets)
            except Exception, err:
                log.error("FILEBOT ERROR {0}".format(err))
                errors[torrent_id] = (str(err), err.msg)
                self._finish_processing(torrent_id, error=err)
                continue

            # noinspection PyUnboundLocalVariable
            deluge_movements = self._translate_filebot_movements(
                torrent_id, filebot_results[1])

            if not deluge_movements:
                self._finish_processing(torrent_id)
                continue

            conflicts = self._file_conflicts(torrent_id, deluge_movements,
                                             filebot_results[2])
            if conflicts:
                log.warning(
                    'Rename unsafe for torrent {0}, conflicting files:{1}'.
                    format(torrent_id, conflicts))
                log.warning('Rolling back torrent {0}.'.format(torrent_id))
                self._rollback(filebot_results, torrent_id)
                errors[torrent_id] = ("FileConflicts",
                                      "Rename is not safe on torrent {0}.\n"
                                      "The following files already exsist:\n"
                                      "{1}"
                                      "Rolling Back and recheking.".format(
                                          torrent_id,
                                          ''.join('    ' + f + '\n'
                                                  for f in conflicts)))
                self._finish_processing(torrent_id, error="File Conflict")
                continue

            log.debug("Attempting to re-reoute torrent: {0}".format(
                deluge_movements))
            self._redirect_torrent_paths(torrent_id, deluge_movements)
Beispiel #3
0
 def do_revert(self, torrent_id):
     """calls filebottool.revert() on files in a torrent. Will only allow
     one torrent at a time"""
     targets = self._get_filebot_target(torrent_id)
     log.debug("reverting torrent {0} with targets {1}".format(torrent_id,
                                                             targets))
     original_torrent_state = self.torrent_manager[torrent_id].state
     self.torrent_manager[torrent_id].pause()
     handler = pyfilebot.FilebotHandler()
     try:
         # noinspection PyUnresolvedReferences
         filebot_results = yield threads.deferToThread(handler.revert,
                                                       targets)
     except Exception, err:
         log.error("FILEBOT ERROR {0}".format(err))
         defer.returnValue((False, err))
Beispiel #4
0
    def do_rename(self, torrent_ids, handler_settings=None, handler=None):
        """executes a filebot run.
        Args:
            torrent_id: id of torrent to execute against
            handler_settings: an optional dictionary of settings build a filebot
                handler from
            handler: an optional FilebotHandler to use (overrides
                handler_settings)
        returns:
            tuple in format (success, errors_dictionary, messages).
        """
        if not handler:
            if handler_settings:
                try:
                    handler_name = handler_settings['handler_name']
                except KeyError:
                    handler_name = None
                handler = self._configure_filebot_handler(handler_settings,
                                                          handler)
            else:
                handler = pyfilebot.FilebotHandler()
                handler_name = None

        errors = {}
        new_files = []
        for torrent_id in torrent_ids:
            self._mark_processing(torrent_id, handler_name)
            if handler.rename_action is not None:
                link = "link" in handler.rename_action or handler.rename_action == 'copy'
            else:
                link = False
            target = self._get_filebot_target(torrent_id)
            log.debug("beginning filebot run on torrent {0}, with target {1}".format(
                torrent_id, target))

            if not link:
                self.torrent_manager[torrent_id].pause()

            try:
                filebot_results = yield threads.deferToThread(handler.rename,
                                                              target)
            except pyfilebot.FilebotRuntimeError as err:
                log.error("FILEBOT ERROR!", exc_info=True)
                errors[torrent_id] = (str(err.__class__.__name__), err.msg)
                filebot_results = ["", {}, {}]
                self._finish_processing(torrent_id, error=err)
                continue
            except pyfilebot.FilebotLicenseError as err:
                log.error("Error Renaming, Unlicensed FileBot!")
                errors[torrent_id] = (str(err.__class__.__name__), err.msg)
                filebot_results = ["", {}, {}]
                self._finish_processing(torrent_id, error=err)
                continue
            except Exception as e:
                log.error("Unexpected error from pyfilebot.", exc_info=True)
                errors[torrent_id] = (str(err.__class__.__name__), err.msg)
                filebot_results = ["", {}, {}]
                self._finish_processing(torrent_id, error=err)
                continue

            log.debug("recieved results from filebot: {0}".format(
                filebot_results))

            if not link:
                deluge_movements = self._translate_filebot_movements(torrent_id,
                                                                     filebot_results[1])
            else:
                deluge_movements = None
                new_files += filebot_results[1]

            conflicts = self._file_conflicts(torrent_id,
                                             deluge_movements,
                                             filebot_results[2])

            if conflicts and handler.on_conflict == 'override':  # for non-fb files
                for conflict in conflicts:
                    os.remove(conflict)
            elif conflicts:
                log.warning("Raname is not safe on torrent {0}. "
                            "Rolling Back and recheking".format(torrent_id))
                self._rollback(filebot_results, torrent_id)
                errors[torrent_id] = (
                    "File Conflict", "Problem with moving torrent \"{0}\".\n"
                    "The following files already exsist:\n{1}"
                    "Rolling back to previous state and rechecking.".format(
                    self.torrent_manager[torrent_id].get_status( ["name"])["name"],
                    ''.join('    '+f+'\n' for f in conflicts)))
                self._finish_processing(torrent_id, error="File Conflict")
                continue
            if deluge_movements:
                log.debug("Attempting to re-reoute torrent: {0}".format(
                    deluge_movements))
                self._redirect_torrent_paths(torrent_id, deluge_movements)

            #  download subs
            if handler_settings:
                if handler_settings['download_subs']:
                    handler.output = None
                    if link:
                        deluge_movements = self._translate_filebot_movements(torrent_id, filebot_results[1])

                    mock = self._get_mockup_files_dictionary(torrent_id, deluge_movements)
                    new_save = deluge_movements[0] if deluge_movements else None
                    if not new_save:
                        torrent = self.torrent_manager[torrent_id]
                        new_save = torrent.get_status(["save_path"])["save_path"]

                    target = [self._get_full_os_path(new_save, f['path']) for f in mock]
                    try:
                        subs = yield threads.deferToThread(handler.get_subtitles,
                            target, language_code=handler_settings['subs_language'])
                        if not subs:
                            log.info("No subs found for torrent {0}".format(torrent_id))
                        else:
                            log.info('Downloaded subs: {0}'.format(subs))
                            new_files += subs
                    except pyfilebot.FilebotRuntimeError as err:
                        log.error("FILEBOT ERROR while getting subs!", exc_info=True)
                        errors[torrent_id] = (str(err), err.msg)

            if not deluge_movements:
                self._finish_processing(torrent_id)


        if errors:
            defer.returnValue((False, errors, new_files))
        else:
            defer.returnValue((True, None, new_files))
Beispiel #5
0
    def do_dry_run(self, torrent_id, handler_settings=None, handler=None):
        """
        Executes a dry run on torrent_id using handler_settings
        Args:
            torrent_id: deluge ID of torrent
            handler_settings: dictionary containing the handler settings
            handler: optional handler object

        Returns: Tuple in format:
            ((success, errors_dict), (new_save_path, files_dictionary))
        """
        if not handler:
            if handler_settings:
                handler = self._configure_filebot_handler(handler_settings,
                                                          handler)
            else:
                handler = pyfilebot.FilebotHandler()

        handler.rename_action = "test"
        target = self._get_filebot_target(torrent_id)
        log.debug("running filbot dry run for torrent: {0} with target {1}".format(
            torrent_id, target))
        try:
            filebot_results = yield threads.deferToThread(handler.rename,
                                                          target)
        except pyfilebot.FilebotRuntimeError as err:
            log.error("FILEBOT ERROR!", exc_info=True)
            defer.returnValue(((False, {torrent_id:('FilebotRuntimeError', err.msg)}),
                              ('FILEBOTERROR', None)))
        except Exception as e:
            log.error("Unexpected error in pyfilebot: {0}".format(e), exc_info=True)
            defer.returnValue(((False, {torrent_id:(str(e.__class__.__name__), str(e))}),
                               ('FILEBOTTOOLERROR', None)))
        # noinspection PyUnboundLocalVariable
        log.debug("recieved results from filebot: {0}".format(filebot_results))
        deluge_movements = self._translate_filebot_movements(torrent_id,
                                                             filebot_results[1])
        if not deluge_movements:
            new_save_path = self.torrent_manager[torrent_id].get_status(
                ["save_path"])["save_path"]
            defer.returnValue(((True, None), (new_save_path, self.torrent_manager[
                torrent_id].get_files())))

        log.debug("REQUIRED DELUGE MOVEMENTS: {0}".format(deluge_movements))
        new_save_path = deluge_movements[0]

        if not new_save_path:
            new_save_path = self.torrent_manager[torrent_id].get_status(
                ["save_path"])["save_path"]
        conflicts = self._file_conflicts(torrent_id, deluge_movements, filebot_results[2])
        if conflicts:
            overwrite = handler.on_conflict == 'override'
            errors = {}
            errors[torrent_id] = ('File Conflict',
                                  'The following files already exsist{0}:\n{1}'.format(
                                    ' and will be overwritten!' if overwrite else '',
                                    ''.join('    ' + f + '\n' for f in conflicts))
                                  )
        defer.returnValue((
            (True if not conflicts else False, None if not conflicts else errors),
            (new_save_path,
             self._get_mockup_files_dictionary(torrent_id, deluge_movements))))