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のクローンをいくつか取り、そこからトラッカー機能を直接実装するコードを噛むことです。

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

Source: https://habr.com/ru/post/J175449/


All Articles