c3d 0.3.5 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e3c857c8641103af8966a052019e2cb72cb51ab
|
4
|
+
data.tar.gz: 422e5af13e5fbd73aa8fff740c9e388cbb60d328
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f21645b41a5e8160cd35e88c79c3da567526678366e6295b2e084073132999aabfbbad5fabee87a8152b1d32e3d8a3879180909b54c6a88f23434a1d58fe17cb
|
7
|
+
data.tar.gz: cc8540abcf257322d7e7ac4015b471f455ead3d9452f0ef400340e261a155ec8dcbbee7ba46c437a5c562f273fc713f86c83e3b444a32cd3e6aa8864d3c8ac99
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
c3d (0.3.
|
4
|
+
c3d (0.3.5)
|
5
5
|
bencode (~> 0.8)
|
6
6
|
celluloid (~> 0.15)
|
7
|
-
|
7
|
+
commander (~> 4.1)
|
8
8
|
httparty (~> 0.13)
|
9
9
|
|
10
10
|
GEM
|
@@ -13,34 +13,35 @@ GEM
|
|
13
13
|
bencode (0.8.1)
|
14
14
|
celluloid (0.15.2)
|
15
15
|
timers (~> 1.1.0)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
ffi-rzmq (2.0.1)
|
23
|
-
ffi-rzmq-core (>= 1.0.1)
|
24
|
-
ffi-rzmq-core (1.0.3)
|
25
|
-
ffi (~> 1.9)
|
26
|
-
foreman (0.67.0)
|
27
|
-
dotenv (~> 0.7.0)
|
28
|
-
thor (~> 0.17.0)
|
16
|
+
commander (4.1.6)
|
17
|
+
highline (~> 1.6.11)
|
18
|
+
diff-lcs (1.2.5)
|
19
|
+
epm (0.3.7)
|
20
|
+
commander (~> 4.1.6)
|
21
|
+
highline (1.6.21)
|
29
22
|
httparty (0.13.1)
|
30
23
|
json (~> 1.8)
|
31
24
|
multi_xml (>= 0.5.2)
|
32
25
|
json (1.8.1)
|
33
26
|
multi_xml (0.5.5)
|
34
|
-
|
27
|
+
rspec (3.0.0)
|
28
|
+
rspec-core (~> 3.0.0)
|
29
|
+
rspec-expectations (~> 3.0.0)
|
30
|
+
rspec-mocks (~> 3.0.0)
|
31
|
+
rspec-core (3.0.1)
|
32
|
+
rspec-support (~> 3.0.0)
|
33
|
+
rspec-expectations (3.0.1)
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
+
rspec-support (~> 3.0.0)
|
36
|
+
rspec-mocks (3.0.1)
|
37
|
+
rspec-support (~> 3.0.0)
|
38
|
+
rspec-support (3.0.0)
|
35
39
|
timers (1.1.0)
|
36
40
|
|
37
41
|
PLATFORMS
|
38
42
|
ruby
|
39
43
|
|
40
44
|
DEPENDENCIES
|
41
|
-
bencode (~> 0.8)
|
42
45
|
c3d!
|
43
|
-
|
44
|
-
|
45
|
-
foreman
|
46
|
-
httparty (~> 0.13)
|
46
|
+
epm
|
47
|
+
rspec (~> 3.0)
|
data/Rakefile
CHANGED
@@ -1,2 +1,14 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
desc "Run all RSpec test examples"
|
5
|
+
task :spec do
|
6
|
+
require 'rspec'
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
RSpec::Core::RakeTask.new do |spec|
|
9
|
+
spec.rspec_opts = ["-c", "-f progress"]
|
10
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
task :default => :spec
|
data/bin/c3d
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'c3d.rb')
|
4
|
+
require 'commander/import'
|
5
|
+
|
6
|
+
program :version, C3D.version
|
7
|
+
program :description, 'Contract Controlled Content Dissemination Server.'
|
8
|
+
|
9
|
+
##
|
10
|
+
## Package Workflow Commands
|
11
|
+
##
|
12
|
+
command :start do |c|
|
13
|
+
c.syntax = 'c3d start'
|
14
|
+
c.description = 'Start your default c3d server.'
|
15
|
+
c.action do
|
16
|
+
print "Please be patient, this will take a few seconds.\n"
|
17
|
+
C3D.start
|
18
|
+
print "Server has started.\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
command :stop do |c|
|
23
|
+
c.syntax = 'c3d stop'
|
24
|
+
c.description = 'Stop your default c3d server.'
|
25
|
+
c.action do
|
26
|
+
C3D.stop
|
27
|
+
print "Server has stopped.\n"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
command :restart do |c|
|
32
|
+
c.syntax = 'c3d restart'
|
33
|
+
c.summary = ''
|
34
|
+
c.description = 'Restart your default c3d server.'
|
35
|
+
c.action do
|
36
|
+
print "Please be patient, this will take a few seconds.\n"
|
37
|
+
C3D.restart
|
38
|
+
print "Server has been restarted.\n"
|
39
|
+
end
|
40
|
+
end
|
data/c3d.gemspec
CHANGED
@@ -20,10 +20,12 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
21
21
|
s.require_paths = ["lib"]
|
22
22
|
|
23
|
-
s.
|
24
|
-
s.
|
25
|
-
s.
|
26
|
-
s.
|
23
|
+
s.add_dependency 'httparty', '~> 0.13'
|
24
|
+
s.add_dependency 'celluloid', '~> 0.15'
|
25
|
+
s.add_dependency 'commander', '~> 4.1'
|
26
|
+
s.add_dependency 'bencode', '~> 0.8'
|
27
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
s.add_development_dependency 'epm'
|
27
29
|
|
28
30
|
s.description = <<desc
|
29
31
|
This gem is designed to assist in distribution mangement of content which is controlled by an Ethereum contract.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module C3D
|
4
|
+
class Crawler
|
5
|
+
include Celluloid
|
6
|
+
|
7
|
+
def initialize contract
|
8
|
+
puts "[C3D::#{Time.now.strftime( "%F %T" )}] Finding Peak of >>\t" + contract
|
9
|
+
@parse = find_the_peak contract
|
10
|
+
@purge = []
|
11
|
+
puts "[C3D::#{Time.now.strftime( "%F %T" )}] Parsing Tree >>\t\t" + @parse
|
12
|
+
C3D::TreeBuilder.new @parse, @purge
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def find_the_peak contract
|
17
|
+
parent = send_query contract, '0x14'
|
18
|
+
until parent == '0x'
|
19
|
+
child = parent
|
20
|
+
parent = send_query parent, '0x14'
|
21
|
+
break if child == parent
|
22
|
+
end
|
23
|
+
return [child]
|
24
|
+
end
|
25
|
+
|
26
|
+
def send_query contract, storage
|
27
|
+
$eth.get_storage_at contract, storage
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module C3D
|
4
|
+
module Getter
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def get blob_id
|
8
|
+
if blob_id[0..1] == '0x'
|
9
|
+
blob_id = blob_id[2..-1]
|
10
|
+
end
|
11
|
+
btih = blob_id[0..39]
|
12
|
+
dn = blob_id[40..-1]
|
13
|
+
mag_link = "magnet:?xt=urn:btih:" + btih + "&dn=" + dn
|
14
|
+
$puller.create mag_link
|
15
|
+
puts "[C3D::#{Time.now.strftime( "%F %T" )}] Getting >>\t\t" + mag_link
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module C3D
|
4
|
+
class Subscribe
|
5
|
+
include Celluloid
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@parse = JSON.load File.read ENV['WATCH_FILE']
|
9
|
+
@purge = JSON.load File.read ENV['IGNORE_FILE']
|
10
|
+
puts "[C3D::#{Time.now.strftime( "%F %T" )}] Parsing Watchlist"
|
11
|
+
C3D::TreeBuilder.new @parse, @purge
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module C3D
|
4
|
+
class ConnectEth
|
5
|
+
include Celluloid
|
6
|
+
|
7
|
+
def initialize client
|
8
|
+
@client = client
|
9
|
+
@uri = URI.parse "http://#{ENV['ETH_HOST']}:#{ENV['ETH_PORT']}"
|
10
|
+
@question_socket = Net::HTTP.new @uri.host, @uri.port
|
11
|
+
@request = Net::HTTP::Post.new @uri.request_uri
|
12
|
+
@request.content_type = 'application/json'
|
13
|
+
@last_push = Time.now
|
14
|
+
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] c3D->eth via RPC on port >>\t#{ENV['ETH_PORT']}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_storage_at address, storage_location
|
18
|
+
address = guard_addresses address
|
19
|
+
storage_location = guard_addresses storage_location
|
20
|
+
|
21
|
+
case @client
|
22
|
+
when :go
|
23
|
+
request = {
|
24
|
+
id: 'c3d-client',
|
25
|
+
method: "EthereumApi.GetStorageAt",
|
26
|
+
params: [{
|
27
|
+
address: address,
|
28
|
+
key: storage_location
|
29
|
+
}]
|
30
|
+
}
|
31
|
+
when :cpp
|
32
|
+
request = {
|
33
|
+
method: "storageAt",
|
34
|
+
params: {
|
35
|
+
a: address,
|
36
|
+
x: storage_location
|
37
|
+
},
|
38
|
+
id: 'c3d-client',
|
39
|
+
jsonrpc: '2.0'
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
send_command request
|
44
|
+
end
|
45
|
+
|
46
|
+
def transact recipient, data='', value='', gas='100000', gas_price='100000000000000'
|
47
|
+
sleep 0.5 if ( Time.now - @last_push < 0.5 )
|
48
|
+
recipient = guard_addresses recipient
|
49
|
+
data = build_data data
|
50
|
+
case @client
|
51
|
+
when :go
|
52
|
+
request = {
|
53
|
+
id: 'c3d-client',
|
54
|
+
method: "EthereumApi.Transact",
|
55
|
+
params: [{
|
56
|
+
recipient: recipient,
|
57
|
+
value: value,
|
58
|
+
gas: gas,
|
59
|
+
gasprice: gas_price
|
60
|
+
}]
|
61
|
+
}
|
62
|
+
when :cpp
|
63
|
+
request = {
|
64
|
+
method: 'transact',
|
65
|
+
params: {
|
66
|
+
sec: ENV['ETH_KEY'],
|
67
|
+
xValue: value.to_s,
|
68
|
+
aDest: recipient,
|
69
|
+
bData: data,
|
70
|
+
xGas: gas.to_s,
|
71
|
+
xGasPrice: gas_price.to_s
|
72
|
+
},
|
73
|
+
id: 'c3d-client',
|
74
|
+
jsonrpc: '2.0'
|
75
|
+
}
|
76
|
+
end
|
77
|
+
@last_push = Time.now
|
78
|
+
send_command request
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def get_key
|
83
|
+
case @client
|
84
|
+
when :go
|
85
|
+
request = {
|
86
|
+
id: 'c3d-client',
|
87
|
+
method: "EthereumApi.GetKey",
|
88
|
+
params: [{}]
|
89
|
+
}
|
90
|
+
when :cpp
|
91
|
+
request = {
|
92
|
+
id: 'c3d-client',
|
93
|
+
method: "key",
|
94
|
+
params: {},
|
95
|
+
jsonrpc: '2.0'
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
send_command request
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def guard_addresses address
|
105
|
+
unless address[0..1] == "0x"
|
106
|
+
address = "0x" + address
|
107
|
+
end
|
108
|
+
address
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_data data
|
112
|
+
if data.class == Array
|
113
|
+
builded = "0x"
|
114
|
+
data.each do |piece|
|
115
|
+
if piece[0..1] == "0x"
|
116
|
+
piece = piece[2..-1]
|
117
|
+
piece = piece.rjust(64,'0')
|
118
|
+
else
|
119
|
+
piece = piece.unpack('c*').map{|s| s.to_s(16)}.join('')
|
120
|
+
piece = piece.ljust(64,'0')
|
121
|
+
end
|
122
|
+
builded << piece
|
123
|
+
end
|
124
|
+
return builded
|
125
|
+
else
|
126
|
+
return data
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def send_command request
|
131
|
+
@request.body = request.to_json
|
132
|
+
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Sending Question >>\t#{@request.body}"
|
133
|
+
handle_response JSON.parse(@question_socket.request(@request).body)
|
134
|
+
end
|
135
|
+
|
136
|
+
def handle_response response
|
137
|
+
unless response["error"]
|
138
|
+
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Received Answer >>\tanswer:#{response['result']}"
|
139
|
+
return response["result"]
|
140
|
+
else
|
141
|
+
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Received Answer >>\tERROR!"
|
142
|
+
return nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,148 @@
|
|
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
|
+
module C3D
|
5
|
+
class ConnectTorrent
|
6
|
+
include Celluloid
|
7
|
+
attr_accessor :session_id, :url, :basic_auth, :fields, :debug_mode
|
8
|
+
|
9
|
+
TORRENT_FIELDS = [
|
10
|
+
"id",
|
11
|
+
"name",
|
12
|
+
"totalSize",
|
13
|
+
"isFinished",
|
14
|
+
"percentDone",
|
15
|
+
]
|
16
|
+
|
17
|
+
def initialize opts
|
18
|
+
@url = opts[:url]
|
19
|
+
@fields = opts[:fields] || TORRENT_FIELDS
|
20
|
+
@basic_auth = { :username => opts[:username], :password => opts[:password] } if opts[:username]
|
21
|
+
@debug_mode = opts[:debug_mode] || false
|
22
|
+
@session_id = "c3d-torrent"
|
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"]["torrents"]
|
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\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
|
148
|
+
end
|
@@ -0,0 +1,84 @@
|
|
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
|
+
module C3D
|
6
|
+
class Blobber
|
7
|
+
include Celluloid
|
8
|
+
attr_accessor :tor_file, :blob_file, :sha1_trun, :btih
|
9
|
+
|
10
|
+
def initialize blob
|
11
|
+
@piecelength = 32 * 1024
|
12
|
+
if blob
|
13
|
+
prepare blob
|
14
|
+
build
|
15
|
+
write_torrent
|
16
|
+
publish_torrent
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def prepare blob
|
23
|
+
sha1_full = Digest::SHA1.hexdigest blob
|
24
|
+
@sha1_trun = sha1_full[0..23]
|
25
|
+
@tor_file = File.join(ENV['TORRENTS_DIR'], "#{sha1_trun}.torrent")
|
26
|
+
@blob_file = File.join(ENV['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\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\t" + "#{@tor_file}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def publish_torrent
|
74
|
+
torrent = $puller.create @tor_file
|
75
|
+
begin
|
76
|
+
@btih = torrent["torrent-added"]['hashString']
|
77
|
+
rescue
|
78
|
+
@btih = torrent["torrent-duplicate"]['hashString']
|
79
|
+
end
|
80
|
+
mag_link = "magnet:?xt=urn:btih:" + @btih + "&dn=" + @sha1_trun
|
81
|
+
puts "[C3D-EPM::#{Time.now.strftime( "%F %T" )}] Magnet Link >>\t\t" + mag_link
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module C3D
|
4
|
+
module TransmissionRunner
|
5
|
+
extend self
|
6
|
+
def start_transmission
|
7
|
+
unless is_trans_running?
|
8
|
+
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')}"
|
9
|
+
sleep 3
|
10
|
+
at_exit { Process.kill("INT", pid) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def is_trans_running?
|
15
|
+
a = `ps ux`.split("\n").select{|e| e[/transmission-daemon/]}
|
16
|
+
b = `ps ux`.split("\n").select{|e| e[/transmission-daemon -f --no-incomplete-dir -o -C -p /]}
|
17
|
+
if ! a.empty? and b.empty?
|
18
|
+
p "Please stop your default Transmission Server with `sudo service transmission-daemon stop` and then restart."
|
19
|
+
exit 0
|
20
|
+
end
|
21
|
+
return (! b.empty?)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module EthRunner
|
26
|
+
extend self
|
27
|
+
|
28
|
+
def start_ethereum settings
|
29
|
+
unless is_eth_running?
|
30
|
+
path = settings["path-to-eth"] || "/opt/cpp-ethereum/build/eth/eth"
|
31
|
+
port = settings["eth_rpc_port"] || "9090"
|
32
|
+
peer_port = settings["eth_peer_port"] || "30303"
|
33
|
+
client_name = settings["eth_client_name"] || "c3d-headless"
|
34
|
+
remote = settings["eth_remote"] || ""
|
35
|
+
if remote != ""
|
36
|
+
remote = "-r #{remote}"
|
37
|
+
end
|
38
|
+
dir = settings["blockchain_dir"] || ""
|
39
|
+
if dir != ""
|
40
|
+
dir = "-d #{dir}"
|
41
|
+
end
|
42
|
+
mine = settings["eth_mine"] || "off"
|
43
|
+
if mine == ("off" || "false")
|
44
|
+
mine = "-m off"
|
45
|
+
elsif mine == ("on" || "true")
|
46
|
+
mine = "-m on"
|
47
|
+
end
|
48
|
+
key = settings["primary_account_key"] || ""
|
49
|
+
if key != ""
|
50
|
+
key = "-s #{key}"
|
51
|
+
end
|
52
|
+
pid = spawn "#{path} --json-rpc-port #{port} -l #{peer_port} -c #{client_name} #{remote} #{dir} #{mine} #{key}"
|
53
|
+
sleep 7
|
54
|
+
at_exit { Process.kill("INT", pid) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def is_eth_running?
|
60
|
+
a = `ps ux`.split("\n").select{|e| e[/eth --json-rpc-port/]}
|
61
|
+
return (! a.empty?)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|