Skip to content

Instantly share code, notes, and snippets.

@ggoral
Forked from Burgestrand/README.md
Created September 24, 2015 20:48
Show Gist options
  • Save ggoral/9630edbf0572eedc060d to your computer and use it in GitHub Desktop.
Save ggoral/9630edbf0572eedc060d to your computer and use it in GitHub Desktop.
A ruby script to construct magnet links out of .torrent files

Magneto

It reads your torrents. Spit out magnet URIs.

Example Usage

$ ./magneto.rb magneto.rb.torrent

Results in:

[WARN] There are no trackers on the torrent. It’s recommended you add at least one.
       Here are a few public free trackers that don’t require registration:

         udp://tracker.publicbt.com:80/announce
         udp://tracker.openbittorrent.com:80/announce

Magnet URI for magneto.rb:
  magnet:?xt=urn:btih:W7TTABVNI4AADW3MWLMKWF32WVY7XE7P&dn=magneto.rb
#!/usr/bin/env ruby
# coding: utf-8
require 'rubygems'
require 'cgi'
require 'openssl'
def require_gem(name)
require(name)
rescue LoadError
abort "[ERROR] Missing the '#{name}' gem, install it with 'gem install #{name}'"
end
require_gem 'bencode'
require_gem 'base32'
require_gem 'rack/utils'
# We cannot trust .torrent file data
ARGF.set_encoding 'BINARY'
# Read torrent from STDIN / ARGV filepath
torrent_data = ARGF.read
# Parse the torrent data
torrent = BEncode.load(torrent_data)
# Calculate the info_hash (actually, info_sha1 *is* the info_hash)
info_hash = torrent["info"].bencode
info_sha1 = OpenSSL::Digest::SHA1.digest(info_hash)
# Build the magnet link
params = {}
params[:xt] = "urn:btih:" << Base32.encode(info_sha1)
params[:dn] = CGI.escape(torrent["info"]["name"])
Array(torrent["announce-list"]).each do |(tracker, _)|
params[:tr] ||= []
params[:tr] << tracker
end
unless params[:tr]
puts "[WARN] There are no trackers on the torrent. It’s recommended you add at least one."
puts " Here are a few public free trackers that don’t require registration:"
puts
puts " udp://tracker.publicbt.com:80/announce"
puts " udp://tracker.openbittorrent.com:80/announce"
puts
end
# params[:tr] = [] << to complement DHT we can add trackers too
magnet_uri = "magnet:?xt=#{params.delete(:xt)}"
magnet_uri << "&" << Rack::Utils.build_query(params)
puts "Magnet URI for #{params[:dn]}:"
puts " #{magnet_uri}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment