c3d 0.2.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.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/LICENSE.md +56 -0
- data/README.md +16 -0
- data/Rakefile +2 -0
- data/c3d.gemspec +29 -0
- data/lib/c3d.rb +64 -0
- data/lib/c3d/connect_ethereum.rb +1 -0
- data/lib/c3d/connect_torrent.rb +150 -0
- data/lib/c3d/publish.rb +79 -0
- data/lib/c3d/subscribe.rb +1 -0
- data/lib/c3d/version.rb +1 -0
- data/spec/checker.rb +44 -0
- data/spec/checker2.rb +10 -0
- data/spec/tmp +1 -0
- metadata +92 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 26d68c3d4b6211fe79be850883d5d1687fec2e83
|
4
|
+
data.tar.gz: f162df881dc458ba326e1fb2a4443d69a8e89701
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8ebf827c9f90d3d50966fab4faa8c20416abc5bbd91b772f5682db3bbeef96af2a82de2ac024bcde64c0f2f2fba23116995212a00198bf981259c6fa8016c881
|
7
|
+
data.tar.gz: ab8401405d171b4317ef6a54d5fb983ad0cb4d70d6ee3b92b0e391012bfb33eefc8a10e9129c276a9f13e0743720f5a21b55d3b326a5c933afbd3475707dcedb
|
data/.gitignore
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Specific to RubyMotion:
|
13
|
+
.dat*
|
14
|
+
.repl_history
|
15
|
+
build/
|
16
|
+
|
17
|
+
## Documentation cache and generated files:
|
18
|
+
/.yardoc/
|
19
|
+
/_yardoc/
|
20
|
+
/doc/
|
21
|
+
/rdoc/
|
22
|
+
|
23
|
+
## Environment normalisation:
|
24
|
+
/.bundle/
|
25
|
+
/lib/bundler/man/
|
26
|
+
|
27
|
+
# for a library or gem, you might want to ignore these files since the code is
|
28
|
+
# intended to run in multiple environments; otherwise, check them in:
|
29
|
+
# Gemfile.lock
|
30
|
+
# .ruby-version
|
31
|
+
# .ruby-gemset
|
32
|
+
|
33
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
34
|
+
.rvmrc
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
c3d
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
Copyright (c) [2014] [Watershed Legal Services, PLLC]
|
2
|
+
|
3
|
+
Any person who (1) obtains a copy of this software and associated documentation
|
4
|
+
files (the "Software") and (2) agrees to the terms of this license agreement may
|
5
|
+
free of charge, deal in the Software without restriction, including (without limitation)
|
6
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
7
|
+
and/or sell copies of the Software, and to permit persons to whom the Software
|
8
|
+
is furnished to do so.
|
9
|
+
|
10
|
+
By using the Software, you agree to the following terms:
|
11
|
+
|
12
|
+
1. The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
2. The software is provided "as is", without warranty of any kind, express or
|
16
|
+
implied, including but not limited to the warranties of merchantability,
|
17
|
+
fitness for a particular purpose and noninfringement. In no event shall the
|
18
|
+
authors or copyright holders be liable for any claim, damages or other
|
19
|
+
liability, whether in an action of contract, tort or otherwise, arising from,
|
20
|
+
out of or in connection with the software or the use or other dealings in
|
21
|
+
the software.
|
22
|
+
|
23
|
+
3. THE SOFTWARE DOES NOT PROVIDE LEGAL ADVICE AND WAS NOT CREATED TO PROVIDE
|
24
|
+
LEGAL ADVICE. IN ADDITION, YOU ALSO AGREE:
|
25
|
+
|
26
|
+
a. The creators of the Software and its contributors are not your lawyers.
|
27
|
+
|
28
|
+
b. The Software is not a lawyer.
|
29
|
+
|
30
|
+
c. Your use of the Software does not, in and of itself, create a legally
|
31
|
+
binding contract in any jurisdiction and does not establish a lawyer-client
|
32
|
+
relationship between either you and the developer of the Software or between
|
33
|
+
you and the Software. Your communication with a non-lawyer will not be subject
|
34
|
+
to the attorney-client privilege and (depending on your jurisdiction) may not
|
35
|
+
be entitled to protection as confidential communication.
|
36
|
+
|
37
|
+
d. The dissemination, distribution, or usage of this software shall not constitute
|
38
|
+
the provision of legal advice within your jurisdiction or any other. Unless you
|
39
|
+
are legally authorized and licensed to do so, you agree to not use the Software
|
40
|
+
to provide or assist in the provision of legal advice.
|
41
|
+
|
42
|
+
e. You acknowledge and understand that each jurisdiction has its own particular
|
43
|
+
rules regarding the practice of law. IF YOU USE THIS SOFTWARE TO PROVIDE LEGAL
|
44
|
+
ADVICE YOU MAY BE SUBJECT TO CIVIL AND CRIMINAL LIABILITY. PRACTICING LAW WITHOUT
|
45
|
+
A LICENSE IS A VIOLATION OF CRIMINAL LAW IN SOME JURISDICTIONS. CONSULT A LAWYER
|
46
|
+
LICENSED IN YOUR JURISDICTION IF YOU HAVE ANY QUESTIONS ABOUT WHAT DOES OR DOES
|
47
|
+
NOT CONSTITUTE THE PRACTICE OF LAW.
|
48
|
+
|
49
|
+
f. The providers of this software neither warrant nor guarantee this software shall
|
50
|
+
meet the requirements of any particular legal system to form a legally binding
|
51
|
+
contract, nor is it their intention to directly or indirectly facilitate or
|
52
|
+
encourage the unauthorized practice of law.
|
53
|
+
|
54
|
+
g. You agree that in order for you to form a legally binding contract that you shall
|
55
|
+
seek legal advice from an appropriately qualified and experienced lawyer within
|
56
|
+
your jurisdiction.
|
data/README.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
## Introduction
|
2
|
+
|
3
|
+
C3D => Contract Controlled Content Distribution
|
4
|
+
|
5
|
+
## Contributing
|
6
|
+
|
7
|
+
1. Fork the repository.
|
8
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
9
|
+
3. Add Tests (and feel free to help here since I don't (yet) really know how to do that.).
|
10
|
+
4. Commit your changes (`git commit -am 'Add some feature'`).
|
11
|
+
5. Push to the branch (`git push origin my-new-feature`).
|
12
|
+
6. Create new Pull Request.
|
13
|
+
|
14
|
+
## License
|
15
|
+
|
16
|
+
Modified MIT, see LICENSE.md
|
data/Rakefile
ADDED
data/c3d.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'c3d/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "c3d"
|
8
|
+
s.version = VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = "Contract Controlled Content Distribution using Ethereum Contracts to Distribute Content."
|
11
|
+
s.homepage = "https://github.com/ethereum-package-manager/c3d"
|
12
|
+
s.authors = [ "Casey Kuhlman" ]
|
13
|
+
s.email = "caseykuhlman@watershedlegal.com"
|
14
|
+
|
15
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
16
|
+
s.has_rdoc = false
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split($/)
|
19
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
20
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_runtime_dependency 'httparty', '~> 0.13'
|
24
|
+
s.add_runtime_dependency 'bencode', '~> 0.8'
|
25
|
+
|
26
|
+
s.description = <<desc
|
27
|
+
This gem is designed to assist in distribution mangement of content which is controlled by an Ethereum contract.
|
28
|
+
desc
|
29
|
+
end
|
data/lib/c3d.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Ruby std_lib Dependencies
|
4
|
+
require 'digest/sha1'
|
5
|
+
require 'json'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
# Gem Dependencies
|
9
|
+
require 'httparty'
|
10
|
+
require 'bencode'
|
11
|
+
|
12
|
+
# This Gem
|
13
|
+
require File.join(File.dirname(__FILE__), 'c3d', 'connect_ethereum')
|
14
|
+
require File.join(File.dirname(__FILE__), 'c3d', 'connect_torrent')
|
15
|
+
require File.join(File.dirname(__FILE__), 'c3d', 'publish')
|
16
|
+
require File.join(File.dirname(__FILE__), 'c3d', 'subscribe')
|
17
|
+
require File.join(File.dirname(__FILE__), 'c3d', 'version')
|
18
|
+
|
19
|
+
# todo - load these variables from a config file in ~/.epm
|
20
|
+
SWARM_DIR = File.join(ENV['HOME'], '.cache', 'c3d')
|
21
|
+
TORRENTS_DIR = File.join(SWARM_DIR, 'torrents')
|
22
|
+
BLOBS_DIR = File.join(SWARM_DIR, 'blobs')
|
23
|
+
TORRENT_RPC = "http://127.0.0.1:9091/transmission/rpc"
|
24
|
+
TORRENT_USER = 'username'
|
25
|
+
TORRENT_PASS = 'password'
|
26
|
+
|
27
|
+
# todo - check swarm directories exist
|
28
|
+
# todo - check that torrent manager is running
|
29
|
+
# todo - torrentapis use a 'fairly std' rpc framework, but with different
|
30
|
+
# endpoints. need to test these though
|
31
|
+
|
32
|
+
swarm_puller = TorrentAPI.new(
|
33
|
+
username: TORRENT_USER,
|
34
|
+
password: TORRENT_PASS,
|
35
|
+
url: TORRENT_RPC,
|
36
|
+
debug_mode: false
|
37
|
+
)
|
38
|
+
|
39
|
+
blob = File.read(ARGV[0]) + "\n#{Time.now}"
|
40
|
+
blob = Publish.new blob, swarm_puller
|
41
|
+
|
42
|
+
# added = swarm_puller.create("#{t.magnet_link}")
|
43
|
+
|
44
|
+
# t = BEncode.load_file('9876.torrent')
|
45
|
+
# puts t
|
46
|
+
|
47
|
+
# torrents = swarm_puller.all
|
48
|
+
# torrents.each{|t| p 'name'] }
|
49
|
+
|
50
|
+
# [{"addedDate"=>1400177739,
|
51
|
+
# "files"=>
|
52
|
+
# [{"bytesCompleted"=>31752192,
|
53
|
+
# "length"=>591396864,
|
54
|
+
# "name"=>"ubuntu-14.04-server-amd64.iso"}],
|
55
|
+
# "id"=>1,
|
56
|
+
# "isFinished"=>false,
|
57
|
+
# "name"=>"ubuntu-14.04-server-amd64.iso",
|
58
|
+
# "percentDone"=>0.0536,
|
59
|
+
# "rateDownload"=>706000,
|
60
|
+
# "rateUpload"=>3000,
|
61
|
+
# "totalSize"=>591396864}]
|
62
|
+
|
63
|
+
# swarm_puller.destroy(1)
|
64
|
+
# torrent = swarm_puller.find(1)
|
@@ -0,0 +1 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
@@ -0,0 +1,150 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is based off of work by fguillen for the transmission_api gem here: https://github.com/fguillen/TransmissionApi
|
3
|
+
|
4
|
+
class TorrentAPI
|
5
|
+
attr_accessor :session_id
|
6
|
+
attr_accessor :url
|
7
|
+
attr_accessor :basic_auth
|
8
|
+
attr_accessor :fields
|
9
|
+
attr_accessor :debug_mode
|
10
|
+
|
11
|
+
TORRENT_FIELDS = [
|
12
|
+
"id",
|
13
|
+
"name",
|
14
|
+
"totalSize",
|
15
|
+
"isFinished",
|
16
|
+
"percentDone",
|
17
|
+
]
|
18
|
+
|
19
|
+
def initialize(opts)
|
20
|
+
@url = opts[:url]
|
21
|
+
@fields = opts[:fields] || TORRENT_FIELDS
|
22
|
+
@basic_auth = { :username => opts[:username], :password => opts[:password] } if opts[:username]
|
23
|
+
@debug_mode = opts[:debug_mode] || false
|
24
|
+
# todo - connect to client, get, and save session_id
|
25
|
+
@session_id = "NOT-INITIALIZED"
|
26
|
+
end
|
27
|
+
|
28
|
+
def all
|
29
|
+
log ("[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Getting All Torrents"), true
|
30
|
+
|
31
|
+
response =
|
32
|
+
post(
|
33
|
+
:method => "torrent-get",
|
34
|
+
:arguments => {
|
35
|
+
:fields => fields
|
36
|
+
}
|
37
|
+
)
|
38
|
+
|
39
|
+
response["arguments"]["torrent-added"]
|
40
|
+
end
|
41
|
+
|
42
|
+
def find(id)
|
43
|
+
log ("[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Getting Torrent ID >> "+ "#{id}"), true
|
44
|
+
|
45
|
+
response =
|
46
|
+
post(
|
47
|
+
:method => "torrent-get",
|
48
|
+
:arguments => {
|
49
|
+
:fields => fields,
|
50
|
+
:ids => [id]
|
51
|
+
}
|
52
|
+
)
|
53
|
+
|
54
|
+
response["arguments"]["torrents"].first
|
55
|
+
end
|
56
|
+
|
57
|
+
def create(filename)
|
58
|
+
log ("[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Adding Blob >> \t"+ "#{filename}"), true
|
59
|
+
|
60
|
+
response =
|
61
|
+
post(
|
62
|
+
:method => "torrent-add",
|
63
|
+
:arguments => {
|
64
|
+
:filename => filename,
|
65
|
+
:'download-dir' => BLOBS_DIR,
|
66
|
+
:'peer-limit' => 99
|
67
|
+
}
|
68
|
+
)
|
69
|
+
|
70
|
+
response["arguments"]["torrent-added"]
|
71
|
+
end
|
72
|
+
|
73
|
+
def destroy(id)
|
74
|
+
log ("[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Remove Torrent ID >> "+ "#{id}"), true
|
75
|
+
|
76
|
+
response =
|
77
|
+
post(
|
78
|
+
:method => "torrent-remove",
|
79
|
+
:arguments => {
|
80
|
+
:ids => [id],
|
81
|
+
:"delete-local-data" => true
|
82
|
+
}
|
83
|
+
)
|
84
|
+
|
85
|
+
response
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def post(opts)
|
90
|
+
JSON::parse( http_post(opts).body )
|
91
|
+
end
|
92
|
+
|
93
|
+
def http_post(opts)
|
94
|
+
post_options = {
|
95
|
+
:body => opts.to_json,
|
96
|
+
:headers => { "x-transmission-session-id" => session_id }
|
97
|
+
}
|
98
|
+
post_options.merge!( :basic_auth => basic_auth ) if basic_auth
|
99
|
+
|
100
|
+
log "url: #{url}"
|
101
|
+
log "post_body:"
|
102
|
+
log JSON.parse(post_options[:body]).to_yaml
|
103
|
+
log "------------------"
|
104
|
+
|
105
|
+
response = HTTParty.post( url, post_options )
|
106
|
+
|
107
|
+
log_response response
|
108
|
+
|
109
|
+
# retry connection if session_id incorrect
|
110
|
+
if( response.code == 409 )
|
111
|
+
log "changing session_id"
|
112
|
+
@session_id = response.headers["x-transmission-session-id"]
|
113
|
+
response = http_post(opts)
|
114
|
+
end
|
115
|
+
|
116
|
+
response
|
117
|
+
end
|
118
|
+
|
119
|
+
def log(message, override = false)
|
120
|
+
if debug_mode || override
|
121
|
+
puts "#{message}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def log_response(response)
|
126
|
+
body = nil
|
127
|
+
begin
|
128
|
+
body = JSON.parse(response.body).to_yaml
|
129
|
+
rescue
|
130
|
+
body = response.body
|
131
|
+
end
|
132
|
+
|
133
|
+
headers = response.headers.to_yaml
|
134
|
+
|
135
|
+
log "response.code: #{response.code}"
|
136
|
+
log "response.message: #{response.message}"
|
137
|
+
|
138
|
+
log "response.body_raw:"
|
139
|
+
log response.body
|
140
|
+
log "-----------------"
|
141
|
+
|
142
|
+
log "response.body:"
|
143
|
+
log body
|
144
|
+
log "-----------------"
|
145
|
+
|
146
|
+
log "response.headers:"
|
147
|
+
log headers
|
148
|
+
log "------------------"
|
149
|
+
end
|
150
|
+
end
|
data/lib/c3d/publish.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# based off of work by @mukaibot here: https://github.com/mukaibot/mktorrent/blob/master/lib/mktorrent.rb
|
3
|
+
# and work by @Burgestrand here: https://gist.github.com/Burgestrand/1733611
|
4
|
+
# note `rhash` dependency
|
5
|
+
|
6
|
+
class Publish
|
7
|
+
attr_accessor :tor_file, :blob_file, :sha1_trun
|
8
|
+
|
9
|
+
def initialize blob, swarm_puller
|
10
|
+
# @tracker = ''
|
11
|
+
# @defaultdir = ""
|
12
|
+
# @filehashes = []
|
13
|
+
# @size = 0
|
14
|
+
@piecelength = 32 * 1024
|
15
|
+
prepare blob
|
16
|
+
build
|
17
|
+
write_torrent
|
18
|
+
publish_torrent swarm_puller
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def prepare blob
|
23
|
+
sha1_full = Digest::SHA1.hexdigest blob
|
24
|
+
@sha1_trun = sha1_full[0..23]
|
25
|
+
@tor_file = File.join(TORRENTS_DIR, "#{sha1_trun}.torrent")
|
26
|
+
@blob_file = File.join(BLOBS_DIR, sha1_trun)
|
27
|
+
File.open(@blob_file, 'w'){|f| f.write(blob)}
|
28
|
+
@files = [{ path: @blob_file.split('/'), length: File::open(@blob_file).size }]
|
29
|
+
end
|
30
|
+
|
31
|
+
def build
|
32
|
+
@info = { :'created by' => "OWIG3",
|
33
|
+
:'creation date' => DateTime.now.strftime("%s").to_i,
|
34
|
+
encoding: "UTF-8",
|
35
|
+
info: { name: @files.first[:path].last,
|
36
|
+
:'piece length' => @piecelength,
|
37
|
+
length: @files.first[:length],
|
38
|
+
:private => 0, #1 is private
|
39
|
+
}
|
40
|
+
}
|
41
|
+
@info[:info][:pieces] = ""
|
42
|
+
i = 0
|
43
|
+
read_pieces(@files.first[:path], @piecelength) do |piece|
|
44
|
+
@info[:info][:pieces] += Digest::SHA1.digest(piece)
|
45
|
+
i += 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def read_pieces(file, length)
|
50
|
+
buffer = ""
|
51
|
+
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Hashing Blob >> \t" + "#{file.join("/")}"
|
52
|
+
File.open(file.join("/")) do |fh|
|
53
|
+
begin
|
54
|
+
read = fh.read(length - buffer.length)
|
55
|
+
if (buffer.length + read.length) == length
|
56
|
+
yield(buffer + read)
|
57
|
+
buffer = ""
|
58
|
+
else
|
59
|
+
buffer += read
|
60
|
+
end
|
61
|
+
end until fh.eof?
|
62
|
+
end
|
63
|
+
yield buffer
|
64
|
+
end
|
65
|
+
|
66
|
+
def write_torrent
|
67
|
+
File.open(@tor_file, 'w') do |torrentfile|
|
68
|
+
torrentfile.write @info.bencode
|
69
|
+
end
|
70
|
+
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Torrent Link >> \t" + "#{@tor_file}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def publish_torrent swarm_puller
|
74
|
+
torrent = swarm_puller.create @tor_file
|
75
|
+
btih = torrent['hashString']
|
76
|
+
mag_link = "magnet:?xt=urn:btih:" + btih + "&dn=" + @sha1_trun
|
77
|
+
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Magnet Link >> \t" + mag_link
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
data/lib/c3d/version.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
VERSION = "0.2.0"
|
data/spec/checker.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'cgi'
|
5
|
+
require 'openssl'
|
6
|
+
|
7
|
+
def require_gem(name)
|
8
|
+
require(name)
|
9
|
+
rescue LoadError
|
10
|
+
abort "[ERROR] Missing the '#{name}' gem, install it with 'gem install #{name}'"
|
11
|
+
end
|
12
|
+
|
13
|
+
require_gem 'bencode'
|
14
|
+
require_gem 'base32'
|
15
|
+
require_gem 'rack/utils'
|
16
|
+
|
17
|
+
# We cannot trust .torrent file data
|
18
|
+
ARGF.set_encoding 'BINARY'
|
19
|
+
|
20
|
+
# Read torrent from STDIN / ARGV filepath
|
21
|
+
torrent_data = ARGF.read
|
22
|
+
|
23
|
+
# Parse the torrent data
|
24
|
+
torrent = BEncode.load(torrent_data)
|
25
|
+
|
26
|
+
# Calculate the info_hash (actually, info_sha1 *is* the info_hash)
|
27
|
+
info_hash = torrent["info"].bencode
|
28
|
+
info_sha1 = OpenSSL::Digest::SHA1.digest(info_hash)
|
29
|
+
|
30
|
+
# Build the magnet link
|
31
|
+
params = {}
|
32
|
+
params[:xt] = "urn:btih:" << Base32.encode(info_sha1)
|
33
|
+
params[:dn] = CGI.escape(torrent["info"]["name"])
|
34
|
+
|
35
|
+
# params[:tr] = [] << to complement DHT we can add trackers too
|
36
|
+
magnet_uri = "magnet:?xt=#{params.delete(:xt)}"
|
37
|
+
magnet_uri << "&" << Rack::Utils.build_query(params)
|
38
|
+
|
39
|
+
puts "Magnet URI for #{params[:dn]}:"
|
40
|
+
puts " #{magnet_uri}"
|
41
|
+
|
42
|
+
|
43
|
+
# magnet:?xt=urn:btih:048ea0d1a27f702ba5e8f7890915d4d6a2454e20&dn=cdae42af3e2d9b7f208f8ec3
|
44
|
+
# magnet:?xt=urn:btih:048ea0d1a27f702ba5e8f7890915d4d6a2454e20&dn=cdae42af3e2d9b7f208f8ec3
|
data/spec/checker2.rb
ADDED
data/spec/tmp
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
the future beckons. hand with care. bitches
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: c3d
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Casey Kuhlman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.13'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bencode
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.8'
|
41
|
+
description: |2
|
42
|
+
This gem is designed to assist in distribution mangement of content which is controlled by an Ethereum contract.
|
43
|
+
email: caseykuhlman@watershedlegal.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".ruby-gemset"
|
50
|
+
- ".ruby-version"
|
51
|
+
- Gemfile
|
52
|
+
- LICENSE.md
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- c3d.gemspec
|
56
|
+
- lib/c3d.rb
|
57
|
+
- lib/c3d/connect_ethereum.rb
|
58
|
+
- lib/c3d/connect_torrent.rb
|
59
|
+
- lib/c3d/publish.rb
|
60
|
+
- lib/c3d/subscribe.rb
|
61
|
+
- lib/c3d/version.rb
|
62
|
+
- spec/checker.rb
|
63
|
+
- spec/checker2.rb
|
64
|
+
- spec/tmp
|
65
|
+
homepage: https://github.com/ethereum-package-manager/c3d
|
66
|
+
licenses: []
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.2.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Contract Controlled Content Distribution using Ethereum Contracts to Distribute
|
88
|
+
Content.
|
89
|
+
test_files:
|
90
|
+
- spec/checker.rb
|
91
|
+
- spec/checker2.rb
|
92
|
+
- spec/tmp
|