Ejemplo n.º 1
0
    def torrent_params_from_magnet_link(self, mag_link):
        res = lt.parse_magnet_uri(mag_link)
        # DAMN YOU LIBTORRENT
        res['info_hash'] = hex_to_hash(str(res['info_hash']).decode('hex'))

        res["save_path"] = self.torrent_data_path
        return res
Ejemplo n.º 2
0
	def addMagnetLink(self, url, paused = False):
		params = libtorrent.parse_magnet_uri(url)
		info_hash = str(params['info_hash']).lower()

		download = self.findTorrentByHash(info_hash)
		if download:
			return download
		else:
			save_path = self.cache_path

			atp = {}
			atp["save_path"] = save_path
			atp["storage_mode"] = libtorrent.storage_mode_t.storage_mode_sparse
			atp["auto_managed"] = True
			atp["duplicate_is_error"] = True
			#atp["paused"] = paused
			atp["url"] = url
			if paused:
				atp['flags'] = libtorrent.add_torrent_params_flags_t.flag_paused
			else:
				atp['flags'] = 0

			handle = self.session.add_torrent(atp)
			handle.set_max_connections(60)
			handle.set_max_uploads(-1)

			download = TorrentDownload(handle, self, save_path)
			self.downloads.append(download)
			self.download_added.emit(download)
			return download
Ejemplo n.º 3
0
 def test_parse_magnet_uri(self):
     ses = lt.session({})
     magnet = 'magnet:?xt=urn:btih:C6EIF4CCYDBTIJVG3APAGM7M4NDONCTI'
     p = lt.parse_magnet_uri(magnet)
     p['save_path'] = '.'
     h = ses.add_torrent(p)
     self.assertEqual(str(h.info_hash()), '178882f042c0c33426a6d81e0333ece346e68a68')
Ejemplo n.º 4
0
 def test_parse_magnet_uri(self):
     ses = lt.session({})
     magnet = 'magnet:?xt=urn:btih:C6EIF4CCYDBTIJVG3APAGM7M4NDONCTI'
     p = lt.parse_magnet_uri(magnet)
     self.assertEqual(str(p.info_hash), '178882f042c0c33426a6d81e0333ece346e68a68')
     p.save_path = '.'
     h = ses.add_torrent(p)
     self.assertEqual(str(h.info_hash()), '178882f042c0c33426a6d81e0333ece346e68a68')
Ejemplo n.º 5
0
    def download_torrent(self, magnet):
        import libtorrent as lt

        if not self.download_dir:
            raise RuntimeError(
                'No download_dir specified in video.omxplayer configuration')

        ses = lt.session()
        ses.listen_on(*self.torrent_ports)

        info = lt.parse_magnet_uri(magnet)
        logging.info('Downloading "{}" to "{}" from [{}]'.format(
            info['name'], self.download_dir, magnet))

        params = {
            'save_path': self.download_dir,
            'storage_mode': lt.storage_mode_t.storage_mode_sparse,
        }

        transfer = lt.add_magnet_uri(ses, magnet, params)
        status = transfer.status()
        files = []

        self.torrent_state = {
            'url': magnet,
            'title': info['name'],
        }

        while (not status.is_seeding):
            status = transfer.status()
            torrent_file = transfer.torrent_file()
            if torrent_file:
                files = [
                    os.path.join(self.download_dir,
                                 torrent_file.files().file_path(i))
                    for i in range(0,
                                   torrent_file.files().num_files())
                    if self._is_video_file(torrent_file.files().file_name(i))
                ]

            self.torrent_state['progress'] = 100 * status.progress
            self.torrent_state['download_rate'] = status.download_rate
            self.torrent_state['upload_rate'] = status.upload_rate
            self.torrent_state['num_peers'] = status.num_peers
            self.torrent_state['state'] = status.state

            logging.info(
                ('Torrent download: {:.2f}% complete (down: {:.1f} kb/s ' +
                 'up: {:.1f} kB/s peers: {} state: {})').format(
                     status.progress * 100, status.download_rate / 1000,
                     status.upload_rate / 1000, status.num_peers,
                     status.state))

            time.sleep(5)

        return Response(output=files)
def magnet_atp(protos: tuple[conftest.Proto, conftest.Proto],
               atp: lt.add_torrent_params) -> lt.add_torrent_params:
    magnet_proto, _ = protos
    assert atp.ti is not None
    magnet = lt.parse_magnet_uri(lt.make_magnet_uri(atp.ti))
    if not (magnet_proto & conftest.V1):
        magnet.info_hashes = lt.info_hash_t(magnet.info_hashes.v2)
    elif not (magnet_proto & conftest.V2):
        magnet.info_hashes = lt.info_hash_t(magnet.info_hashes.v1)
    return magnet
Ejemplo n.º 7
0
    def process(self, entry, destination_folder, timeout):
        import libtorrent

        magnet_uri = entry['url']
        params = libtorrent.parse_magnet_uri(magnet_uri)
        session = libtorrent.session()
        lt_version = [int(v) for v in libtorrent.version.split('.')]
        if lt_version > [0, 16, 13, 0] and lt_version < [1, 1, 3, 0]:
            # for some reason the info_hash needs to be bytes but it's a struct called sha1_hash
            params['info_hash'] = params['info_hash'].to_bytes()
        params.url = magnet_uri
        handle = session.add_torrent(params)
        log.debug('Acquiring torrent metadata for magnet %s', magnet_uri)
        handle.force_dht_announce()
        timeout_value = timeout
        while not handle.has_metadata():
            time.sleep(0.1)
            timeout_value -= 0.1
            if timeout_value <= 0:
                raise plugin.PluginError(
                    'Timed out after {} seconds trying to magnetize'.format(
                        timeout))
        log.debug('Metadata acquired')
        torrent_info = handle.get_torrent_info()
        torrent_file = libtorrent.create_torrent(torrent_info)
        torrent_path = pathscrub(
            os.path.join(destination_folder,
                         torrent_info.name() + ".torrent"))
        with open(torrent_path, "wb") as f:
            f.write(libtorrent.bencode(torrent_file.generate()))
        log.debug('Torrent file wrote to %s', torrent_path)

        # Windows paths need an extra / prepended to them for url
        if not torrent_path.startswith('/'):
            torrent_path = '/' + torrent_path
        entry['url'] = torrent_path
        entry['file'] = torrent_path
        # make sure it's first in the list because of how download plugin works
        entry['urls'].insert(0, 'file://{}'.format(torrent_path))
        entry['content_size'] = torrent_info.total_size() / 1024 / 1024

        # Might as well get some more info
        while handle.status(0).num_complete < 0:
            time.sleep(0.1)
            timeout_value -= 0.1
            if timeout_value <= 0:
                log.debug('Timed out after {} seconds trying to get peer info'.
                          format(timeout))
                return
        log.debug('Peer info acquired')
        torrent_status = handle.status(0)
        entry['torrent_seeds'] = torrent_status.num_complete
        entry['torrent_leeches'] = torrent_status.num_incomplete
Ejemplo n.º 8
0
    def addTorrent(self):
        print(self.torrent)
        if self.torrent.startswith('magnet:'):
            atp = lt.add_torrent_params()
            atp = lt.parse_magnet_uri(self.torrent)
            atp.save_path = '.'
            h = self.ses.add_torrent(atp)
        else:
            info = lt.torrent_info(self.torrent)
            h = self.ses.add_torrent({'ti': info, 'save_path': '.'})

        return h
Ejemplo n.º 9
0
    def _get_torrent_info(self, torrent, download_dir):
        import libtorrent as lt

        torrent_file = None
        magnet = None
        info = {}
        file_info = {}

        # noinspection HttpUrlsUsage
        if torrent.startswith('magnet:?'):
            magnet = torrent
            magnet_info = lt.parse_magnet_uri(magnet)
            if isinstance(magnet_info, dict):
                info = {
                    'name': magnet_info.get('name'),
                    'url': magnet,
                    'magnet': magnet,
                    'trackers': magnet_info.get('trackers', []),
                    'save_path': download_dir,
                }
            else:
                info = {
                    'name': magnet_info.name,
                    'url': magnet,
                    'magnet': magnet,
                    'trackers': magnet_info.trackers,
                    'save_path': download_dir,
                }
        elif torrent.startswith('http://') or torrent.startswith('https://'):
            response = requests.get(torrent, allow_redirects=True)
            torrent_file = os.path.join(download_dir,
                                        self._generate_rand_filename())

            with open(torrent_file, 'wb') as f:
                f.write(response.content)
        else:
            torrent_file = os.path.abspath(os.path.expanduser(torrent))
            if not os.path.isfile(torrent_file):
                raise RuntimeError(
                    '{} is not a valid torrent file'.format(torrent_file))

        if torrent_file:
            file_info = lt.torrent_info(torrent_file)
            # noinspection PyArgumentList
            info = {
                'name': file_info.name(),
                'url': torrent,
                'trackers': [t.url for t in list(file_info.trackers())],
                'save_path': download_dir,
            }

        return info, file_info, torrent_file, magnet
Ejemplo n.º 10
0
def download_torrent(torrent_source, save_location, output_file_name):
    #Start a session
    session = libtorrent.session({'listen_interfaces': '0.0.0.0:6881'})

    #Check if we are dealing with a torrent file or a magnet link
    if torrent_source.endswith('.torrent'):
        #Parse torrent file parameters
        torrent_file = download_file(torrent_source)
        torrent_info = libtorrent.torrent_info(torrent_file)
        torrent_in_progress = session.add_torrent({
            'ti': torrent_info,
            'save_path': save_location
        })
        remove(torrent_file)
    else:
        #Parse magnet URI parameters
        torrent_info = libtorrent.parse_magnet_uri(torrent_source).get(
            'info_hash')
        torrent_in_progress = session.add_torrent({
            'ti': torrent_info,
            'save_path': save_location
        })

    logging.info(f'Starting download: {torrent_in_progress.name()}.')

    while (not torrent_in_progress.is_seed()):
        status = torrent_in_progress.status()

        sleep(1)
        logging.info('{:.2f}% complete. (Speed: {:.1f} kB/s)'.format(
            status.progress * 100, status.download_rate / 1000))

        alerts = session.pop_alerts()
        for a in alerts:
            if a.category() & libtorrent.alert.category_t.error_notification:
                logging.error(f'{str(a)}')

    #TODO test files with more than one . in the name
    output_file_name += str(path.splitext(str(torrent_in_progress.name()))[1])

    rename(f'{save_location}/{torrent_in_progress.name()}',
           f'{save_location}/{output_file_name}')
    logging.info(f'{torrent_in_progress.name()} - Download complete.')

    #return output_file_name, torrent_in_progress.name()
    return f'{save_location}/{output_file_name}', f'{torrent_in_progress.name()}'
