1

J'essaye de convertir des URL d'aimant de torrent en .torrent utilisant le manuscrit de python. Le script python se connecte à dht et attend les méta-données, puis crée un fichier torrent à partir de celui-ci.Pourquoi est-ce que utorrents Magnet to Torrent est plus rapide que mon script Python?

par exemple.

#!/usr/bin/env python 
''' 
Created on Apr 19, 2012 
@author: dan, Faless 

    GNU GENERAL PUBLIC LICENSE - Version 3 

    This program is free software: you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation, either version 3 of the License, or 
    (at your option) any later version. 

    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
    GNU General Public License for more details. 

    You should have received a copy of the GNU General Public License 
    along with this program. If not, see <http://www.gnu.org/licenses/>. 

    http://www.gnu.org/licenses/gpl-3.0.txt 

''' 

import shutil 
import tempfile 
import os.path as pt 
import sys 
import libtorrent as lt 
from time import sleep 


def magnet2torrent(magnet, output_name=None): 
    if output_name and \ 
      not pt.isdir(output_name) and \ 
      not pt.isdir(pt.dirname(pt.abspath(output_name))): 
     print("Invalid output folder: " + pt.dirname(pt.abspath(output_name))) 
     print("") 
     sys.exit(0) 

    tempdir = tempfile.mkdtemp() 
    ses = lt.session() 
    params = { 
     'save_path': tempdir, 
     'duplicate_is_error': True, 
     'storage_mode': lt.storage_mode_t(2), 
     'paused': False, 
     'auto_managed': True, 
     'duplicate_is_error': True 
    } 
    handle = lt.add_magnet_uri(ses, magnet, params) 

    print("Downloading Metadata (this may take a while)") 
    while (not handle.has_metadata()): 
     try: 
      sleep(1) 
     except KeyboardInterrupt: 
      print("Aborting...") 
      ses.pause() 
      print("Cleanup dir " + tempdir) 
      shutil.rmtree(tempdir) 
      sys.exit(0) 
    ses.pause() 
    print("Done") 

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

    output = pt.abspath(torinfo.name() + ".torrent") 

    if output_name: 
     if pt.isdir(output_name): 
      output = pt.abspath(pt.join(
       output_name, torinfo.name() + ".torrent")) 
     elif pt.isdir(pt.dirname(pt.abspath(output_name))): 
      output = pt.abspath(output_name) 

    print("Saving torrent file here : " + output + " ...") 
    torcontent = lt.bencode(torfile.generate()) 
    f = open(output, "wb") 
    f.write(lt.bencode(torfile.generate())) 
    f.close() 
    print("Saved! Cleaning up dir: " + tempdir) 
    ses.remove_torrent(handle) 
    shutil.rmtree(tempdir) 

    return output 


def showHelp(): 
    print("") 
    print("USAGE: " + pt.basename(sys.argv[0]) + " MAGNET [OUTPUT]") 
    print(" MAGNET\t- the magnet url") 
    print(" OUTPUT\t- the output torrent file name") 
    print("") 


def main(): 
    if len(sys.argv) < 2: 
     showHelp() 
     sys.exit(0) 

    magnet = sys.argv[1] 
    output_name = None 

    if len(sys.argv) >= 3: 
     output_name = sys.argv[2] 

    magnet2torrent(magnet, output_name) 


if __name__ == "__main__": 
    main() 

ci-dessus script prend environ 1+ minutes pour aller chercher les métadonnées et créer un fichier .torrent alors que utorrent client ne prend que quelques secondes, pourquoi est-ce?

Comment rendre mon script plus rapide?

Je voudrais chercher des métadonnées pour environ 1k + torrents.

par exemple. Aimant Lien

magnet:?xt=urn:btih:BFEFB51F4670D682E98382ADF81014638A25105A&dn=openSUSE+13.2+DVD+x86_64.iso&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80 

mise à jour:

