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.
Files changed (75) hide show
  1. data/README +23 -0
  2. data/Rakefile +51 -0
  3. data/bin/sinatra-s3 +30 -0
  4. data/db/migrate/001_create_bits.rb +28 -0
  5. data/db/migrate/002_create_users.rb +24 -0
  6. data/db/migrate/003_create_bits_users.rb +16 -0
  7. data/db/migrate/004_create_torrents.rb +22 -0
  8. data/db/migrate/005_create_torrent_peers.rb +26 -0
  9. data/examples/README +9 -0
  10. data/examples/wiki.rb +199 -0
  11. data/examples/wiki.ru +5 -0
  12. data/examples/wikicloth/MIT-LICENSE +20 -0
  13. data/examples/wikicloth/README +81 -0
  14. data/examples/wikicloth/Rakefile +23 -0
  15. data/examples/wikicloth/init.rb +1 -0
  16. data/examples/wikicloth/install.rb +0 -0
  17. data/examples/wikicloth/lib/core_ext.rb +43 -0
  18. data/examples/wikicloth/lib/wiki_buffer/html_element.rb +237 -0
  19. data/examples/wikicloth/lib/wiki_buffer/link.rb +70 -0
  20. data/examples/wikicloth/lib/wiki_buffer/table.rb +159 -0
  21. data/examples/wikicloth/lib/wiki_buffer/var.rb +77 -0
  22. data/examples/wikicloth/lib/wiki_buffer.rb +279 -0
  23. data/examples/wikicloth/lib/wiki_cloth.rb +61 -0
  24. data/examples/wikicloth/lib/wiki_link_handler.rb +138 -0
  25. data/examples/wikicloth/lib/wikicloth.rb +5 -0
  26. data/examples/wikicloth/run_tests.rb +48 -0
  27. data/examples/wikicloth/sample_documents/air_force_one.wiki +170 -0
  28. data/examples/wikicloth/sample_documents/cheatsheet.wiki +205 -0
  29. data/examples/wikicloth/sample_documents/default.css +34 -0
  30. data/examples/wikicloth/sample_documents/elements.wiki +7 -0
  31. data/examples/wikicloth/sample_documents/george_washington.wiki +526 -0
  32. data/examples/wikicloth/sample_documents/images.wiki +15 -0
  33. data/examples/wikicloth/sample_documents/lists.wiki +421 -0
  34. data/examples/wikicloth/sample_documents/pipe_trick.wiki +68 -0
  35. data/examples/wikicloth/sample_documents/random.wiki +55 -0
  36. data/examples/wikicloth/sample_documents/tv.wiki +312 -0
  37. data/examples/wikicloth/sample_documents/wiki.png +0 -0
  38. data/examples/wikicloth/sample_documents/wiki_tables.wiki +410 -0
  39. data/examples/wikicloth/tasks/wikicloth_tasks.rake +0 -0
  40. data/examples/wikicloth/test/test_helper.rb +3 -0
  41. data/examples/wikicloth/test/wiki_cloth_test.rb +8 -0
  42. data/examples/wikicloth/uninstall.rb +0 -0
  43. data/examples/wikicloth/wikicloth-0.1.3.gem +0 -0
  44. data/examples/wikicloth/wikicloth.gemspec +69 -0
  45. data/lib/sinatra-s3/admin.rb +626 -0
  46. data/lib/sinatra-s3/base.rb +526 -0
  47. data/lib/sinatra-s3/errors.rb +51 -0
  48. data/lib/sinatra-s3/ext.rb +20 -0
  49. data/lib/sinatra-s3/helpers/acp.rb +100 -0
  50. data/lib/sinatra-s3/helpers/admin.rb +41 -0
  51. data/lib/sinatra-s3/helpers/tracker.rb +42 -0
  52. data/lib/sinatra-s3/helpers/versioning.rb +27 -0
  53. data/lib/sinatra-s3/helpers.rb +79 -0
  54. data/lib/sinatra-s3/models/bit.rb +180 -0
  55. data/lib/sinatra-s3/models/bucket.rb +81 -0
  56. data/lib/sinatra-s3/models/file_info.rb +3 -0
  57. data/lib/sinatra-s3/models/git_bucket.rb +3 -0
  58. data/lib/sinatra-s3/models/slot.rb +47 -0
  59. data/lib/sinatra-s3/models/torrent.rb +6 -0
  60. data/lib/sinatra-s3/models/torrent_peer.rb +5 -0
  61. data/lib/sinatra-s3/models/user.rb +35 -0
  62. data/lib/sinatra-s3/s3.rb +57 -0
  63. data/lib/sinatra-s3/tasks.rb +62 -0
  64. data/lib/sinatra-s3/tracker.rb +134 -0
  65. data/lib/sinatra-s3.rb +1 -0
  66. data/public/css/control.css +225 -0
  67. data/public/css/wiki.css +47 -0
  68. data/public/images/external-link.gif +0 -0
  69. data/public/js/prototype.js +2539 -0
  70. data/public/js/upload_status.js +117 -0
  71. data/public/test.html +8 -0
  72. data/s3.yml.example +17 -0
  73. data/test/s3api_test.rb +121 -0
  74. data/test/test_helper.rb +25 -0
  75. 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
+ }
@@ -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