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 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
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
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
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
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
@@ -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
@@ -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
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bencode'
4
+ require 'digest/sha1'
5
+ require 'base32'
6
+
7
+ t = BEncode.load_file(ARGV[0])
8
+ f = BEncode.load_file(ARGV[1])
9
+ puts t
10
+ puts f
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