j'ai spécifié connus routeur dht urls comme celui-ci dans mon script.

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

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("router.bitcomet.com", 6881) 
session.add_dht_router("dht.aelitis.com", 6881) 
session.start_dht() 

mais il reste lent et parfois j'obtiens des erreurs comme

DHT error [hostname lookup] (1) Host not found (authoritative) 
could not map port using UPnP: no router found 

mise à jour:

j'ai écrit ce script scmall qui va chercher hachage info hex de DB et essais pour extraire les méta-données de dht, puis insère le fichier torrent dans DB. Je l'ai fait tourner indéfiniment car je ne savais pas comment enregistrer l'état, donc le garder en cours d'exécution aura plus de pairs et aller chercher des méta-données sera plus rapide.

#!/usr/bin/env python 
# this file will run as client or daemon and fetch torrent meta data i.e. torrent files from magnet uri 

import libtorrent as lt # libtorrent library 
import tempfile # for settings parameters while fetching metadata as temp dir 
import sys #getting arguiments from shell or exit script 
from time import sleep #sleep 
import shutil # removing directory tree from temp directory 
import os.path # for getting pwd and other things 
from pprint import pprint # for debugging, showing object data 
import MySQLdb # DB connectivity 
import os 
from datetime import date, timedelta 

#create lock file to make sure only single instance is running 
lock_file_name = "/daemon.lock" 

if(os.path.isfile(lock_file_name)): 
    sys.exit('another instance running') 
#else: 
    #f = open(lock_file_name, "w") 
    #f.close() 

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

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("router.bitcomet.com", 6881) 
session.add_dht_router("dht.aelitis.com", 6881) 
session.start_dht() 

alive = True 
while alive: 

    db_conn = MySQLdb.connect( host = 'localhost',  user = '', passwd = '', db = 'basesite', unix_socket='') # Open database connection 
    #print('reconnecting') 
    #get all records where enabled = 0 and uploaded within yesterday 
    subset_count = 5 ; 

    yesterday = date.today() - timedelta(1) 
    yesterday = yesterday.strftime('%Y-%m-%d %H:%M:%S') 
    #print(yesterday) 

    total_count_query = ("SELECT COUNT(*) as total_count FROM content WHERE upload_date > '"+ yesterday +"' AND enabled = '0' ") 
    #print(total_count_query) 
    try: 
     total_count_cursor = db_conn.cursor()# prepare a cursor object using cursor() method 
     total_count_cursor.execute(total_count_query) # Execute the SQL command 
     total_count_results = total_count_cursor.fetchone() # Fetch all the rows in a list of lists. 
     total_count = total_count_results[0] 
     print(total_count) 
    except: 
      print "Error: unable to select data" 

    total_pages = total_count/subset_count 
    #print(total_pages) 

    current_page = 1 
    while(current_page <= total_pages): 
     from_count = (current_page * subset_count) - subset_count 

     #print(current_page) 
     #print(from_count) 

     hashes = [] 

     get_mysql_data_query = ("SELECT hash FROM content WHERE upload_date > '" + yesterday +"' AND enabled = '0' ORDER BY record_num ASC LIMIT "+ str(from_count) +" , " + str(subset_count) +" ") 
     #print(get_mysql_data_query) 
     try: 
      get_mysql_data_cursor = db_conn.cursor()# prepare a cursor object using cursor() method 
      get_mysql_data_cursor.execute(get_mysql_data_query) # Execute the SQL command 
      get_mysql_data_results = get_mysql_data_cursor.fetchall() # Fetch all the rows in a list of lists. 
      for row in get_mysql_data_results: 
       hashes.append(row[0].upper()) 
     except: 
      print "Error: unable to select data" 

     print(hashes) 

     handles = [] 

     for hash in hashes: 
      tempdir = tempfile.mkdtemp() 
      add_magnet_uri_params = { 
       'save_path': tempdir, 
       'duplicate_is_error': True, 
       'storage_mode': lt.storage_mode_t(2), 
       'paused': False, 
       'auto_managed': True, 
       'duplicate_is_error': True 
      } 
      magnet_uri = "magnet:?xt=urn:btih:" + hash.upper() + "&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80" 
      #print(magnet_uri) 
      handle = lt.add_magnet_uri(session, magnet_uri, add_magnet_uri_params) 
      handles.append(handle) #push handle in handles list 

     #print("handles length is :") 
     #print(len(handles)) 

     while(len(handles) != 0): 
      for h in handles: 
       #print("inside handles for each loop") 
       if h.has_metadata(): 
        torinfo = h.get_torrent_info() 
        final_info_hash = str(torinfo.info_hash()) 
        final_info_hash = final_info_hash.upper() 
        torfile = lt.create_torrent(torinfo) 
        torcontent = lt.bencode(torfile.generate()) 
        tfile_size = len(torcontent) 
        try: 
         insert_cursor = db_conn.cursor()# prepare a cursor object using cursor() method 
         insert_cursor.execute("""INSERT INTO dht_tfiles (hash, tdata) VALUES (%s, %s)""", [final_info_hash , torcontent]) 
         db_conn.commit() 
         #print "data inserted in DB" 
        except MySQLdb.Error, e: 
         try: 
          print "MySQL Error [%d]: %s" % (e.args[0], e.args[1]) 
         except IndexError: 
          print "MySQL Error: %s" % str(e)  

        shutil.rmtree(h.save_path()) # remove temp data directory 
        session.remove_torrent(h) # remove torrnt handle from session 
        handles.remove(h) #remove handle from list 

       else: 
        if(h.status().active_time > 600): # check if handle is more than 10 minutes old i.e. 600 seconds 
         #print('remove_torrent') 
         shutil.rmtree(h.save_path()) # remove temp data directory 
         session.remove_torrent(h) # remove torrnt handle from session 
         handles.remove(h) #remove handle from list 
       sleep(1)   
       #print('sleep1') 

     print('sleep10') 
     sleep(10) 
     current_page = current_page + 1 
    #print('sleep20') 
    sleep(20) 

