mktorrent 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/lib/mktorrent.rb +86 -0
  2. data/test/mktorrent_test.rb +39 -0
  3. metadata +79 -0
@@ -0,0 +1,86 @@
1
+ require 'bencode'
2
+ require 'digest/sha1'
3
+ require 'active_support'
4
+
5
+ # Sample usage
6
+ #t = Torrent.new("http://your.tracker.com")
7
+ #t.add_file("path/to/file.foo")
8
+ #t.write_torrent("~/Downloads/mytorrent.torrent")
9
+
10
+ # TODO
11
+ # Support tracker-list
12
+
13
+ class Torrent
14
+ attr_accessor :info, :filehashes, :piecelength, :files, :defaultdir, :tracker, :size
15
+
16
+ # optionally initialize filename
17
+ def initialize(tracker)
18
+ @tracker = tracker
19
+ @piecelength = 512.kilobytes
20
+ @files = []
21
+ @filehashes = []
22
+ @size = 0
23
+ @defaultdir = "torrent"
24
+ build_the_torrent
25
+ end
26
+
27
+ def count
28
+ @files.count
29
+ end
30
+
31
+ def build
32
+ @info = { :announce => @tracker,
33
+ :info => { :name => @defaultdir,
34
+ :'piece length' => @piecelength,
35
+ :pieces => @filehashes.join,
36
+ :files => @files
37
+ #:private => 1,
38
+ }
39
+ }
40
+ end
41
+
42
+ def write_torrent(filename)
43
+ build_the_torrent
44
+ open(filename, 'w') do |torrentfile|
45
+ torrentfile.write self.to_s
46
+ #torrentfile.puts self.to_s
47
+ end
48
+ puts "Wrote #{filename}"
49
+ end
50
+
51
+ # Return the .torrent file as a string
52
+ def to_s
53
+ return "You must add at least one file." if(@files.count < 1)
54
+ build_the_torrent unless (@info[:info][:files].count == @files.count)
55
+ @info.bencode
56
+ end
57
+
58
+ def add_file(filepath)
59
+ if((@files.select { |f| f[:path].join('/') == filepath } ).count > 0)
60
+ raise IOError, "Can't add duplicate file #{File.basename(filepath)}"
61
+ end
62
+
63
+ if File.exists?(filepath)
64
+ filesize = hash_pieces(filepath)
65
+ # TODO tidy the path up...
66
+ @files << { path: filepath.split('/'), length: filesize }
67
+ else
68
+ raise IOError, "Couldn't access #{filepath}"
69
+ end
70
+ end
71
+
72
+ def hash_pieces(file)
73
+ offset = 0
74
+ f = File::open(file, "rb")
75
+ @size += f.size
76
+ while offset < f.size do
77
+ @filehashes << Digest::SHA1.digest(IO::binread(f, offset, @piecelength))
78
+ offset += @piecelength
79
+ STDOUT.write "\r#{File.basename(file)}: hashed #{(offset.to_f / f.size.to_f)*100}%"
80
+ STDOUT.flush
81
+ end
82
+ return f.size
83
+ end
84
+
85
+ alias build_the_torrent build
86
+ end
@@ -0,0 +1,39 @@
1
+ require 'test/unit'
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'mktorrent')
3
+
4
+ class MktorrentTest < Test::Unit::TestCase
5
+ TRACKER = "http://test.example.com"
6
+ VALIDFILEPATH = File.expand_path("#{File.dirname(__FILE__)}/../tmp/randomfile.vhd")
7
+ VALIDFILENAME = "randomfile.vhd"
8
+ VALIDFILE2PATH = File.expand_path("#{File.dirname(__FILE__)}/../tmp/randomfile2.vhd")
9
+
10
+ def setup
11
+ @torrent = Torrent.new(TRACKER)
12
+ end
13
+
14
+ def test_create_torrent
15
+ assert_equal @torrent.tracker, TRACKER
16
+ end
17
+
18
+ def test_add_file_with_invalid_file
19
+ assert_raise(IOError) { @torrent.add_file("../tmp/bogusfile.vhd") }
20
+ end
21
+
22
+ def test_add_single_valid_file
23
+ @torrent.add_file(VALIDFILEPATH)
24
+ assert_equal @torrent.count, 1
25
+ assert(@torrent.info[:info][:files].select { |f| f[:name] == VALIDFILENAME })
26
+ end
27
+
28
+ def test_add_another_valid_file
29
+ @torrent.add_file(VALIDFILEPATH)
30
+ @torrent.add_file(VALIDFILE2PATH)
31
+ assert_equal 2, @torrent.count
32
+ end
33
+
34
+ def test_prevent_duplicate_file_from_being_added
35
+ @torrent.add_file(VALIDFILEPATH)
36
+ assert_raise(IOError) { @torrent.add_file(VALIDFILEPATH) }
37
+ end
38
+
39
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mktorrent
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Timothy Mukaibo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bencode
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.7.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.7.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: active_support
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Create .torrent files easily with this gem
47
+ email: timothy.mukaibo@gmail.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - lib/mktorrent.rb
53
+ - test/mktorrent_test.rb
54
+ homepage: https://github.com/mukaibot/mktorrent
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.23
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Create .torrent files easily with this gem
78
+ test_files:
79
+ - test/mktorrent_test.rb