def __init__(self, url, callback, timeout):
     self._callback = callback
     dn, xt, tr = self._parse_url(url)
     self._name = dn
     self._info_hash = xt
     self._tracker = tr
     magnet_handler = MagnetHandler.get_instance()
     magnet_handler.add_magnet(self, timeout)
     self._swarm = MiniSwarm(self._info_hash, magnet_handler.get_raw_server(), self.metainfo_retrieved)
class MagnetLink:

    def __init__(self, url, callback, timeout):
        self._callback = callback
        dn, xt, tr = self._parse_url(url)
        self._name = dn
        self._info_hash = xt
        self._tracker = tr
        magnet_handler = MagnetHandler.get_instance()
        magnet_handler.add_magnet(self, timeout)
        self._swarm = MiniSwarm(self._info_hash, magnet_handler.get_raw_server(), self.metainfo_retrieved)

    def get_infohash(self):
        return self._info_hash

    def get_name(self):
        return self._name

    def retrieve(self):
        if self._info_hash:
            dht = mainlineDHT.dht
            dht.get_peers(self._info_hash, Id(self._info_hash), self.potential_peers_from_dht, 0)
            try:
                if self._tracker:
                    MiniTracker(self._swarm, self._tracker)
            except:
                print_exc()

            return True
        else:
            print >> sys.stderr, 'No Infohash'
            return False

    def potential_peers_from_dht(self, lookup_id, peers):
        if peers:
            self._swarm.add_potential_peers(peers)

    def metainfo_retrieved(self, metainfo, peers = []):
        metadata = {'info': metainfo}
        if self._tracker:
            metadata['announce'] = self._tracker
        else:
            metadata['nodes'] = []
        if peers:
            metadata['initial peers'] = peers
        self._callback(metadata)
        self.close()

    def close(self):
        magnet_handler = MagnetHandler.get_instance()
        magnet_handler.remove_magnet(self)
        if DEBUG:
            print >> sys.stderr, 'Magnet.close()'
        self._swarm.close()

    @staticmethod
    def _parse_url(url):
        dn = None
        xt = None
        tr = None
        if DEBUG:
            print >> sys.stderr, 'Magnet._parse_url()', url
        schema, netloc, path, query, fragment = urlsplit(url)
        if schema == 'magnet':
            if '?' in path:
                pre, post = path.split('?', 1)
                if query:
                    query = '&'.join((post, query))
                else:
                    query = post
            for key, value in parse_qsl(query):
                if key == 'dn':
                    dn = value.decode()
                elif key == 'xt' and value.startswith('urn:btih:'):
                    xt = unhexlify(value[9:49])
                elif key == 'tr':
                    tr = value

            if DEBUG:
                print >> sys.stderr, 'Magnet._parse_url() NAME:', dn
            if DEBUG:
                print >> sys.stderr, 'Magnet._parse_url() HASH:', xt
            if DEBUG:
                print >> sys.stderr, 'Magnet._parse_url() TRAC:', tr
        return (dn, xt, tr)