Exemplo n.º 1
0
    def on_alert_save_resume_data_failed(self, alert):
        log.debug("on_alert_save_resume_data_failed: %s",
                  decode_string(alert.message()))
        torrent_id = str(alert.handle.info_hash())

        if torrent_id in self.waiting_on_resume_data:
            self.waiting_on_resume_data[torrent_id].errback(
                Exception(decode_string(alert.message())))
Exemplo n.º 2
0
    def on_alert_storage_moved_failed(self, alert):
        """Alert handler for libtorrent storage_moved_failed_alert"""
        log.debug("on_alert_storage_moved_failed: %s", decode_string(alert.message()))
        try:
            torrent_id = str(alert.handle.info_hash())
            torrent = self.torrents[torrent_id]
        except (RuntimeError, KeyError):
            return

        log.error("Torrent %s, %s", torrent_id, decode_string(alert.message()))
        if torrent_id in self.waiting_on_finish_moving:
            self.waiting_on_finish_moving.remove(torrent_id)
            torrent.is_finished = True
            component.get("EventManager").emit(TorrentFinishedEvent(torrent_id))
Exemplo n.º 3
0
    def on_alert_tracker_error(self, alert):
        """Alert handler for libtorrent tracker_error_alert"""
        error_message = decode_string(alert.msg)
        # If alert.msg is empty then it's a '-1' code so fallback to a.e.message. Note that alert.msg
        # cannot be replaced by a.e.message because the code is included in the string (for non-'-1').
        if not error_message:
            error_message = decode_string(alert.error.message())
        log.debug("Tracker Error Alert: %s [%s]", decode_string(alert.message()), error_message)
        try:
            torrent = self.torrents[str(alert.handle.info_hash())]
        except (RuntimeError, KeyError):
            return

        torrent.set_tracker_status("%s: %s" % (_("Error"), error_message))
Exemplo n.º 4
0
    def get_peers(self):
        """Returns a list of peers and various information about them"""
        ret = []
        peers = self.handle.get_peer_info()

        for peer in peers:
            # We do not want to report peers that are half-connected
            if peer.flags & peer.connecting or peer.flags & peer.handshake:
                continue

            client = decode_string(str(peer.client))
            # Make country a proper string
            country = str()
            for c in peer.country:
                if not c.isalpha():
                    country += " "
                else:
                    country += c

            ret.append({
                "client": client,
                "country": country,
                "down_speed": peer.payload_down_speed,
                "ip": "%s:%s" % (peer.ip[0], peer.ip[1]),
                "progress": peer.progress,
                "seed": peer.flags & peer.seed,
                "up_speed": peer.payload_up_speed,
            })

        return ret
Exemplo n.º 5
0
 def on_alert_file_completed(self, alert):
     log.debug("file_completed_alert: %s", decode_string(alert.message()))
     try:
         torrent_id = str(alert.handle.info_hash())
     except:
         return
     component.get("EventManager").emit(TorrentFileCompletedEvent(torrent_id, alert.index))
Exemplo n.º 6
0
    def on_alert_file_renamed(self, alert):
        log.debug("on_alert_file_renamed")
        log.debug("index: %s name: %s", alert.index, decode_string(alert.name))
        try:
            torrent = self.torrents[str(alert.handle.info_hash())]
            torrent_id = str(alert.handle.info_hash())
        except:
            return

        # We need to see if this file index is in a waiting_on_folder list
        folder_rename = False
        for i, wait_on_folder in enumerate(torrent.waiting_on_folder_rename):
            if alert.index in wait_on_folder[2]:
                folder_rename = True
                if len(wait_on_folder[2]) == 1:
                    # This is the last alert we were waiting for, time to send signal
                    component.get("EventManager").emit(TorrentFolderRenamedEvent(torrent_id, wait_on_folder[0], wait_on_folder[1]))
                    # Empty folders are removed after libtorrent folder renames
                    self.remove_empty_folders(torrent_id, wait_on_folder[0])
                    del torrent.waiting_on_folder_rename[i]
                    self.save_resume_data((torrent_id,))
                    break
                # This isn't the last file to be renamed in this folder, so just
                # remove the index and continue
                torrent.waiting_on_folder_rename[i][2].remove(alert.index)

        if not folder_rename:
            # This is just a regular file rename so send the signal
            component.get("EventManager").emit(TorrentFileRenamedEvent(torrent_id, alert.index, alert.name))
            self.save_resume_data((torrent_id,))
Exemplo n.º 7
0
 def on_alert_file_error(self, alert):
     log.debug("on_alert_file_error: %s", decode_string(alert.message()))
     try:
         torrent = self.torrents[str(alert.handle.info_hash())]
     except:
         return
     torrent.update_state()
Exemplo n.º 8
0
    def get_peers(self):
        """Returns a list of peers and various information about them"""
        ret = []
        peers = self.handle.get_peer_info()

        for peer in peers:
            # We do not want to report peers that are half-connected
            if peer.flags & peer.connecting or peer.flags & peer.handshake:
                continue

            client = decode_string(str(peer.client))
            # Make country a proper string
            country = str()
            for c in peer.country:
                if not c.isalpha():
                    country += " "
                else:
                    country += c

            ret.append({
                "client": client,
                "country": country,
                "down_speed": peer.payload_down_speed,
                "ip": "%s:%s" % (peer.ip[0], peer.ip[1]),
                "progress": peer.progress,
                "seed": peer.flags & peer.seed,
                "up_speed": peer.payload_up_speed,
            })

        return ret
