Libtorrent - 如何根据磁链生成种子文件?

20 投票
4 回答
10387 浏览
提问于 2025-04-17 09:20

我看过手册,但是找不到答案。我想要根据一个磁力链接生成一个种子文件,这样下次启动的时候就可以直接加载这个文件,避免重新下载元数据。我试过快速恢复功能,但在使用这个功能时,我还是得去获取元数据,这样会花费不少时间。我看到的例子都是关于为新的种子创建种子文件,而我想要的是生成一个与磁力链接对应的种子文件。

4 个回答

0

如果保存恢复数据没有成功,你可以利用当前连接的信息生成一个新的种子文件。

fs = libtorrent.file_storage()
libtorrent.add_files(fs, "somefiles")
t = libtorrent.create_torrent(fs)
t.add_tracker("http://10.0.0.1:312/announce")
t.set_creator("My Torrent")
t.set_comment("Some comments")
t.set_priv(True)
libtorrent.set_piece_hashes(t, "C:\\", lambda x: 0),  libtorrent.bencode(t.generate())
f=open("mytorrent.torrent", "wb")
f.write(libtorrent.bencode(t.generate()))
f.close()

我怀疑这样做的恢复速度会比专门为这个目的设计的功能更快。

6

我想给大家分享一个关于现代 libtorrent Python 包的快速更新:libtorrent 现在有了一个叫 parse_magnet_uri 的方法,你可以用它来生成一个 torrent 句柄。

import libtorrent, os, time

def magnet_to_torrent(magnet_uri, dst):
    """
    Args:
        magnet_uri (str): magnet link to convert to torrent file
        dst (str): path to the destination folder where the torrent will be saved
    """
    # Parse magnet URI parameters
    params = libtorrent.parse_magnet_uri(magnet_uri)
    params.save_path = "."

    # Download torrent info
    session = libtorrent.session()
    handle = session.add_torrent(params)
    print "Downloading metadata..."
    while not handle.has_metadata():
        time.sleep(0.1)

    # Create torrent and save to file
    torrent_info = handle.get_torrent_info()
    torrent_file = libtorrent.create_torrent(torrent_info)
    torrent_path = os.path.join(dst, torrent_info.name() + ".torrent")
    with open(torrent_path, "wb") as f:
        f.write(libtorrent.bencode(torrent_file.generate()))
    print "Torrent saved to %s" % torrent_path
13

这里找到了解决方案:

http://code.google.com/p/libtorrent/issues/detail?id=165#c5

关于创建种子文件的内容可以参考这里:

http://www.rasterbar.com/products/libtorrent/make_torrent.html

修改前面的几行代码:

file_storage fs;

// recursively adds files in directories
add_files(fs, "./my_torrent");

create_torrent t(fs);

改成这样:

torrent_info ti = handle.get_torrent_info()

create_torrent t(ti)

“handle”是从这里来的:

torrent_handle add_magnet_uri(session& ses, std::string const& uri add_torrent_params p);

在创建种子文件之前,你需要确保元数据已经下载,可以通过调用 handle.has_metadata() 来检查。

更新

看起来libtorrent的Python接口缺少一些创建种子文件所需的重要C++接口,上面的例子在Python中无法使用,因为 create_torrent 这个Python类不接受torrent_info作为参数(C++中是可以的)。

所以我尝试了另一种方法,但也遇到了一个障碍,让这变得不可能,以下是代码:

if handle.has_metadata():

    torinfo = handle.get_torrent_info()

    fs = libtorrent.file_storage()
    for file in torinfo.files():
        fs.add_file(file)

    torfile = libtorrent.create_torrent(fs)
    torfile.set_comment(torinfo.comment())
    torfile.set_creator(torinfo.creator())

    for i in xrange(0, torinfo.num_pieces()):
        hash = torinfo.hash_for_piece(i)
        torfile.set_hash(i, hash)

    for url_seed in torinfo.url_seeds():
        torfile.add_url_seed(url_seed)

    for http_seed in torinfo.http_seeds():
        torfile.add_http_seed(http_seed)

    for node in torinfo.nodes():
        torfile.add_node(node)

    for tracker in torinfo.trackers():
        torfile.add_tracker(tracker)

    torfile.set_priv(torinfo.priv())

    f = open(magnet_torrent, "wb")
    f.write(libtorrent.bencode(torfile.generate()))
    f.close()

在这一行抛出了一个错误:

torfile.set_hash(i, hash)

它期望hash是 const char* 类型,但 torrent_info.hash_for_piece(int) 返回的是 big_number 类,而这个类没有可以转换回const char*的接口。

等我有时间,我会把这个缺失的接口问题报告给libtorrent的开发者,因为目前在使用Python绑定时,从磁力链接创建.torrent文件是不可能的。

torrent_info.orig_files() 在Python绑定中也缺失了,我不确定 torrent_info.files() 是否足够。

更新 2

我已经在这个问题上创建了一个议题,可以在这里查看: http://code.google.com/p/libtorrent/issues/detail?id=294

给它点个星,这样他们能更快修复。

更新 3

现在已经修复了,发布了0.16.0版本。Windows的二进制文件也可以下载了。

撰写回答