os.remove(lock_file_name); 

maintenant j'ai besoin d'implémenter de nouvelles choses comme suggéré par Arvid.


MISE À JOUR

j'ai réussi à mettre en œuvre ce qui a suggéré Arvid.et un peu plus l'extension i trouvé dans les forums de soutien déluge http://forum.deluge-torrent.org/viewtopic.php?f=7&t=42299&start=10

#!/usr/bin/env python 

import libtorrent as lt # libtorrent library 
import tempfile # for settings parameters while fetching metadata as temp dir 
import sys #getting arguiments from shell or exit script 
from time import sleep #sleep 
import shutil # removing directory tree from temp directory 
import os.path # for getting pwd and other things 
from pprint import pprint # for debugging, showing object data 
import MySQLdb # DB connectivity 
import os 
from datetime import date, timedelta 

def var_dump(obj): 
    for attr in dir(obj): 
    print "obj.%s = %s" % (attr, getattr(obj, attr)) 

session = lt.session() 
session.add_extension('ut_pex') 
session.add_extension('ut_metadata') 
session.add_extension('smart_ban') 
session.add_extension('metadata_transfer') 

#session = lt.session(lt.fingerprint("DE", 0, 1, 0, 0), flags=1) 

session_save_filename = "/tmp/new.client.save_state" 

if(os.path.isfile(session_save_filename)): 

    fileread = open(session_save_filename, 'rb') 
    session.load_state(lt.bdecode(fileread.read())) 
    fileread.close() 
    print('session loaded from file') 
else: 
    print('new session started') 

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("router.bitcomet.com", 6881) 
session.add_dht_router("dht.aelitis.com", 6881) 
session.start_dht() 

alerts = [] 

alive = True 
while alive: 
    a = session.pop_alert() 
    alerts.append(a) 
    print('----------') 
    for a in alerts: 
     var_dump(a) 
     alerts.remove(a) 


    print('sleep10') 
    sleep(10) 
    filewrite = open(session_save_filename, "wb") 
    filewrite.write(lt.bencode(session.save_state())) 
    filewrite.close() 

