sinatra-s3 0.98
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.
- data/README +23 -0
- data/Rakefile +51 -0
- data/bin/sinatra-s3 +30 -0
- data/db/migrate/001_create_bits.rb +28 -0
- data/db/migrate/002_create_users.rb +24 -0
- data/db/migrate/003_create_bits_users.rb +16 -0
- data/db/migrate/004_create_torrents.rb +22 -0
- data/db/migrate/005_create_torrent_peers.rb +26 -0
- data/examples/README +9 -0
- data/examples/wiki.rb +199 -0
- data/examples/wiki.ru +5 -0
- data/examples/wikicloth/MIT-LICENSE +20 -0
- data/examples/wikicloth/README +81 -0
- data/examples/wikicloth/Rakefile +23 -0
- data/examples/wikicloth/init.rb +1 -0
- data/examples/wikicloth/install.rb +0 -0
- data/examples/wikicloth/lib/core_ext.rb +43 -0
- data/examples/wikicloth/lib/wiki_buffer/html_element.rb +237 -0
- data/examples/wikicloth/lib/wiki_buffer/link.rb +70 -0
- data/examples/wikicloth/lib/wiki_buffer/table.rb +159 -0
- data/examples/wikicloth/lib/wiki_buffer/var.rb +77 -0
- data/examples/wikicloth/lib/wiki_buffer.rb +279 -0
- data/examples/wikicloth/lib/wiki_cloth.rb +61 -0
- data/examples/wikicloth/lib/wiki_link_handler.rb +138 -0
- data/examples/wikicloth/lib/wikicloth.rb +5 -0
- data/examples/wikicloth/run_tests.rb +48 -0
- data/examples/wikicloth/sample_documents/air_force_one.wiki +170 -0
- data/examples/wikicloth/sample_documents/cheatsheet.wiki +205 -0
- data/examples/wikicloth/sample_documents/default.css +34 -0
- data/examples/wikicloth/sample_documents/elements.wiki +7 -0
- data/examples/wikicloth/sample_documents/george_washington.wiki +526 -0
- data/examples/wikicloth/sample_documents/images.wiki +15 -0
- data/examples/wikicloth/sample_documents/lists.wiki +421 -0
- data/examples/wikicloth/sample_documents/pipe_trick.wiki +68 -0
- data/examples/wikicloth/sample_documents/random.wiki +55 -0
- data/examples/wikicloth/sample_documents/tv.wiki +312 -0
- data/examples/wikicloth/sample_documents/wiki.png +0 -0
- data/examples/wikicloth/sample_documents/wiki_tables.wiki +410 -0
- data/examples/wikicloth/tasks/wikicloth_tasks.rake +0 -0
- data/examples/wikicloth/test/test_helper.rb +3 -0
- data/examples/wikicloth/test/wiki_cloth_test.rb +8 -0
- data/examples/wikicloth/uninstall.rb +0 -0
- data/examples/wikicloth/wikicloth-0.1.3.gem +0 -0
- data/examples/wikicloth/wikicloth.gemspec +69 -0
- data/lib/sinatra-s3/admin.rb +626 -0
- data/lib/sinatra-s3/base.rb +526 -0
- data/lib/sinatra-s3/errors.rb +51 -0
- data/lib/sinatra-s3/ext.rb +20 -0
- data/lib/sinatra-s3/helpers/acp.rb +100 -0
- data/lib/sinatra-s3/helpers/admin.rb +41 -0
- data/lib/sinatra-s3/helpers/tracker.rb +42 -0
- data/lib/sinatra-s3/helpers/versioning.rb +27 -0
- data/lib/sinatra-s3/helpers.rb +79 -0
- data/lib/sinatra-s3/models/bit.rb +180 -0
- data/lib/sinatra-s3/models/bucket.rb +81 -0
- data/lib/sinatra-s3/models/file_info.rb +3 -0
- data/lib/sinatra-s3/models/git_bucket.rb +3 -0
- data/lib/sinatra-s3/models/slot.rb +47 -0
- data/lib/sinatra-s3/models/torrent.rb +6 -0
- data/lib/sinatra-s3/models/torrent_peer.rb +5 -0
- data/lib/sinatra-s3/models/user.rb +35 -0
- data/lib/sinatra-s3/s3.rb +57 -0
- data/lib/sinatra-s3/tasks.rb +62 -0
- data/lib/sinatra-s3/tracker.rb +134 -0
- data/lib/sinatra-s3.rb +1 -0
- data/public/css/control.css +225 -0
- data/public/css/wiki.css +47 -0
- data/public/images/external-link.gif +0 -0
- data/public/js/prototype.js +2539 -0
- data/public/js/upload_status.js +117 -0
- data/public/test.html +8 -0
- data/s3.yml.example +17 -0
- data/test/s3api_test.rb +121 -0
- data/test/test_helper.rb +25 -0
- metadata +156 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
module S3
|
|
2
|
+
|
|
3
|
+
TRACKER_INTERVAL = 10.minutes
|
|
4
|
+
EVENT_CODES = {
|
|
5
|
+
'started' => 200,
|
|
6
|
+
'completed' => 201,
|
|
7
|
+
'stopped' => 202
|
|
8
|
+
}
|
|
9
|
+
# All tracker errors are thrown as this class.
|
|
10
|
+
class TrackerError < Exception; end
|
|
11
|
+
|
|
12
|
+
class Tracker < Sinatra::Base
|
|
13
|
+
|
|
14
|
+
helpers do
|
|
15
|
+
include S3::AdminHelpers
|
|
16
|
+
include S3::TrackerHelper
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
configure do
|
|
20
|
+
ActiveRecord::Base.establish_connection(S3.config[:db])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
before do
|
|
24
|
+
ActiveRecord::Base.verify_active_connections!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
get '/tracker/announce/?' do
|
|
28
|
+
raise TrackerError, "No info_hash present." unless params[:info_hash]
|
|
29
|
+
raise TrackerError, "No peer_id present." unless params[:peer_id]
|
|
30
|
+
|
|
31
|
+
info_hash = params[:info_hash].to_hex_s
|
|
32
|
+
guid = params[:peer_id].to_hex_s
|
|
33
|
+
trnt = Torrent.find_by_info_hash(info_hash)
|
|
34
|
+
raise TrackerError, "No file found with hash of `#{params[:info_hash]}'." unless trnt
|
|
35
|
+
|
|
36
|
+
peer = TorrentPeer.find_by_guid_and_torrent_id(guid, trnt.id)
|
|
37
|
+
unless peer
|
|
38
|
+
peer = TorrentPeer.find_by_ipaddr_and_port_and_torrent_id(env['REMOTE_ADDR'], params[:port], trnt.id)
|
|
39
|
+
end
|
|
40
|
+
unless peer
|
|
41
|
+
peer = TorrentPeer.new(:torrent_id => trnt.id)
|
|
42
|
+
trnt.hits += 1
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
trnt.total += 1 if params[:event] == "completed"
|
|
46
|
+
params[:event] = 'completed' if params[:left] == 0
|
|
47
|
+
if params[:event]
|
|
48
|
+
peer.update_attributes(:uploaded => params[:uploaded], :downloaded => params[:downloaded],
|
|
49
|
+
:remaining => params[:left], :event => EVENT_CODES[params[:event]], :key => params[:key],
|
|
50
|
+
:port => params[:port], :ipaddr => env['REMOTE_ADDR'], :guid => guid)
|
|
51
|
+
end
|
|
52
|
+
complete, incomplete = 0, 0
|
|
53
|
+
peers = trnt.torrent_peers.map do |peer|
|
|
54
|
+
if peer.updated_at < Time.now - (TRACKER_INTERVAL * 2) or (params[:event] == 'stopped' and peer.guid == guid)
|
|
55
|
+
peer.destroy
|
|
56
|
+
next
|
|
57
|
+
end
|
|
58
|
+
if peer.event == EVENT_CODES['completed']
|
|
59
|
+
complete += 1
|
|
60
|
+
else
|
|
61
|
+
incomplete += 1
|
|
62
|
+
end
|
|
63
|
+
next if peer.guid == guid
|
|
64
|
+
{'peer id' => peer.guid.from_hex_s, 'ip' => peer.ipaddr, 'port' => peer.port}
|
|
65
|
+
end.compact
|
|
66
|
+
trnt.seeders = complete
|
|
67
|
+
trnt.leechers = incomplete
|
|
68
|
+
trnt.save
|
|
69
|
+
tracker_reply('peers' => peers, 'complete' => complete, 'incomplete' => incomplete)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
get '/tracker/scrape/?' do
|
|
73
|
+
@torrents = torrent_list params[:info_hash]
|
|
74
|
+
tracker_reply('files' => @torrents.map { |t|
|
|
75
|
+
{'complete' => t.seeders, 'downloaded' => t.total, 'incomplete' => t.leechers, 'name' => t.bit.name} })
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
get '/tracker/?' do
|
|
79
|
+
@torrents = torrent_list params[:info_hash]
|
|
80
|
+
@transfer = TorrentPeer.sum :downloaded, :group => :torrent
|
|
81
|
+
torrent_view
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
protected
|
|
85
|
+
def torrent_view
|
|
86
|
+
builder do |html|
|
|
87
|
+
html.html do
|
|
88
|
+
html.head do
|
|
89
|
+
html.title "Sinatra-S3 Torrents"
|
|
90
|
+
html.style "@import '/control/s/css/control.css';", :type => 'text/css'
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
html.div :id => "page" do
|
|
94
|
+
html.div :id => "header" do
|
|
95
|
+
html.h1 "Sinatra-S3 Tracker"
|
|
96
|
+
html.h2 "Active Torrents"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
html.div :id => "content" do
|
|
100
|
+
html.body do
|
|
101
|
+
html.table do
|
|
102
|
+
html.thead do
|
|
103
|
+
html.tr do
|
|
104
|
+
html.th "Name"
|
|
105
|
+
html.th "Size"
|
|
106
|
+
html.th "Seeders"
|
|
107
|
+
html.th "Leechers"
|
|
108
|
+
html.th "Downloads"
|
|
109
|
+
html.th "Transfered"
|
|
110
|
+
html.th "Since"
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
html.tbody do
|
|
114
|
+
@torrents.each do |t|
|
|
115
|
+
html.tr do
|
|
116
|
+
html.td t.bit.name
|
|
117
|
+
html.td number_to_human_size(t.bit.size)
|
|
118
|
+
html.td t.seeders
|
|
119
|
+
html.td t.leechers
|
|
120
|
+
html.td t.total
|
|
121
|
+
html.td number_to_human_size(@transfer[t])
|
|
122
|
+
html.td RubyTorrent::MetaInfo.from_stream(StringIO.new(t.metainfo)).creation_date #t.metainfo.creation_date
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
data/lib/sinatra-s3.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'sinatra-s3', 's3')
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#progress-bar {
|
|
2
|
+
width:500px;
|
|
3
|
+
height:25px;
|
|
4
|
+
margin:15px 0px;
|
|
5
|
+
border:solid 1px #000;
|
|
6
|
+
position:relative;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
#progress-bar #status-bar {
|
|
10
|
+
display:block;
|
|
11
|
+
height:25px;
|
|
12
|
+
width:0;
|
|
13
|
+
background-color:#3F7C5F;
|
|
14
|
+
border-right:solid 1px #000;
|
|
15
|
+
position:absolute;
|
|
16
|
+
top:0; left:0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#progress-bar #status-text {
|
|
20
|
+
display:block;
|
|
21
|
+
padding: 0 15px;
|
|
22
|
+
line-height:25px;
|
|
23
|
+
position:absolute;
|
|
24
|
+
top:0; left:0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body {
|
|
28
|
+
font-family: arial, helvetica, sans-serif;
|
|
29
|
+
font-size: 16px;
|
|
30
|
+
margin: 20px;
|
|
31
|
+
background-color: #f5f8e1;
|
|
32
|
+
text-align: center;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
h1, h2, h3, h4, h5 {
|
|
36
|
+
font-weight: normal;
|
|
37
|
+
margin: 0; padding: 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h1 { font-size: 15px; color: #797; }
|
|
41
|
+
h2 { font-size: 34px; }
|
|
42
|
+
h3 { font-size: 26px; margin-top: 12px; }
|
|
43
|
+
h4 { font-size: 21px; }
|
|
44
|
+
|
|
45
|
+
#page {
|
|
46
|
+
width: 700px;
|
|
47
|
+
margin: 0 auto;
|
|
48
|
+
padding: 3px 20px;
|
|
49
|
+
border: solid 1px #d5d8c1;
|
|
50
|
+
background-color: white;
|
|
51
|
+
text-align: left;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#header, #content {
|
|
55
|
+
margin: 12px 0px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.menu {
|
|
59
|
+
float: right;
|
|
60
|
+
font-size: 11px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.menu ul {
|
|
64
|
+
list-style: none;
|
|
65
|
+
margin: 0; padding: 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.menu ul li {
|
|
69
|
+
display: inline;
|
|
70
|
+
margin: 0; padding: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.menu ul li a {
|
|
74
|
+
color: black;
|
|
75
|
+
text-decoration: none;
|
|
76
|
+
margin: 0px 2px; padding: 3px 6px;
|
|
77
|
+
font-weight: bold;
|
|
78
|
+
background-color: #f1f4d8;
|
|
79
|
+
-moz-opacity: 0.92;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.menu ul li a.active {
|
|
83
|
+
background-color: #f1e428;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.menu ul li a:hover {
|
|
87
|
+
color: white;
|
|
88
|
+
background-color: #C13438;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
ul.errors {
|
|
92
|
+
color: black;
|
|
93
|
+
background-color: #f1e428;
|
|
94
|
+
padding: 4px;
|
|
95
|
+
margin: 0 0 10px 0;
|
|
96
|
+
-moz-opacity: 0.80;
|
|
97
|
+
width: 250px;
|
|
98
|
+
list-style: none;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
form.create {
|
|
102
|
+
padding: 0 0 10px 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
form.create .required,
|
|
106
|
+
form.create .optional {
|
|
107
|
+
padding: 5px 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
form.create label {
|
|
111
|
+
display: block;
|
|
112
|
+
color: #575;
|
|
113
|
+
font-size: 10px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
form.create div.inline input,
|
|
117
|
+
form.create div.inline label,
|
|
118
|
+
form.create div.inline select
|
|
119
|
+
{
|
|
120
|
+
display: inline;
|
|
121
|
+
width: auto;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
form.create div input,
|
|
125
|
+
form.create div select {
|
|
126
|
+
font-size: 16px;
|
|
127
|
+
width: 250px;
|
|
128
|
+
padding: 1px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
form.create div input.fixed {
|
|
132
|
+
font-family: "Lucida Console", monospace;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
form.create div input.large {
|
|
136
|
+
font-size: 21px;
|
|
137
|
+
font-weight: bold;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
form.create div input.long {
|
|
141
|
+
width: 450px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
table {
|
|
145
|
+
border-collapse: collapse;
|
|
146
|
+
border: 2px solid #3f3c5f;
|
|
147
|
+
color: #000;
|
|
148
|
+
background: #fff;
|
|
149
|
+
width: 100%;
|
|
150
|
+
}
|
|
151
|
+
caption {
|
|
152
|
+
margin: 0.3em 0;
|
|
153
|
+
font-size: .7em;
|
|
154
|
+
font-weight: normal;
|
|
155
|
+
text-align: left;
|
|
156
|
+
color: #000;
|
|
157
|
+
background: transparent;
|
|
158
|
+
}
|
|
159
|
+
td, th {
|
|
160
|
+
border: 1px solid #336;
|
|
161
|
+
padding: 0.3em;
|
|
162
|
+
}
|
|
163
|
+
thead th {
|
|
164
|
+
border: 1px solid #336;
|
|
165
|
+
text-align: left;
|
|
166
|
+
font-weight: bold;
|
|
167
|
+
background-color: #f1f478;
|
|
168
|
+
color: #333;
|
|
169
|
+
}
|
|
170
|
+
tfoot th, tfoot td {
|
|
171
|
+
border: 1px solid #396;
|
|
172
|
+
text-align: left;
|
|
173
|
+
background: #e8e8cf;
|
|
174
|
+
}
|
|
175
|
+
tfoot th {
|
|
176
|
+
font-weight: bold;
|
|
177
|
+
}
|
|
178
|
+
tbody td a {
|
|
179
|
+
background: transparent;
|
|
180
|
+
color: #00c;
|
|
181
|
+
text-decoration: underline;
|
|
182
|
+
}
|
|
183
|
+
tbody td a:hover {
|
|
184
|
+
background: transparent;
|
|
185
|
+
color: #00c;
|
|
186
|
+
text-decoration: underline;
|
|
187
|
+
}
|
|
188
|
+
tbody tr:hover th {
|
|
189
|
+
background-color: #c66;
|
|
190
|
+
}
|
|
191
|
+
tbody tr:hover th a {
|
|
192
|
+
color: white;
|
|
193
|
+
}
|
|
194
|
+
tbody th a {
|
|
195
|
+
background: transparent;
|
|
196
|
+
color: #3f7c5f;
|
|
197
|
+
text-decoration: underline;
|
|
198
|
+
font-weight: normal;
|
|
199
|
+
}
|
|
200
|
+
tbody th, tbody td {
|
|
201
|
+
vertical-align: top;
|
|
202
|
+
text-align: left;
|
|
203
|
+
font-size: 15px;
|
|
204
|
+
}
|
|
205
|
+
tfoot td {
|
|
206
|
+
border: 1px solid #996;
|
|
207
|
+
}
|
|
208
|
+
tbody tr:hover {
|
|
209
|
+
background: #efffd9;
|
|
210
|
+
}
|
|
211
|
+
tbody th:hover p {
|
|
212
|
+
color: #fec;
|
|
213
|
+
}
|
|
214
|
+
tbody th p {
|
|
215
|
+
font-size: 12px;
|
|
216
|
+
font-weight: normal;
|
|
217
|
+
margin: 4px 0;
|
|
218
|
+
}
|
|
219
|
+
.details {
|
|
220
|
+
padding-left: 12px;
|
|
221
|
+
}
|
|
222
|
+
.details p {
|
|
223
|
+
font-size: 10px;
|
|
224
|
+
line-height: 110%;
|
|
225
|
+
}
|
data/public/css/wiki.css
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
.exlink { padding-right:15px;background:transparent url(/control/s/images/external-link.gif) no-repeat center right }
|
|
2
|
+
#title { text-decoration:none;font-weight:bold;color:#000 }
|
|
3
|
+
.thumb { background-color:#F8FCFF;border:1px solid #fff;margin-bottom:0.5em }
|
|
4
|
+
.tright { border-width:0.5em 0 0.8em 1.4em;margin:0.5em 0 0.8em 1.4em;clear:right;float:right }
|
|
5
|
+
.thumbinner {
|
|
6
|
+
background-color:#F9F9F9;
|
|
7
|
+
border:1px solid #CCCCCC;
|
|
8
|
+
font-size:94%;
|
|
9
|
+
overflow:hidden;
|
|
10
|
+
padding:3px !important;
|
|
11
|
+
text-align:center;
|
|
12
|
+
}
|
|
13
|
+
.thumbimage { border:1px solid #CCCCCC }
|
|
14
|
+
ins,del { display:block }
|
|
15
|
+
ins { text-decoration:none }
|
|
16
|
+
#page h1, #page h2, #page h3, #page h4, #page h5, #page h6 {
|
|
17
|
+
padding-bottom:0.17em;
|
|
18
|
+
padding-top:0.5em;
|
|
19
|
+
color:#000;
|
|
20
|
+
}
|
|
21
|
+
#page h1 { border-bottom:1px solid #AAAAAA; }
|
|
22
|
+
.editsection {
|
|
23
|
+
font-size:76%;
|
|
24
|
+
font-weight:normal;
|
|
25
|
+
}
|
|
26
|
+
.editsection {
|
|
27
|
+
display:none;
|
|
28
|
+
float:right;
|
|
29
|
+
margin-left:5px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pre {
|
|
33
|
+
background-color:#F9F9F9;
|
|
34
|
+
border:1px dashed #2F6FAB;
|
|
35
|
+
color:black;
|
|
36
|
+
line-height:1.1em;
|
|
37
|
+
padding:1em;
|
|
38
|
+
white-space: pre-wrap; /* css-3 */
|
|
39
|
+
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
|
40
|
+
white-space: -pre-wrap; /* Opera 4-6 */
|
|
41
|
+
white-space: -o-pre-wrap; /* Opera 7 */
|
|
42
|
+
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
|
43
|
+
}
|
|
44
|
+
#header { text-align:left;padding:10px 0;width:700px;margin:0 auto }
|
|
45
|
+
#page #revision_history { border:0px;margin:15px 0 }
|
|
46
|
+
#revision_history td, #revision_history th { border:0px }
|
|
47
|
+
#revision_history .check { width:1.5em;text-align:center }
|
|
Binary file
|