Exemplo n.º 9
0
 def on_alert_tracker_error(self, alert):
     log.debug("on_alert_tracker_error")
     try:
         torrent = self.torrents[str(alert.handle.info_hash())]
     except:
         return
     tracker_status = "%s: %s" % (_("Error"), decode_string(alert.msg))
     torrent.set_tracker_status(tracker_status)
Exemplo n.º 10
0
 def on_alert_file_completed(self, alert):
     log.debug("file_completed_alert: %s", decode_string(alert.message()))
     try:
         torrent_id = str(alert.handle.info_hash())
     except:
         return
     component.get("EventManager").emit(
         TorrentFileCompletedEvent(torrent_id, alert.index))
Exemplo n.º 11
0
 def get_name(self):
     if self.has_metadata:
         name = self.torrent_info.file_at(0).path.replace("\\", "/", 1).split("/", 1)[0]
         if not name:
             name = self.torrent_info.name()
         return decode_string(name)
     elif self.magnet:
         try:
             keys = dict([k.split('=') for k in self.magnet.split('?')[-1].split('&')])
             name = keys.get('dn')
             if not name:
                 return self.torrent_id
             name = unquote(name).replace('+', ' ')
             return decode_string(name)
         except:
             pass
     return self.torrent_id
Exemplo n.º 12
0
 def on_alert_tracker_error(self, alert):
     log.debug("on_alert_tracker_error")
     try:
         torrent = self.torrents[str(alert.handle.info_hash())]
     except:
         return
     tracker_status = "%s: %s" % (_("Error"), decode_string(alert.msg))
     torrent.set_tracker_status(tracker_status)
Exemplo n.º 13
0
 def on_alert_tracker_warning(self, alert):
     log.debug("on_alert_tracker_warning")
     try:
         torrent = self.torrents[str(alert.handle.info_hash())]
     except:
         return
     tracker_status = '%s: %s' % (_("Warning"), decode_string(alert.message()))
     # Set the tracker status for the torrent
     torrent.set_tracker_status(tracker_status)
Exemplo n.º 14
0
    def on_alert_save_resume_data_failed(self, alert):
        log.debug("on_alert_save_resume_data_failed: %s", decode_string(alert.message()))
        try:
            torrent = self.torrents[str(alert.handle.info_hash())]
        except:
            return

        self.num_resume_data -= 1
        torrent.waiting_on_resume_data = False

        self.save_resume_data_file()
Exemplo n.º 15
0
 def get_name(self):
     if self.has_metadata:
         name = self.torrent_info.file_at(0).path.replace("\\", "/",
                                                          1).split("/",
                                                                   1)[0]
         if not name:
             name = self.torrent_info.name()
         return decode_string(name)
     elif self.magnet:
         try:
             keys = dict([
                 k.split('=') for k in self.magnet.split('?')[-1].split('&')
             ])
             name = keys.get('dn')
             if not name:
                 return self.torrent_id
             name = unquote(name).replace('+', ' ')
             return decode_string(name)
         except:
             pass
     return self.torrent_id
Exemplo n.º 16
0
    def on_alert_storage_moved_failed(self, alert):
        """Alert handler for libtorrent storage_moved_failed_alert"""
        log.debug("on_alert_storage_moved_failed: %s", decode_string(alert.message()))
        try:
            torrent_id = str(alert.handle.info_hash())
            torrent = self.torrents[torrent_id]
        except (RuntimeError, KeyError):
            return

        if torrent_id in self.waiting_on_finish_moving:
            self.waiting_on_finish_moving.remove(torrent_id)
            torrent.is_finished = True
            component.get("EventManager").emit(TorrentFinishedEvent(torrent_id))
Exemplo n.º 17
0
    def on_alert_tracker_reply(self, alert):
        log.debug("on_alert_tracker_reply: %s", decode_string(alert.message()))
        try:
            torrent = self.torrents[str(alert.handle.info_hash())]
        except:
            return

        # Set the tracker status for the torrent
        if alert.message() != "Got peers from DHT":
            torrent.set_tracker_status(_("Announce OK"))

        # Check to see if we got any peer information from the tracker
        if alert.handle.status().num_complete == -1 or alert.handle.status().num_incomplete == -1:
            # We didn't get peer information, so lets send a scrape request
            torrent.scrape_tracker()
Exemplo n.º 18
0
    def on_alert_tracker_reply(self, alert):
        log.debug("on_alert_tracker_reply: %s", decode_string(alert.message()))
        try:
            torrent = self.torrents[str(alert.handle.info_hash())]
        except:
            return

        # Set the tracker status for the torrent
        if alert.message() != "Got peers from DHT":
            torrent.set_tracker_status(_("Announce OK"))

        # Check to see if we got any peer information from the tracker
        if alert.handle.status().num_complete == -1 or \
            alert.handle.status().num_incomplete == -1:
            # We didn't get peer information, so lets send a scrape request
            torrent.scrape_tracker()
