Example #1
0
 def add_rss(self, bot, update):
     try:
         component.get('Core').enable_plugin('YaRSS2')
         self.isRss = True
         return self.prepare_categoies(bot, update)
     except Exception as e:
         log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #2
0
    def execute_commands(self, torrent_id, event):
        if event == "added" and not self.torrent_manager.session_started:
            return
        elif event == "removed":
            torrent_id, torrent_name, save_path = self.preremoved_cache.pop(torrent_id)
        else:
            torrent = component.get("TorrentManager").torrents[torrent_id]
            info = torrent.get_status(["name", "save_path"])
            # getProcessOutputAndValue requires args to be str
            torrent_id = utf8_encoded(torrent_id)
            torrent_name = utf8_encoded(info["name"])
            save_path = utf8_encoded(info["save_path"])

        log.debug("[execute] Running commands for %s", event)

        def log_error(result, command):
            (stdout, stderr, exit_code) = result
            if exit_code:
                log.warn("[execute] command '%s' failed with exit code %d", command, exit_code)
                if stdout:
                    log.warn("[execute] stdout: %s", stdout)
                if stderr:
                    log.warn("[execute] stderr: %s", stderr)

        # Go through and execute all the commands
        for command in self.config["commands"]:
            if command[EXECUTE_EVENT] == event:
                command = os.path.expandvars(command[EXECUTE_COMMAND])
                command = os.path.expanduser(command)
                if os.path.isfile(command) and os.access(command, os.X_OK):
                    log.debug("[execute] Running %s", command)
                    d = getProcessOutputAndValue(command, (torrent_id, torrent_name, save_path), env=os.environ)
                    d.addCallback(log_error, command)
                else:
                    log.error("[execute] Execute script not found or not executable")
    def __init__(self, con_pool_size=1, proxy_url=None, urllib3_proxy_kwargs=None):
        try:
            if urllib3_proxy_kwargs is None:
                urllib3_proxy_kwargs = dict()

            # This was performed on Windows only, but it shouldn't be a problem
            # managing cacert.pem on Linux as well
            #if os.name == 'nt':
            try:
                import urllib2
                import tempfile
                capath = os.path.join(tempfile.gettempdir(), 'tg-cacert.pem')
                # Check if tg-cacert.pem exists and if it's older than 7 days
                if not os.path.exists(capath) or (os.path.exists(capath) \
                        and (time.time() - os.path.getctime(capath)) // (24 * 3600) >= 7):
                    CACERT_URL = "https://curl.haxx.se/ca/cacert.pem"
                    request = urllib2.Request(CACERT_URL)
                    file_contents = urllib2.urlopen(request).read()
                    log.debug("## Telegramer downloaded "+os.path.realpath(capath))
                    cafile = open(os.path.realpath(capath), 'wb')
                    cafile.write(file_contents)
                    cafile.close()
            except:
                try:
                    capath = certifi.where()
                except:
                    capath = os.path.join(tempfile.gettempdir(), 'tg-cacert.pem')

            kwargs = dict(
                maxsize=con_pool_size,
                cert_reqs='CERT_REQUIRED',
                ca_certs=capath,
                #ca_certs=certifi.where(),
                socket_options=HTTPConnection.default_socket_options + [
                    (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
                ])

            # Set a proxy according to the following order:
            # * proxy defined in proxy_url (+ urllib3_proxy_kwargs)
            # * proxy set in `HTTPS_PROXY` env. var.
            # * proxy set in `https_proxy` env. var.
            # * None (if no proxy is configured)

            if not proxy_url:
                proxy_url = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy')

            if not proxy_url:
                mgr = urllib3.PoolManager(**kwargs)
            else:
                kwargs.update(urllib3_proxy_kwargs)
                mgr = urllib3.proxy_from_url(proxy_url, **kwargs)
                if mgr.proxy.auth:
                    # TODO: what about other auth types?
                    auth_hdrs = urllib3.make_headers(proxy_basic_auth=mgr.proxy.auth)
                    mgr.proxy_headers.update(auth_hdrs)

            self._con_pool = mgr

        except Exception as e:
            log.error(str(e) + '\n' + traceback.format_exc())
Example #4
0
    def start_daemon(self, port, config):
        """
        Starts a daemon process.

        :param port: the port for the daemon to listen on
        :type port: int
        :param config: the path to the current config folder
        :type config: str
        :returns: True if started, False if not
        :rtype: bool

        :raises OSError: received from subprocess.call()

        """
        try:
            if deluge.common.windows_check():
                subprocess.Popen(
                    ["deluged",
                     "--port=%s" % port,
                     "--config=%s" % config])
            else:
                subprocess.call(
                    ["deluged",
                     "--port=%s" % port,
                     "--config=%s" % config])
        except OSError, e:
            from errno import ENOENT
            if e.errno == ENOENT:
                log.error(
                    _("Deluge cannot find the 'deluged' executable, it is likely \
that you forgot to install the deluged package or it's not in your PATH."))
            else:
                log.exception(e)
            raise e
Example #5
0
    def add_magnet(self, bot, update):
        if str(update.message.chat.id) in self.whitelist:
            try:
                user = update.message.chat.id
                log.debug("addmagnet of %s: %s" %
                          (str(user), update.message.text))

                try:
                    #options = None
                    metainfo = update.message.text
                    """Adds a torrent with the given options.
                    metainfo could either be base64 torrent data or a magnet link.
                    Available options are listed in deluge.core.torrent.TorrentOptions.
                    """
                    if self.opts is None:
                        self.opts = {}
                    if is_magnet(metainfo):
                        log.debug(
                            prelog() +
                            'Adding torrent from magnet URI `%s` using options `%s` ...',
                            metainfo, self.opts)
                        tid = self.core.add_torrent_magnet(metainfo, self.opts)
                        self.apply_label(tid)
                    else:
                        update.message.reply_text(
                            STRINGS['not_magnet'],
                            reply_markup=ReplyKeyboardRemove())
                except Exception as e:
                    log.error(prelog() + str(e) + '\n' +
                              traceback.format_exc())

                return ConversationHandler.END

            except Exception as e:
                log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #6
0
    def __init__(self, options=None, args=None, classic=False):
        # Check for another running instance of the daemon
        if os.path.isfile(deluge.configmanager.get_config_dir("deluged.pid")):
            # Get the PID and the port of the supposedly running daemon
            try:
                (pid, port) = open(deluge.configmanager.get_config_dir("deluged.pid")).read().strip().split(";")
                pid = int(pid)
                port = int(port)
            except ValueError:
                pid = None
                port = None


            def process_running(pid):
                if deluge.common.windows_check():
                    # Do some fancy WMI junk to see if the PID exists in Windows
                    from win32com.client import GetObject
                    def get_proclist():
                        WMI = GetObject('winmgmts:')
                        processes = WMI.InstancesOf('Win32_Process')
                        return [process.Properties_('ProcessID').Value for process in processes]
                    return pid in get_proclist()
                else:
                    # We can just use os.kill on UNIX to test if the process is running
                    try:
                        os.kill(pid, 0)
                    except OSError:
                        return False
                    else:
                        return True

            if pid is not None and process_running(pid):
                # Ok, so a process is running with this PID, let's make doubly-sure
                # it's a deluged process by trying to open a socket to it's port.
                import socket
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                try:
                    s.connect(("127.0.0.1", port))
                except socket.error:
                    # Can't connect, so it must not be a deluged process..
                    pass
                else:
                    # This is a deluged!
                    s.close()
                    raise deluge.error.DaemonRunningError("There is a deluge daemon running with this config directory!")

        # Initialize gettext
        try:
            locale.setlocale(locale.LC_ALL, '')
            if hasattr(locale, "bindtextdomain"):
                locale.bindtextdomain("deluge", pkg_resources.resource_filename("deluge", "i18n"))
            if hasattr(locale, "textdomain"):
                locale.textdomain("deluge")
            gettext.bindtextdomain("deluge", pkg_resources.resource_filename("deluge", "i18n"))
            gettext.textdomain("deluge")
            gettext.install("deluge", pkg_resources.resource_filename("deluge", "i18n"))
        except Exception, e:
            log.error("Unable to initialize gettext/locale: %s", e)
            import __builtin__
            __builtin__.__dict__["_"] = lambda x: x
Example #7
0
    def save_resume_data_file(self, resume_data=None):
        """
        Saves the resume data file with the contents of self.resume_data.  If
        `resume_data` is None, then we grab the resume_data from the file on
        disk, else, we update `resume_data` with self.resume_data and save
        that to disk.

        :param resume_data: the current resume_data, this will be loaded from disk if not provided
        :type resume_data: dict

        """
        # Check to see if we're waiting on more resume data
        if self.num_resume_data or not self.resume_data:
            return

        filepath = os.path.join(get_config_dir(), "state", "torrents.fastresume")
        filepath_tmp = filepath + ".tmp"
        filepath_bak = filepath + ".bak"

        # First step is to load the existing file and update the dictionary
        if resume_data is None:
            resume_data = self.load_resume_data_file()

        resume_data.update(self.resume_data)
        self.resume_data = {}

        try:
            os.remove(filepath_bak)
        except OSError:
            pass
        try:
            log.debug("Creating backup of fastresume at: %s", filepath_bak)
            os.rename(filepath, filepath_bak)
        except OSError, ex:
            log.error("Unable to backup %s to %s: %s", filepath, filepath_bak, ex)
 def __init__(self, plugin_api, plugin_name):
     # Load the GtkUI portion of the plugin
     try:
         from webui import WebUI
         self.plugin = WebUI(plugin_api, plugin_name)
     except Exception, e:
         log.error("Failed to load PreventSuspend WebUI plugin: %s", e)
Example #9
0
    def enable(self):
        log.info("AutoTrackerEdit: started")

        self._edits = []
        config_path = get_default_config_dir("autotrackeredit.json")
        try:
            with open(config_path) as f:
                items = json.load(f)
                for item in items:
                    try:
                        regex = re.compile(item['regex'])
                    except re.error:
                        log.info("AutoTrackerEdit: invalid regex %s" % item['regex'])
                    else:
                        self._edits.append((regex, item['repl']))
        except IOError:
            log.error("AutoTrackerEdit: failed to open config file")

        log.info("AutoTrackerEdit: loaded %d regex from the config file", len(self._edits))

        self._core = component.get("Core")
        self._em = component.get("EventManager")
        self._em.register_event_handler("TorrentAddedEvent", self._scan_torrent)
        self._em.register_event_handler("TorrentResumedEvent", self._scan_torrent)
        for id in self._core.get_session_state():
            self._scan_torrent(id)
Example #10
0
    def _notify_email(self, subject='', message=''):
        log.debug("Email prepared")
        to_addrs = self.config['smtp_recipients']
        to_addrs_str = ', '.join(self.config['smtp_recipients'])
        headers = """\
From: %(smtp_from)s
To: %(smtp_recipients)s
Subject: %(subject)s


""" % {'smtp_from': self.config['smtp_from'],
       'subject': subject,
       'smtp_recipients': to_addrs_str,
       'date': formatdate()
      }

        message = '\r\n'.join((headers + message).splitlines())

        try:
            try:
                # Python 2.6
                server = smtplib.SMTP(self.config["smtp_host"],
                                      self.config["smtp_port"],
                                      timeout=60)
            except:
                # Python 2.5
                server = smtplib.SMTP(self.config["smtp_host"],
                                      self.config["smtp_port"])
        except Exception, err:
            err_msg = _("There was an error sending the notification email:"
                        " %s") % err
            log.error(err_msg)
            return err
Example #11
0
    def on_torrent_finished(self, torrent_id):
        """
        Copy the torrent now. It will do this in a separate thread to avoid
        freezing up this thread (which causes freezes in the daemon and hence
        web/gtk UI.)
        """
        torrent = component.get("TorrentManager").torrents[torrent_id]
        info = torrent.get_status([
            "name", "save_path", "move_on_completed", "move_on_completed_path"
        ])
        old_path = info["move_on_completed_path"] if info[
            "move_on_completed"] else info["save_path"]
        new_path = self.config["copy_to"]
        files = torrent.get_files()
        umask = self.config["umask"]

        # validate parameters
        if new_path.strip() == "" or not os.path.isdir(new_path):
            log.error(
                "COPYCOMPLETED: No path to copy to was specified, or that path was invalid. Copy aborted."
            )
            return

        log.info("COPYCOMPLETED: Copying %s from %s to %s" %
                 (info["name"], old_path, new_path))
        thread.start_new_thread(Core._thread_copy,
                                (torrent_id, old_path, new_path, files, umask))
Example #12
0
 def delete_lockfile():
     log.debug("Removing lockfile since it's stale.")
     try:
         os.remove(lockfile)
         os.remove(socket)
     except OSError, ex:
         log.error("Failed to delete lockfile: %s", ex)
Example #13
0
    def _notify_email(self, subject='', message=''):
        log.debug("Email prepared")
        to_addrs = self.config['smtp_recipients']
        to_addrs_str = ', '.join(self.config['smtp_recipients'])
        headers = """\
From: %(smtp_from)s
To: %(smtp_recipients)s
Subject: %(subject)s


""" % {
            'smtp_from': self.config['smtp_from'],
            'subject': subject,
            'smtp_recipients': to_addrs_str,
            'date': formatdate()
        }

        message = '\r\n'.join((headers + message).splitlines())

        try:
            try:
                # Python 2.6
                server = smtplib.SMTP(self.config["smtp_host"],
                                      self.config["smtp_port"],
                                      timeout=60)
            except:
                # Python 2.5
                server = smtplib.SMTP(self.config["smtp_host"],
                                      self.config["smtp_port"])
        except Exception, err:
            err_msg = _("There was an error sending the notification email:"
                        " %s") % err
            log.error(err_msg)
            return err
Example #14
0
    def run_converter(self, input_range, output_version, func):
        """
        Runs a function that will convert file versions in the `:param:input_range`
        to the `:param:output_version`.

        :param input_range: tuple, (int, int) the range of input versions this
            function will accept
        :param output_version: int, the version this function will return
        :param func: func, the function that will do the conversion, it will take
            the config dict as an argument and return the augmented dict

        :raises ValueError: if the output_version is less than the input_range

        """
        if output_version in input_range or output_version <= max(input_range):
            raise ValueError(
                "output_version needs to be greater than input_range")

        if self.__version["file"] not in input_range:
            log.debug(
                "File version %s is not in input_range %s, ignoring converter function..",
                self.__version["file"], input_range)
            return

        try:
            self.__config = func(self.__config)
        except Exception, e:
            log.exception(e)
            log.error(
                "There was an exception try to convert config file %s %s to %s",
                self.__config_file, self.__version["file"], output_version)
            raise e
Example #15
0
    def run_converter(self, input_range, output_version, func):
        """
        Runs a function that will convert file versions in the `:param:input_range`
        to the `:param:output_version`.

        :param input_range: tuple, (int, int) the range of input versions this
            function will accept
        :param output_version: int, the version this function will return
        :param func: func, the function that will do the conversion, it will take
            the config dict as an argument and return the augmented dict

        :raises ValueError: if the output_version is less than the input_range

        """
        if output_version in input_range or output_version <= max(input_range):
            raise ValueError("output_version needs to be greater than input_range")

        if self.__version["file"] not in input_range:
            log.debug("File version %s is not in input_range %s, ignoring converter function..",
                self.__version["file"], input_range)
            return

        try:
            self.__config = func(self.__config)
        except Exception, e:
            log.exception(e)
            log.error("There was an exception try to convert config file %s %s to %s",
                self.__config_file, self.__version["file"], output_version)
            raise e
Example #16
0
    def add_torrent(self, bot, update):
        if str(update.message.chat.id) in self.whitelist:
            try:
                user = update.message.chat.id
                log.debug("addtorrent of %s: %s" %
                          (str(user), update.message.document))

                if update.message.document.mime_type == 'application/x-bittorrent':
                    # Get file info
                    file_info = self.bot.getFile(update.message.document.file_id)
                    # Download file
                    request = urllib2.Request(file_info.file_path, headers=HEADERS)
                    status_code = urllib2.urlopen(request).getcode()
                    if status_code == 200:
                        file_contents = urllib2.urlopen(request).read()
                        # Base64 encode file data
                        metainfo = b64encode(file_contents)
                        if self.opts is None:
                            self.opts = {}
                        log.info(prelog() + 'Adding torrent from base64 string' +
                                 'using options `%s` ...', self.opts)
                        tid = self.core.add_torrent_file(None, metainfo, self.opts)
                        self.apply_label(tid)
                    else:
                        update.message.reply_text(STRINGS['download_fail'],
                                                  reply_markup=ReplyKeyboardRemove())
                else:
                    update.message.reply_text(STRINGS['not_file'],
                                              reply_markup=ReplyKeyboardRemove())

                return ConversationHandler.END

            except Exception as e:
                log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #17
0
    def add(
        self,
        torrent_info=None,
        state=None,
        options=None,
        save_state=True,
        filedump=None,
        filename=None,
        magnet=None,
        resume_data=None,
    ):
        """Add a torrent to the manager and returns it's torrent_id"""

        if torrent_info is None and state is None and filedump is None and magnet is None:
            log.debug("You must specify a valid torrent_info, torrent state or magnet.")
            return

        log.debug("torrentmanager.add")
        add_torrent_params = {}

        if filedump is not None:
            try:
                torrent_info = lt.torrent_info(lt.bdecode(filedump))
            except Exception, e:
                log.error("Unable to decode torrent file!: %s", e)
                # XXX: Probably should raise an exception here..
                return
Example #18
0
    def add_magnet(self, bot, update):
        if str(update.message.chat.id) in self.whitelist:
            try:
                user = update.message.chat.id
                log.debug("addmagnet of %s: %s" % (str(user), update.message.text))

                try:
                    # options = None
                    metainfo = update.message.text
                    """Adds a torrent with the given options.
                    metainfo could either be base64 torrent
                    data or a magnet link. Available options
                    are listed in deluge.core.torrent.TorrentOptions.
                    """
                    if self.opts is None:
                        self.opts = {}
                    if is_magnet(metainfo):
                        log.debug(prelog() + 'Adding torrent from magnet ' +
                                  'URI `%s` using options `%s` ...',
                                  metainfo, self.opts)
                        tid = self.core.add_torrent_magnet(metainfo, self.opts)
                        self.apply_label(tid)
                    else:
                        update.message.reply_text(STRINGS['not_magnet'],
                                                  reply_markup=ReplyKeyboardRemove())
                except Exception as e:
                    log.error(prelog() + str(e) + '\n' + traceback.format_exc())

                return ConversationHandler.END

            except Exception as e:
                log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #19
0
    def torrent_type(self, bot, update):
        if str(update.message.chat.id) in self.whitelist:
            try:
                user = update.message.chat.id
                torrent_type_selected = update.message.text

                if torrent_type_selected == 'Magnet':
                    update.message.reply_text(STRINGS['send_magnet'],
                                              reply_markup=ReplyKeyboardRemove())
                    return ADD_MAGNET

                elif torrent_type_selected == '.torrent':
                    update.message.reply_text(STRINGS['send_file'],
                                              reply_markup=ReplyKeyboardRemove())
                    return ADD_TORRENT

                elif torrent_type_selected == 'URL':
                    update.message.reply_text(STRINGS['send_url'],
                                              reply_markup=ReplyKeyboardRemove())
                    return ADD_URL

                else:
                    update.message.reply_text(STRINGS['error'],
                                              reply_markup=ReplyKeyboardRemove())
                return ConversationHandler.END

            except Exception as e:
                log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #20
0
    def add(self, bot, update):
        # log.error(type(update.message.chat.id) + str(update.message.chat.id))
        if str(update.message.chat.id) in self.whitelist:
            try:
                self.set_dirs = {}
                self.opts = {}
                keyboard_options = []
                """Currently there are 3 possible categories so
                loop through cat1-3 and dir1-3, check if directories exist
                """
                for i in range(3):
                    i = i+1
                    if os.path.isdir(self.config['dir'+str(i)]):
                        log.debug(prelog() + self.config['cat'+str(i)] +
                                  ' ' + self.config['dir'+str(i)])
                        self.set_dirs[self.config['cat'+str(i)]] = \
                            self.config['dir'+str(i)]

                if self.set_dirs:
                    for k in self.set_dirs.keys():
                        log.debug(prelog() + k)
                        keyboard_options.append([k])
                keyboard_options.append([STRINGS['no_category']])

                update.message.reply_text(
                    '%s\n%s' % (STRINGS['which_cat'], STRINGS['cancel']),
                    reply_markup=ReplyKeyboardMarkup(keyboard_options,
                                                     one_time_keyboard=True))

                return CATEGORY

            except Exception as e:
                log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #21
0
 def save_stats(self):
     try:
         self.saved_stats.set("stats", self.stats)
         self.saved_stats.config.update(self.export_get_totals())
         self.saved_stats.save()
     except Exception,e:
         log.error(e.message)
Example #22
0
            def on_extract(result, torrent_id, fpath, sonarr_radarr_support,
                           extraction_count):
                # increment extraction_count complete
                extraction_count[1] += 1
                # tmp logging
                log.debug(
                    "EXTRACTOR: 1: extraction count total %d, complete %d",
                    extraction_count[0], extraction_count[1])

                # if sonarr_radarr_support is enabled and we have extracted all files
                if sonarr_radarr_support and extraction_count[
                        0] == extraction_count[1]:
                    log.info("EXTRACTOR: Setting is_finished to true: %s",
                             tid_status["name"])
                    tid = component.get("TorrentManager").torrents[torrent_id]
                    # set is_finished back to True
                    tid.is_finished = True

                # Check command exit code.
                if not result[2]:
                    log.info("EXTRACTOR: Extract successful: %s (%s)", fpath,
                             torrent_id)
                else:
                    log.error("EXTRACTOR: Extract failed: %s (%s) %s", fpath,
                              torrent_id, result[1])
Example #23
0
    def add(self,
            torrent_info=None,
            state=None,
            options=None,
            save_state=True,
            filedump=None,
            filename=None,
            magnet=None,
            resume_data=None):
        """Add a torrent to the manager and returns it's torrent_id"""

        if torrent_info is None and state is None and filedump is None and magnet is None:
            log.debug(
                "You must specify a valid torrent_info, torrent state or magnet."
            )
            return

        log.debug("torrentmanager.add")
        add_torrent_params = {}

        if filedump is not None:
            try:
                torrent_info = lt.torrent_info(lt.bdecode(filedump))
            except Exception, e:
                log.error("Unable to decode torrent file!: %s", e)
                # XXX: Probably should raise an exception here..
                return
Example #24
0
    def on_torrent_event(self, torrent_id, sqs_queue_name, msg_tpl):
	if self.config["aws_connect_to_region"].strip() == "":
            return

	if self.config["aws_access_key_id"].strip() == "":
            return

	if self.config["aws_secret_access_key"].strip() == "":
            return

        # setup sqs connection
        self.sqs_conn = boto.sqs.connect_to_region(
                self.config['aws_connect_to_region'],
                aws_access_key_id=self.config['aws_access_key_id'],
                aws_secret_access_key=self.config['aws_secret_access_key'])

        if (sqs_queue_name.strip() == ""):
            return

        try:
            msg_body = self.build_msg_body(torrent_id, msg_tpl)

            self.send_msg(sqs_queue_name, msg_body)

        except Exception, e:
            log.error("SQSNotify error %s" % e)
Example #25
0
def get_localhost_auth():
    """
    Grabs the localclient auth line from the 'auth' file and creates a localhost uri

    :returns: with the username and password to login as
    :rtype: tuple
    """
    auth_file = deluge.configmanager.get_config_dir("auth")
    if os.path.exists(auth_file):
        for line in open(auth_file):
            line = line.strip()
            if line.startswith("#") or not line:
                # This is a comment or blank line
                continue

            try:
                lsplit = line.split(":")
            except Exception, e:
                log.error("Your auth file is malformed: %s", e)
                continue

            if len(lsplit) == 2:
                username, password = lsplit
            elif len(lsplit) == 3:
                username, password, level = lsplit
            else:
                log.error("Your auth file is malformed: Incorrect number of fields!")
                continue

            if username == "localclient":
                return (username, password)
Example #26
0
 def on_apply_prefs(self):
     log.debug("Telegramer: applying prefs for Telegramer")
     config = {
         "telegram_notify_added": self.glade.get_widget("telegram_notify_added").get_active(),
         "telegram_notify_finished": self.glade.get_widget("telegram_notify_finished").get_active(),
         "telegram_token": self.glade.get_widget("telegram_token").get_text(),
         "telegram_user": self.glade.get_widget("telegram_user").get_text(),
         "telegram_users": self.glade.get_widget("telegram_users").get_text(),
         "telegram_users_notify": self.glade.get_widget("telegram_users_notify").get_text(),
         "categories": {self.glade.get_widget("cat1").get_text():
                          self.glade.get_widget("dir1").get_text(),
                      self.glade.get_widget("cat2").get_text():
                          self.glade.get_widget("dir2").get_text(),
                      self.glade.get_widget("cat3").get_text():
                          self.glade.get_widget("dir3").get_text()
                      },
         "regex_exp": {self.glade.get_widget("rname1").get_text():
                            self.glade.get_widget("reg1").get_text(),
                       self.glade.get_widget("rname2").get_text():
                           self.glade.get_widget("reg2").get_text(),
                       self.glade.get_widget("rname3").get_text():
                           self.glade.get_widget("reg3").get_text()
                        },
         "proxy_url": self.glade.get_widget("proxy_url").get_text(),
         "urllib3_proxy_kwargs_username": self.glade.get_widget("urllib3_proxy_kwargs_username").get_text(),
         "urllib3_proxy_kwargs_password": self.glade.get_widget("urllib3_proxy_kwargs_password").get_text()
     }
     #log.error(config)
     client.telegramer.set_config(config)
     for ind, (n, r) in enumerate(config["regex_exp"].items()):
         if REGEX_TMPL_FILE_NAME not in r:
             log.error("Your regex " + n + "template doesn't contains "
                       + REGEX_TMPL_FILE_NAME + " string and wouldn't work")
             break
Example #27
0
 def telegram_poll_stop(self):
     try:
         log.debug(prelog() + 'Stop polling')
         if self.updater:
             self.updater.stop()
     except Exception as e:
         log.error(prelog() + str(e) + '\n' + traceback.format_exc())
    def enable_plugin(self, plugin_name):
        """Enables a plugin"""
        if plugin_name not in self.available_plugins:
            log.warning("Cannot enable non-existant plugin %s", plugin_name)
            return

        if plugin_name in self.plugins:
            log.warning("Cannot enable already enabled plugin %s", plugin_name)
            return

        plugin_name = plugin_name.replace(" ", "-")
        egg = self.pkg_env[plugin_name][0]
        egg.activate()
        for name in egg.get_entry_map(self.entry_name):
            entry_point = egg.get_entry_info(self.entry_name, name)
            try:
                cls = entry_point.load()
                instance = cls(plugin_name.replace("-", "_"))
            except Exception, e:
                log.error("Unable to instantiate plugin!")
                log.exception(e)
                continue
            instance.enable()
            if self._component_state == "Started":
                component.start([instance.plugin._component_name])
            plugin_name = plugin_name.replace("-", " ")
            self.plugins[plugin_name] = instance
            if plugin_name not in self.config["enabled_plugins"]:
                log.debug("Adding %s to enabled_plugins list in config",
                    plugin_name)
                self.config["enabled_plugins"].append(plugin_name)
            log.info("Plugin %s enabled..", plugin_name)
Example #29
0
 def save_stats(self):
     try:
         self.saved_stats["stats"] = self.stats
         self.saved_stats.config.update(self.get_totals())
         self.saved_stats.save()
     except Exception, e:
         log.error("Stats save error", e)
Example #30
0
def load_libs():
    egg = pkg_resources.require("Telegramer")[0]
    for name in egg.get_entry_map("telegramer.libpaths"):
        ep = egg.get_entry_info("telegramer.libpaths", name)
        location = "%s/%s" % (egg.location, ep.module_name.replace(".", "/"))
        sys.path.append(location)
        log.error("Appending to sys.path: '%s'" % location)
Example #31
0
 def telegram_poll_stop(self):
     try:
         log.debug(prelog() + 'Stop polling')
         if self.updater:
             self.updater.stop()
     except Exception as e:
         log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #32
0
 def email(self, status):
     """sends email notification of finished torrent"""
     import smtplib
     headers = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (
         self.config["ntf_email_add"], self.config["ntf_email_add"],
         "Finished torrent %s" % (status["name"]))
     text = _(
         "This email is to inform you that Deluge has finished downloading %(name)s , \
         which includes %(num_files)i files.\nTo stop receiving these alerts, simply turn off \
         email notification in Deluge's preferences.\n\nThank you,\nDeluge"
     ) % {
         "name": status["name"],
         "num_files": status["num_files"]
     }
     message = headers + text
     if self.config["ntf_security"] == 'SSL':
         port = 465
     elif self.config["ntf_security"] == 'TLS':
         port = 587
     elif self.config["ntf_security"] == None:
         port = 25
     try:
         mailServer = smtplib.SMTP(self.config["ntf_server"], port)
     except Exception, e:
         log.error("There was an error sending the notification email: %s",
                   e)
         return
Example #33
0
def get_default_config_dir(filename=None):
    """
    :param filename: if None, only the config path is returned, if provided, a path including the filename will be returned
    :type filename: string
    :returns: a file path to the config directory and optional filename
    :rtype: string

    """
    if windows_check():
        appDataPath = os.environ.get("APPDATA")
        if not appDataPath:
            import _winreg
            hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
            appDataReg = _winreg.QueryValueEx(hkey, "AppData")
            appDataPath = appDataReg[0]
            _winreg.CloseKey(hkey)
        if filename:
            return os.path.join(appDataPath, "deluge", filename)
        else:
            return os.path.join(appDataPath, "deluge")
    else:
        from xdg.BaseDirectory import save_config_path
        try:
            if filename:
                return os.path.join(save_config_path("deluge"), filename)
            else:
                return save_config_path("deluge")
        except OSError, e:
            log.error("Unable to use default config directory, exiting... (%s)", e)
            sys.exit(1)
Example #34
0
    def add(self, bot, update):
        # log.error(type(update.message.chat.id) + str(update.message.chat.id))
        if str(update.message.chat.id) in self.whitelist:
            try:
                self.set_dirs = {}
                self.opts = {}
                keyboard_options = []
                """Currently there are 3 possible categories so
                loop through cat1-3 and dir1-3, check if directories exist
                """
                for i in range(3):
                    i = i + 1
                    if os.path.isdir(self.config['dir' + str(i)]):
                        log.debug(prelog() + self.config['cat' + str(i)] +
                                  ' ' + self.config['dir' + str(i)])
                        self.set_dirs[self.config['cat'+str(i)]] = \
                            self.config['dir'+str(i)]

                if self.set_dirs:
                    for k in self.set_dirs.keys():
                        log.debug(prelog() + k)
                        keyboard_options.append([k])
                keyboard_options.append([STRINGS['no_category']])

                update.message.reply_text(
                    '%s\n%s' % (STRINGS['which_cat'], STRINGS['cancel']),
                    reply_markup=ReplyKeyboardMarkup(keyboard_options,
                                                     one_time_keyboard=True))

                return CATEGORY

            except Exception as e:
                log.error(prelog() + str(e) + '\n' + traceback.format_exc())
    def enable_plugin(self, plugin_name):
        """Enables a plugin"""
        if plugin_name not in self.available_plugins:
            log.warning("Cannot enable non-existant plugin %s", plugin_name)
            return

        if plugin_name in self.plugins:
            log.warning("Cannot enable already enabled plugin %s", plugin_name)
            return

        plugin_name = plugin_name.replace(" ", "-")
        egg = self.pkg_env[plugin_name][0]
        egg.activate()
        for name in egg.get_entry_map(self.entry_name):
            entry_point = egg.get_entry_info(self.entry_name, name)
            try:
                cls = entry_point.load()
                instance = cls(plugin_name.replace("-", "_"))
            except Exception, e:
                log.error("Unable to instantiate plugin!")
                log.exception(e)
                continue
            instance.enable()
            if self._component_state == "Started":
                component.start([instance.plugin._component_name])
            plugin_name = plugin_name.replace("-", " ")
            self.plugins[plugin_name] = instance
            if plugin_name not in self.config["enabled_plugins"]:
                log.debug("Adding %s to enabled_plugins list in config",
                          plugin_name)
                self.config["enabled_plugins"].append(plugin_name)
            log.info("Plugin %s enabled..", plugin_name)
Example #36
0
 def _shutdown(self, *args, **kwargs):
     if os.path.exists(deluge.configmanager.get_config_dir("deluged.pid")):
         try:
             os.remove(deluge.configmanager.get_config_dir("deluged.pid"))
         except Exception, e:
             log.exception(e)
             log.error("Error removing deluged.pid!")
Example #37
0
 def _shutdown(self, *args, **kwargs):
     if os.path.exists(deluge.configmanager.get_config_dir("deluged.pid")):
         try:
             os.remove(deluge.configmanager.get_config_dir("deluged.pid"))
         except Exception, e:
             log.exception(e)
             log.error("Error removing deluged.pid!")
Example #38
0
 def delete_lockfile():
     log.debug("Removing lockfile since it's stale.")
     try:
         os.remove(lockfile)
         os.remove(socket)
     except OSError, ex:
         log.error("Failed to delete lockfile: %s", ex)
Example #39
0
    def load_limits(self):
        log.debug("TrafficLimits: Loading limits...")

        try:
            limits = open(deluge.configmanager.get_config_dir("trafficlimits"))
            limits_mtime = os.fstat(limits.fileno()).st_mtime
            label = limits.readline().rstrip(os.linesep)
            maximum_upload = int(limits.readline().rstrip(os.linesep))
            maximum_download = int(limits.readline().rstrip(os.linesep))

            line = limits.readline().rstrip(os.linesep)
            maximum_total = -1 if line == '' else int(line)

        except (IOError, OSError, ValueError) as error:
            log.error("TrafficLimits: "
                      + deluge.configmanager.get_config_dir("trafficlimits")
                      + ": " + str(error))
            return

        self.limits_mtime = limits_mtime
        self.label = label
        self.config["maximum_upload"] = maximum_upload
        self.config["maximum_download"] = maximum_download
        self.config["maximum_total"] = maximum_total

        if self.label != self.config["label"]:
            self.config["label"] = self.label
            self.reset_initial()
            if self.paused:
                self.paused = False
                component.get("Core").session.resume()

        log.debug("TrafficLimits: Loaded limits.")
Example #40
0
def associate_magnet_links(overwrite=False):
    """
    Associates magnet links to Deluge.

    :param overwrite: if this is True, the current setting will be overwritten
    :type overwrite: bool
    :returns: True if association was set
    :rtype: bool

    """
    if not deluge.common.windows_check():
        # gconf method is only available in a GNOME environment
        try:
            import gconf
        except ImportError:
            log.debug("gconf not available, so will not attempt to register magnet uri handler")
            return False
        else:
            key = "/desktop/gnome/url-handlers/magnet/command"
            gconf_client = gconf.client_get_default()
            if (gconf_client.get(key) and overwrite) or not gconf_client.get(key):
                # We are either going to overwrite the key, or do it if it hasn't been set yet
                if gconf_client.set_string(key, "deluge '%s'"):
                    gconf_client.set_bool("/desktop/gnome/url-handlers/magnet/needs_terminal", False)
                    gconf_client.set_bool("/desktop/gnome/url-handlers/magnet/enabled", True)
                    log.info("Deluge registered as default magnet uri handler!")
                    return True
                else:
                    log.error("Unable to register Deluge as default magnet uri handler.")
                    return False
    return False
Example #41
0
    def enable(self):
        log.debug("[AutoShutDown] Enabling plugin...")
        if osx_check():
            log.error("[AutoShutDown] OSX not currently supported")
            #Using subprocess could call osascript
            #subprocess.call(['osascript', '-e', 'tell app "System Events" to shut down'])
            self.disable()

        if not windows_check():
            try:
                bus = dbus.SystemBus()
                try:
                    self.bus_name = LOGIN1
                    self.bus_obj = bus.get_object(self.bus_name, LOGIN1_PATH)
                    self.bus_iface = dbus.Interface(self.bus_obj,
                                                    self.bus_name + '.Manager')
                except DBusException:
                    self.bus_name = UPOWER
                    self.bus_obj = bus.get_object(self.bus_name, UPOWER_PATH)
                    self.bus_iface = dbus.Interface(self.bus_obj,
                                                    self.bus_name)
            except:
                log.debug(
                    "[AutoShutDown] Fallback to older dbus PowerManagement")
                bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
                self.bus_name = POWERMAN
                self.bus_obj = bus.get_object(self.bus_name, POWERMAN_PATH)
                self.bus_iface = dbus.Interface(self.bus_obj, self.bus_name)

        self.config = deluge.configmanager.ConfigManager(
            "autoshutdown.conf", DEFAULT_PREFS)
        self.check_suspend_hibernate_flags()

        component.get("EventManager").register_event_handler(
            "TorrentFinishedEvent", self.on_event_torrent_finished)
Example #42
0
    def torrent_type(self, bot, update):
        if str(update.message.chat.id) in self.whitelist:
            try:
                user = update.message.chat.id
                torrent_type_selected = update.message.text

                if torrent_type_selected == 'Magnet':
                    update.message.reply_text(
                        STRINGS['send_magnet'],
                        reply_markup=ReplyKeyboardRemove())
                    return ADD_MAGNET

                elif torrent_type_selected == '.torrent':
                    update.message.reply_text(
                        STRINGS['send_file'],
                        reply_markup=ReplyKeyboardRemove())
                    return ADD_TORRENT

                elif torrent_type_selected == 'URL':
                    update.message.reply_text(
                        STRINGS['send_url'],
                        reply_markup=ReplyKeyboardRemove())
                    return ADD_URL

                else:
                    update.message.reply_text(
                        STRINGS['error'], reply_markup=ReplyKeyboardRemove())
                return ConversationHandler.END

            except Exception as e:
                log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #43
0
    def start_daemon(self, port, config):
        """
        Starts a daemon process.

        :param port: the port for the daemon to listen on
        :type port: int
        :param config: the path to the current config folder
        :type config: str
        :returns: True if started, False if not
        :rtype: bool

        :raises OSError: received from subprocess.call()

        """
        try:
            if deluge.common.windows_check():
                subprocess.Popen(["deluged", "--port=%s" % port, "--config=%s" % config])
            else:
                subprocess.call(["deluged", "--port=%s" % port, "--config=%s" % config])
        except OSError, e:
            from errno import ENOENT
            if e.errno == ENOENT:
                log.error(_("Deluge cannot find the 'deluged' executable, it is likely \
that you forgot to install the deluged package or it's not in your PATH."))
            else:
                log.exception(e)
            raise e
Example #44
0
def get_localhost_auth():
    """
    Grabs the localclient auth line from the 'auth' file and creates a localhost uri

    :returns: with the username and password to login as
    :rtype: tuple
    """
    auth_file = deluge.configmanager.get_config_dir("auth")
    if os.path.exists(auth_file):
        for line in open(auth_file):
            if line.startswith("#"):
                # This is a comment line
                continue
            line = line.strip()
            try:
                lsplit = line.split(":")
            except Exception, e:
                log.error("Your auth file is malformed: %s", e)
                continue

            if len(lsplit) == 2:
                username, password = lsplit
            elif len(lsplit) == 3:
                username, password, level = lsplit
            else:
                log.error("Your auth file is malformed: Incorrect number of fields!")
                continue

            if username == "localclient":
                return (username, password)
Example #45
0
    def enable(self):
        log.debug("[AutoShutDown] Enabling plugin...")
        if osx_check():
            log.error("[AutoShutDown] OSX not currently supported")
            #Using subprocess could call osascript
            #subprocess.call(['osascript', '-e', 'tell app "System Events" to shut down'])
            self.disable()

        if not windows_check():
            self.bus_name = UPOWER
            bus_path = UPOWER_PATH
            try:
                bus = dbus.SystemBus()
                self.bus_obj = bus.get_object(self.bus_name, bus_path)
            except:
                log.debug("[AutoShutDown] Fallback to older dbus PowerManagement")
                self.bus_name = POWERMAN
                bus_path = POWERMAN_PATH
                bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
                self.bus_obj = bus.get_object(self.bus_name, bus_path)

            self.bus_iface = dbus.Interface(self.bus_obj, self.bus_name)
            self.bus_iface_props = dbus.Interface(self.bus_obj, 'org.freedesktop.DBus.Properties')

        self.config = deluge.configmanager.ConfigManager("autoshutdown.conf", DEFAULT_PREFS)
        self.check_suspend_hibernate_flags()

        component.get("EventManager").register_event_handler("TorrentFinishedEvent", self.on_event_torrent_finished)
Example #46
0
 def disable(self):
     try:
         log.info(prelog() + 'Disable')
         reactor.callLater(2, self.disconnect_events)
         self.whitelist = []
         self.telegram_poll_stop()
         # self.bot = None
     except Exception as e:
         log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #47
0
 def adjust_windows_shutdown_privileges(self):
     if not windows_check():
         log.error("Only usable on Windows platform")
         return
     flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
     htoken = OpenProcessToken(GetCurrentProcess(), flags)
     id = LookupPrivilegeValue(None, SE_SHUTDOWN_NAME)
     newPrivileges = [(id, SE_PRIVILEGE_ENABLED)]
     AdjustTokenPrivileges(htoken, 0, newPrivileges)
Example #48
0
def process_args(args):
    """Process arguments sent to already running Deluge"""
    # Make sure args is a list
    args = list(args)
    log.debug("Processing args from other process: %s", args)
    if not client.connected():
        # We're not connected so add these to the queue
        log.debug("Not connected to host.. Adding to queue.")
        component.get("QueuedTorrents").add_to_queue(args)
        return
    config = ConfigManager("gtkui.conf")

    for arg in args:
        if not arg.strip():
            continue
        log.debug("arg: %s", arg)

        if deluge.common.is_url(arg):
            log.debug("Attempting to add url (%s) from external source...",
                      arg)
            if config["interactive_add"]:
                component.get("AddTorrentDialog").add_from_url(arg)
                component.get("AddTorrentDialog").show(
                    config["focus_add_dialog"])
            else:
                client.core.add_torrent_url(arg, None)

        elif deluge.common.is_magnet(arg):
            log.debug("Attempting to add magnet (%s) from external source...",
                      arg)
            if config["interactive_add"]:
                component.get("AddTorrentDialog").add_from_magnets([arg])
                component.get("AddTorrentDialog").show(
                    config["focus_add_dialog"])
            else:
                client.core.add_torrent_magnet(arg, {})

        else:
            log.debug("Attempting to add file (%s) from external source...",
                      arg)
            if urlparse(arg).scheme == "file":
                arg = url2pathname(urlparse(arg).path)
            path = os.path.abspath(deluge.common.decode_string(arg))

            if not os.path.exists(path):
                log.error("No such file: %s", path)
                continue

            if config["interactive_add"]:
                component.get("AddTorrentDialog").add_from_files([path])
                component.get("AddTorrentDialog").show(
                    config["focus_add_dialog"])
            else:
                with open(path, "rb") as _file:
                    filedump = base64.encodestring(_file.read())
                client.core.add_torrent_file(
                    os.path.split(path)[-1], filedump, None)
Example #49
0
 def adjust_windows_shutdown_privileges(self):
     if not windows_check():
         log.error("Only usable on Windows platform")
         return
     flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
     htoken = OpenProcessToken(GetCurrentProcess(), flags)
     id = LookupPrivilegeValue(None, SE_SHUTDOWN_NAME)
     newPrivileges = [(id, SE_PRIVILEGE_ENABLED)]
     AdjustTokenPrivileges(htoken, 0, newPrivileges)
Example #50
0
 def disable(self):
     try:
         log.info(prelog() + 'Disable')
         reactor.callLater(2, self.disconnect_events)
         self.whitelist = []
         self.telegram_poll_stop()
         # self.bot = None
     except Exception as e:
         log.error(prelog() + str(e) + '\n' + traceback.format_exc())
Example #51
0
    def _on_torrent_finished(self, torrent_id):
        """
        This is called when a torrent finishes and checks if any files to extract.
        """
        tid = component.get("TorrentManager").torrents[torrent_id]
        tid_status = tid.get_status(["save_path", "name"])

        files = tid.get_files()
        for f in files:
            file_root, file_ext = os.path.splitext(f["path"])
            file_ext_sec = os.path.splitext(file_root)[1]
            if file_ext_sec and file_ext_sec + file_ext in EXTRACT_COMMANDS:
                file_ext = file_ext_sec + file_ext
            elif file_ext not in EXTRACT_COMMANDS or file_ext_sec == '.tar':
                log.warning(
                    "EXTRACTOR: Can't extract file with unknown file type: %s"
                    % f["path"])
                continue
            cmd = EXTRACT_COMMANDS[file_ext]

            # Now that we have the cmd, lets run it to extract the files
            fpath = os.path.join(tid_status["save_path"],
                                 os.path.normpath(f["path"]))

            # Get the destination path
            dest = os.path.normpath(self.config["extract_path"])
            if self.config["use_name_folder"]:
                name = tid_status["name"]
                dest = os.path.join(dest, name)

            # Create the destination folder if it doesn't exist
            if not os.path.exists(dest):
                try:
                    os.makedirs(dest)
                except Exception, e:
                    log.error(
                        "EXTRACTOR: Error creating destination folder: %s", e)
                    return

            def on_extract_success(result, torrent_id, fpath):
                # XXX: Emit an event
                log.info("EXTRACTOR: Extract successful: %s (%s)", fpath,
                         torrent_id)

            def on_extract_failed(result, torrent_id, fpath):
                # XXX: Emit an event
                log.error("EXTRACTOR: Extract failed: %s (%s)", fpath,
                          torrent_id)

            # Run the command and add some callbacks
            log.debug("EXTRACTOR: Extracting %s with %s %s to %s", fpath,
                      cmd[0], cmd[1], dest)
            d = getProcessValue(cmd[0], cmd[1].split() + [str(fpath)], {},
                                str(dest))
            d.addCallback(on_extract_success, torrent_id, fpath)
            d.addErrback(on_extract_failed, torrent_id, fpath)
Example #52
0
 def on_connect_fail(result, try_counter):
     log.error("Connection to host failed..")
     # We failed connecting to the daemon, but lets try again
     if try_counter:
         log.info("Retrying connection.. Retries left: %s", try_counter)
         try_counter -= 1
         import time
         time.sleep(0.5)
         do_retry_connect(try_counter)
     return result
Example #53
0
    def save_state(self):
        """Save the state of the TorrentManager to the torrents.state file"""
        state = TorrentManagerState()
        # Create the state for each Torrent and append to the list
        for torrent in self.torrents.values():
            if self.session.is_paused():
                paused = torrent.handle.is_paused()
            elif torrent.forced_error:
                paused = torrent.forced_error.was_paused
            elif torrent.state == "Paused":
                paused = True
            else:
                paused = False

            torrent_state = TorrentState(
                torrent.torrent_id,
                torrent.filename,
                torrent.get_status(["total_uploaded"])["total_uploaded"],
                torrent.trackers,
                torrent.options["compact_allocation"],
                paused,
                torrent.options["download_location"],
                torrent.options["max_connections"],
                torrent.options["max_upload_slots"],
                torrent.options["max_upload_speed"],
                torrent.options["max_download_speed"],
                torrent.options["prioritize_first_last_pieces"],
                torrent.options["file_priorities"],
                torrent.get_queue_position(),
                torrent.options["auto_managed"],
                torrent.is_finished,
                torrent.options["stop_ratio"],
                torrent.options["stop_at_ratio"],
                torrent.options["remove_at_ratio"],
                torrent.options["move_completed"],
                torrent.options["move_completed_path"],
                torrent.magnet,
                torrent.time_added,
            )
            state.torrents.append(torrent_state)

        # Pickle the TorrentManagerState object
        filepath = os.path.join(get_config_dir(), "state", "torrents.state")
        filepath_tmp = filepath + ".tmp"
        filepath_bak = filepath + ".bak"

        try:
            os.remove(filepath_bak)
        except OSError:
            pass
        try:
            log.debug("Creating backup of state at: %s", filepath_bak)
            os.rename(filepath, filepath_bak)
        except OSError, ex:
            log.error("Unable to backup %s to %s: %s", filepath, filepath_bak, ex)
Example #54
0
    def enable(self):
        self.config = deluge.configmanager.ConfigManager("copycompleted.conf", DEFAULT_PREFS)

        # validate settings here as an aid to user
        # don't act differently, as this won't be called again if settings are
        # changed during the session.
        if self.config["copy_to"].strip() == "" or not os.path.isdir(self.config["copy_to"]):
            log.error("COPYCOMPLETED: No path to copy to was specified, or that path was invalid. Please amend.")

        # Get notified when a torrent finishes downloading
        component.get("EventManager").register_event_handler("TorrentFinishedEvent", self.on_torrent_finished)