Ejemplo n.º 11
0
def add_torrent(ses, filename, options):
    atp = lt.add_torrent_params()
    if filename.startswith('magnet:'):
        atp = lt.parse_magnet_uri(filename)
    else:
        atp.ti = lt.torrent_info(filename)
        try:
            atp.resume_data = open(os.path.join(options.save_path, atp.info.name() + '.fastresume'), 'rb').read()
        except Exception:
            pass

    atp.save_path = options.save_path
    atp.storage_mode = lt.storage_mode_t.storage_mode_sparse
    atp.flags |= lt.torrent_flags.duplicate_is_error \
        | lt.torrent_flags.auto_managed \
        | lt.torrent_flags.duplicate_is_error
    ses.async_add_torrent(atp)
Ejemplo n.º 12
0
def add_torrent(ses, filename, options):
    atp = lt.add_torrent_params()
    if filename.startswith('magnet:'):
        atp = lt.parse_magnet_uri(filename)
    else:
        atp.ti = lt.torrent_info(filename)
        try:
            atp.resume_data = open(os.path.join(options.save_path, atp.info.name() + '.fastresume'), 'rb').read()
        except Exception:
            pass

    atp.save_path = options.save_path
    atp.storage_mode = lt.storage_mode_t.storage_mode_sparse
    atp.flags |= lt.torrent_flags.duplicate_is_error \
        | lt.torrent_flags.auto_managed \
        | lt.torrent_flags.duplicate_is_error
    ses.async_add_torrent(atp)
Ejemplo n.º 13
0
def magnet2torrent_worker(magnet):
    logger.info('magnet2torrent: start [%s]', magnet)

    session = libtorrent.session()
    params = libtorrent.parse_magnet_uri(magnet)

    # bug: TypeError: No registered converter was able to produce a C++
    # rvalue of type bytes from this Python object of type sha1_hash
    params.update({'info_hash': params['info_hash'].to_bytes()})
    handle = session.add_torrent(params)
    if not handle.is_valid():
        logger.error('magnet2torrent: invalid handle')

    time_lim = time.time() + 3 * 60

    while not handle.has_metadata():
        time.sleep(0.1)
        if time.time() > time_lim:
            logger.info(
                'magnet2torrent: the waiting time of metadata has expired')
            break

    session.pause()
    try:
        torinfo = handle.get_torrent_info()
        if not torinfo:
            raise ValueError('magnet2torrent: failed getting torrent info')
        torfile = libtorrent.create_torrent(torinfo)
    except Exception:
        logger.exception('magnet2torrent: failed creating torrent file')
        return

    try:
        torrent_content = libtorrent.bencode(torfile.generate())
        if torrent_content:
            logger.info('magnet2torrent: done [%s]', magnet)
            return torinfo.name() + '.torrent', torrent_content
        else:
            logger.error('magnet2torrent: empty torrent content body [%s]',
                         magnet)
    except Exception:
        logger.exception('magnet2torrent: torrent generating problem [%s]',
                         magnet)
Ejemplo n.º 14
0
def add_torrent(ses, filename, options):
    atp = lt.add_torrent_params()
    if filename.startswith('magnet:'):
        atp = lt.parse_magnet_uri(filename)
    else:
        ti = lt.torrent_info(filename)
        resume_file = os.path.join(options.save_path,
                                   ti.name() + '.fastresume')
        try:
            atp = lt.read_resume_data(open(resume_file, 'rb').read())
        except Exception as e:
            print('failed to open resume file "%s": %s' % (resume_file, e))
        atp.ti = ti

    atp.save_path = options.save_path
    atp.storage_mode = lt.storage_mode_t.storage_mode_sparse
    atp.flags |= lt.torrent_flags.duplicate_is_error \
        | lt.torrent_flags.auto_managed \
        | lt.torrent_flags.duplicate_is_error
    ses.async_add_torrent(atp)
Ejemplo n.º 15
0
def add_torrent(ses: lt.session, filename: str,
                options: optparse.Values) -> None:
    atp = lt.add_torrent_params()
    if filename.startswith("magnet:"):
        atp = lt.parse_magnet_uri(filename)
    else:
        ti = lt.torrent_info(filename)
        resume_file = os.path.join(options.save_path,
                                   ti.name() + ".fastresume")
        try:
            atp = lt.read_resume_data(open(resume_file, "rb").read())
        except Exception as e:
            print('failed to open resume file "%s": %s' % (resume_file, e))
        atp.ti = ti

    atp.save_path = options.save_path
    atp.storage_mode = lt.storage_mode_t.storage_mode_sparse
    atp.flags |= (lt.torrent_flags.duplicate_is_error
                  | lt.torrent_flags.auto_managed
                  | lt.torrent_flags.duplicate_is_error)
    ses.async_add_torrent(atp)
Ejemplo n.º 16
0
def magnet2torrent_worker(magnet):
    logger.info('magnet2torrent: start [%s]', magnet)

    session = libtorrent.session()
    params = libtorrent.parse_magnet_uri(magnet)

    # bug: TypeError: No registered converter was able to produce a C++
    # rvalue of type bytes from this Python object of type sha1_hash
    params.update({'info_hash': params['info_hash'].to_bytes()})
    handle = session.add_torrent(params)
    if not handle.is_valid():
        logger.error('magnet2torrent: invalid handle')

    time_lim = time.time() + 3*60

    while not handle.has_metadata():
        time.sleep(0.1)
        if time.time() > time_lim:
            logger.info('magnet2torrent: the waiting time of metadata has expired')
            break

    session.pause()
    try:
        torinfo = handle.get_torrent_info()
        if not torinfo:
            raise ValueError('magnet2torrent: failed getting torrent info')
        torfile = libtorrent.create_torrent(torinfo)
    except Exception:
        logger.exception('magnet2torrent: failed creating torrent file')
        return

    try:
        torrent_content = libtorrent.bencode(torfile.generate())
        if torrent_content:
            logger.info('magnet2torrent: done [%s]', magnet)
            return torinfo.name() + '.torrent', torrent_content
        else:
            logger.error('magnet2torrent: empty torrent content body [%s]', magnet)
    except Exception:
        logger.exception('magnet2torrent: torrent generating problem [%s]', magnet)
Ejemplo n.º 17
0
 def magnet_to_torrent(self, magnet_uri, destination_folder, timeout=60):
     import libtorrent
     params = libtorrent.parse_magnet_uri(magnet_uri)
     session = libtorrent.session()
     handle = session.add_torrent(params)
     log.debug('Acquiring torrent metadata for magnet {}'.format(magnet_uri))
     timeout_value = timeout
     while not handle.has_metadata():
         time.sleep(0.1)
         timeout_value -= 0.1
         if timeout_value <= 0:
             raise Exception('Timed out after {} seconds acquiring torrent metadata from the DHT/trackers.'.format(
                 timeout
             ))
     log.debug('Metadata acquired')
     torrent_info = handle.get_torrent_info()
     torrent_file = libtorrent.create_torrent(torrent_info)
     torrent_path = pathscrub(os.path.join(destination_folder, torrent_info.name() + ".torrent"))
     with open(torrent_path, "wb") as f:
         f.write(libtorrent.bencode(torrent_file.generate()))
     log.debug('Torrent file wrote to {}'.format(torrent_path))
     return torrent_path
Ejemplo n.º 18
0
def magnet2torrent(magnet, output_path):
    """
    Convert magnet link to Torrent file.

    Code from Daniel Folkes: https://github.com/danfolkes/Magnet2Torrent

    Args:
        magnet(str): The magnet link.
        output_path(str): The absolute path to write the Torrent file.

    """
    global logger

    tempdir = tempfile.mkdtemp()
    session = lt.session()
    params = lt.parse_magnet_uri(magnet)
    params.save_path = tempdir
    handle = session.add_torrent(params)

    logger.debug("Downloading Metadata...")
    while not handle.status().has_metadata:
        try:
            sleep(1)
        except KeyboardInterrupt:
            logger.debug("Aborting...")
            session.pause()
            logger.debug("Cleanup dir %s", tempdir)
            shutil.rmtree(tempdir)
            sys.exit(0)
    session.pause()

    torinfo = handle.torrent_file()
    torfile = lt.create_torrent(torinfo)

    with open(output_path, "wb") as f:
        f.write(lt.bencode(torfile.generate()))
    logger.debug("Saved! Cleaning up dir: %s", tempdir)
    session.remove_torrent(handle)
    shutil.rmtree(tempdir)
Ejemplo n.º 19
0
    def magnet_to_torrent(self, magnet_uri, destination_folder, timeout):
        import libtorrent

        params = libtorrent.parse_magnet_uri(magnet_uri)
        session = libtorrent.session()
        # for some reason the info_hash needs to be bytes but it's a struct called sha1_hash
        params["info_hash"] = bytes(params["info_hash"])
        handle = libtorrent.add_magnet_uri(session, magnet_uri, params)
        log.debug("Acquiring torrent metadata for magnet %s", magnet_uri)
        timeout_value = timeout
        while not handle.has_metadata():
            time.sleep(0.1)
            timeout_value -= 0.1
            if timeout_value <= 0:
                raise plugin.PluginError("Timed out after {} seconds trying to magnetize".format(timeout))
        log.debug("Metadata acquired")
        torrent_info = handle.get_torrent_info()
        torrent_file = libtorrent.create_torrent(torrent_info)
        torrent_path = pathscrub(os.path.join(destination_folder, torrent_info.name() + ".torrent"))
        with open(torrent_path, "wb") as f:
            f.write(libtorrent.bencode(torrent_file.generate()))
        log.debug("Torrent file wrote to %s", torrent_path)
        return torrent_path