Exemplo n.º 19
0
    def on_alert_file_renamed(self, alert):
        log.debug("on_alert_file_renamed")
        log.debug("index: %s name: %s", alert.index, decode_string(alert.name))
        try:
            torrent = self.torrents[str(alert.handle.info_hash())]
            torrent_id = str(alert.handle.info_hash())
        except:
            return

        # We need to see if this file index is in a waiting_on_folder dict
        for wait_on_folder in torrent.waiting_on_folder_rename:
            if alert.index in wait_on_folder:
                wait_on_folder[alert.index].callback(None)
                break
        else:
            # This is just a regular file rename so send the signal
            component.get("EventManager").emit(TorrentFileRenamedEvent(torrent_id, alert.index, alert.name))
            self.save_resume_data((torrent_id,))
Exemplo n.º 20
0
    def on_alert_fastresume_rejected(self, alert):
        """Alert handler for libtorrent fastresume_rejected_alert"""
        alert_msg = decode_string(alert.message())
        log.error("on_alert_fastresume_rejected: %s", alert_msg)
        try:
            torrent_id = str(alert.handle.info_hash())
            torrent = self.torrents[torrent_id]
        except (RuntimeError, KeyError):
            return

        if alert.error.value() == 134:
            if not os.path.isdir(torrent.options["download_location"]):
                error_msg = "Unable to locate Download Folder!"
            else:
                error_msg = "Missing or invalid torrent data!"
        else:
            error_msg = "Problem with resume data: %s" % alert_msg.split(":", 1)[1].strip()

        torrent.force_error_state(error_msg, restart_to_resume=True)
Exemplo n.º 21
0
    def on_alert_file_renamed(self, alert):
        log.debug("on_alert_file_renamed")
        log.debug("index: %s name: %s", alert.index, decode_string(alert.name))
        try:
            torrent = self.torrents[str(alert.handle.info_hash())]
            torrent_id = str(alert.handle.info_hash())
        except:
            return

        # We need to see if this file index is in a waiting_on_folder dict
        for wait_on_folder in torrent.waiting_on_folder_rename:
            if alert.index in wait_on_folder:
                wait_on_folder[alert.index].callback(None)
                break
        else:
            # This is just a regular file rename so send the signal
            component.get("EventManager").emit(
                TorrentFileRenamedEvent(torrent_id, alert.index, alert.name))
            self.save_resume_data((torrent_id, ))
Exemplo n.º 22
0
    def handle_alerts(self, wait=False):
        """
        Pops all libtorrent alerts in the session queue and handles them
        appropriately.

        :param wait: bool, if True then the handler functions will be run right
            away and waited to return before processing the next alert
        """
        alerts = self.session.pop_alerts()
        # Loop through all alerts in the queue
        for alert in alerts:
            alert_type = type(alert).__name__
            # Display the alert message
            if log.isEnabledFor(logging.DEBUG):
                log.debug("%s: %s", alert_type, decode_string(alert.message()))
            # Call any handlers for this alert type
            if alert_type in self.handlers:
                for handler in self.handlers[alert_type]:
                    if not wait:
                        self.delayed_calls.append(reactor.callLater(0, handler, alert))
                    else:
                        handler(alert)
Exemplo n.º 23
0
    def handle_alerts(self, wait=False):
        """
        Pops all libtorrent alerts in the session queue and handles them
        appropriately.

        :param wait: bool, if True then the handler functions will be run right
            away and waited to return before processing the next alert
        """
        alerts = self.session.pop_alerts()
        # Loop through all alerts in the queue
        for alert in alerts:
            alert_type = type(alert).__name__
            # Display the alert message
            if log.isEnabledFor(logging.DEBUG):
                log.debug("%s: %s", alert_type, decode_string(alert.message()))
            # Call any handlers for this alert type
            if alert_type in self.handlers:
                for handler in self.handlers[alert_type]:
                    if not wait:
                        self.delayed_calls.append(reactor.callLater(0, handler, alert))
                    else:
                        handler(alert)
Exemplo n.º 24
0
    def begin_import(self,
                     resume_data=None,
                     use_wine_mappings=False,
                     force_recheck=True,
                     resume=False,
                     transfer_meta=None):
        """
        attempts to add utorrent torrents to deluge and reports the results back
        resume_data: path to utorrent resume data
        use_wine_mappings: bool to check torrent paths against wine mappings before
            import
        force_recheck: recheck all torrents after import
        resume: Do not add torrents in the paused state
        transfer_meta: a list of torrent option tags to transfer to the new torrent
            (also support 'time_added')
        """

        self.find_wine_drives()
        if not resume_data:
            resume_data = self.get_default_resume_path()
        try:
            data = self.read_resume_data(resume_data)
        except Exception as e:
            with log:
                log.error('Failed to get resume.dat. Reason: {0}'.format(e))
            defer.returnValue((None, None))

        added = []
        failed = []
        with self.event_ledger:
            with log:
                counter = 0
                for torrent, info in data.iteritems():
                    if torrent in self.config["torrent_blacklist"]:
                        log.debug('skipping {0}'.format(torrent))
                        continue
                    torrent = decode_string(torrent)
                    counter += 1
                    if counter > 10:
                        yield self.take_breath()
                        counter = 0
                    if use_wine_mappings:
                        torrent = os.path.abspath(
                            os.path.join(
                                os.path.dirname(resume_data),
                                self.wine_path_check(torrent)))
                    else:
                        torrent = os.path.abspath(
                            os.path.join(os.path.dirname(resume_data), torrent))
                    success, name = self._import_torrent(torrent, info, use_wine_mappings,
                                                         force_recheck, resume,
                                                         transfer_meta)
                    if success:
                        added.append(name)
                    else:
                        if not name:
                            log.debug('blacklisted torrent, skipping')
                        else:
                            failed.append(name)

        defer.returnValue((added, failed))
