Format: text/x-python
⬇ Download File (3.2 KB)
   1  import libtorrent as lt
   2  import time
   3  import os
   4  
   5  # Global session object (consider managing this better in a full app)
   6  ses = lt.session({'listen_interfaces': '0.0.0.0:6881'})
   7  downloads = {}
   8  
   9  DEFAULT_SAVE_PATH = os.path.join(os.getcwd(), 'downloads')
  10  if not os.path.exists(DEFAULT_SAVE_PATH):
  11      os.makedirs(DEFAULT_SAVE_PATH)
  12  
  13  def add_torrent(magnet_link, save_path=DEFAULT_SAVE_PATH):
  14      """Adds a torrent using a magnet link."""
  15      params = {
  16          'save_path': save_path,
  17          'storage_mode': lt.storage_mode_t(2), # storage_mode_sparse
  18      }
  19      try:
  20          handle = lt.add_magnet_uri(ses, magnet_link, params)
  21          handle.set_sequential_download(True) # Good for streaming
  22          downloads[handle.info_hash()] = handle
  23          print(f"Torrent added: {handle.name() if handle.has_metadata() else 'Fetching metadata...'}")
  24          return handle.info_hash()
  25      except Exception as e:
  26          print(f"Error adding torrent: {e}")
  27          return None
  28  
  29  def get_status(info_hash):
  30      """Returns current status of a torrent"""
  31      if info_hash not in downloads:
  32          return {'error': 'Invalid info_hash'}
  33      
  34      handle = downloads[info_hash]['handle']
  35      status = handle.status()
  36      
  37      return {
  38          'progress': round(status.progress * 100, 2),
  39          'download_rate': status.download_rate,
  40          'num_peers': status.num_peers,
  41          'state': str(status.state).split('.')[1],
  42          'name': status.name,
  43          'total_size': status.total_wanted
  44      }
  45  
  46  def get_streamable_files(info_hash):
  47      """Returns list of completed media files for streaming"""
  48      if info_hash not in downloads:
  49          return {'error': 'Invalid info_hash'}
  50      
  51      handle = downloads[info_hash]['handle']
  52      status = handle.status()
  53      
  54      if not status.is_seeding:
  55          return {'status': 'Download not complete'}
  56      
  57      save_path = downloads[info_hash]['save_path']
  58      torrent_info = handle.get_torrent_info()
  59      files = []
  60      
  61      for idx in range(torrent_info.num_files()):
  62          file_entry = torrent_info.file_at(idx)
  63          if file_entry.size > 0:
  64              files.append({
  65                  'path': os.path.join(save_path, file_entry.path),
  66                  'size': file_entry.size,
  67                  'name': os.path.basename(file_entry.path)
  68              })
  69      
  70      return {'files': files}
  71  
  72  def get_all_torrents_status():
  73      """Gets the status of all active torrents."""
  74      return {str(info_hash): get_torrent_status(info_hash) for info_hash in downloads.keys()}
  75  
  76  # Example usage (can be removed or moved to app.py)
  77  if __name__ == '__main__':
  78      # Replace with a real magnet link for testing
  79      test_magnet = "magnet:?xt=urn:btih:YOUR_TORRENT_INFO_HASH_HERE"
  80      info_hash = add_torrent(test_magnet)
  81  
  82      if info_hash:
  83          print(f"Added torrent with info_hash: {info_hash}")
  84          while True:
  85              status = get_torrent_status(info_hash)
  86              print(f"Status: {status['status']}, Progress: {status['progress']:.2f}%, Peers: {status['num_peers']}")
  87              if status['status'] == 'finished' or status['status'] == 'seeding':
  88                  print("Download finished!")
  89                  break
  90              time.sleep(5)
  91      else:
  92          print("Failed to add torrent.")