Ejemplo n.º 20
0
    def actionAddTorrent(self, to, torrentIdentifier):
        if not self.hasSitePermission(self.site.address):
            return self.response(to, {"error": "Forbidden"})

        save_path = './data/' + self.site.address + '/downloads/'
        try:
            e = libtorrent.bdecode(base64.b64decode(torrentIdentifier))
            info = libtorrent.torrent_info(e)
            params = { 'save_path': save_path, \
                        'storage_mode': libtorrent.storage_mode_t.storage_mode_sparse, \
                        'ti': info }
        except Exception as exception:
            try:
                # Test if a magnet
                params = libtorrent.parse_magnet_uri(torrentIdentifier)
                params.save_path = save_path
                # HACK:
                # Doesn't recognise sha1_hash python object when added to session if not converted to string
                # 'No registered converter was able to produce a C++ rvalue of type bytes from this Python object of type sha1_hash'
                #params['info_hash'] = params['info_hash'].to_string()
            except Exception as exception:
                params = { 'save_path': save_path, \
                            'storage_mode': libtorrent.storage_mode_t.storage_mode_sparse, \
                            'info_hash': torrentIdentifier.decode('hex') }
        try:
            session.async_add_torrent(params)
        except Exception as exception:
            self.response(to, {'error': str(exception)})
        else:
            if type(params) is libtorrent.add_torrent_params:
                info_hash = params.info_hashes.get_best()
            else:
                if not info is None:
                    info_hash = info.info_hashes().get_best()
                else:
                    info_hash = params['info_hash']
            self.response(to, {'info_hash': str(info_hash)})
Ejemplo n.º 21
0
 def magnet_to_torrent(self, magnet_uri, destination_folder, timeout):
     import libtorrent
     params = libtorrent.parse_magnet_uri(magnet_uri)
     session = libtorrent.session()
     lt_version = [int(v) for v in libtorrent.version.split('.')]
     if lt_version > [0,16,13,0]:
         # for some reason the info_hash needs to be bytes but it's a struct called sha1_hash
         params['info_hash'] = params['info_hash'].to_bytes()
     handle = libtorrent.add_magnet_uri(session, magnet_uri, params)
     log.debug('Acquiring torrent metadata for magnet %s', magnet_uri)
     timeout_value = timeout
     while not handle.has_metadata():
         time.sleep(0.1)
         timeout_value -= 0.1
         if timeout_value <= 0:
             raise plugin.PluginError('Timed out after {} seconds trying to magnetize'.format(timeout))
     log.debug('Metadata acquired')
     torrent_info = handle.get_torrent_info()
     torrent_file = libtorrent.create_torrent(torrent_info)
     torrent_path = pathscrub(os.path.join(destination_folder, torrent_info.name() + ".torrent"))
     with open(torrent_path, "wb") as f:
         f.write(libtorrent.bencode(torrent_file.generate()))
     log.debug('Torrent file wrote to %s', torrent_path)
     return torrent_path
Ejemplo n.º 22
0
def api_upload(magnet_url_or_hash=None):
    """
	<h5>Description:</h5>
	<p>
		Adds a new torrent to the system and retrieves its data if its not already in the system.
		Note: If the torrent is added via a SHA-1 info_hash, a magnet link is constructed and we attempt to retrieve the torrent via DHT		
	</p>

	<h5>Parameters:</h5>
	<ul>
		<li><strong>magnet_url_or_hash</strong> - A magnet link, a HTTP url to the .torrent file, or a SHA-1 info_hash. Can also be the base64 encoding of a binary .torrent file</li>
	</ul>

	<h5>Returns:</h5>
	<p>
		If successful, a data structure like so:
<pre>
{
    "data": {
        "url": "(the contents of the url_magnet_or_hash parameter)",
        "added": true,
        "hash": "a4b93e50187930206dcf1351bceceb29f5a119ca"
    },
    "success": true
}
</pre>
		If an error occured, the following data structure will be returned:
<pre>
{
    "message": "Cannot recognise this url: foo",
    "success": false
}
</pre>
	</p>

	<h5>Examples:</h5>
	<p>
		Add based on a magnet link:<br />
		<pre>/api/upload/magnet%3A%3Fxt%3Durn%3Abtih%3Addceab34ac388ca56b0cdbc6eb726ca1844233c5%26dn%3DPioneer%2BOne%2BS01E03%2BXvid-VODO%26tr%3Dudp%253A%252F%252Ftracker.openbittorrent.com%253A80%26tr%3Dudp%253A%252F%252Ftracker.publicbt.com%253A80%26tr%3Dudp%253A%252F%252Ftracker.istole.it%253A6969%26tr%3Dudp%253A%252F%252Ftracker.ccc.de%253A80</pre>
		
		Add based on a HTTP url:<br />
		<pre>/api/upload/http%3A%2F%2Ftorrents.thepiratebay.se%2F6753216%2FPioneer_One_S01E03_Xvid-VODO.6753216.TPB.torrent</pre>
		
		Add based on a SHA-1 info_hash:<br />
		<pre>/api/upload/ddceab34ac388ca56b0cdbc6eb726ca1844233c5</pre>
	</p>
	"""
    url = magnet_url_or_hash if magnet_url_or_hash else request.params.get(
        "magnet_url_or_hash")
    if not url:
        return api_error("No magnet, url or hash supplied")
    item = url.strip()
    info_hash = ""
    try:
        if is_hash(item):
            info_hash = item
            if not is_in_database(item):
                add_to_database(item)
        elif is_base64(item):
            decoded = base64.b64decode(item)
            info = lt.torrent_info(lt.bdecode(decoded))
            info_hash = "%s" % info.info_hash()
            if not is_in_database(info_hash):
                add_to_database(info_hash, fetch_metadata=False)
                thread.start_new_thread(add_from_torrent_info,
                                        (info, torrent_data))
        elif is_magnet(item):
            params = lt.parse_magnet_uri(item)
            info_hash = str(params["info_hash"])
            if not info_hash.replace("0", ""):
                raise RuntimeError(
                    "The hash was all 0's, did you urlencode the magnet link properly?"
                )
            else:
                if not is_in_database(info_hash):
                    add_to_database(info_hash, item)
        elif is_url(item):
            item = urllib.unquote_plus(item)
            logger.debug("Fetching %s" % item)
            download_to = tempfile.mkstemp(suffix=".torrent")[1]
            urllib.urlretrieve(item, download_to)
            handle = open(download_to, "rb")
            torrent_data = handle.read()
            info = lt.torrent_info(lt.bdecode(torrent_data))
            handle.close()
            os.remove(download_to)
            info_hash = "%s" % info.info_hash()
            if not is_in_database(info_hash):
                add_to_database(info_hash, fetch_metadata=False)
                thread.start_new_thread(add_from_torrent_info,
                                        (info, torrent_data))
        else:
            raise RuntimeError("Cannot recognise this url: %s" % item)
    except (RuntimeError, IOError) as e:
        return api_error(str(e))

    return api_success({"url": item, "hash": info_hash, "added": True})
Ejemplo n.º 23
0
def get_file(fn):
    # request_uri = fn.split("/",1)[-1]
    fsize = None
    exists = False
    mime_type = ''

    request_uri = fn.replace(STATIC_FILES_DIR + "/", "")
    print request_uri
    if request_uri.startswith(atp["static_path"]):
        torrent = atp
        chosen_file = "/".join(request_uri.split("/")[2:])
        print "chosen file:" + chosen_file
        url = "magnet:?xt=urn:btih:" + request_uri.split("/")[1]
        info_hash = libtorrent.parse_magnet_uri(url)["info_hash"]
        handle = torrent_session.find_torrent(info_hash)
        # print str(info_hash)+".resume", os.listdir("resume")
        if handle.is_valid():
            print "Magnet already in the session"
            torrent_handle = handle
        # elif str(info_hash)+".resume" in os.listdir("resume"):
        #     torrent["resume_data"] = io.open("resume/"+str(info_hash)+".resume", "rb").read()
        #     torrent_handle = torrent_session.add_torrent(torrent)
        else:
            print " start new torrent"
            torrent["url"] = url
            torrent["save_path"] = os.path.join(TORRENTS_DIR, str(info_hash))
            # torrent["paused"]=True
            torrent_handle = torrent_session.add_torrent(torrent)
            while not torrent_handle.has_metadata():
                sleep(0.5)

        info = torrent_handle.get_torrent_info()
        torrent_files = info.files()
        # torrent_handle.auto_managed(False)
        if chosen_file is not None:
            for i, file_info in enumerate(torrent_files):
                print "path:", file_info.path
                if chosen_file == file_info.path:
                    torrent_handle.file_priority(i, 1)
                    torrent_file = file_info
                    file_index = i
                else:
                    torrent_handle.file_priority(i, 0)
        torrent_handle.map_piece = lambda offset: info.map_file(
            file_index, offset, 1)

        path = os.path.join(TORRENTS_DIR, torrent_file.path)
        first_byte = torrent_file.offset
        last_byte = torrent_file.offset + torrent_file.size
        torrent_handle.set_sequential_download(True)
        first_piece = torrent_handle.map_piece(first_byte).piece
        last_piece = torrent_handle.map_piece(last_byte).piece
        num_pieces = info.num_pieces()
        future_pieces = int((last_piece - first_piece) * 0.01)
        print "offset", torrent_file.offset, "piece", first_piece, "total", num_pieces
        piece_priorities = first_piece * [0] + (num_pieces - first_piece) * [1]
        piece_priorities = piece_priorities[:num_pieces]
        # piece_priorities=first_piece*[0]+future_pieces*[7]+more_pieces*[1]+(num_pieces-first_piece-future_pieces-more_pieces)*[0]
        torrent_handle.prioritize_pieces(piece_priorities)
        # torrent_handle.prioritize_pieces(num_pieces*[0])
        # torrent_handle.piece_priority(first_piece,7)
        torrent_handle.piece_priority(last_piece, 7)
        torrent_handle.piece_priority(last_piece - 1, 7)
        # torrent_handle.num_pieces=info.num_pieces()
        piece = first_piece
        waiting = True

        while waiting:
            sleep(1)
            # if torrent_handle.have_piece(first_piece) and torrent_handle.have_piece(last_piece):
            #     waiting =False
            status = torrent_handle.status()
            pieces = status.pieces
            print pieces[piece:piece + future_pieces], last_piece, pieces[
                last_piece -
                1], status.progress, status.download_rate, status.state
            if pieces[piece:piece +
                      future_pieces] == future_pieces * [True] and pieces[
                          last_piece - 1]:
                waiting = False
        print "first and last piece received"
        # torrent_handle.prioritize_pieces(num_pieces*[1])
    else:
        torrent_handle = None
    try:
        fsize = os.path.getsize(fn)
        exists = True
        type, encoding = mimetypes.guess_type(request_uri)
        if type:
            mime_type = type
    except:
        pass

    return File(request_uri, fn, fsize, exists, mime_type, torrent_handle)