Exemplo n.º 25
0
    def _import_torrent(self,
                        torrent,
                        info,
                        use_wine_mappings=False,
                        force_recheck=True,
                        resume=False,
                        transfer_meta=None):
        """handles importing of a single torrent. Same arguments as `begin_import`"""

        try:
            with open(torrent, 'rb') as f:
                filedump = base64.encodestring(f.read())
        except IOError:
            log.error(u'Could not open torrent {0}! skipping...'.format(torrent))
            return False, torrent

        try:
            ut_save_path = decode_string(info['path'])
        except TypeError:
            pass

        if use_wine_mappings:
            ut_save_path = self.wine_path_check(ut_save_path)

        torrent_root = os.path.basename(ut_save_path)
        deluge_storage_path = os.path.dirname(ut_save_path)

        try:
            log.debug(u'Adding {0} to deluge.'.format(torrent_root))
        except UnicodeDecodeError:
            log.error('Bad Filename, skipping')
            return False, torrent_root
        options = {
            'download_location': deluge_storage_path,
            'add_paused': True if not resume else False,
            'file_priorities': [0 if p == '\x80' else 1 for p in info['prio']],
        }
        torrent_id = component.get("Core").add_torrent_file(
            os.path.basename(torrent), filedump=filedump, options=options)

        if torrent_id is None:
            try:
                log.info(u'FAILURE: "{0}" could not be added, may already '
                         u'exsist...'.format(torrent_root))
            except UnicodeDecodeError:
                log.error(u'FAILURE: Torrent Unicode Error')

            return False, torrent_root

        else:
            try:
                log.info(u'SUCCESS!: "{0}" added successfully'.format(torrent_root))
            except UnicodeDecodeError:
                log.info(u'SUCCESS: added but with UnicodeError')
            try:
                targets = info['targets']
            except KeyError:
                targets = None
            self.resolve_path_renames(
                torrent_id, torrent_root, force_recheck=force_recheck, targets=targets)
            if transfer_meta:
                translate_meta.transfer(torrent_id, info, transfer_meta)
            return True, torrent_root
Exemplo n.º 26
0
    def parse(self, filetree=1):
        if not self.__m_filedata:
            log.error("No data to process!")
            return
        try:
            self.__m_metadata = bencode.bdecode(self.__m_filedata)
        except Exception as e:
            log.warning("Failed to decode torrent data %s: %s",
                        self.filename if self.filename else "", e)
            raise e

        self.__m_info_hash = sha(bencode.bencode(
            self.__m_metadata["info"])).hexdigest()

        # Get encoding from torrent file if available
        self.encoding = None
        if "encoding" in self.__m_metadata:
            self.encoding = self.__m_metadata["encoding"]
        elif "codepage" in self.__m_metadata:
            self.encoding = str(self.__m_metadata["codepage"])
        if not self.encoding:
            self.encoding = "UTF-8"

        # Check if 'name.utf-8' is in the torrent and if not try to decode the string
        # using the encoding found.
        if "name.utf-8" in self.__m_metadata["info"]:
            self.__m_name = decode_string(
                self.__m_metadata["info"]["name.utf-8"])
        else:
            self.__m_name = decode_string(self.__m_metadata["info"]["name"],
                                          self.encoding)

        # Get list of files from torrent info
        paths = {}
        dirs = {}
        if "files" in self.__m_metadata["info"]:
            prefix = ""
            if len(self.__m_metadata["info"]["files"]) > 1:
                prefix = self.__m_name

            for index, f in enumerate(self.__m_metadata["info"]["files"]):
                if "path.utf-8" in f:
                    path = os.path.join(prefix, *f["path.utf-8"])
                else:
                    path = decode_string(
                        os.path.join(
                            prefix,
                            decode_string(os.path.join(*f["path"]),
                                          self.encoding)), self.encoding)
                f["index"] = index
                paths[path] = f

                dirname = os.path.dirname(path)
                while dirname:
                    dirinfo = dirs.setdefault(dirname, {})
                    dirinfo["length"] = dirinfo.get("length", 0) + f["length"]
                    dirname = os.path.dirname(dirname)

            if filetree == 2:

                def walk(path, item):
                    if item["type"] == "dir":
                        item.update(dirs[path])
                    else:
                        item.update(paths[path])
                    item["download"] = True

                file_tree = FileTree2(paths.keys())
                file_tree.walk(walk)
            else:

                def walk(path, item):
                    if type(item) is dict:
                        return item
                    return [paths[path]["index"], paths[path]["length"], True]

                file_tree = FileTree(paths)
                file_tree.walk(walk)
            self.__m_files_tree = file_tree.get_tree()
        else:
            if filetree == 2:
                self.__m_files_tree = {
                    "contents": {
                        self.__m_name: {
                            "type": "file",
                            "index": 0,
                            "length": self.__m_metadata["info"]["length"],
                            "download": True
                        }
                    }
                }
            else:
                self.__m_files_tree = {
                    self.__m_name:
                    (0, self.__m_metadata["info"]["length"], True)
                }

        self.__m_files = []
        if "files" in self.__m_metadata["info"]:
            prefix = ""
            if len(self.__m_metadata["info"]["files"]) > 1:
                prefix = self.__m_name

            for f in self.__m_metadata["info"]["files"]:
                if "path.utf-8" in f:
                    path = os.path.join(prefix, *f["path.utf-8"])
                else:
                    path = decode_string(
                        os.path.join(
                            prefix,
                            decode_string(os.path.join(*f["path"]),
                                          self.encoding)), self.encoding)
                self.__m_files.append({
                    'path': path,
                    'size': f["length"],
                    'download': True
                })
        else:
            self.__m_files.append({
                "path": self.__m_name,
                "size": self.__m_metadata["info"]["length"],
                "download": True
            })