gardé en cours d'exécution pendant une minute et a reçu alerte

obj.msg = no router found 

mise à jour:

après quelques tests ressemble

session.add_dht_router("router.bitcomet.com", 6881) 

provoquant

('%s: %s', 'alert', 'DHT error [hostname lookup] (1) Host not found (authoritative)') 

mise à jour: i ajouté

session.start_dht() 
session.start_lsd() 
session.start_upnp() 
session.start_natpmp() 

et obtenu alerte

('%s: %s', 'portmap_error_alert', 'could not map port using UPnP: no router found') 
+2

Probablement votre client torrent a déjà un bon nombre d'homologues connectés, ce qui permet une requête DHT rapide. Votre script, à la place, part de zéro, il doit donc être amorcé à partir d'un seul nœud connu. –

+0

@MatteoItalia comment puis-je le démarrer en tant que démon et le garder en marche tout en lui fournissant des URL magnétiques? Y at-il un moyen, coz maintenant j'exécute ce script pour chaque aimant de l'aimant. donc il faut recommencer à zéro à chaque fois je suppose. – AMB

+0

@AMB: À quelle vitesse s'exécute-t-il si vous transmettez plusieurs URI d'aimant et écrivez plusieurs fichiers torrent dans la même session? – Blender

Répondre

3

comme MatteoItalia souligne, bootstrapping la DHT n'est pas instantanée, et peut parfois prendre un certain temps. Il n'y a pas de moment précis où le processus d'amorçage est terminé, c'est un continuum d'être de plus en plus connecté au réseau.

Plus les nœuds sont connectés et stables, plus vous les connaissez, plus les recherches sont rapides. Une façon de prendre en compte la plus grande partie du processus de bootstrapping (pour obtenir plus de comparaison pommes-pommes) serait de commencer à chronométrer après vous obtenez le dht_bootstrap_alert (et aussi attendre l'ajout du lien de l'aimant jusque là).

Ajout des nœuds bootstrap dht fera principalement possible pour bootstrap, il ne sera pas nécessairement particulièrement rapide. Vous voulez généralement environ 270 nœuds ou plus (y compris les nœuds de remplacement) pour être considérés comme amorcés. Une chose que vous pouvez faire pour accélérer le processus d'amorçage est de vous assurer que l'état de la session est save and load, ce qui inclut le dht routing table. Cela rechargera tous les noeuds de la session précédente dans la table de routage et (en supposant que vous n'avez pas changé d'adresse IP et que tout fonctionne correctement), l'amorçage devrait être plus rapide.

Assurez-vous ne commencer la DHT dans le session constructor (comme argument de drapeaux, il suffit de passer à add_default_plugins), load the state, ajoutez les nœuds du routeur puis start the dht.

Malheureusement, il y a beaucoup de pièces mobiles impliquées pour que cela fonctionne en interne, la commande est importante et il peut y avoir des problèmes subtils. De plus, notez que le fonctionnement continu du DHT serait plus rapide, car le rechargement de l'état passera toujours par un bootstrap, il aura juste plus de nœuds à l'avant pour faire un ping et essayer de "se connecter".

Si vous désactivez le drapeau start_default_features, cela signifie également que UPnP et NAT-PMP ne seront pas démarrés. Si vous les utilisez, vous devrez également les ajouter à start.

+0

Merci pour votre réponse, cela a effacé la plupart de mes requêtes, y at-il un échantillon de code python qui utilise load et save state, add_default_plugins, j'ai écrit un petit script pour récupérer les métadonnées je suis mise à jour la question. – AMB

+0

s'il vous plaît vérifier le code ajouté en question., J'apprécie vraiment votre entrée, merci – AMB

+0

mise à jour: je peux enregistrer et charger l'état, mais je ne pouvais pas faire add_default_plugins, theres peu de manuels python disponibles. – AMB