Ejemplo n.º 24
0
def main_torrent_descr(options):
    main_default(options)
    sett = {
        'enable_lsd': True,
        'enable_dht': True,
        'enable_upnp': True,
        'enable_natpmp': True,
    }
    torrent_session = libtorrent.session(sett)
    alert_mask = (libtorrent.alert.category_t.storage_notification
                  | libtorrent.alert.category_t.status_notification)

    torrent_session.apply_settings({'alert_mask': alert_mask})
    torrent_session.listen_on(6881, 6891)
    torrent_session.dht_nodes = [('router.bittorrent.com', 6881),
                                 ('router.utorrent.com', 6881),
                                 ('dht.transmissionbt.com', 6881),
                                 ('dht.libtorrent.org', 25401),
                                 ('dht.aelitis.com', 6881)]
    torrent_session.start_dht()
    torrent_session.start_lsd()
    torrent_session.add_extension('ut_metadata')
    torrent_session.add_extension('ut_pex_plugin')
    torrent_session.add_extension('smart_ban_plugin')

    torrent_descr = {"save_path": options["save-path"]}
    if "hash-file" in options:
        if options["hash-file"].startswith('magnet:?'):
            magnet = libtorrent.parse_magnet_uri(options["hash-file"])
            e = str(magnet.info_hash)
            if len(e) == 40:
                info_hash = binascii.unhexlify(e)
            elif len(e) == 32:
                info_hash = base64.b32decode(e)
            else:
                raise Exception("Unable to parse infohash")

            trackers = magnet.trackers
            torrent_handle = torrent_session.add_torrent({
                'info_hashes':
                info_hash,
                'trackers':
                trackers,
                "save_path":
                options["save-path"]
            })
            dots = 0
            while not torrent_handle.has_metadata():
                dots += 1
                sys.stdout.write('.')
                sys.stdout.flush()
                time.sleep(1)
            if (dots): sys.stdout.write('\n')
            torrent_info = torrent_handle.get_torrent_info()
        else:
            torrent_info = libtorrent.torrent_info(options["hash-file"])
            torrent_descr["ti"] = torrent_info
            torrent_handle = torrent_session.add_torrent(torrent_descr)

    piece_par_ref0 = reference()

    piece_server0 = piece_server()
    piece_server0.torrent_handle = torrent_handle
    piece_server0.torrent_info = torrent_info
    piece_server0.init()

    alert_client0 = alert_client()
    alert_client0.torrent_session = torrent_session
    alert_client0.torrent_handle = torrent_handle
    alert_client0.piece_server = piece_server0
    alert_client0.start()

    r = torrent_read_bt2p()
    r.torrent_handle = torrent_handle
    r.torrent_info = torrent_info
    #r.init()

    http_server = http_server_bt2p((options["domain-name"], options["port"]),
                                   http_responder_bt2p)
    http_server.daemon_threads = True
    http_server.torrent = r
    http_server.piece_server = piece_server0

    http_responder_bt2p.torrent_session = torrent_session
    http_responder_bt2p.torrent_handle = torrent_handle
    http_responder_bt2p.delete_files = options["delete-files"]
    http_responder_bt2p.http_server = http_server
    try:
        http_server.serve_forever()
    except KeyboardInterrupt:
        print("An exception occurred")
Ejemplo n.º 25
0
    def magnet_to_torrent(self, magnet_uri, destination_folder, timeout, num_try, use_dht, http_proxy):
        import libtorrent as lt

        # parameters
        params = lt.parse_magnet_uri(magnet_uri)

        # prevent downloading
        # https://stackoverflow.com/q/45680113
        if isinstance(params, dict):
            params['flags'] |= lt.add_torrent_params_flags_t.flag_upload_mode
        else:
            params.flags |= lt.add_torrent_params_flags_t.flag_upload_mode
        
        lt_version = [int(v) for v in lt.version.split('.')]
        if [0, 16, 13, 0] < lt_version < [1, 1, 3, 0]:
            # for some reason the info_hash needs to be bytes but it's a struct called sha1_hash
            if isinstance(params, dict):
                params['info_hash'] = params['info_hash'].to_bytes()
            else:
                params.info_hash = params.info_hash.to_bytes()

        # add_trackers - currently always append
        try:
            if isinstance(params, dict):
                params['trackers'] += self.trackers
            else:
                params.trackers += self.trackers
        except Exception as e:
            logger.debug('Failed to add trackers: {}', str(e))

        # session from setting pack
        settings = {
            # basics
            # 'user_agent': 'libtorrent/' + lt.__version__,
            'listen_interfaces': '0.0.0.0:6881',
            # dht
            'enable_dht': use_dht,
            'use_dht_as_fallback': True,
            'dht_bootstrap_nodes': 'router.bittorrent.com:6881,dht.transmissionbt.com:6881,router.utorrent.com:6881,127.0.0.1:6881',
            'enable_lsd': False,
            'enable_upnp': True,
            'enable_natpmp': True,
            'announce_to_all_tiers': True,
            'announce_to_all_trackers': True,
            'aio_threads': 4*2,
            'checking_mem_usage': 1024*2,
        }
        if http_proxy:
            # TODO: TEST http_proxy
            proxy_url = urlparse(http_proxy)
            logger.debug(proxy_url)
            settings.update({
                'proxy_username': proxy_url.username,
                'proxy_password': proxy_url.password,
                'proxy_hostname': proxy_url.hostname,
                'proxy_port': proxy_url.port,
                'proxy_type': lt.proxy_type_t.http_pw if proxy_url.username and proxy_url.password else lt.proxy_type_t.http,
                'force_proxy': True,
                'anonymous_mode': True,
            })
        session = lt.session(settings)

        # session.add_extension('ut_metadata')
        # session.add_extension('ut_pex')
        # session.add_extension('metadata_transfer')

        # handle
        handle = session.add_torrent(params)

        if use_dht:
            handle.force_dht_announce()

        logger.debug('Acquiring torrent metadata for magnet {}', magnet_uri)
        
        max_try = max(num_try, 1)
        for tryid in range(max_try):
            timeout_value = timeout
            logger.debug('Trying to get metadata ... {}/{}'.format(tryid+1, max_try))
            while not handle.has_metadata():
                time.sleep(0.1)
                timeout_value -= 0.1
                if timeout_value <= 0:
                    break

            if handle.has_metadata():
                lt_info = handle.get_torrent_info()
                logger.debug('Metadata acquired after {}*{}+{:.1f} seconds', tryid, timeout, timeout - timeout_value)
                break
            else:
                if tryid+1 == max_try:
                    session.remove_torrent(handle, True)
                    raise plugin.PluginError(
                        'Timed out after {}*{} seconds'.format(max_try, timeout)
                    )
    
        # create torrent object
        torrent = lt.create_torrent(lt_info)
        torrent.set_creator('libtorrent v{}'.format(lt.version))    # signature
        torrent_dict = torrent.generate()

        torrent_info = self.convert_torrent_info(lt_info)
        torrent_info.update({
            'trackers': params['trackers'] if isinstance(params, dict) else params.trackers,
            'creation_date': datetime.fromtimestamp(torrent_dict[b'creation date']).isoformat(),
        })
        
        # start scraping
        timeout_value = timeout
        logger.debug('Trying to get peerinfo ... ')
        while handle.status(0).num_complete < 0:
            time.sleep(0.1)
            timeout_value -= 0.1
            if timeout_value <= 0:
                break

        if handle.status(0).num_complete >= 0:
            torrent_status = handle.status(0)
            logger.debug('Peerinfo acquired after {:.1f} seconds', timeout - timeout_value)
            
            torrent_info.update({
                'seeders': torrent_status.num_complete,
                'peers': torrent_status.num_incomplete,
            })
        else:
            raise plugin.PluginError('Timed out after {} seconds'.format(timeout))

        session.remove_torrent(handle, True)

        torrent_path = pathscrub(
            os.path.join(destination_folder, lt_info.name() + ".torrent")
        )
        with open(torrent_path, "wb") as f:
            f.write(lt.bencode(torrent_dict))
        logger.debug('Torrent file wrote to {}', torrent_path)

        return torrent_path, torrent_info
Ejemplo n.º 26
0
    def magnet_to_torrent(self, magnet_uri, destination_folder, timeout,
                          num_try):
        import libtorrent

        # parameters
        params = libtorrent.parse_magnet_uri(magnet_uri)

        # prevent downloading
        # https://stackoverflow.com/q/45680113
        params.flags |= libtorrent.add_torrent_params_flags_t.flag_upload_mode

        lt_version = [int(v) for v in libtorrent.version.split('.')]
        if [0, 16, 13, 0] < lt_version < [1, 1, 3, 0]:
            # for some reason the info_hash needs to be bytes but it's a struct called sha1_hash
            params.info_hash = params.info_hash.to_bytes()

        # add_trackers
        if len(params.trackers) == 0:
            try:
                import random
                params.trackers = random.sample(self.trackers, 5)
            except Exception as e:
                logger.debug('Failed to add trackers: {}', str(e))

        # session
        session = libtorrent.session()

        session.listen_on(6881, 6891)

        session.add_extension('ut_metadata')
        session.add_extension('ut_pex')
        session.add_extension('metadata_transfer')

        session.add_dht_router('router.utorrent.com', 6881)
        session.add_dht_router('router.bittorrent.com', 6881)
        session.add_dht_router("dht.transmissionbt.com", 6881)
        session.add_dht_router('127.0.0.1', 6881)
        session.start_dht()

        # handle
        handle = session.add_torrent(params)
        handle.force_dht_announce()
        logger.debug('Acquiring torrent metadata for magnet {}', magnet_uri)

        for tryid in range(max(num_try, 1)):
            timeout_value = timeout
            while not handle.has_metadata():
                time.sleep(0.1)
                timeout_value -= 0.1
                if timeout_value <= 0:
                    logger.debug(
                        'Failed to get metadata on trial: {}/{}'.format(
                            tryid + 1, num_try))
                    break

            if handle.has_metadata():
                logger.debug(
                    'Metadata acquired after {} seconds on trial {}'.format(
                        timeout - timeout_value, tryid + 1))
                break
            else:
                if tryid + 1 == max(num_try, 1):
                    session.remove_torrent(handle, True)
                    raise plugin.PluginError(
                        'Timed out after {}x{} seconds trying to magnetize'.
                        format(timeout, num_try))

        torrent_info = handle.get_torrent_info()
        torrent_file = libtorrent.create_torrent(torrent_info)
        torrent_path = pathscrub(
            os.path.join(destination_folder,
                         torrent_info.name() + ".torrent"))
        with open(torrent_path, "wb") as f:
            f.write(libtorrent.bencode(torrent_file.generate()))
        logger.debug('Torrent file wrote to {}', torrent_path)
        return torrent_path