Exemplo n.º 27
0
    def begin_import(self,
                     resume_data=None,
                     use_wine_mappings=False,
                     force_recheck=True,
                     resume=False,
                     transfer_meta=None):
        """
        attempts to add utorrent torrents to deluge and reports the results back
        resume_data: path to utorrent resume data
        use_wine_mappings: bool to check torrent paths against wine mappings before
            import
        force_recheck: recheck all torrents after import
        resume: Do not add torrents in the paused state
        transfer_meta: a list of torrent option tags to transfer to the new torrent
            (also support 'time_added')
        """

        self.find_wine_drives()
        if not resume_data:
            resume_data = self.get_default_resume_path()
        try:
            data = self.read_resume_data(resume_data)
        except Exception as e:
            with log:
                log.error('Failed to get resume.dat. Reason: {0}'.format(e))
            defer.returnValue((None, None))

        added = []
        failed = []
        with self.event_ledger:
            with log:
                counter = 0
                for torrent, info in data.iteritems():
                    if torrent in self.config["torrent_blacklist"]:
                        log.debug('skipping {0}'.format(torrent))
                        continue
                    torrent = decode_string(torrent)
                    counter += 1
                    if counter > 10:
                        yield self.take_breath()
                        counter = 0
                    if use_wine_mappings:
                        torrent = os.path.abspath(
                            os.path.join(os.path.dirname(resume_data),
                                         self.wine_path_check(torrent)))
                    else:
                        torrent = os.path.abspath(
                            os.path.join(os.path.dirname(resume_data),
                                         torrent))
                    success, name = self._import_torrent(
                        torrent, info, use_wine_mappings, force_recheck,
                        resume, transfer_meta)
                    if success:
                        added.append(name)
                    else:
                        if not name:
                            log.debug('blacklisted torrent, skipping')
                        else:
                            failed.append(name)

        defer.returnValue((added, failed))
Exemplo n.º 28
0
    def _import_torrent(self,
                        torrent,
                        info,
                        use_wine_mappings=False,
                        force_recheck=True,
                        resume=False,
                        transfer_meta=None):
        """handles importing of a single torrent. Same arguments as `begin_import`"""

        try:
            with open(torrent, 'rb') as f:
                filedump = base64.encodestring(f.read())
        except IOError:
            log.error(
                u'Could not open torrent {0}! skipping...'.format(torrent))
            return False, torrent

        try:
            ut_save_path = decode_string(info['path'])
        except TypeError:
            pass

        if use_wine_mappings:
            ut_save_path = self.wine_path_check(ut_save_path)

        torrent_root = os.path.basename(ut_save_path)
        deluge_storage_path = os.path.dirname(ut_save_path)

        try:
            log.debug(u'Adding {0} to deluge.'.format(torrent_root))
        except UnicodeDecodeError:
            log.error('Bad Filename, skipping')
            return False, torrent_root
        options = {
            'download_location': deluge_storage_path,
            'add_paused': True if not resume else False,
            'file_priorities': [0 if p == '\x80' else 1 for p in info['prio']],
        }
        torrent_id = component.get("Core").add_torrent_file(
            os.path.basename(torrent), filedump=filedump, options=options)

        if torrent_id is None:
            try:
                log.info(u'FAILURE: "{0}" could not be added, may already '
                         u'exsist...'.format(torrent_root))
            except UnicodeDecodeError:
                log.error(u'FAILURE: Torrent Unicode Error')

            return False, torrent_root

        else:
            try:
                log.info(
                    u'SUCCESS!: "{0}" added successfully'.format(torrent_root))
            except UnicodeDecodeError:
                log.info(u'SUCCESS: added but with UnicodeError')
            try:
                targets = info['targets']
            except KeyError:
                targets = None
            self.resolve_path_renames(torrent_id,
                                      torrent_root,
                                      force_recheck=force_recheck,
                                      targets=targets)
            if transfer_meta:
                translate_meta.transfer(torrent_id, info, transfer_meta)
            return True, torrent_root
