BitTorrentトラッカーをPythonサイトに固定する方法:XBTトラッカーとの統合

Pythonで書かれたWebサイトがあり、rutracker.orgのようなBitTorrentトラッカーをそれに追加するとします。



タスク分離



タスクは、2つの大きな機能に分けることができます。

  1. サイト上のトレント分布のディレクトリ(通常、フォーラムとして実装されています)、
  2. 配信プロセスに直接関与するトラッカー自体。


トラッカーは、BitTorrentプロトコルの仕様に従ってhttpアプリケーションであり、要求に応じて、配信のすべての参加者についてクライアントに通知します。 クライアントは絶えず定期的にリクエストを送信するため、トラッカーは生産的である必要があります。応答時間は最小限である必要があります。



PHPの世界では、CatalogとTrackerは多くの場合、2つの専用アプリケーションに分割されていません。 たとえば、人気のあるTBDevトラッカーは、カタログフォーラムとトラッカーを組み合わせたアプリケーションとして存在します。 (作成者は、アプリケーションの人気にうんざりしているので、サイトが長い間更新されておらず、アプリケーションをダウンロードするのは非現実的です。しかし、Webで多くのクローンを見つけることができます。)



一部のTracker実装は、もともとPythonで記述されていましたが、パフォーマンス上の理由からC ++で書き直されました。 そのため、最近ではPythonトラッカーは存在しません(少なくとも私は見つけることができませんでした)。 したがって、残っている唯一のことは、個別のトラッカーアプリケーションをインストールし、Pythonディレクトリと統合することです。



制御と保護



コントロールが必要ない場合は、次のとおりです。



その後、 プログラムの 1つをインストールするだけで、最も軽量で生産性の高いプログラムを選択できます。

さらに、ユーザーにディレクトリエントリを作成し、自分で作成した.torrentファイルをアップロードおよびダウンロードする機会を与えるだけです。 トラッカーの正しいアナウンスアドレスを事前に通知しておくと、トラッカーはディストリビューションの作成時に.torrentファイルに書き込みます。



私の場合のように、少なくともある種の制御を確立したい場合、さらにそれを実現したい場合は、特定のディストリビューションへのユーザーグループのアクセスを制限したい場合、いわゆる「プライベートトラッカー」が必要です。



理論的には、これは次のように行われます。



実装



上記のすべてを考慮すると、私が選択したのは、任意のディレクトリサイトと統合するように設計されたプライベートトラッカーの唯一の実装としてのXBTトラッカーです。

XBT TrackerはC ++で記述され、ソースからビルドしてインストールされます。 Ubuntu Server 12.04では、64ビットが初めてビルドされます。



依存関係


XBTトラッカーとの相互作用はトラッカーMySQLデータベースを介して行われるため、PythonディレクトリはMySQLデータベースを読み書きできる必要があります。 このために、 pymysql



パッケージを使用しpymysql





.torrentファイルを解析および変更するには、 BitTorrent-bencode



パッケージも必要です。

 import bencode, pymysql
      
      





機能


まだ許可されていない場合は、許可ユーザーを追加します。 ここでは、 torrent_pass



テーブルのtorrent_pass



フィールドを使用して、サイトのユーザーIDとXBTトラッカーのユーザーIDをリンクします。 以前、torrent_passは、アナウンスURLで指定されたキーを使用してユーザーを承認するために使用されていましたが、現在はXBTトラッカーが異なるアルゴリズムを使用しています-以下を参照してください。 uid



フィールドは自動インクリメントです。

  c = db.cursor() c.execute("SELECT uid, torrent_pass, torrent_pass_version, downloaded, uploaded FROM xbt_users WHERE torrent_pass = %s", (request.user.id,)) rec = c.fetchone() if not rec: # insert a new user c.execute("INSERT INTO xbt_users(torrent_pass) VALUES(%s)", (request.user.id)) c.execute("SELECT uid, torrent_pass, torrent_pass_version, downloaded, uploaded FROM xbt_users WHERE torrent_pass = %s", (request.user.id,)) #rowcount =0 rec = c.fetchone() db.commit() uid, torrent_pass, torrent_pass_version, downloaded, uploaded = rec
      
      





.torrentファイルの読み取りと解析:

  with open(fpath, 'rb') as f: buf = f.read() bt = bencode.bdecode(buf)
      
      





プライベートフラグを強制的に設定し、info_hashを計算します(プライベートフラグはinfoセクションに含まれており、ハッシュに影響します)。

  if xbt_force_private: bt['info']['private'] = 1 info_hash_obj = hashlib.sha1(bencode.bencode(bt['info']))
      
      





xbt_files



テーブルにディストリビューションが登録されていない場合は登録します。

  sha = info_hash_obj.hexdigest() c = db.cursor() c.execute("SELECT flags FROM xbt_files WHERE info_hash=UNHEX(%s)", (sha,)) flag = c.fetchone() if flag is None: c.execute("INSERT INTO xbt_files(info_hash, mtime, ctime) VALUES(UNHEX(%s), UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", (sha,)) db.commit() elif flag[0] % 2 : error_msg(pagename, request, _("Torrent is marked for deletion!")) return
      
      





アナウンスURLの認証キーの計算


XBT Trackerは非常にトリッキーなキー計算アルゴリズムを使用します。 値のセットが取得されます。



これらはすべて、「私はひねり、混乱させたい」という原則に従って、魔法のように混ぜられています。

  c.execute("select value from xbt_config where name = 'torrent_pass_private_key'") torrent_pass_private_key = c.fetchone()[0] s = "%s %d %d %s" % (torrent_pass_private_key, torrent_pass_version, uid, info_hash_obj.digest()) sha = hashlib.sha1(s).hexdigest()[0:24] pwd = "%08x%s" % (uid, sha) bt['announce'] = 'http://xbt.host:port/%s/announce' % pwd # remove other trackers if bt.has_key('announce-list'): del bt['announce-list']
      
      





これにより、 xbt_users.torrent_pass_version



の目的がxbt_users.torrent_pass_version



なります。この値を変更することにより、以前にダウンロードしたすべての.torrentファイルを無効にすることができます。 つまり、一種のパ​​スワードリセットアナログです。

最後に、.torrentファイルをエンコードして行に戻し、クライアントに送信します。

  buf = bencode.bencode(bt)
      
      





ディストリビューションを削除する


添付ファイルを削除する場合、登録済みディストリビューションのリストからディストリビューションを削除する必要があります(テーブルxbt_files



)。

ポライト削除の方法があります。この方法では、ディストリビューションを削除済みとしてマークしますが、実際には、最後の人が完全にダウンロードしたときにトラッカーによって削除されます。

 c.execute("update xbt_files set flags = 1 where info_hash = UNHEX(%s)", (info_hash, ))
      
      







まあ、それだけです。 さらなるサイトのねじれ:ディストリビューターの数とリストの表示、評価のカウント、ディストリビューション内のファイルのリストの表示、装飾に起因します。 それらは非常に明らかに実装されています:統計を含むすべての必要な情報はトラッカーデータベースで利用でき、Pierre Fermatに続いて私はそれらの場所を無駄にすみません。



概説されたソリューションは、人気のあるWikiエンジンMoinMoinの プラグインとして実装されます



提案されたソリューションには重大な欠点があることに注意する必要があります。Pythonサポートを使用した仮想ホスティングは一般に比較的まれであり、C ++アプリケーションを実際に構築する可能性はありません。 唯一の選択肢は、TBDev Trackerのクローンをいくつか取り、そこからトラッカー機能を直接実装するコードを噛むことです。



私の経験が誰かに役立つことを願っています。



All Articles