Ejemplo n.º 27
0
def magnet2torrent(magnet):
    tempdir = tempfile.mkdtemp()
    ses = lt.session()
    torrent_data = {}

    def clean_up_before_abort(abort_message):
        print(abort_message)
        ses.pause()
        print("Cleanup dir " + tempdir)
        shutil.rmtree(tempdir)

    params = {
        'save_path': tempdir,
        'storage_mode': lt.storage_mode_t(2),
        'paused': False,
        'auto_managed': True,
        'duplicate_is_error': True
    }

    magnet_info = lt.parse_magnet_uri(magnet)
    torrent_data['trackers'] = magnet_info['trackers']
    torrent_data['info_hash'] = magnet_info['info_hash']
    torrent_name = magnet_info['name']

    handle = lt.add_magnet_uri(ses, magnet, params)

    try:
        print("{0}: ".format(torrent_name))
        print("Downloading Metadata (this may take a while)")

        time_spent_converting = 0
        while (not handle.has_metadata()):
            if time_spent_converting >= TORRENT_CREATE_TIMEOUT:
                clean_up_before_abort(
                    "Failed to convert magent link -- aborting")
                return None
            sleep(1)
            time_spent_converting += 1

        torinfo = handle.get_torrent_info()
        info_list = [
            'name', 'total_size', 'piece_length', 'num_pieces', 'num_files',
            'metadata_size'
        ]
        for info_name in info_list:
            torrent_data[info_name] = getattr(torinfo, info_name)()

        print("Done downloading meta data")
        print("Starting to download torrent ...")

        handle.set_upload_limit(0)  #DO NOT UPLOAD ANYTHING

        peer_info_list = {}

        def update_ip_results(peer_list):
            for peer in peer_list:
                if peer.ip in peer_info_list:
                    peer_in_hash = peer_info_list[peer.ip]
                    peer_in_hash['up_speed'] = max(peer_in_hash['up_speed'],
                                                   peer.up_speed)
                    peer_in_hash['down_speed'] = max(
                        peer_in_hash['down_speed'], peer.down_speed)
                else:
                    peer_info_list[peer.ip] = {
                        'up_speed': peer.up_speed,
                        'down_speed': peer.down_speed
                    }

        counter = 0
        while (not handle.is_seed() and counter < TORRENT_DONWLOAD_LOOPS):
            print("counter: {0}".format(counter))
            counter += 1

            peer_list = handle.get_peer_info()
            update_ip_results(peer_list)
            if len(peer_info_list) > NUMBER_OF_PEERS_INFO: break

            sleep(5)

        torrent_data['peer_info'] = [{
            'ip': key,
            'down_speed': value['down_speed'],
            'up_speed': value['up_speed']
        } for key, value in peer_info_list.iteritems()]
    except KeyboardInterrupt:
        clean_up_before_abort('Keyboard Interrupt Triggered')
        return

    print("Downloading stopped as peer data gathered ...")

    print("\nTORRENT INFO: {0} \n".format(torrent_data))
    print("Done info gathered ...\n\n")
    ses.pause()
    ses.remove_torrent(handle)
    shutil.rmtree(tempdir)

    return torrent_data
Ejemplo n.º 28
0
import libtorrent as lt
import time
import sys
import base64
import binascii

ses = lt.session()
ses.listen_on(6881, 6891)

magnet = lt.parse_magnet_uri(sys.argv[1])
e = str(magnet.info_hash)
if len(e) == 40:
    info_hash = binascii.unhexlify(e)
elif len(e) == 32:
    info_hash = base64.b32decode(e)
else:
    raise Exception("Unable to parse infohash")

trackers = magnet.trackers
h = ses.add_torrent({'info_hash': info_hash, 'trackers': trackers})
dots=0
while not h.has_metadata():
    dots += 1
    sys.stdout.write('.')
    sys.stdout.flush()
    time.sleep(1)