Exemplo n.º 29
0
 def _create_status_funcs(self):
     #if you add a key here->add it to core.py STATUS_KEYS too.
     self.status_funcs = {
         "active_time":            lambda: self.status.active_time,
         "all_time_download":      lambda: self.status.all_time_download,
         "compact":                lambda: self.options["compact_allocation"],
         "distributed_copies":     lambda: 0.0 if self.status.distributed_copies < 0 else \
             self.status.distributed_copies, # Adjust status.distributed_copies to return a non-negative value
         "download_payload_rate":  lambda: self.status.download_payload_rate,
         "file_priorities":        lambda: self.options["file_priorities"],
         "hash":                   lambda: self.torrent_id,
         "is_auto_managed":        lambda: self.options["auto_managed"],
         "is_finished":            lambda: self.is_finished,
         "max_connections":        lambda: self.options["max_connections"],
         "max_download_speed":     lambda: self.options["max_download_speed"],
         "max_upload_slots":       lambda: self.options["max_upload_slots"],
         "max_upload_speed":       lambda: self.options["max_upload_speed"],
         "message":                lambda: self.statusmsg,
         "move_on_completed_path": lambda: self.options["move_completed_path"],
         "move_on_completed":      lambda: self.options["move_completed"],
         "move_completed_path":    lambda: self.options["move_completed_path"],
         "move_completed":         lambda: self.options["move_completed"],
         "next_announce":          lambda: self.status.next_announce.seconds,
         "num_peers":              lambda: self.status.num_peers - self.status.num_seeds,
         "num_seeds":              lambda: self.status.num_seeds,
         "owner":                  lambda: self.owner,
         "paused":                 lambda: self.status.paused,
         "prioritize_first_last":  lambda: self.options["prioritize_first_last_pieces"],
         "sequential_download":    lambda: self.options["sequential_download"],
         "progress":               lambda: self.status.progress * 100,
         "shared":                 lambda: self.options["shared"],
         "remove_at_ratio":        lambda: self.options["remove_at_ratio"],
         "save_path":              lambda: self.options["download_location"],
         "seeding_time":           lambda: self.status.seeding_time,
         "seeds_peers_ratio":      lambda: -1.0 if self.status.num_incomplete == 0 else \
             self.status.num_complete / float(self.status.num_incomplete), # Use -1.0 to signify infinity
         "seed_rank":              lambda: self.status.seed_rank,
         "state":                  lambda: self.state,
         "stop_at_ratio":          lambda: self.options["stop_at_ratio"],
         "stop_ratio":             lambda: self.options["stop_ratio"],
         "time_added":             lambda: self.time_added,
         "total_done":             lambda: self.status.total_done,
         "total_payload_download": lambda: self.status.total_payload_download,
         "total_payload_upload":   lambda: self.status.total_payload_upload,
         "total_peers":            lambda: self.status.num_incomplete,
         "total_seeds":            lambda: self.status.num_complete,
         "total_uploaded":         lambda: self.status.all_time_upload,
         "total_wanted":           lambda: self.status.total_wanted,
         "tracker":                lambda: self.status.current_tracker,
         "trackers":               lambda: self.trackers,
         "tracker_status":         lambda: self.tracker_status,
         "upload_payload_rate":    lambda: self.status.upload_payload_rate,
         "comment":                lambda: decode_string(self.torrent_info.comment()) if self.has_metadata else u"",
         "num_files":              lambda: self.torrent_info.num_files() if self.has_metadata else 0,
         "num_pieces":             lambda: self.torrent_info.num_pieces() if self.has_metadata else 0,
         "piece_length":           lambda: self.torrent_info.piece_length() if self.has_metadata else 0,
         "private":                lambda: self.torrent_info.priv() if self.has_metadata else False,
         "total_size":             lambda: self.torrent_info.total_size() if self.has_metadata else 0,
         "eta":                    self.get_eta,
         "file_progress":          self.get_file_progress, # Adjust progress to be 0-100 value
         "files":                  self.get_files,
         "is_seed":                self.handle.is_seed,
         "peers":                  self.get_peers,
         "queue":                  self.handle.queue_position,
         "ratio":                  self.get_ratio,
         "tracker_host":           self.get_tracker_host,
         "last_seen_complete":     lambda: self.status.last_seen_complete,
         "name":                   self.get_name,
         "pieces":                 self._get_pieces_info,
         }
Exemplo n.º 30
0
    def on_alert_save_resume_data_failed(self, alert):
        log.debug("on_alert_save_resume_data_failed: %s", decode_string(alert.message()))
        torrent_id = str(alert.handle.info_hash())

        if torrent_id in self.waiting_on_resume_data:
            self.waiting_on_resume_data[torrent_id].errback(Exception(decode_string(alert.message())))
