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
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
|