if (dots): sys.stdout.write('\n')
ses.pause()
tinf = h.get_torrent_info()
f = open('/tmp/b2pgen' + '.torrent', 'wb')
f.write(lt.bencode(
Ejemplo n.º 29
0
    def parse_magnet_uri(
        self,
        magnet_uri,
        scrape=None,
        use_dht=None,
        timeout=None,
        trackers=None,
        no_cache=None,
        n_try=None,
        to_torrent=None,
        http_proxy=None,
    ):
        try:
            import libtorrent as lt
        except ImportError as _e:
            raise ImportError("libtorrent package required") from _e

        # default function arguments from db
        if scrape is None:
            scrape = ModelSetting.get_bool("scrape")
        if use_dht is None:
            use_dht = ModelSetting.get_bool("use_dht")
        if timeout is None:
            timeout = ModelSetting.get_int("timeout")
        if trackers is None:
            trackers = json.loads(ModelSetting.get("trackers"))
        if n_try is None:
            n_try = ModelSetting.get_int("n_try")
        if no_cache is None:
            no_cache = False
        if to_torrent is None:
            to_torrent = False
        if http_proxy is None:
            http_proxy = ModelSetting.get("http_proxy")

        # parameters
        params = lt.parse_magnet_uri(magnet_uri)

        # prevent downloading
        # https://stackoverflow.com/q/45680113
        if isinstance(params, dict):
            params["flags"] |= lt.add_torrent_params_flags_t.flag_upload_mode
        else:
            params.flags |= lt.add_torrent_params_flags_t.flag_upload_mode

        lt_version = [int(v) for v in lt.version.split(".")]
        if [0, 16, 13, 0] < lt_version < [1, 1, 3, 0]:
            # for some reason the info_hash needs to be bytes but it's a struct called sha1_hash
            if isinstance(params, dict):
                params["info_hash"] = params["info_hash"].to_bytes()
            else:
                params.info_hash = params.info_hash.to_bytes()

        # 캐시에 있으면...
        info_hash_from_magnet = str(params["info_hash"] if isinstance(params, dict) else params.info_hash)
        self.cache_init()
        if (not no_cache) and (info_hash_from_magnet in self.torrent_cache):
            return self.torrent_cache[info_hash_from_magnet]["info"]

        # add trackers
        if isinstance(params, dict):
            if len(params["trackers"]) == 0:
                params["trackers"] = trackers
        else:
            if len(params.trackers) == 0:
                params.trackers = trackers

        # session
        settings = {
            # basics
            # 'user_agent': 'libtorrent/' + lt.__version__,
            "listen_interfaces": "0.0.0.0:6881",
            # dht
            "enable_dht": use_dht,
            "use_dht_as_fallback": True,
            "dht_bootstrap_nodes": "router.bittorrent.com:6881,dht.transmissionbt.com:6881,router.utorrent.com:6881,127.0.0.1:6881",
            "enable_lsd": False,
            "enable_upnp": True,
            "enable_natpmp": True,
            "announce_to_all_tiers": True,
            "announce_to_all_trackers": True,
            "aio_threads": 4 * 2,
            "checking_mem_usage": 1024 * 2,
        }
        if http_proxy:
            proxy_url = urlparse(http_proxy)
            settings.update(
                {
                    "proxy_username": proxy_url.username,
                    "proxy_password": proxy_url.password,
                    "proxy_hostname": proxy_url.hostname,
                    "proxy_port": proxy_url.port,
                    "proxy_type": lt.proxy_type_t.http_pw
                    if proxy_url.username and proxy_url.password
                    else lt.proxy_type_t.http,
                    "force_proxy": True,
                    "anonymous_mode": True,
                }
            )
        session = lt.session(settings)

        session.add_extension("ut_metadata")
        session.add_extension("ut_pex")
        session.add_extension("metadata_transfer")

        # handle
        handle = session.add_torrent(params)

        if use_dht:
            handle.force_dht_announce()

        max_try = max(n_try, 1)
        for tryid in range(max_try):
            timeout_value = timeout
            logger.debug("Trying to get metadata... %d/%d", tryid + 1, max_try)
            while not handle.has_metadata():
                time.sleep(0.1)
                timeout_value -= 0.1
                if timeout_value <= 0:
                    break

            if handle.has_metadata():
                lt_info = handle.get_torrent_info()
                logger.debug(
                    "Successfully got metadata after %d*%d+%.2f seconds", tryid, timeout, timeout - timeout_value
                )
                time_metadata = tryid * timeout + (timeout - timeout_value)
                break
            if tryid + 1 == max_try:
                session.remove_torrent(handle, True)
                raise Exception(f"Timed out after {max_try}*{timeout} seconds")

        # create torrent object and generate file stream
        torrent = lt.create_torrent(lt_info)
        torrent.set_creator(f"libtorrent v{lt.version}")  # signature
        torrent_dict = torrent.generate()

        torrent_info = self.convert_torrent_info(lt_info)
        torrent_info.update(
            {
                "trackers": params.trackers if not isinstance(params, dict) else params["trackers"],
                "creation_date": datetime.fromtimestamp(torrent_dict[b"creation date"]).isoformat(),
                "time": {"total": time_metadata, "metadata": time_metadata},
            }
        )

        if scrape:
            # start scraping
            for tryid in range(max_try):
                timeout_value = timeout
                logger.debug("Trying to get peerinfo... %d/%d", tryid + 1, max_try)
                while handle.status(0).num_complete < 0:
                    time.sleep(0.1)
                    timeout_value -= 0.1
                    if timeout_value <= 0:
                        break

                if handle.status(0).num_complete >= 0:
                    torrent_status = handle.status(0)
                    logger.debug(
                        "Successfully got peerinfo after %d*%d+%.2f seconds", tryid, timeout, timeout - timeout_value
                    )
                    time_scrape = tryid * timeout + (timeout - timeout_value)

                    torrent_info.update(
                        {
                            "seeders": torrent_status.num_complete,
                            "peers": torrent_status.num_incomplete,
                        }
                    )
                    torrent_info["time"]["scrape"] = time_scrape
                    torrent_info["time"]["total"] = torrent_info["time"]["metadata"] + torrent_info["time"]["scrape"]
                    break
                if tryid + 1 == max_try:
                    logger.error("Timed out after %d*%d seconds", max_try, timeout)

        session.remove_torrent(handle, True)

        # caching for later use
        self.torrent_cache[torrent_info["info_hash"]] = {
            "info": torrent_info,
        }
        if to_torrent:
            return lt.bencode(torrent_dict), pathscrub(lt_info.name(), os="windows", filename=True)
        return torrent_info
Ejemplo n.º 30
0
def handle_request(clientsock, addr):

    data = clientsock.recv(RECV_BUFSIZ)

    #Log('Request received: %s' % data)

    request = parse_http_request(data)

    path = STATIC_FILES_DIR + clean_path(request.request_uri)
    request_uri = request.request_uri[1:]
    if request_uri.startswith("_omx"):
        req = request_uri.split("/")
        cmd = req[1]
        if cmd == "play":
            omxplayer.reset_tv()
            link = ("/").join(req[2:])
            path = STATIC_FILES_DIR + "/" + clean_path(req[2])
            print path
            if os.path.isdir(path):
                link = "http://localhost/" + link
                playing_video = omxplayer.omxplayer(str(link))
            elif link.split(".").pop() in omxplayer.FORMATS:
                playing_video = omxplayer.omxplayer(str(link))
            elif link.split(".").pop() in omxplayer.FBI_FORMATS:
                shown_image = omxplayer.image(str(link))
            elif link.split(".").pop() in ["pdf"]:
                shown_pdf = omxplayer.pdf(str(link))
            else:
                link = omxplayer.ytdl(link)
                playing_video = omxplayer.omxplayer(str(link))
            response = HttpResponse(protocol=request.protocol, status_code=200)
            response.write_to(clientsock)
            clientsock.close()

    # if request_uri.startswith("magnet") or request_uri.endswith(".torrent") or request_uri.startswith(atp["static_path"]):
    if request_uri.startswith("magnet") or request_uri.endswith(".torrent"):
        chosen_file = None
        torrent = atp

        print "req uri:" + request_uri
        if request_uri.startswith("magnet"):
            info_hash = libtorrent.parse_magnet_uri(request_uri)["info_hash"]
        elif request_uri.startswith(atp["static_path"]):
            chosen_file = urllib.unquote("/".join(request_uri.split("/")[2:]))
            print "chosen file:" + chosen_file
            request_uri = "magnet:?xt=urn:btih:" + request_uri.split("/")[1]
            info_hash = libtorrent.parse_magnet_uri(request_uri)["info_hash"]
        elif request_uri.endswith(".torrent"):

            #get info hash
            pass
        handle = torrent_session.find_torrent(info_hash)

        if handle.is_valid():
            print "Magnet already in the session"
            torrent_handle = handle
        elif (str(info_hash) + ".resume") in os.listdir("resume"):
            torrent["resume_data"] = io.open(
                "resume/" + str(info_hash) + ".resume", "rb").read()
            torrent_handle = torrent_session.add_torrent(torrent)
        else:
            print " start new torrrent"
            torrent["url"] = request_uri
            # torrent["paused"]=True
            torrent["save_path"] = os.path.join(TORRENTS_DIR, str(info_hash))
            torrent_handle = torrent_session.add_torrent(torrent)
            print "getting metadata"
            while not torrent_handle.has_metadata():
                sleep(1)
        print "getting info"
        info = torrent_handle.get_torrent_info()
        torrent_files = info.files()
        torrent_handle.auto_managed(False)
        if chosen_file is not None:
            for i, file_info in enumerate(torrent_files):
                print "path:", file_info.path
                if chosen_file == file_info.path:

                    torrent_handle.file_priority(i, 1)
                    file_index = i
                else:
                    torrent_handle.file_priority(i, 0)

            file = get_torrent_file(torrent_handle, file_index)

            if file.exists and request.is_range_requested():
                response = HttpResponse(protocol=request.protocol,
                                        status_code=206,
                                        range=request.get_range())
                response.file = file

            elif file.exists:
                response = HttpResponse(protocol=request.protocol,
                                        status_code=200)
                response.file = file
                Log('%s GET "%s" %s %s %s' %
                    (addr[0], request.request_uri, request.protocol,
                     request.get_range(), response.status_code))

                response.write_to(clientsock)
                clientsock.close()

        info = torrent_handle.get_torrent_info()
        name = info.name()
        # f = str()
        # f += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'
        # f += "<html>\n<title>Directory listing for %s</title>\n" % name
        # f +="<body>\n<h2>Directory listing for %s</h2>\n" % name
        # f += "<hr>\n<ul>\n"
        f = {}
        for i, file_info in enumerate(torrent_files):
            f[i] = {
                "link":
                "/" + os.path.join(atp["static_path"], str(info_hash),
                                   file_info.path),
                "size":
                file_info.size,
                "path":
                file_info.path
            }
            # f += '<li><a href="%s">%s</a><h6>%s</h6></li>\n' % (os.path.join(atp["static_path"],str(info_hash),file_info.path), file_info.path,file_info.size)
        # f += "</ul>\n<hr>\n</body>\n</html>\n"
        f = json.dumps(f)
        response = HttpResponse(protocol=request.protocol, status_code=200)
        response.headers['Content-type'] = 'application/json'
        response.headers['Content-Length'] = len(f)
        # response.headers['Accept-Ranges'] = 'bytes'
        response.content = f
        Log('%s GET "%s" %s %s %s' %
            (addr[0], request.request_uri, request.protocol,
             request.get_range(), response.status_code))
        response.write_to(clientsock)
        clientsock.close()
        return None

        # h.set_sequential_download(True)
        # while h.status().progress < 0.01:
        #     sleep(1)
        # h.file_index=max_i
        # h.offset=max_offset

    # check if path is dir (copy from the SimpleHttpServer)
    path = STATIC_FILES_DIR + clean_path(request.request_uri)
    if os.path.isdir(path):
        print path
        if not path.endswith('/'):
            # redirect browser - doing basically what apache does
            response = HttpResponse(protocol=request.protocol, status_code=301)
            response.headers['Location'] = path + "/"
            Log('%s GET "%s" %s %s %s' %
                (addr[0], request.request_uri, request.protocol,
                 request.get_range(), response.status_code))
            response.write_to(clientsock)
            clientsock.close()
            return None
        for index in "index.html", "index.htm":
            index = os.path.join(path, index)
            if os.path.exists(index):
                path = index
                break
        else:
            # quick and dirty but it works :P (also copy from SimpleHttpServer)
            try:
                list = os.listdir(path)
            except os.error:
                response = HttpResponse(protocol=request.protocol,
                                        status_code=404)
                response.headers['Content-type'] = 'text/plain'
                response.content = 'No permission to list directory'
                Log('%s GET "%s" %s %s %s' %
                    (addr[0], request.request_uri, request.protocol,
                     request.get_range(), response.status_code))
                response.write_to(clientsock)
                clientsock.close()
                return None
            list.sort(key=lambda a: a.lower())
            f = str()
            displaypath = cgi.escape(urllib.unquote(request.request_uri))
            # f += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'
            # f += "<html>\n<title>Directory listing for %s</title>\n" % displaypath
            # f +="<body>\n<h2>Directory listing for %s</h2>\n" % displaypath
            f += "<hr>\n<ul>\n"
            for name in list:
                fullname = os.path.join(path, name)
                displayname = linkname = name
                # Append / for directories or @ for symbolic links
                if os.path.isdir(fullname):
                    displayname = name + "/"
                    linkname = name + "/"
                if os.path.islink(fullname):
                    displayname = name + "/"  # "@"
                    # Note: a link to a directory displays with @ and links with /
                f += '<li><a href="%s">%s</a>\n' % (urllib.quote(linkname),
                                                    cgi.escape(displayname))
            f += "</ul>\n<hr>\n</body>\n</html>\n"
            response = HttpResponse(protocol=request.protocol, status_code=200)
            response.headers['Content-type'] = 'text/html'
            response.headers['Content-Length'] = len(f)
            response.headers['Accept-Ranges'] = 'bytes'
            response.content = f
            Log('%s GET "%s" %s %s %s' %
                (addr[0], request.request_uri, request.protocol,
                 request.get_range(), response.status_code))
            response.write_to(clientsock)
            clientsock.close()
            return None
    print urllib.unquote(request.request_uri)[1:]

    file = get_file(path)

    if file.exists and request.is_range_requested():
        response = HttpResponse(protocol=request.protocol,
                                status_code=206,
                                range=request.get_range())
        response.headers["Content-Type"] = file.mime_type
        response.headers["Connection"] = "Keep-Alive"
        response.file = file

    elif file.exists:
        response = HttpResponse(protocol=request.protocol, status_code=200)
        response.file = file

    else:
        response = HttpResponse(protocol=request.protocol, status_code=404)
        response.headers['Content-type'] = 'text/plain'
        response.content = 'This file does not exist!'

    Log('%s GET "%s" %s %s %s' %
        (addr[0], request.request_uri, request.protocol, request.get_range(),
         response.status_code))

    response.write_to(clientsock)
    clientsock.close()
Ejemplo n.º 31
0
def api_upload(magnet_url_or_hash=None):
	"""
	<h5>Description:</h5>
	<p>
		Adds a new torrent to the system and retrieves its data if its not already in the system.
		Note: If the torrent is added via a SHA-1 info_hash, a magnet link is constructed and we attempt to retrieve the torrent via DHT		
	</p>

	<h5>Parameters:</h5>
	<ul>
		<li><strong>magnet_url_or_hash</strong> - A magnet link, a HTTP url to the .torrent file, or a SHA-1 info_hash. Can also be the base64 encoding of a binary .torrent file</li>
	</ul>

	<h5>Returns:</h5>
	<p>
		If successful, a data structure like so:
<pre>
{
    "data": {
        "url": "(the contents of the url_magnet_or_hash parameter)",
        "added": true,
        "hash": "a4b93e50187930206dcf1351bceceb29f5a119ca"
    },
    "success": true
}
</pre>
		If an error occured, the following data structure will be returned:
<pre>
{
    "message": "Cannot recognise this url: foo",
    "success": false
}
</pre>
	</p>

	<h5>Examples:</h5>
	<p>
		Add based on a magnet link:<br />
		<pre>/api/upload/magnet%3A%3Fxt%3Durn%3Abtih%3Addceab34ac388ca56b0cdbc6eb726ca1844233c5%26dn%3DPioneer%2BOne%2BS01E03%2BXvid-VODO%26tr%3Dudp%253A%252F%252Ftracker.openbittorrent.com%253A80%26tr%3Dudp%253A%252F%252Ftracker.publicbt.com%253A80%26tr%3Dudp%253A%252F%252Ftracker.istole.it%253A6969%26tr%3Dudp%253A%252F%252Ftracker.ccc.de%253A80</pre>
		
		Add based on a HTTP url:<br />
		<pre>/api/upload/http%3A%2F%2Ftorrents.thepiratebay.se%2F6753216%2FPioneer_One_S01E03_Xvid-VODO.6753216.TPB.torrent</pre>
		
		Add based on a SHA-1 info_hash:<br />
		<pre>/api/upload/ddceab34ac388ca56b0cdbc6eb726ca1844233c5</pre>
	</p>
	"""
	url = magnet_url_or_hash if magnet_url_or_hash else request.params.get("magnet_url_or_hash")
	if not url:
		return api_error("No magnet, url or hash supplied")	
	item = url.strip()
	info_hash = "";
	try :
		if is_hash(item):
			info_hash = item;			
			if not is_in_database(item):
				add_to_database(item)
		elif is_base64(item):
			decoded = base64.b64decode(item)
			info = lt.torrent_info(lt.bdecode(decoded))
			info_hash = "%s" % info.info_hash()
			if not is_in_database(info_hash):
				add_to_database(info_hash, fetch_metadata=False)
				thread.start_new_thread(add_from_torrent_info, (info, torrent_data))			
		elif is_magnet(item):			
			params = lt.parse_magnet_uri(item)			
			info_hash = str(params["info_hash"])
			if not info_hash.replace("0", ""):
				raise RuntimeError("The hash was all 0's, did you urlencode the magnet link properly?")
			else:
				if not is_in_database(info_hash):
					add_to_database(info_hash, item)
		elif is_url(item):
			item = urllib.unquote_plus(item)
			logger.debug("Fetching %s" % item)			
			download_to = tempfile.mkstemp(suffix=".torrent")[1]				
			urllib.urlretrieve(item, download_to)
			handle = open(download_to, "rb");
			torrent_data = handle.read()
			info = lt.torrent_info(lt.bdecode(torrent_data))
			handle.close()
			os.remove(download_to)
			info_hash = "%s" % info.info_hash()
			if not is_in_database(info_hash):
				add_to_database(info_hash, fetch_metadata=False)
				thread.start_new_thread(add_from_torrent_info, (info, torrent_data))			
		else:
			raise RuntimeError("Cannot recognise this url: %s" % item)
	except (RuntimeError, IOError) as e:
		return api_error(str(e))
	
	return api_success({ "url" : item, "hash" : info_hash, "added" : True})
Ejemplo n.º 32
0
def get_file(fn):
    # request_uri = fn.split("/",1)[-1]
    fsize = None
    exists = False
    mime_type = ''

    request_uri=fn.replace(STATIC_FILES_DIR+"/","")
    print request_uri
    if request_uri.startswith(atp["static_path"]):
        torrent=atp
        chosen_file="/".join(request_uri.split("/")[2:])
        print "chosen file:"+chosen_file
        url="magnet:?xt=urn:btih:"+request_uri.split("/")[1]
        info_hash=libtorrent.parse_magnet_uri(url)["info_hash"]
        handle=torrent_session.find_torrent(info_hash)
        # print str(info_hash)+".resume", os.listdir("resume")
        if handle.is_valid():
            print "Magnet already in the session"
            torrent_handle=handle
        # elif str(info_hash)+".resume" in os.listdir("resume"):
        #     torrent["resume_data"] = io.open("resume/"+str(info_hash)+".resume", "rb").read()
        #     torrent_handle = torrent_session.add_torrent(torrent)
        else:
            print " start new torrent"
            torrent["url"]=url
            torrent["save_path"]=os.path.join(TORRENTS_DIR,str(info_hash))
            # torrent["paused"]=True
            torrent_handle = torrent_session.add_torrent(torrent)
            while not torrent_handle.has_metadata():
                sleep(0.5)  

        info=torrent_handle.get_torrent_info()        
        torrent_files=info.files()
        # torrent_handle.auto_managed(False)    
        if chosen_file is not None:
            for i,file_info in enumerate(torrent_files):
                print "path:",file_info.path 
                if chosen_file == file_info.path:
                    torrent_handle.file_priority(i,1)
                    torrent_file=file_info
                    file_index=i
                else:
                    torrent_handle.file_priority(i,0)
        torrent_handle.map_piece = lambda offset: info.map_file(file_index, offset, 1)
        
        path=os.path.join(TORRENTS_DIR,torrent_file.path)
        first_byte=torrent_file.offset
        last_byte=torrent_file.offset+torrent_file.size
        torrent_handle.set_sequential_download(True)   
        first_piece=torrent_handle.map_piece(first_byte).piece
        last_piece=torrent_handle.map_piece(last_byte).piece
        num_pieces=info.num_pieces()
        future_pieces=int((last_piece-first_piece)*0.01)
        print "offset",torrent_file.offset,"piece",first_piece,"total", num_pieces
        piece_priorities=first_piece*[0]+(num_pieces-first_piece)*[1]
        piece_priorities=piece_priorities[:num_pieces]
        # piece_priorities=first_piece*[0]+future_pieces*[7]+more_pieces*[1]+(num_pieces-first_piece-future_pieces-more_pieces)*[0]
        torrent_handle.prioritize_pieces(piece_priorities)
        # torrent_handle.prioritize_pieces(num_pieces*[0])
        # torrent_handle.piece_priority(first_piece,7)
        torrent_handle.piece_priority(last_piece,7)
        torrent_handle.piece_priority(last_piece-1,7)
        # torrent_handle.num_pieces=info.num_pieces()
        piece=first_piece
        waiting=True


        while waiting:
            sleep(1)
            # if torrent_handle.have_piece(first_piece) and torrent_handle.have_piece(last_piece):
            #     waiting =False
            status=torrent_handle.status()
            pieces=status.pieces
            print pieces[piece:piece+future_pieces],last_piece  ,pieces[last_piece-1] , status.progress,status.download_rate,status.state
            if pieces[piece:piece+future_pieces] == future_pieces*[True] and pieces[last_piece-1]:
                waiting=False
        print "first and last piece received"
        # torrent_handle.prioritize_pieces(num_pieces*[1])
    else:
        torrent_handle=None    
    try:
        fsize = os.path.getsize(fn)
        exists = True
        type, encoding = mimetypes.guess_type(request_uri)
        if type:
            mime_type = type
    except:
        pass

    return File(request_uri, fn, fsize, exists, mime_type,torrent_handle)
Ejemplo n.º 33
0
    def parse_magnet_uri(magnet_uri,
                         scrape=False,
                         use_dht=True,
                         force_dht=False,
                         timeout=10,
                         trackers=None,
                         no_cache=False,
                         n_try=3):
        try:
            import libtorrent as lt
        except ImportError:
            raise ImportError('libtorrent package required')

        # parameters
        params = lt.parse_magnet_uri(magnet_uri)

        # prevent downloading
        # https://stackoverflow.com/q/45680113
        if isinstance(params, dict):
            params['flags'] |= lt.add_torrent_params_flags_t.flag_upload_mode
        else:
            params.flags |= lt.add_torrent_params_flags_t.flag_upload_mode

        lt_version = [int(v) for v in lt.version.split('.')]
        if [0, 16, 13, 0] < lt_version < [1, 1, 3, 0]:
            # for some reason the info_hash needs to be bytes but it's a struct called sha1_hash
            if type({}) == type(params):
                params['info_hash'] = params['info_hash'].to_bytes()
            else:
                params.info_hash = params.info_hash.to_bytes()

        # 캐시에 있으면 ...
        info_hash_from_magnet = str(params['info_hash'] if type({}) ==
                                    type(params) else params.info_hash)
        if (not no_cache) and (info_hash_from_magnet in Logic.torrent_cache):
            return Logic.torrent_cache[info_hash_from_magnet]['info']

        # add trackers
        if type({}) == type(params):
            if len(params['trackers']) == 0:
                if trackers is None:
                    trackers = json.loads(ModelSetting.get('trackers'))
                params['trackers'] = random.sample(trackers, 5)
        else:
            if len(params.trackers) == 0:
                if trackers is None:
                    trackers = json.loads(ModelSetting.get('trackers'))
                params.trackers = random.sample(trackers, 5)

        # session
        session = lt.session()

        session.listen_on(6881, 6891)

        session.add_extension('ut_metadata')
        session.add_extension('ut_pex')
        session.add_extension('metadata_transfer')

        if use_dht:
            session.add_dht_router('router.utorrent.com', 6881)
            session.add_dht_router('router.bittorrent.com', 6881)
            session.add_dht_router("dht.transmissionbt.com", 6881)
            session.add_dht_router('127.0.0.1', 6881)
            session.start_dht()

        # handle
        handle = session.add_torrent(params)

        if force_dht:
            handle.force_dht_announce()

        for tryid in range(max(n_try, 1)):
            timeout_value = timeout
            while not handle.has_metadata():
                time.sleep(0.1)
                timeout_value -= 0.1
                if timeout_value <= 0:
                    logger.debug(
                        'Failed to get metadata on trial: {}/{}'.format(
                            tryid + 1, n_try))
                    break

            if handle.has_metadata():
                lt_info = handle.get_torrent_info()
                logger.debug(
                    'Successfully get metadata after {} seconds on trial {}'.
                    format(timeout - timeout_value, tryid + 1))
                break
            else:
                if tryid + 1 == max(n_try, 1):
                    session.remove_torrent(handle, True)
                    raise Exception(
                        'Timed out after {}x{} seconds trying to get metainfo'.
                        format(timeout, n_try))

        # create torrent object and generate file stream
        torrent = lt.create_torrent(lt_info)
        torrent.set_creator('libtorrent v{}'.format(lt.version))  # signature
        torrent_dict = torrent.generate()

        torrent_info = Logic.convert_torrent_info(lt_info)
        torrent_info.update({
            'trackers':
            params.trackers
            if type({}) != type(params) else params['trackers'],
            'creation_date':
            datetime.fromtimestamp(torrent_dict[b'creation date']).isoformat(),
            'time': {
                'total': timeout - timeout_value,
                'metadata': timeout - timeout_value
            },
        })

        if scrape:
            # start scraping
            timeout_value = timeout
            while handle.status(0).num_complete < 0:
                time.sleep(0.1)
                timeout_value -= 0.1
                if timeout_value <= 0:
                    logger.error(
                        'Timed out after {} seconds trying to get peer info'.
                        format(timeout))

            if handle.status(0).num_complete >= 0:
                torrent_status = handle.status(0)

                torrent_info.update({
                    'seeders': torrent_status.num_complete,
                    'peers': torrent_status.num_incomplete,
                })
                torrent_info['time']['scrape'] = timeout - timeout_value
                torrent_info['time']['total'] = torrent_info['time'][
                    'metadata'] + torrent_info['time']['scrape']

        session.remove_torrent(handle, True)

        # caching for later use
        if Logic.torrent_cache is None:
            Logic.cache_init()
        Logic.torrent_cache[torrent_info['info_hash']] = {
            'info': torrent_info,
        }
        return torrent_info
Ejemplo n.º 34
0
 def test_parse_to_atp_error(self) -> None:
     with self.assertRaises(RuntimeError):
         lt.parse_magnet_uri("magnet:?")
Ejemplo n.º 35
0
 def test_parse_to_atp(self) -> None:
     uri = f"magnet:?xt=urn:btih:{self.info_hash_sha1}"
     atp = lt.parse_magnet_uri(uri)
     self.assertEqual(str(atp.info_hash).lower(), self.info_hash_sha1)
Ejemplo n.º 36
0
def handle_request(clientsock, addr):

    data = clientsock.recv(RECV_BUFSIZ)

    #Log('Request received: %s' % data)

    request = parse_http_request(data)

    path = STATIC_FILES_DIR + clean_path(request.request_uri)
    request_uri=request.request_uri[1:]
    if request_uri.startswith("_omx"):
        req=request_uri.split("/")
        cmd=req[1]
        if cmd=="play":
            omxplayer.reset_tv()
            link=("/").join(req[2:])
            path=STATIC_FILES_DIR + "/"+clean_path(req[2])
            print path
            if os.path.isdir(path):
                link= "http://localhost/"+link
                playing_video=omxplayer.omxplayer(str(link))
            elif link.split(".").pop()  in omxplayer.FORMATS:
                playing_video=omxplayer.omxplayer(str(link))
            elif link.split(".").pop()  in omxplayer.FBI_FORMATS:
                shown_image= omxplayer.image(str(link))
            elif link.split(".").pop() in ["pdf"]:
                shown_pdf= omxplayer.pdf(str(link))
            else:
                link=omxplayer.ytdl(link)  
                playing_video=omxplayer.omxplayer(str(link))
            response = HttpResponse(protocol=request.protocol, status_code=200)
            response.write_to(clientsock)
            clientsock.close()


    # if request_uri.startswith("magnet") or request_uri.endswith(".torrent") or request_uri.startswith(atp["static_path"]):
    if request_uri.startswith("magnet") or request_uri.endswith(".torrent"):
        chosen_file=None
        torrent=atp
        
        print "req uri:"+request_uri
        if request_uri.startswith("magnet"):
            info_hash=libtorrent.parse_magnet_uri(request_uri)["info_hash"]
        elif request_uri.startswith(atp["static_path"]):
            chosen_file=urllib.unquote("/".join(request_uri.split("/")[2:]))
            print "chosen file:"+chosen_file
            request_uri="magnet:?xt=urn:btih:"+request_uri.split("/")[1]
            info_hash=libtorrent.parse_magnet_uri(request_uri)["info_hash"]
        elif request_uri.endswith(".torrent"):

            #get info hash
            pass
        handle=torrent_session.find_torrent(info_hash)

        if handle.is_valid():
            print "Magnet already in the session"
            torrent_handle=handle 
        elif (str(info_hash)+".resume") in os.listdir("resume"):
            torrent["resume_data"] = io.open("resume/"+str(info_hash)+".resume", "rb").read()
            torrent_handle = torrent_session.add_torrent(torrent)
        else:
            print " start new torrrent"
            torrent["url"]=request_uri
            # torrent["paused"]=True
            torrent["save_path"]=os.path.join(TORRENTS_DIR,str(info_hash))
            torrent_handle = torrent_session.add_torrent(torrent)
            print "getting metadata"
            while not torrent_handle.has_metadata():
                sleep(1)
        print "getting info"       
        info=torrent_handle.get_torrent_info()        
        torrent_files=info.files()
        torrent_handle.auto_managed(False)    
        if chosen_file is not None:
            for i,file_info in enumerate(torrent_files):
                print "path:",file_info.path 
                if chosen_file == file_info.path:

                    torrent_handle.file_priority(i,1)
                    file_index=i
                else:
                    torrent_handle.file_priority(i,0)    

            file = get_torrent_file(torrent_handle,file_index)

            if file.exists and request.is_range_requested():
                response = HttpResponse(protocol=request.protocol, status_code=206,
                                        range=request.get_range())
                response.file = file

            elif file.exists:
                response = HttpResponse(protocol=request.protocol, status_code=200)
                response.file = file
                Log('%s GET "%s" %s %s %s' %
                    (addr[0], request.request_uri, request.protocol, request.get_range(), response.status_code))

                response.write_to(clientsock)
                clientsock.close()    
         
        info=torrent_handle.get_torrent_info()
        name= info.name()
        # f = str()
        # f += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'
        # f += "<html>\n<title>Directory listing for %s</title>\n" % name
        # f +="<body>\n<h2>Directory listing for %s</h2>\n" % name
        # f += "<hr>\n<ul>\n"
        f={}
        for i,file_info in enumerate(torrent_files):
            f[i]={"link":"/"+os.path.join(atp["static_path"],str(info_hash),file_info.path),
                  "size":file_info.size,
                  "path":file_info.path
            }
            # f += '<li><a href="%s">%s</a><h6>%s</h6></li>\n' % (os.path.join(atp["static_path"],str(info_hash),file_info.path), file_info.path,file_info.size)
        # f += "</ul>\n<hr>\n</body>\n</html>\n"
        f=json.dumps(f)
        response = HttpResponse(protocol=request.protocol, status_code=200)
        response.headers['Content-type'] = 'application/json'
        response.headers['Content-Length'] = len(f)
        # response.headers['Accept-Ranges'] = 'bytes'
        response.content = f
        Log('%s GET "%s" %s %s %s' %
            (addr[0], request.request_uri, request.protocol, request.get_range(), response.status_code))
        response.write_to(clientsock)
        clientsock.close()
        return None

      
        
        # h.set_sequential_download(True)
        # while h.status().progress < 0.01:
        #     sleep(1)          
        # h.file_index=max_i  
        # h.offset=max_offset     
    
    # check if path is dir (copy from the SimpleHttpServer)
    path=STATIC_FILES_DIR + clean_path(request.request_uri)
    if os.path.isdir(path):
        print path
        if not path.endswith('/'):
            # redirect browser - doing basically what apache does
            response = HttpResponse(protocol=request.protocol, status_code=301)
            response.headers['Location'] = path + "/"
            Log('%s GET "%s" %s %s %s' %
                (addr[0], request.request_uri, request.protocol, request.get_range(), response.status_code))
            response.write_to(clientsock)
            clientsock.close()
            return None
        for index in "index.html", "index.htm":
            index = os.path.join(path, index)
            if os.path.exists(index):
                path = index
                break
        else:
            # quick and dirty but it works :P (also copy from SimpleHttpServer)
            try:
                list = os.listdir(path)
            except os.error:
                response = HttpResponse(protocol=request.protocol, status_code=404)
                response.headers['Content-type'] = 'text/plain'
                response.content = 'No permission to list directory'
                Log('%s GET "%s" %s %s %s' %
                    (addr[0], request.request_uri, request.protocol, request.get_range(), response.status_code))
                response.write_to(clientsock)
                clientsock.close()
                return None
            list.sort(key=lambda a: a.lower())
            f = str()
            displaypath = cgi.escape(urllib.unquote(request.request_uri))
            # f += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'
            # f += "<html>\n<title>Directory listing for %s</title>\n" % displaypath
            # f +="<body>\n<h2>Directory listing for %s</h2>\n" % displaypath
            f += "<hr>\n<ul>\n"
            for name in list:
                fullname = os.path.join(path, name)
                displayname = linkname = name
                # Append / for directories or @ for symbolic links
                if os.path.isdir(fullname):
                    displayname = name + "/"
                    linkname = name + "/"
                if os.path.islink(fullname):
                    displayname = name + "/" # "@"
                    # Note: a link to a directory displays with @ and links with /
                f += '<li><a href="%s">%s</a>\n' % (urllib.quote(linkname), cgi.escape(displayname))
            f += "</ul>\n<hr>\n</body>\n</html>\n"
            response = HttpResponse(protocol=request.protocol, status_code=200)
            response.headers['Content-type'] = 'text/html'
            response.headers['Content-Length'] = len(f)
            response.headers['Accept-Ranges'] = 'bytes'
            response.content = f
            Log('%s GET "%s" %s %s %s' %
                (addr[0], request.request_uri, request.protocol, request.get_range(), response.status_code))
            response.write_to(clientsock)
            clientsock.close()
            return None
    print urllib.unquote(request.request_uri)[1:]

    file = get_file(path)

    if file.exists and request.is_range_requested():
        response = HttpResponse(protocol=request.protocol, status_code=206,
                                range=request.get_range())
        response.headers["Content-Type"]=file.mime_type
        response.headers["Connection"]="Keep-Alive"
        response.file = file

    elif file.exists:
        response = HttpResponse(protocol=request.protocol, status_code=200)
        response.file = file

    else:
        response = HttpResponse(protocol=request.protocol, status_code=404)
        response.headers['Content-type'] = 'text/plain'
        response.content = 'This file does not exist!'

    Log('%s GET "%s" %s %s %s' %
        (addr[0], request.request_uri, request.protocol, request.get_range(), response.status_code))

    response.write_to(clientsock)
    clientsock.close()