Exemplo n.º 31
0
        self.__m_info_hash = sha(bencode.bencode(self.__m_metadata["info"])).hexdigest()

        # Get encoding from torrent file if available
        self.encoding = None
        if "encoding" in self.__m_metadata:
            self.encoding = self.__m_metadata["encoding"]
        elif "codepage" in self.__m_metadata:
            self.encoding = str(self.__m_metadata["codepage"])
        if not self.encoding:
            self.encoding = "UTF-8"

        # Check if 'name.utf-8' is in the torrent and if not try to decode the string
        # using the encoding found.
        if "name.utf-8" in self.__m_metadata["info"]:
            self.__m_name = decode_string(self.__m_metadata["info"]["name.utf-8"])
        else:
            self.__m_name = decode_string(self.__m_metadata["info"]["name"], self.encoding)

        # Get list of files from torrent info
        paths = {}
        dirs = {}
        if self.__m_metadata["info"].has_key("files"):
            prefix = ""
            if len(self.__m_metadata["info"]["files"]) > 1:
                prefix = self.__m_name

            for index, f in enumerate(self.__m_metadata["info"]["files"]):
                if "path.utf-8" in f:
                    path = os.path.join(prefix, *f["path.utf-8"])
                else:
Exemplo n.º 32
0
class TorrentInfo(object):
    """
    Collects information about a torrent file.

    :param filename: The path to the torrent
    :type filename: string

    """
    def __init__(self, filename, filetree=1):
        # Get the torrent data from the torrent file
        try:
            log.debug("Attempting to open %s.", filename)
            self.__m_filedata = open(filename, "rb").read()
            self.__m_metadata = bencode.bdecode(self.__m_filedata)
        except Exception, e:
            log.warning("Unable to open %s: %s", filename, e)
            raise e

        self.__m_info_hash = sha(bencode.bencode(
            self.__m_metadata["info"])).hexdigest()

        # Get encoding from torrent file if available
        self.encoding = None
        if "encoding" in self.__m_metadata:
            self.encoding = self.__m_metadata["encoding"]
        elif "codepage" in self.__m_metadata:
            self.encoding = str(self.__m_metadata["codepage"])
        if not self.encoding:
            self.encoding = "UTF-8"

        # Check if 'name.utf-8' is in the torrent and if not try to decode the string
        # using the encoding found.
        if "name.utf-8" in self.__m_metadata["info"]:
            self.__m_name = decode_string(
                self.__m_metadata["info"]["name.utf-8"])
        else:
            self.__m_name = decode_string(self.__m_metadata["info"]["name"],
                                          self.encoding)

        # Get list of files from torrent info
        paths = {}
        dirs = {}
        if self.__m_metadata["info"].has_key("files"):
            prefix = ""
            if len(self.__m_metadata["info"]["files"]) > 1:
                prefix = self.__m_name

            for index, f in enumerate(self.__m_metadata["info"]["files"]):
                if "path.utf-8" in f:
                    path = os.path.join(prefix, *f["path.utf-8"])
                else:
                    path = decode_string(
                        os.path.join(
                            prefix,
                            decode_string(os.path.join(*f["path"]),
                                          self.encoding)), self.encoding)
                f["index"] = index
                if "sha1" in f and len(f["sha1"]) == 20:
                    f["sha1"] = f["sha1"].encode('hex')
                if "ed2k" in f and len(f["ed2k"]) == 16:
                    f["ed2k"] = f["ed2k"].encode('hex')
                paths[path] = f
                dirname = os.path.dirname(path)
                while dirname:
                    dirinfo = dirs.setdefault(dirname, {})
                    dirinfo["length"] = dirinfo.get("length", 0) + f["length"]
                    dirname = os.path.dirname(dirname)

            if filetree == 2:

                def walk(path, item):
                    if item["type"] == "dir":
                        item.update(dirs[path])
                    else:
                        item.update(paths[path])
                    item["download"] = True

                file_tree = FileTree2(paths.keys())
                file_tree.walk(walk)
            else:

                def walk(path, item):
                    if type(item) is dict:
                        return item
                    return [paths[path]["index"], paths[path]["length"], True]

                file_tree = FileTree(paths)
                file_tree.walk(walk)
            self.__m_files_tree = file_tree.get_tree()
        else:
            if filetree == 2:
                self.__m_files_tree = {
                    "contents": {
                        self.__m_name: {
                            "type": "file",
                            "index": 0,
                            "length": self.__m_metadata["info"]["length"],
                            "download": True
                        }
                    }
                }
            else:
                self.__m_files_tree = {
                    self.__m_name:
                    (0, self.__m_metadata["info"]["length"], True)
                }

        self.__m_files = []
        if self.__m_metadata["info"].has_key("files"):
            prefix = ""
            if len(self.__m_metadata["info"]["files"]) > 1:
                prefix = self.__m_name

            for f in self.__m_metadata["info"]["files"]:
                if "path.utf-8" in f:
                    path = os.path.join(prefix, *f["path.utf-8"])
                else:
                    path = decode_string(
                        os.path.join(
                            prefix,
                            decode_string(os.path.join(*f["path"]),
                                          self.encoding)), self.encoding)
                self.__m_files.append({
                    'path': path,
                    'size': f["length"],
                    'download': True
                })
        else:
            self.__m_files.append({
                "path": self.__m_name,
                "size": self.__m_metadata["info"]["length"],
                "download": True
            })
