c3d 0.3.5 → 0.4.2
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 +4 -4
- data/Gemfile +1 -7
- data/Gemfile.lock +22 -21
- data/Rakefile +12 -0
- data/bin/c3d +40 -0
- data/c3d.gemspec +6 -4
- data/lib/c3d/actors/blacklist.rb +13 -0
- data/lib/c3d/actors/crawler.rb +30 -0
- data/lib/c3d/actors/getter.rb +18 -0
- data/lib/c3d/actors/subscribe.rb +14 -0
- data/lib/c3d/connectors/connect_ethereum.rb +146 -0
- data/lib/c3d/connectors/connect_torrent.rb +148 -0
- data/lib/c3d/util/blobber.rb +84 -0
- data/lib/c3d/util/processes.rb +64 -0
- data/lib/c3d/util/purger.rb +22 -0
- data/lib/c3d/util/setup.rb +123 -0
- data/lib/c3d/util/trees.rb +226 -0
- data/lib/c3d/util/util.rb +16 -0
- data/lib/c3d/util/watch.rb +71 -0
- data/lib/c3d/version.rb +1 -1
- data/lib/c3d.rb +42 -18
- data/settings/c3d-config.json +22 -12
- data/settings/transmission.json +64 -64
- data/spec/{tmp → fixtures/tmp} +0 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/unit/1.setup_spec.rb +32 -0
- metadata +61 -28
- data/lib/c3d/connect_ethereum_rpc.rb +0 -147
- data/lib/c3d/connect_ethereum_socket.rb +0 -122
- data/lib/c3d/connect_torrent.rb +0 -147
- data/lib/c3d/connect_ui.rb +0 -102
- data/lib/c3d/get.rb +0 -0
- data/lib/c3d/processes.rb +0 -44
- data/lib/c3d/publish.rb +0 -101
- data/lib/c3d/setup.rb +0 -105
- data/lib/c3d/subscribe.rb +0 -138
- data/lib/c3d/util.rb +0 -22
- data/spec/checker.rb +0 -44
- data/spec/checker2.rb +0 -10
data/lib/c3d/connect_torrent.rb
DELETED
@@ -1,147 +0,0 @@
|
|
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
|
-
include Celluloid
|
6
|
-
attr_accessor :session_id, :url, :basic_auth, :fields, :debug_mode
|
7
|
-
|
8
|
-
TORRENT_FIELDS = [
|
9
|
-
"id",
|
10
|
-
"name",
|
11
|
-
"totalSize",
|
12
|
-
"isFinished",
|
13
|
-
"percentDone",
|
14
|
-
]
|
15
|
-
|
16
|
-
def initialize opts
|
17
|
-
@url = opts[:url]
|
18
|
-
@fields = opts[:fields] || TORRENT_FIELDS
|
19
|
-
@basic_auth = { :username => opts[:username], :password => opts[:password] } if opts[:username]
|
20
|
-
@debug_mode = opts[:debug_mode] || false
|
21
|
-
# todo - connect to client, get, and save session_id
|
22
|
-
@session_id = "NOT-INITIALIZED"
|
23
|
-
end
|
24
|
-
|
25
|
-
def all
|
26
|
-
log ("[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Getting All Torrents"), true
|
27
|
-
|
28
|
-
response =
|
29
|
-
post(
|
30
|
-
:method => "torrent-get",
|
31
|
-
:arguments => {
|
32
|
-
:fields => fields
|
33
|
-
}
|
34
|
-
)
|
35
|
-
|
36
|
-
response["arguments"]["torrent-added"]
|
37
|
-
end
|
38
|
-
|
39
|
-
def find id
|
40
|
-
log ("[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Getting Torrent ID >> "+ "#{id}"), true
|
41
|
-
|
42
|
-
response =
|
43
|
-
post(
|
44
|
-
:method => "torrent-get",
|
45
|
-
:arguments => {
|
46
|
-
:fields => fields,
|
47
|
-
:ids => [id]
|
48
|
-
}
|
49
|
-
)
|
50
|
-
|
51
|
-
response["arguments"]["torrents"].first
|
52
|
-
end
|
53
|
-
|
54
|
-
def create filename
|
55
|
-
log ("[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Adding Blob >> \t"+ "#{filename}"), true
|
56
|
-
|
57
|
-
response =
|
58
|
-
post(
|
59
|
-
:method => "torrent-add",
|
60
|
-
:arguments => {
|
61
|
-
:filename => filename,
|
62
|
-
:'download-dir' => ENV['BLOBS_DIR'],
|
63
|
-
:'peer-limit' => 99
|
64
|
-
}
|
65
|
-
)
|
66
|
-
|
67
|
-
response["arguments"]
|
68
|
-
end
|
69
|
-
|
70
|
-
def destroy(id)
|
71
|
-
log ("[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Remove Torrent ID >> "+ "#{id}"), true
|
72
|
-
|
73
|
-
response =
|
74
|
-
post(
|
75
|
-
:method => "torrent-remove",
|
76
|
-
:arguments => {
|
77
|
-
:ids => [id],
|
78
|
-
:"delete-local-data" => true
|
79
|
-
}
|
80
|
-
)
|
81
|
-
|
82
|
-
response
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
def post(opts)
|
87
|
-
JSON::parse( http_post(opts).body )
|
88
|
-
end
|
89
|
-
|
90
|
-
def http_post(opts)
|
91
|
-
post_options = {
|
92
|
-
:body => opts.to_json,
|
93
|
-
:headers => { "x-transmission-session-id" => session_id }
|
94
|
-
}
|
95
|
-
post_options.merge!( :basic_auth => basic_auth ) if basic_auth
|
96
|
-
|
97
|
-
log "url: #{url}"
|
98
|
-
log "post_body:"
|
99
|
-
log JSON.parse(post_options[:body]).to_yaml
|
100
|
-
log "------------------"
|
101
|
-
|
102
|
-
response = HTTParty.post( url, post_options )
|
103
|
-
|
104
|
-
log_response response
|
105
|
-
|
106
|
-
# retry connection if session_id incorrect
|
107
|
-
if( response.code == 409 )
|
108
|
-
log "changing session_id"
|
109
|
-
@session_id = response.headers["x-transmission-session-id"]
|
110
|
-
response = http_post(opts)
|
111
|
-
end
|
112
|
-
|
113
|
-
response
|
114
|
-
end
|
115
|
-
|
116
|
-
def log(message, override = false)
|
117
|
-
if debug_mode || override
|
118
|
-
puts "#{message}"
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def log_response(response)
|
123
|
-
body = nil
|
124
|
-
begin
|
125
|
-
body = JSON.parse(response.body).to_yaml
|
126
|
-
rescue
|
127
|
-
body = response.body
|
128
|
-
end
|
129
|
-
|
130
|
-
headers = response.headers.to_yaml
|
131
|
-
|
132
|
-
log "response.code: #{response.code}"
|
133
|
-
log "response.message: #{response.message}"
|
134
|
-
|
135
|
-
log "response.body_raw:"
|
136
|
-
log response.body
|
137
|
-
log "-----------------"
|
138
|
-
|
139
|
-
log "response.body:"
|
140
|
-
log body
|
141
|
-
log "-----------------"
|
142
|
-
|
143
|
-
log "response.headers:"
|
144
|
-
log headers
|
145
|
-
log "------------------"
|
146
|
-
end
|
147
|
-
end
|
data/lib/c3d/connect_ui.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
require 'celluloid/zmq'
|
5
|
-
|
6
|
-
# commands - sent over ZMQ but using a standard JSONRPC structure.
|
7
|
-
# * `makeBlob`: make blob
|
8
|
-
# params: filename: "FILENAME" || filecontents: "CONTENTS"
|
9
|
-
# returns success: BLOB_ID or error
|
10
|
-
# * `destroyBlob`: destroy blob
|
11
|
-
# params: blob: "BLOB_ID"
|
12
|
-
# returns success: true or error
|
13
|
-
# * `addBlobToG`: add blob to group
|
14
|
-
# params: blob: "BLOB_ID", contract: "CONTRACT_ADDRESS", group: "GROUP_ID"
|
15
|
-
# returns success: true or error
|
16
|
-
# * `rmBlobFromG`: remove blob from contract
|
17
|
-
# params: blob: "BLOB_ID", contract: "CONTRACT_ADDRESS", group: "GROUP_ID"
|
18
|
-
# returns success: true or error
|
19
|
-
# * `subscribeK`: add a contract's blobs to the subscribed list
|
20
|
-
# params: contract: "CONTRACT_ADDRESS"
|
21
|
-
# returns success: true or error
|
22
|
-
# * `subscribeG`: add a group's blobs to the subscribed list
|
23
|
-
# params: contract: "CONTRACT_ADDRESS", group: "GROUP_ID"
|
24
|
-
# returns success: true or error
|
25
|
-
# * `unsubscribeK` remove a contract's blobs from the subscribed list
|
26
|
-
# params: contract: "CONTRACT_ADDRESS"
|
27
|
-
# returns success: true or error
|
28
|
-
# * `unsubscribeG` remove a group's blobs from the subscribed list
|
29
|
-
# params: contract: "CONTRACT_ADDRESS", group: "GROUP_ID"
|
30
|
-
# returns success: true or error
|
31
|
-
# * `ignoreG` add a group to the ignore list
|
32
|
-
# params: contract: "CONTRACT_ADDRESS", group: "GROUP_ID"
|
33
|
-
# returns success: true or error
|
34
|
-
# * `publish`: sugar for make blob + add to g
|
35
|
-
# params: filename: "FILENAME" || filecontents: "CONTENTS",
|
36
|
-
# contract: "CONTRACT_ADDRESS", [group]: ["GROUP1_ID", "GROUP2_ID", ...]
|
37
|
-
# returns success: BLOB_ID or error)
|
38
|
-
# * `get`: add a magnet link to the cache
|
39
|
-
# params: id: "BLOB_ID"
|
40
|
-
# returns success: true or error
|
41
|
-
|
42
|
-
Celluloid::ZMQ.init
|
43
|
-
|
44
|
-
class ConnectUI
|
45
|
-
include Celluloid::ZMQ
|
46
|
-
|
47
|
-
def initialize
|
48
|
-
@answer_socket = RepSocket.new
|
49
|
-
|
50
|
-
begin
|
51
|
-
@answer_socket.bind ENV['UI_ADDRESS']
|
52
|
-
rescue IOError
|
53
|
-
@answer_socket.close
|
54
|
-
raise
|
55
|
-
end
|
56
|
-
|
57
|
-
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] c3D<-ui on port >>\t#{ENV['UI_ADDRESS'].split(':').last}"
|
58
|
-
end
|
59
|
-
|
60
|
-
def run
|
61
|
-
loop { async.handle_message @answer_socket.read }
|
62
|
-
self.terminate
|
63
|
-
end
|
64
|
-
|
65
|
-
def handle_message message
|
66
|
-
message = JSON.load message
|
67
|
-
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Received Question >>\tcommand:#{message['command']}\tparams:#{message['params']}"
|
68
|
-
case message['command']
|
69
|
-
when 'get'
|
70
|
-
# todo
|
71
|
-
when 'makeBlob'
|
72
|
-
blob = message['params'][0]
|
73
|
-
PublishBlob.new blob, nil
|
74
|
-
when 'destroyBlob'
|
75
|
-
#todo
|
76
|
-
when 'addBlobToG'
|
77
|
-
sending_addr = message['params'][0]
|
78
|
-
contract_id = message['params'][1]
|
79
|
-
group_id = message['params'][2]
|
80
|
-
PublishBlob.new nil, sending_addr, contract_id, group_id
|
81
|
-
when 'rmBlobFromG'
|
82
|
-
#todo
|
83
|
-
when 'subscribeK'
|
84
|
-
#todo
|
85
|
-
when 'subscribeG'
|
86
|
-
#todo
|
87
|
-
when 'unsubscribeK'
|
88
|
-
#todo
|
89
|
-
when 'unsubscribeG'
|
90
|
-
#todo
|
91
|
-
when 'ignoreG'
|
92
|
-
#todo
|
93
|
-
when 'publish'
|
94
|
-
sending_addr = message['params'][0]
|
95
|
-
contract_id = message['params'][1]
|
96
|
-
group_id = message['params'][2]
|
97
|
-
blob = message['params'][3]
|
98
|
-
PublishBlob.new blob, sending_addr, contract_id, group_id
|
99
|
-
end
|
100
|
-
@answer_socket.send JSON.dump message
|
101
|
-
end
|
102
|
-
end
|
data/lib/c3d/get.rb
DELETED
File without changes
|
data/lib/c3d/processes.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
class TransmissionRunner
|
4
|
-
def start_transmission
|
5
|
-
unless is_trans_running?
|
6
|
-
pid = spawn "transmission-daemon -f --no-incomplete-dir -o -C -p #{ENV['TORRENT_RPC'].split(':').last[0..3]} -w #{ENV['BLOBS_DIR']} -g #{File.join(ENV['HOME'], '.epm')}"
|
7
|
-
at_exit { Process.kill("INT", pid) }
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def is_trans_running?
|
12
|
-
a = `ps ux`.split("\n").select{|e| e[/transmission-daemon/]}
|
13
|
-
return (! a.empty?)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class EthZmqRunner
|
18
|
-
def start_ethereum_zmq_bridge
|
19
|
-
unless is_bridge_running?
|
20
|
-
c3d_node = File.join(File.dirname(__FILE__), '..', '..', 'node_modules', 'c3d', 'connect_aleth.js')
|
21
|
-
pid = spawn "node #{c3d_node}"
|
22
|
-
at_exit { Process.kill("INT", pid) }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def is_bridge_running?
|
27
|
-
a = `ps ux`.split("\n").select{|e| e[/node.*connect_aleth.js$/]}
|
28
|
-
return (! a.empty?)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class EthRunner
|
33
|
-
def start_ethereum
|
34
|
-
unless is_eth_running?
|
35
|
-
pid = spawn #{todo}""
|
36
|
-
at_exit { Process.kill("INT", pid) }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def is_eth_running?
|
41
|
-
a = `ps ux`.split("\n").select{|e| e[/eth/]} #todo cleanup
|
42
|
-
return (! a.empty?)
|
43
|
-
end
|
44
|
-
end
|
data/lib/c3d/publish.rb
DELETED
@@ -1,101 +0,0 @@
|
|
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
|
-
|
5
|
-
class Publish
|
6
|
-
include Celluloid
|
7
|
-
attr_accessor :tor_file, :blob_file, :sha1_trun
|
8
|
-
|
9
|
-
def initialize puller, eth, blob, sending_addr, contract_id='', group_id=''
|
10
|
-
@swarm_puller = puller
|
11
|
-
@eth = eth
|
12
|
-
@piecelength = 32 * 1024
|
13
|
-
|
14
|
-
unless blob == nil
|
15
|
-
prepare blob
|
16
|
-
build
|
17
|
-
write_torrent
|
18
|
-
publish_torrent
|
19
|
-
end
|
20
|
-
unless sending_addr == nil
|
21
|
-
publish_ethereum sending_addr, contract_id, group_id
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
def prepare blob
|
27
|
-
sha1_full = Digest::SHA1.hexdigest blob
|
28
|
-
@sha1_trun = sha1_full[0..23]
|
29
|
-
@tor_file = File.join(ENV['TORRENTS_DIR'], "#{sha1_trun}.torrent")
|
30
|
-
@blob_file = File.join(ENV['BLOBS_DIR'], sha1_trun)
|
31
|
-
File.open(@blob_file, 'w'){|f| f.write(blob)}
|
32
|
-
@files = [{ path: @blob_file.split('/'), length: File::open(@blob_file).size }]
|
33
|
-
end
|
34
|
-
|
35
|
-
def build
|
36
|
-
@info = { :'created by' => "OWIG3",
|
37
|
-
:'creation date' => DateTime.now.strftime("%s").to_i,
|
38
|
-
encoding: "UTF-8",
|
39
|
-
info: { name: @files.first[:path].last,
|
40
|
-
:'piece length' => @piecelength,
|
41
|
-
length: @files.first[:length],
|
42
|
-
:private => 0, #1 is private
|
43
|
-
}
|
44
|
-
}
|
45
|
-
@info[:info][:pieces] = ""
|
46
|
-
i = 0
|
47
|
-
read_pieces(@files.first[:path], @piecelength) do |piece|
|
48
|
-
@info[:info][:pieces] += Digest::SHA1.digest(piece)
|
49
|
-
i += 1
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def read_pieces file, length
|
54
|
-
buffer = ""
|
55
|
-
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Hashing Blob >> \t" + "#{file.join("/")}"
|
56
|
-
File.open(file.join("/")) do |fh|
|
57
|
-
begin
|
58
|
-
read = fh.read(length - buffer.length)
|
59
|
-
if (buffer.length + read.length) == length
|
60
|
-
yield(buffer + read)
|
61
|
-
buffer = ""
|
62
|
-
else
|
63
|
-
buffer += read
|
64
|
-
end
|
65
|
-
end until fh.eof?
|
66
|
-
end
|
67
|
-
yield buffer
|
68
|
-
end
|
69
|
-
|
70
|
-
def write_torrent
|
71
|
-
File.open(@tor_file, 'w') do |torrentfile|
|
72
|
-
torrentfile.write @info.bencode
|
73
|
-
end
|
74
|
-
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Torrent Link >> \t" + "#{@tor_file}"
|
75
|
-
end
|
76
|
-
|
77
|
-
def publish_torrent
|
78
|
-
p "#{@swarm_puller}"
|
79
|
-
torrent = @swarm_puller.create @tor_file
|
80
|
-
begin
|
81
|
-
@btih = torrent["torrent-added"]['hashString']
|
82
|
-
rescue
|
83
|
-
@btih = torrent["torrent-duplicate"]['hashString']
|
84
|
-
end
|
85
|
-
mag_link = "magnet:?xt=urn:btih:" + @btih + "&dn=" + @sha1_trun
|
86
|
-
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Magnet Link >> \t" + mag_link
|
87
|
-
end
|
88
|
-
|
89
|
-
def publish_ethereum sending_addr, contract_id, group_id
|
90
|
-
message = {}
|
91
|
-
post_id = "0x#{@btih}#{@sha1_trun}"
|
92
|
-
data = [
|
93
|
-
'3', #data_slots
|
94
|
-
'newp', #....data
|
95
|
-
group_id,
|
96
|
-
post_id
|
97
|
-
]
|
98
|
-
@eth.transact contract_id, sending_addr, data
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
data/lib/c3d/setup.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'celluloid/autostart'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
class SetupC3D
|
6
|
-
include Celluloid
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
set_deps
|
10
|
-
config = get_config
|
11
|
-
set_the_env config
|
12
|
-
set_trans_config config
|
13
|
-
set_c3d_config config
|
14
|
-
end
|
15
|
-
|
16
|
-
def set_deps
|
17
|
-
dep_exist? 'transmission-daemon', 'sudo apt-get install transmission-daemon'
|
18
|
-
dep_exist? 'node', 'sudo apt-get install nodejs'
|
19
|
-
unless File.directory? File.join(File.dirname(__FILE__), '..', '..', 'node_modules', 'c3d')
|
20
|
-
`cd #{File.join(File.dirname(__FILE__), '..', '..')} && npm install c3d`
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def get_config
|
25
|
-
dir_exist? File.join(ENV['HOME'], '.epm')
|
26
|
-
config_file = File.join(ENV['HOME'], '.epm', 'c3d-config.json')
|
27
|
-
config_example = File.join(File.dirname(__FILE__), '..', '..', 'settings', 'c3d-config.json')
|
28
|
-
unless File.exists? config_file
|
29
|
-
FileUtils.cp config_example, config_file
|
30
|
-
end
|
31
|
-
return JSON.load(File.read(config_file))
|
32
|
-
end
|
33
|
-
|
34
|
-
def set_the_env config
|
35
|
-
ENV['SWARM_DIR'] = config['swarm_dir']
|
36
|
-
ENV['TORRENTS_DIR'] = config['torrents_dir']
|
37
|
-
ENV['BLOBS_DIR'] = config['blobs_dir']
|
38
|
-
ENV['WATCH_FILE'] = config['watch_file']
|
39
|
-
ENV['IGNORE_FILE'] = config['ignore_file']
|
40
|
-
ENV['TORRENT_RPC'] = config['torrent_rpc']
|
41
|
-
ENV['TORRENT_USER'] = config['torrent_user']
|
42
|
-
ENV['TORRENT_PASS'] = config['torrent_pass']
|
43
|
-
ENV['UI_ADDRESS'] = config['ui_address']
|
44
|
-
ENV['ETH_ZMQ_ADDR'] = config['eth_zmq_addr']
|
45
|
-
ENV['ETH_HOST'] = config['eth_host']
|
46
|
-
ENV['ETH_PORT'] = config['eth_port']
|
47
|
-
end
|
48
|
-
|
49
|
-
def set_trans_config config
|
50
|
-
trans_file = File.join(ENV['HOME'], '.epm', 'settings.json')
|
51
|
-
trans_example = File.join(File.dirname(__FILE__), '..', '..', 'settings', 'transmission.json')
|
52
|
-
unless File.exists? trans_file
|
53
|
-
FileUtils.cp trans_example, trans_file
|
54
|
-
end
|
55
|
-
trans_config = JSON.load(File.read(trans_file))
|
56
|
-
trans_config["incomplete-dir"] = config['download_dir']
|
57
|
-
trans_config["download-queue-size"] = config['download-queue-size'].to_i
|
58
|
-
trans_config["queue-stalled-minutes"] = config['queue-stalled-minutes'].to_i
|
59
|
-
trans_config["seed-queue-size"] = config['seed-queue-size'].to_i
|
60
|
-
File.open(trans_file, 'w'){|f| f.write(JSON.pretty_generate(trans_config))}
|
61
|
-
end
|
62
|
-
|
63
|
-
def set_c3d_config config
|
64
|
-
dir_exist? ENV['SWARM_DIR']
|
65
|
-
dir_exist? ENV['TORRENTS_DIR']
|
66
|
-
dir_exist? ENV['BLOBS_DIR']
|
67
|
-
dir_exist? config['download_dir']
|
68
|
-
file_exist? ENV['WATCH_FILE']
|
69
|
-
file_exist? ENV['IGNORE_FILE']
|
70
|
-
end
|
71
|
-
|
72
|
-
def dir_exist? directry
|
73
|
-
unless File.directory? directry
|
74
|
-
Dir.mkdir directry
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def file_exist? fil
|
79
|
-
unless File.exists? fil
|
80
|
-
File.open(fil, "w") {}
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def dep_exist? dependency, fixer
|
85
|
-
unless which dependency
|
86
|
-
`#{fixer}`
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def which cmd
|
91
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
92
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
93
|
-
exts.each { |ext|
|
94
|
-
exe = File.join(path, "#{cmd}#{ext}")
|
95
|
-
return exe if File.executable? exe
|
96
|
-
}
|
97
|
-
end
|
98
|
-
return nil
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
if __FILE__==$0
|
103
|
-
require 'json'
|
104
|
-
SetupC3D.new
|
105
|
-
end
|
data/lib/c3d/subscribe.rb
DELETED
@@ -1,138 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Queries:
|
4
|
-
# * `subscribe-k`: add a contract's blobs to the subscribed list (params: contract: "CONTRACT_ADDRESS") (returns success: true or error)
|
5
|
-
# * `subscribe-g`: add a group's blobs to the subscribed list (params: contract: "CONTRACT_ADDRESS", group: "GROUP_ID") (returns success: true or error)
|
6
|
-
# * `unsubscribe-k` remove a contract's blobs from the subscribed list (params: contract: "CONTRACT_ADDRESS") (returns success: true or error)
|
7
|
-
# * `unsubscribe-g` remove a group's blobs from the subscribed list (params: contract: "CONTRACT_ADDRESS", group: "GROUP_ID") (returns success: true or error)
|
8
|
-
# * `ignore-g` add a group to the ignore list (params: contract: "CONTRACT_ADDRESS", group: "GROUP_ID") (returns success: true or error)
|
9
|
-
|
10
|
-
require 'json'
|
11
|
-
require 'celluloid/autostart'
|
12
|
-
require 'base64'
|
13
|
-
|
14
|
-
class Subscribe
|
15
|
-
include Celluloid
|
16
|
-
attr_accessor :tor_file, :blob_file, :sha1_trun
|
17
|
-
|
18
|
-
def initialize action, eth
|
19
|
-
@eth = eth
|
20
|
-
case action
|
21
|
-
when 'subscribeK'
|
22
|
-
subscribe_k
|
23
|
-
when 'subscribeG'
|
24
|
-
subscribe_g
|
25
|
-
when 'unsubscribeK'
|
26
|
-
unsubscribe_k
|
27
|
-
when 'unsubscribeG'
|
28
|
-
unsubscribe_g
|
29
|
-
when 'ignoreG'
|
30
|
-
ignore_g
|
31
|
-
when 'assembleQueries'
|
32
|
-
assemble_queries
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def assemble_queries
|
37
|
-
# watched, ignored = load_library
|
38
|
-
# watched[contract] = [group1,group2] || watched[contract]=[] <=all
|
39
|
-
watched = {"97d1f086800920e8fd2344be52fb22d7bf6036d2" => []}
|
40
|
-
watched.each_key do |contract|
|
41
|
-
# todo - build
|
42
|
-
latest_group = send_query contract, '0x18'
|
43
|
-
latest_group_author = send_query contract, latest_group
|
44
|
-
step = iterate latest_group
|
45
|
-
prev_group = send_query contract, step # prev_group == '0x16' => first_group
|
46
|
-
step = iterate step
|
47
|
-
next_group = send_query contract, step # next_group == '0x' => last_group
|
48
|
-
step = iterate step
|
49
|
-
title1 = send_query contract, step
|
50
|
-
step = iterate step
|
51
|
-
title2 = send_query contract, step
|
52
|
-
title = eth_strings title1
|
53
|
-
title << eth_strings(title2) unless title2 == '0x'
|
54
|
-
step = iterate step
|
55
|
-
posts_in_group = (send_query contract, step).to_i(16)
|
56
|
-
step = iterate step
|
57
|
-
latest_blob = send_query contract, step
|
58
|
-
p latest_group
|
59
|
-
p latest_group_author
|
60
|
-
p next_group
|
61
|
-
p prev_group
|
62
|
-
p title
|
63
|
-
p posts_in_group
|
64
|
-
p latest_blob
|
65
|
-
next_blob = ''
|
66
|
-
until next_blob == '0x'
|
67
|
-
next_blob = send_query contract, latest_blob
|
68
|
-
latest_blob_author = send_query contract, latest_blob.next
|
69
|
-
blob_id = send_query contract, latest_blob.next.next
|
70
|
-
p next_blob
|
71
|
-
p latest_blob_author
|
72
|
-
get_the_blob blob_id unless do_i_have_it? blob_id
|
73
|
-
latest_blob = next_blob
|
74
|
-
end
|
75
|
-
end
|
76
|
-
#read watcher file && build hash
|
77
|
-
#read igored file && delete from hash
|
78
|
-
#for each watched contract
|
79
|
-
# for each watched group
|
80
|
-
#first subquery is to group_id + 5 - contains the number of blobs -> compare to stored val in the JSON
|
81
|
-
#if that number is has not changed, check group_id + 6 - contains the newest post -> compare to stored val in the JSON
|
82
|
-
#if that number is the same, do nothing
|
83
|
-
#if that number has changed, check blob_id + 1 - contains next in linked list -> compare to stored val in the JSON
|
84
|
-
#if that number has changed, loop through the posts and check that each
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
def load_library
|
90
|
-
watched = JSON.load File.read ENV['WATCH_FILE']
|
91
|
-
ignored = JSON.load File.read ENV['IGNORE_FILE']
|
92
|
-
[watched, ignored]
|
93
|
-
end
|
94
|
-
|
95
|
-
def send_query contract, storage
|
96
|
-
@eth.get_storage_at contract, storage
|
97
|
-
end
|
98
|
-
|
99
|
-
def eth_strings input
|
100
|
-
input.scan(/../).map{|x| x.hex }.reject{|c| c == 0}.pack('c*')
|
101
|
-
end
|
102
|
-
|
103
|
-
def iterate input
|
104
|
-
last_place = input[-1]
|
105
|
-
input[-1] = last_place.next
|
106
|
-
input
|
107
|
-
end
|
108
|
-
|
109
|
-
def do_i_have_it? blob
|
110
|
-
dn = blob[42..-1]
|
111
|
-
p 'dont have this'
|
112
|
-
File.exists?(File.join(ENV['BLOBS_DIR'], dn))
|
113
|
-
end
|
114
|
-
|
115
|
-
def get_the_blob blob
|
116
|
-
btih = blob[2..41]
|
117
|
-
dn = blob[42..-1]
|
118
|
-
link = "magnet:?xt=urn:btih:" + btih + "&dn=" + dn
|
119
|
-
p 'getting_link'
|
120
|
-
torrent = @@swarm_puller.create link
|
121
|
-
p torrent
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
if __FILE__==$0
|
126
|
-
require './connect_ethereum.rb'
|
127
|
-
require './connect_torrent'
|
128
|
-
require 'yaml'
|
129
|
-
require 'httparty'
|
130
|
-
@@swarm_puller = TorrentAPI.new(
|
131
|
-
username: ENV['TORRENT_USER'],
|
132
|
-
password: ENV['TORRENT_PASS'],
|
133
|
-
url: ENV['TORRENT_RPC'],
|
134
|
-
debug_mode: true
|
135
|
-
)
|
136
|
-
questions_for_eth = ConnectEth.new :zmq, :cpp
|
137
|
-
Subscribe.new 'assembleQueries', questions_for_eth
|
138
|
-
end
|
data/lib/c3d/util.rb
DELETED
@@ -1,22 +0,0 @@
|
|
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
|
-
module Utility
|
7
|
-
def self.add_group_to_ethereum sending_addr, contract_id, title, eth
|
8
|
-
message = {}
|
9
|
-
message['command'] = 'transact'
|
10
|
-
message['params'] = [
|
11
|
-
sending_addr, #sender_addr
|
12
|
-
'', #value
|
13
|
-
contract_id, #recipient_addr
|
14
|
-
'10000', #gas
|
15
|
-
'2', #data_slots
|
16
|
-
'newt', #....data
|
17
|
-
title
|
18
|
-
]
|
19
|
-
eth.write JSON.dump message
|
20
|
-
### somehow this is not currently working.
|
21
|
-
end
|
22
|
-
end
|