Example #1
0
    def run(self):
        """Worker loop"""
        while 1:
            # Wait for work from the queue. Defers / waits if there is no new
            # work.
            if not self.dqueue.has_new_work():
                self.working = False
                self.log.debug("worker %s: waiting for new task", self.id)

            self.task = yield self.dqueue.get()
            self.working = True
            self.dqueue.log_active = True

            if self.task is None:
                # kill all workers
                self.dqueue.put(None)
                return

            # Set task id
            self.seq = Worker.tasks
            Worker.tasks = Worker.tasks + 1

            # Do the work
            try:
                self.log.debug("worker %s, task %d: picked up task" %
                               (self.id, self.seq))
                yield self.work(self.task)
            except Exception as e:
                for line in error.format_exception():
                    self.log.error("worker %s, task %d, : %s" %
                                   (self.id, self.seq, line))
            finally:
                self.log.debug("worker %s, task %s: completed" %
                               (self.id, self.seq))
                self.task = None
Example #2
0
    def run(self):
        """Worker loop"""
        while 1:
            # Wait for work from the queue. Defers / waits if there is no new
            # work.
            if not self.dqueue.has_new_work():
                self.working = False
                self.log.debug("worker %s: waiting for new task", self.id)

            self.task              = yield self.dqueue.get()
            self.working           = True
            self.dqueue.log_active = True

            if self.task is None:
                # kill all workers
                self.dqueue.put(None)
                return

            # Set task id
            self.seq = Worker.tasks
            Worker.tasks = Worker.tasks + 1

            # Do the work
            try:
                self.log.debug("worker %s, task %d: picked up task" % (self.id, self.seq))
                yield self.work(self.task)
            except Exception as e:
                for line in error.format_exception():
                   self.log.error("worker %s, task %d, : %s" % (self.id, self.seq, line))
            finally:
                self.log.debug("worker %s, task %s: completed" % (self.id, self.seq))
                self.task = None
    def work(self, task):

        task.status = TaskStatus.PROCESSING
        tid = task.torrent_info.id

        try:
            # Store pointer to task
            self.task = task

            # Save worker info to task
            self.task.worker_id = self.id
            self.task.worker_seq = self.seq

            # Initialize logger adapter with task being worked on
            self.tlog.set_task(self.task)
            self.wlog.set_task(self.task)

            torrent = task.torrent
            name = TorrentInfo.get_display_name(torrent)
            id = TorrentInfo.get_id(torrent)

            self.tlog.info("post-process torrent(%s)" % name)

            if torrent is None:
                self.tlog.error(
                    "torrent with id '%s' is no longer with us anymore." % id)
                defer.returnValue(False)

            result = yield self.call_sickbeard(task)
            task.status = TaskStatus.SUCCESS if result else TaskStatus.FAILED

            remove, remove_data = (self.config['remove'],
                                   self.config['remove_data'])
            if result and remove:
                self.tlog.info("schedule torrent(%s) for removal" % name)
                self.manager.remove(id, remove_data)
            else:
                self.tlog.info("*skip* schedule torrent(%s) for removal" %
                               name)

            log_level = logging.INFO if result else logging.ERROR
            self.tlog.log(log_level, "post-process status %s" % task.status)

        except Exception as e:
            result = False
            task.status = TaskStatus.FAILED

            self.tlog.error('Exception occurred while processing torrent: ' +
                            str(e))
            for line in sb_err.format_exception():
                self.tlog.error("%s" % line)
        finally:
            self.tasklog.add(task)
            defer.returnValue(result)
    def work(self, task):

        task.status = TaskStatus.PROCESSING
        tid         = task.torrent_info.id

        try:
            # Store pointer to task
            self.task = task

            # Save worker info to task
            self.task.worker_id  = self.id
            self.task.worker_seq = self.seq

            # Initialize logger adapter with task being worked on
            self.tlog.set_task(self.task)
            self.wlog.set_task(self.task)

            torrent   = task.torrent
            name      = TorrentInfo.get_display_name(torrent)
            id        = TorrentInfo.get_id(torrent)

            self.tlog.info("post-process torrent(%s)" % name)

            if torrent is None:
                self.tlog.error("torrent with id '%s' is no longer with us anymore." % id)
                defer.returnValue(False)

            result      = yield self.call_sickbeard(task)
            task.status = TaskStatus.SUCCESS if result else TaskStatus.FAILED

            remove, remove_data = (self.config['remove'], self.config['remove_data'])
            if result and remove:
                self.tlog.info("schedule torrent(%s) for removal" % name)
                self.manager.remove(id, remove_data)
            else:
                self.tlog.info("*skip* schedule torrent(%s) for removal" % name)

            log_level = logging.INFO if result else logging.ERROR
            self.tlog.log(log_level, "post-process status %s" % task.status)

        except Exception as e:
            result      = False
            task.status = TaskStatus.FAILED

            self.tlog.error('Exception occurred while processing torrent: ' + str(e))
            for line in sb_err.format_exception():
                self.tlog.error("%s" % line)
        finally:
            self.tasklog.add(task)
            defer.returnValue(result)
    def call_sickbeard(self, task):
        """
        Call Sickbeard to post-process torrent.

        Sickbeard post-processing API:

        dir        : Directory to be post-processed by Sickbeard
                     SINGLE-FILE torrent: download-complete-path
                     MULTI-FILE  torrent: download-complete-path/name (see spec below)
        nzbname    : name of torrent to be post-processed by Sickbeard
        quiet      : Output type
                     1    : no HTML output
                     unset: HTML output by Sickbeard
        type       : Sickbeard type of post-processing
                     manual: Scheduled Post Processing (Processes files and dirs in TV_DOWNLOAD_DIR)
                     auto  : Script Post Processing (Processes files in a specified directory. Supports single file torrent.)
        force      : Force already Post Processed Dir/Files (on | unset)
        is_priority: Mark Dir/Files as priority download (on | unset)
          (Replace the file, even if it already exists at higher quality)
        failed     : Mark download as failed (1 or 0)
        method     : copy, move, hardlink or symlink

        Sickbeard uses the "nzbname" to look for a "resource" in the post-processing
        directory(dir). A "resource" is either a single video file file, or a directory
        with video files. This to support SINGLE-FILE and MULTI-FILE torrents.

        During post-processing this "resource" is first looked up in the "history"
        table to quickly associate the "resource" to a tv-show, seasion, episode. In case
        no "resource" is available in the history, Sickbeard falls back to scan the
        post-processing directory(dir) for files and directories containing video files
        and use its default naming parse to extract tv-show, seasion, episode details
        from the directory and vide file names it discovered. This is very convenient
        in case we manually downloaded torrents and still want them to be post-processed
        with Sickbeard.

        Failed downloading uses a release name, stored in a separate history table in the


        SINGLE-FILE torrent spec:
          name: the filename. This is purely advisory. (string)
        MULTI-FILE  torrent spec:
          name: the file path of the directory in which to store all the files.
                This is purely advisory. (string)

        Deluge follows the Torrent specifcation advisory.

        Returns:
          bool: True on success. False otherwise.
        """

        try:
            torrent = task.torrent

            dir = TorrentInfo.get_saved_path(torrent)
            name = TorrentInfo.get_display_name(torrent)
            mode = TorrentInfo.get_mode(torrent)
            id = TorrentInfo.get_id(torrent)

            params = {}
            params['dir'] = dir.encode('utf-8')
            params['nzbName'] = name.encode('utf-8')
            params['quiet'] = 1 if self.config["quiet"] else None

            params['type'] = ProccessType.AUTOMATIC
            params['process_method'] = self.config["method"] if self.config[
                "method"] != ProccessMethod.SB_DEFAULT else None
            params[
                'force'] = "on" if self.config["force"] or task.force else None
            params['is_priority'] = "on" if self.config[
                "priority"] or task.priority else None
            params['failed'] = 1 if task.failed else 0

            base_url = self.get_base_url()

            self.tlog.info("Contacting Sickbeard for post-processing")
            self.tlog.info("Torrent(nzbname): %s" % name)
            self.tlog.info("Using base URL  : %s" % base_url)
            self.tlog.info("Username        : %s" % self.config['username'])
            self.tlog.info("Request Type    : %s" % params['type'])
            self.tlog.info("Directory       : %s" % params['dir'])
            self.tlog.info("Mode            : %s" % mode)
            methodDisplay = self.config["method"] if self.config[
                "method"] != ProccessMethod.SB_DEFAULT else "Sickbeard Default"
            self.tlog.info("Method          : %s" % methodDisplay)
            self.tlog.info("Priority        : %s" % self.config["priority"])
            self.tlog.info("Failed          : %s" % params['failed'])
            self.tlog.info("Quiet           : %s" % self.config["quiet"])

            # Downloaded content directory/file must exist, even if it download actually failed, in order
            # for Sickbeard to be able to process the torrent
            self._ensure_saved_path(torrent)

            client = WebClient(self.wlog)
            result = yield client.get(base_url,
                                      args=params,
                                      username=self.config['username'],
                                      password=self.config['password'])
        except Exception as e:
            result = False

            self.tlog.error('Exception occurred while processing torrent: ' +
                            str(e))
            for line in sb_err.format_exception():
                self.tlog.error("%s" % line)

        errors = 0
        success = 0
        if result:
            self.tlog.info("%s bytes received:" % len(result))

            for line in result.split('\n'):
                self.tlog.info("  %s" % line)
                if line:
                    for pattern in SickbeardWorker.ERRORS:
                        errors += line.count(pattern)
                    for pattern in SickbeardWorker.SUCCESS:
                        success += line.count(pattern)

        succeeded = True if errors == 0 and success >= 1 else False

        if succeeded:
            self.tlog.info("Sickbeard post-processing torrent(%s) succeeded" %
                           name)
        else:
            self.tlog.info("Sickbeard post-processing torrent(%s) failed" %
                           name)

        defer.returnValue(succeeded)
    def call_sickbeard(self, task):
        """
        Call Sickbeard to post-process torrent.

        Sickbeard post-processing API:

        dir        : Directory to be post-processed by Sickbeard
                     SINGLE-FILE torrent: download-complete-path
                     MULTI-FILE  torrent: download-complete-path/name (see spec below)
        nzbname    : name of torrent to be post-processed by Sickbeard
        quiet      : Output type
                     1    : no HTML output
                     unset: HTML output by Sickbeard
        type       : Sickbeard type of post-processing
                     manual: Scheduled Post Processing (Processes files and dirs in TV_DOWNLOAD_DIR)
                     auto  : Script Post Processing (Processes files in a specified directory. Supports single file torrent.)
        force      : Force already Post Processed Dir/Files (on | unset)
        is_priority: Mark Dir/Files as priority download (on | unset)
          (Replace the file, even if it already exists at higher quality)
        failed     : Mark download as failed (1 or 0)
        method     : copy, move, hardlink or symlink

        Sickbeard uses the "nzbname" to look for a "resource" in the post-processing
        directory(dir). A "resource" is either a single video file file, or a directory
        with video files. This to support SINGLE-FILE and MULTI-FILE torrents.

        During post-processing this "resource" is first looked up in the "history"
        table to quickly associate the "resource" to a tv-show, seasion, episode. In case
        no "resource" is available in the history, Sickbeard falls back to scan the
        post-processing directory(dir) for files and directories containing video files
        and use its default naming parse to extract tv-show, seasion, episode details
        from the directory and vide file names it discovered. This is very convenient
        in case we manually downloaded torrents and still want them to be post-processed
        with Sickbeard.

        Failed downloading uses a release name, stored in a separate history table in the


        SINGLE-FILE torrent spec:
          name: the filename. This is purely advisory. (string)
        MULTI-FILE  torrent spec:
          name: the file path of the directory in which to store all the files.
                This is purely advisory. (string)

        Deluge follows the Torrent specifcation advisory.

        Returns:
          bool: True on success. False otherwise.
        """

        try:
            torrent = task.torrent

            dir  = TorrentInfo.get_saved_path(torrent)
            name = TorrentInfo.get_display_name(torrent)
            mode = TorrentInfo.get_mode(torrent)
            id   = TorrentInfo.get_id(torrent)

            params                   = {}
            params['dir']            = dir.encode('utf-8')
            params['nzbName']        = name.encode('utf-8')
            params['quiet']          = 1 if self.config["quiet"] else None

            params['type']           = ProccessType.AUTOMATIC
            params['process_method'] = self.config["method"] if self.config["method"] != ProccessMethod.SB_DEFAULT else None
            params['force']          = "on" if self.config["force"]    or task.force    else None
            params['is_priority']    = "on" if self.config["priority"] or task.priority else None
            params['failed']         = 1 if task.failed else 0

            base_url = self.get_base_url()

            self.tlog.info("Contacting Sickbeard for post-processing")
            self.tlog.info("Torrent(nzbname): %s" % name)
            self.tlog.info("Using base URL  : %s" % base_url)
            self.tlog.info("Username        : %s" % self.config['username'])
            self.tlog.info("Request Type    : %s" % params['type'])
            self.tlog.info("Directory       : %s" % params['dir'])
            self.tlog.info("Mode            : %s" % mode)
            methodDisplay = self.config["method"] if self.config["method"] != ProccessMethod.SB_DEFAULT else "Sickbeard Default"
            self.tlog.info("Method          : %s" % methodDisplay)
            self.tlog.info("Priority        : %s" % self.config["priority"])
            self.tlog.info("Failed          : %s" % params['failed'])
            self.tlog.info("Quiet           : %s" % self.config["quiet"])

            # Downloaded content directory/file must exist, even if it download actually failed, in order
            # for Sickbeard to be able to process the torrent
            self._ensure_saved_path(torrent);

            client  = WebClient(self.wlog)
            result  = yield client.get(base_url, args = params, username = self.config['username'], password = self.config['password'])
        except Exception as e:
            result = False

            self.tlog.error('Exception occurred while processing torrent: ' + str(e))
            for line in sb_err.format_exception():
                self.tlog.error("%s" % line)

        errors  = 0
        success = 0
        if result:
            self.tlog.info("%s bytes received:" % len(result))

            for line in result.split('\n'):
                self.tlog.info("  %s" % line)
                if line:
                    for pattern in SickbeardWorker.ERRORS:
                        errors  += line.count(pattern)
                    for pattern in SickbeardWorker.SUCCESS:
                        success += line.count(pattern)

        succeeded = True if errors == 0 and success >= 1 else False

        if succeeded:
            self.tlog.info("Sickbeard post-processing torrent(%s) succeeded" % name)
        else:
            self.tlog.info("Sickbeard post-processing torrent(%s) failed" % name)

        defer.returnValue(succeeded)