Exemplo n.º 33
0
 def _create_status_funcs(self):
     #if you add a key here->add it to core.py STATUS_KEYS too.
     self.status_funcs = {
         "active_time":            lambda: self.status.active_time,
         "all_time_download":      lambda: self.status.all_time_download,
         "compact":                lambda: self.options["compact_allocation"],
         "distributed_copies":     lambda: 0.0 if self.status.distributed_copies < 0 else \
             self.status.distributed_copies, # Adjust status.distributed_copies to return a non-negative value
         "download_payload_rate":  lambda: self.status.download_payload_rate,
         "file_priorities":        lambda: self.options["file_priorities"],
         "hash":                   lambda: self.torrent_id,
         "is_auto_managed":        lambda: self.options["auto_managed"],
         "is_finished":            lambda: self.is_finished,
         "max_connections":        lambda: self.options["max_connections"],
         "max_download_speed":     lambda: self.options["max_download_speed"],
         "max_upload_slots":       lambda: self.options["max_upload_slots"],
         "max_upload_speed":       lambda: self.options["max_upload_speed"],
         "message":                lambda: self.statusmsg,
         "move_on_completed_path": lambda: self.options["move_completed_path"],
         "move_on_completed":      lambda: self.options["move_completed"],
         "move_completed_path":    lambda: self.options["move_completed_path"],
         "move_completed":         lambda: self.options["move_completed"],
         "next_announce":          lambda: self.status.next_announce.seconds,
         "num_peers":              lambda: self.status.num_peers - self.status.num_seeds,
         "num_seeds":              lambda: self.status.num_seeds,
         "owner":                  lambda: self.owner,
         "paused":                 lambda: self.status.paused,
         "prioritize_first_last":  lambda: self.options["prioritize_first_last_pieces"],
         "sequential_download":    lambda: self.options["sequential_download"],
         "progress":               lambda: self.status.progress * 100,
         "shared":                 lambda: self.options["shared"],
         "remove_at_ratio":        lambda: self.options["remove_at_ratio"],
         "save_path":              lambda: self.options["download_location"],
         "seeding_time":           lambda: self.status.seeding_time,
         "seeds_peers_ratio":      lambda: -1.0 if self.status.num_incomplete == 0 else \
             self.status.num_complete / float(self.status.num_incomplete), # Use -1.0 to signify infinity
         "seed_rank":              lambda: self.status.seed_rank,
         "state":                  lambda: self.state,
         "stop_at_ratio":          lambda: self.options["stop_at_ratio"],
         "stop_ratio":             lambda: self.options["stop_ratio"],
         "time_added":             lambda: self.time_added,
         "total_done":             lambda: self.status.total_done,
         "total_payload_download": lambda: self.status.total_payload_download,
         "total_payload_upload":   lambda: self.status.total_payload_upload,
         "total_peers":            lambda: self.status.num_incomplete,
         "total_seeds":            lambda: self.status.num_complete,
         "total_uploaded":         lambda: self.status.all_time_upload,
         "total_wanted":           lambda: self.status.total_wanted,
         "tracker":                lambda: self.status.current_tracker,
         "trackers":               lambda: self.trackers,
         "tracker_status":         lambda: self.tracker_status,
         "upload_payload_rate":    lambda: self.status.upload_payload_rate,
         "comment":                lambda: decode_string(self.torrent_info.comment()) if self.has_metadata else u"",
         "num_files":              lambda: self.torrent_info.num_files() if self.has_metadata else 0,
         "num_pieces":             lambda: self.torrent_info.num_pieces() if self.has_metadata else 0,
         "piece_length":           lambda: self.torrent_info.piece_length() if self.has_metadata else 0,
         "private":                lambda: self.torrent_info.priv() if self.has_metadata else False,
         "total_size":             lambda: self.torrent_info.total_size() if self.has_metadata else 0,
         "eta":                    self.get_eta,
         "file_progress":          self.get_file_progress, # Adjust progress to be 0-100 value
         "files":                  self.get_files,
         "is_seed":                self.handle.is_seed,
         "peers":                  self.get_peers,
         "queue":                  self.handle.queue_position,
         "ratio":                  self.get_ratio,
         "tracker_host":           self.get_tracker_host,
         "last_seen_complete":     lambda: self.status.last_seen_complete,
         "name":                   self.get_name,
         "pieces":                 self._get_pieces_info,
         }
Exemplo n.º 34
0
        self.__m_info_hash = sha(bencode.bencode(
            self.__m_metadata["info"])).hexdigest()

        # Get encoding from torrent file if available
        self.encoding = None
        if "encoding" in self.__m_metadata:
            self.encoding = self.__m_metadata["encoding"]
        elif "codepage" in self.__m_metadata:
            self.encoding = str(self.__m_metadata["codepage"])
        if not self.encoding:
            self.encoding = "UTF-8"

        # Check if 'name.utf-8' is in the torrent and if not try to decode the string
        # using the encoding found.
        if "name.utf-8" in self.__m_metadata["info"]:
            self.__m_name = decode_string(
                self.__m_metadata["info"]["name.utf-8"])
        else:
            self.__m_name = decode_string(self.__m_metadata["info"]["name"],
                                          self.encoding)

        # Get list of files from torrent info
        paths = {}
        dirs = {}
        if "files" in self.__m_metadata["info"]:
            prefix = ""
            if len(self.__m_metadata["info"]["files"]) > 1:
                prefix = self.__m_name

            for index, f in enumerate(self.__m_metadata["info"]["files"]):
                if "path.utf-8" in f:
                    path = os.path.join(prefix, *f["path.utf-8"])