# Magnet2Torrent
Pure python project to turn a magnet link into a .torrent file.
The goal is to do it as fast as possible.
## Getting Started
### Installing
```bash
pip install magnet2torrent
```
### Usage
Download an ubuntu iso torrent.
```bash
magnet2torrent fetch "magnet:?xt=urn:btih:e2467cbf021192c241367b892230dc1e05c0580e&dn=ubuntu-19.10-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce"
```
Run it as an HTTP server.
```bash
magnet2torrent serve
```
Run it as an HTTP server with lots of features enabled.
```bash
magnet2torrent --use-dht --dht-state-file dht.state --torrent-cache-folder torcache serve --apikey secretkey
# try to fetch a torrent from the running server
# The response is json encoded and contains either the torrent or an error about it
curl "http://127.0.0.1:18667/?apikey=secretkey&magnet=magnet%3A%3Fxt%3Durn%3Abtih%3Ae2467cbf021192c241367b892230dc1e05c0580e%26dn%3Dubuntu-19.10-desktop-amd64.iso%26tr%3Dhttps%253A%252F%252Ftorrent.ubuntu.com%252Fannounce%26tr%3Dhttps%253A%252F%252Fipv6.torrent.ubuntu.com%252Fannounce"
# it will return {"status": "success", "filename": "ubuntu-19.10-desktop-amd64.iso.torrent", "torrent_data": "... base64 encoded torrent data ..."}
```
Use from python
```python
import asyncio
from magnet2torrent import Magnet2Torrent, FailedToFetchException
async def fetch_that_torrent():
m2t = Magnet2Torrent("magnet:?xt=urn:btih:e2467cbf021192c241367b892230dc1e05c0580e&dn=ubuntu-19.10-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce")
try:
filename, torrent_data = await m2t.retrieve_torrent()
except FailedToFetchException:
print("Failed")
asyncio.run(fetch_that_torrent())
```
If you want to use DHT to retrieve, you will have to bootstrap and run it.
```python
import asyncio
import os
from magnet2torrent import Magnet2Torrent, FailedToFetchException, settings
DHT_STATE_FILE = "/tmp/dht.state"
async def start_dht():
if os.path.exists(DHT_STATE_FILE):
dht_server = DHTServer.load_state(DHT_STATE_FILE)
await dht_server.listen(settings.DHT_PORT)
else:
dht_server = DHTServer()
await dht_server.listen(settings.DHT_PORT)
await dht_server.bootstrap(settings.DHT_BOOTSTRAP_NODES)
return dht_server
async def fetch_that_torrent(dht_server):
m2t = Magnet2Torrent("magnet:?xt=urn:btih:e2467cbf021192c241367b892230dc1e05c0580e&dn=ubuntu-19.10-desktop-amd64.iso", dht_server=dht_server)
try:
filename, torrent_data = await m2t.retrieve_torrent()
except FailedToFetchException:
print("Failed")
dht_server = asyncio.run(start_dht())
asyncio.run(fetch_that_torrent(dht_server))
dht_server.save_state(DHT_STATE_FILE)
```
## Attacks on DHT
There are a number of attacks against Bittorrent DHT going on permanently.
They have a variety of goals like trying to find new content on the DHT or just disrupt its operation.
One specific affects magnet2torrent, the "i am the peer for this" and then give back zero peers or just itself.
This attack kinda short circuits the attempt to find a torrent.
It mostly happen with low-peer torrents and when only the DHT got peers so it will be a bit uncommon.
The question I'm trying to answer here is "why can deluge/qbittorrent/picotorret etc. find a torrent when this library cannot".
And that's probably why, libtorrent-rasterbar is smarter about it.
## License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
The DHT part is forked from [bmueller/kademlia](https://github.com/bmuller/kademlia/) - its license can be
found in the dht folder or in the original project.
Raw data
{
"_id": null,
"home_page": "https://github.com/JohnDoee/magnet2torrent",
"name": "magnet2torrent",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "",
"author": "Anders Jensen",
"author_email": "andersandjensen@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/11/35/62b00d45692cc88d14245044c8e19f9d462a5a00227a406927c397103787/magnet2torrent-1.2.1.tar.gz",
"platform": null,
"description": "# Magnet2Torrent\n\nPure python project to turn a magnet link into a .torrent file.\nThe goal is to do it as fast as possible.\n\n## Getting Started\n\n### Installing\n\n```bash\npip install magnet2torrent\n```\n\n### Usage\n\nDownload an ubuntu iso torrent.\n\n```bash\nmagnet2torrent fetch \"magnet:?xt=urn:btih:e2467cbf021192c241367b892230dc1e05c0580e&dn=ubuntu-19.10-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce\"\n```\n\nRun it as an HTTP server.\n\n\n```bash\nmagnet2torrent serve\n```\n\nRun it as an HTTP server with lots of features enabled.\n\n```bash\nmagnet2torrent --use-dht --dht-state-file dht.state --torrent-cache-folder torcache serve --apikey secretkey\n\n# try to fetch a torrent from the running server\n# The response is json encoded and contains either the torrent or an error about it\ncurl \"http://127.0.0.1:18667/?apikey=secretkey&magnet=magnet%3A%3Fxt%3Durn%3Abtih%3Ae2467cbf021192c241367b892230dc1e05c0580e%26dn%3Dubuntu-19.10-desktop-amd64.iso%26tr%3Dhttps%253A%252F%252Ftorrent.ubuntu.com%252Fannounce%26tr%3Dhttps%253A%252F%252Fipv6.torrent.ubuntu.com%252Fannounce\"\n# it will return {\"status\": \"success\", \"filename\": \"ubuntu-19.10-desktop-amd64.iso.torrent\", \"torrent_data\": \"... base64 encoded torrent data ...\"}\n```\n\nUse from python\n\n```python\nimport asyncio\n\nfrom magnet2torrent import Magnet2Torrent, FailedToFetchException\n\nasync def fetch_that_torrent():\n m2t = Magnet2Torrent(\"magnet:?xt=urn:btih:e2467cbf021192c241367b892230dc1e05c0580e&dn=ubuntu-19.10-desktop-amd64.iso&tr=https%3A%2F%2Ftorrent.ubuntu.com%2Fannounce&tr=https%3A%2F%2Fipv6.torrent.ubuntu.com%2Fannounce\")\n try:\n filename, torrent_data = await m2t.retrieve_torrent()\n except FailedToFetchException:\n print(\"Failed\")\n\nasyncio.run(fetch_that_torrent())\n```\n\nIf you want to use DHT to retrieve, you will have to bootstrap and run it.\n\n```python\n\nimport asyncio\nimport os\n\nfrom magnet2torrent import Magnet2Torrent, FailedToFetchException, settings\n\n\nDHT_STATE_FILE = \"/tmp/dht.state\"\n\nasync def start_dht():\n if os.path.exists(DHT_STATE_FILE):\n dht_server = DHTServer.load_state(DHT_STATE_FILE)\n await dht_server.listen(settings.DHT_PORT)\n else:\n dht_server = DHTServer()\n await dht_server.listen(settings.DHT_PORT)\n await dht_server.bootstrap(settings.DHT_BOOTSTRAP_NODES)\n return dht_server\n\nasync def fetch_that_torrent(dht_server):\n m2t = Magnet2Torrent(\"magnet:?xt=urn:btih:e2467cbf021192c241367b892230dc1e05c0580e&dn=ubuntu-19.10-desktop-amd64.iso\", dht_server=dht_server)\n try:\n filename, torrent_data = await m2t.retrieve_torrent()\n except FailedToFetchException:\n print(\"Failed\")\n\ndht_server = asyncio.run(start_dht())\nasyncio.run(fetch_that_torrent(dht_server))\ndht_server.save_state(DHT_STATE_FILE)\n```\n\n## Attacks on DHT\n\nThere are a number of attacks against Bittorrent DHT going on permanently.\nThey have a variety of goals like trying to find new content on the DHT or just disrupt its operation.\n\nOne specific affects magnet2torrent, the \"i am the peer for this\" and then give back zero peers or just itself.\nThis attack kinda short circuits the attempt to find a torrent.\nIt mostly happen with low-peer torrents and when only the DHT got peers so it will be a bit uncommon.\n\nThe question I'm trying to answer here is \"why can deluge/qbittorrent/picotorret etc. find a torrent when this library cannot\".\nAnd that's probably why, libtorrent-rasterbar is smarter about it.\n\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details\n\nThe DHT part is forked from [bmueller/kademlia](https://github.com/bmuller/kademlia/) - its license can be\nfound in the dht folder or in the original project.\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Turn a bittorrent magnet links into a .torrent file.",
"version": "1.2.1",
"project_urls": {
"Homepage": "https://github.com/JohnDoee/magnet2torrent"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "cd6454a0c46c9994cc6556f4af1788c8bae89e20deb57385ef87a70263a03836",
"md5": "0bab1709e1d3f8e074b3558297b8692f",
"sha256": "f909e0f58776167b7c078b38bfdcc91663db2b9fd5af86b1c1473054a9f34e0f"
},
"downloads": -1,
"filename": "magnet2torrent-1.2.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0bab1709e1d3f8e074b3558297b8692f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 28709,
"upload_time": "2024-01-11T16:47:50",
"upload_time_iso_8601": "2024-01-11T16:47:50.703627Z",
"url": "https://files.pythonhosted.org/packages/cd/64/54a0c46c9994cc6556f4af1788c8bae89e20deb57385ef87a70263a03836/magnet2torrent-1.2.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "113562b00d45692cc88d14245044c8e19f9d462a5a00227a406927c397103787",
"md5": "5d0021e24a6b21c2f7092de32217c39d",
"sha256": "4ba53d304f1db33d33fe227aee5b34f6e640fd2d3199ff0ec3d8cc050cded631"
},
"downloads": -1,
"filename": "magnet2torrent-1.2.1.tar.gz",
"has_sig": false,
"md5_digest": "5d0021e24a6b21c2f7092de32217c39d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 24022,
"upload_time": "2024-01-11T16:47:51",
"upload_time_iso_8601": "2024-01-11T16:47:51.963185Z",
"url": "https://files.pythonhosted.org/packages/11/35/62b00d45692cc88d14245044c8e19f9d462a5a00227a406927c397103787/magnet2torrent-1.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-11 16:47:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "JohnDoee",
"github_project": "magnet2torrent",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "magnet2torrent"
}