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,117 @@
1
+ var UploadProgress = {
2
+ uploading: null,
3
+ monitor: function(upid) {
4
+ if(!this.periodicExecuter) {
5
+ $('upload-form').style.display = 'none';
6
+ $('progress-bar').style.display = 'block';
7
+ $('results').innerHTML = '<h3>Uploading File...</h3>';
8
+ this.periodicExecuter = new PeriodicalExecuter(function() {
9
+ if(!UploadProgress.uploading) return;
10
+ new Ajax.Request('/control/progress/' + upid, { method: 'get', onSuccess: function(response) { eval(response.responseText); } });
11
+ }, 3);
12
+ }
13
+
14
+ this.uploading = true;
15
+ this.StatusBar.create();
16
+ },
17
+
18
+ update: function(total, current) {
19
+ if(!this.uploading) return;
20
+ var status = current / total;
21
+ var statusHTML = status.toPercentage();
22
+ $('results').innerHTML = '<h3>Uploading File...</h3>' + statusHTML + "<br /><small>" + current.toHumanSize() + ' of ' + total.toHumanSize() + " uploaded.</small>";
23
+ this.StatusBar.update(status, statusHTML);
24
+ },
25
+
26
+ finish: function() {
27
+ this.uploading = false;
28
+ this.StatusBar.finish();
29
+ $('results').innerHTML = '<h3>Upload finished!</h3>';
30
+ setTimeout(function () { window.location.href=window.location.href; },2000);
31
+ },
32
+
33
+ cancel: function(msg) {
34
+ if(!this.uploading) return;
35
+ this.uploading = false;
36
+ if(this.StatusBar.statusText) this.StatusBar.statusText.innerHTML = msg || 'canceled';
37
+ },
38
+
39
+ StatusBar: {
40
+ statusBar: null,
41
+ statusText: null,
42
+ statusBarWidth: 500,
43
+
44
+ create: function() {
45
+ this.statusBar = this._createStatus('status-bar');
46
+ this.statusText = this._createStatus('status-text');
47
+ this.statusText.innerHTML = '0%';
48
+ this.statusBar.style.width = '0';
49
+ },
50
+
51
+ update: function(status, statusHTML) {
52
+ this.statusText.innerHTML = statusHTML;
53
+ this.statusBar.style.width = Math.floor(this.statusBarWidth * status) + 'px';
54
+ },
55
+
56
+ finish: function() {
57
+ this.statusText.innerHTML = '100%';
58
+ this.statusBar.style.width = '100%';
59
+ },
60
+
61
+ _createStatus: function(id) {
62
+ el = $(id);
63
+ if(!el) {
64
+ el = document.createElement('span');
65
+ el.setAttribute('id', id);
66
+ $('progress-bar').appendChild(el);
67
+ }
68
+ return el;
69
+ }
70
+ },
71
+
72
+ FileField: {
73
+ add: function() {
74
+ new Insertion.Bottom('file-fields', '<p style="display:none"><input id="data" name="data" type="file" /> <a href="#" onclick="UploadProgress.FileField.remove(this);return false;">x</a></p>')
75
+ $$('#file-fields p').last().visualEffect('blind_down', {duration:0.3});
76
+ },
77
+
78
+ remove: function(anchor) {
79
+ anchor.parentNode.visualEffect('drop_out', {duration:0.25});
80
+ }
81
+ }
82
+ }
83
+
84
+ Number.prototype.bytes = function() { return this; };
85
+ Number.prototype.kilobytes = function() { return this * 1024; };
86
+ Number.prototype.megabytes = function() { return this * (1024).kilobytes(); };
87
+ Number.prototype.gigabytes = function() { return this * (1024).megabytes(); };
88
+ Number.prototype.terabytes = function() { return this * (1024).gigabytes(); };
89
+ Number.prototype.petabytes = function() { return this * (1024).terabytes(); };
90
+ Number.prototype.exabytes = function() { return this * (1024).petabytes(); };
91
+ ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte', 'exabyte'].each(function(meth) {
92
+ Number.prototype[meth] = Number.prototype[meth+'s'];
93
+ });
94
+
95
+ Number.prototype.toPrecision = function() {
96
+ var precision = arguments[0] || 2;
97
+ var s = Math.round(this * Math.pow(10, precision)).toString();
98
+ var pos = s.length - precision;
99
+ var last = s.substr(pos, precision);
100
+ return s.substr(0, pos) + (last.match("^0{" + precision + "}$") ? '' : '.' + last);
101
+ }
102
+
103
+ // (1/10).toPercentage()
104
+ // # => '10%'
105
+ Number.prototype.toPercentage = function() {
106
+ return (this * 100).toPrecision() + '%';
107
+ }
108
+
109
+ Number.prototype.toHumanSize = function() {
110
+ if(this < (1).kilobyte()) return this + " Bytes";
111
+ if(this < (1).megabyte()) return (this / (1).kilobyte()).toPrecision() + ' KB';
112
+ if(this < (1).gigabytes()) return (this / (1).megabyte()).toPrecision() + ' MB';
113
+ if(this < (1).terabytes()) return (this / (1).gigabytes()).toPrecision() + ' GB';
114
+ if(this < (1).petabytes()) return (this / (1).terabytes()).toPrecision() + ' TB';
115
+ if(this < (1).exabytes()) return (this / (1).petabytes()).toPrecision() + ' PB';
116
+ return (this / (1).exabytes()).toPrecision() + ' EB';
117
+ }
data/public/test.html ADDED
@@ -0,0 +1,8 @@
1
+ <form action="/test/test.html" method="post">
2
+ <input type="hidden" name="redirect" value="/test/test.html" />
3
+ <input type="hidden" name="Content-Type" value="text/html" />
4
+ <input type="hidden" name="Content-Disposition" value="inline" />
5
+ <p><textarea name="file"></textarea></p>
6
+ <p><input type="text" name="x-amz-meta-comment" value="" /></p>
7
+ <input type="submit" value="Update" />
8
+ </form>
data/s3.yml.example ADDED
@@ -0,0 +1,17 @@
1
+ :development:
2
+ :storage: storage
3
+ :db:
4
+ :database: db/development.db
5
+ :adapter: sqlite3
6
+
7
+ :test:
8
+ :storage: test/storage
9
+ :db:
10
+ :database: db/test.db
11
+ :adapter: sqlite3
12
+
13
+ :production:
14
+ :storage: storage
15
+ :db:
16
+ :database: db/production.db
17
+ :adapter: sqlite3
@@ -0,0 +1,121 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class S3ApiTest < Test::Unit::TestCase
4
+
5
+ def test_create
6
+ begin
7
+ AWS::S3::Bucket.find(bucket_name)
8
+ rescue => e
9
+ assert e.instance_of?(AWS::S3::NoSuchBucket)
10
+ end
11
+
12
+ begin
13
+ bucket = AWS::S3::Bucket.create(bucket_name)
14
+ assert bucket.instance_of?(AWS::S3::Bucket)
15
+ rescue => e
16
+
17
+ end
18
+
19
+ begin
20
+ bucket = AWS::S3::Bucket.create(bucket_name)
21
+ rescue => e
22
+ assert e.instance_of?(AWS::S3::BucketAlreadyExists)
23
+ end
24
+
25
+ begin
26
+ assert AWS::S3::Bucket.delete(bucket_name)
27
+ rescue => e
28
+ end
29
+ end
30
+
31
+ def test_delete
32
+ assert AWS::S3::Bucket.create(bucket_name)
33
+ assert AWS::S3::Bucket.delete(bucket_name)
34
+ end
35
+
36
+ def test_upload
37
+ assert AWS::S3::Bucket.create(bucket_name)
38
+ file = File.join(File.dirname(__FILE__), 'file.jpg')
39
+ bucket = AWS::S3::Bucket.find(bucket_name)
40
+ assert bucket.size == 0
41
+ assert S3Object.store('file.jpg', open(file), bucket_name, { :access => :public_read })
42
+ assert bucket.size == 1
43
+ begin
44
+ AWS::S3::Bucket.delete(bucket_name)
45
+ rescue => e
46
+ assert e.instance_of?(AWS::S3::BucketNotEmpty)
47
+ assert AWS::S3::Bucket.delete(bucket_name, :force => true)
48
+ end
49
+ end
50
+
51
+ def test_move
52
+ AWS::S3::Bucket.create(bucket_name)
53
+ file = File.join(File.dirname(__FILE__), 'file.jpg')
54
+ S3Object.store('file.jpg', open(file), bucket_name)
55
+ obj = S3Object.find('file.jpg', bucket_name)
56
+ assert obj.rename('new.jpg')
57
+
58
+ begin
59
+ AWS::S3::S3Object.find('file.jpg', bucket_name)
60
+ rescue => e
61
+ assert e.instance_of?(AWS::S3::NoSuchKey)
62
+ end
63
+
64
+ obj = AWS::S3::S3Object.find('new.jpg', bucket_name)
65
+ assert obj.instance_of?(AWS::S3::S3Object)
66
+ assert AWS::S3::Bucket.delete(bucket_name, :force => true)
67
+ end
68
+
69
+ def test_acl
70
+ AWS::S3::Bucket.create(bucket_name, { :access => :public_read })
71
+ bucket = AWS::S3::Bucket.find(bucket_name)
72
+ policy = bucket.acl
73
+ assert policy.owner.id == User.find_by_login('admin').key
74
+ assert policy.grants.include?(:public_read)
75
+
76
+ AWS::S3::Bucket.delete(bucket_name, :force => true)
77
+ AWS::S3::Bucket.create(bucket_name)
78
+ bucket = AWS::S3::Bucket.find(bucket_name)
79
+ policy = bucket.acl
80
+ assert !policy.grants.include?(:public_read)
81
+ AWS::S3::Bucket.delete(bucket_name, :force => true)
82
+
83
+ AWS::S3::Bucket.create(bucket_name)
84
+ bucket = AWS::S3::Bucket.find(bucket_name)
85
+ bucket.acl.grants << AWS::S3::ACL::Grant.grant(:public_read_acp)
86
+ bucket.acl(bucket.acl)
87
+ assert bucket.acl.grants.include?(:public_read_acp)
88
+ AWS::S3::Bucket.delete(bucket_name, :force => true)
89
+ end
90
+
91
+ def test_versioning
92
+ AWS::S3::Bucket.create(bucket_name, { :access => :public_read })
93
+ get "/#{bucket_name}/?versioning"
94
+ assert last_response.ok?
95
+ assert !last_response.body.include?('<Versioning>')
96
+ assert last_response.body.include?('<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"></VersioningConfiguration>')
97
+
98
+ @user = User.find_by_login('admin')
99
+ sts = hmac_sha1(@user.secret, "PUT\n\ntext/plain\n\n/#{bucket_name}/?versioning")
100
+ aws_header = "AWS " + "#{@user.key}:#{sts}"
101
+
102
+ header "Content-Type", "text/plain"
103
+ header "Authorization", aws_header
104
+ xml_data = '<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Status>Enabled</Status></VersioningConfiguration>';
105
+ put "/#{bucket_name}/?versioning", xml_data
106
+ assert last_response.ok?
107
+
108
+ header "Authorization", nil
109
+
110
+ get "/#{bucket_name}/?versioning"
111
+ assert last_response.body.include?('<Versioning>Enabled</Versioning>')
112
+
113
+ AWS::S3::Bucket.delete(bucket_name, :force => true)
114
+ end
115
+
116
+ protected
117
+ def bucket_name
118
+ @bucket_name ||= "test_#{Time.now.to_i}"
119
+ end
120
+
121
+ end
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'rack/test'
4
+ require 'aws/s3'
5
+ require File.join(File.dirname(__FILE__), '..','lib','sinatra-s3')
6
+
7
+ admin = User.find_by_login('admin')
8
+
9
+ AWS::S3::Base.establish_connection!(
10
+ :access_key_id => admin.key,
11
+ :secret_access_key => admin.secret,
12
+ :port => 6060,
13
+ :server => 'localhost'
14
+ )
15
+
16
+ class Test::Unit::TestCase
17
+ include AWS::S3
18
+ include Rack::Test::Methods
19
+ include S3::Helpers
20
+
21
+ def app
22
+ S3::Application
23
+ end
24
+
25
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-s3
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.98"
5
+ platform: ruby
6
+ authors:
7
+ - David Ricciardi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-07-29 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sinatra
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: aws-s3
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.6.2
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: haml
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.2.15
44
+ version:
45
+ description:
46
+ email: nricciar@gmail.com
47
+ executables:
48
+ - sinatra-s3
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - README
53
+ files:
54
+ - bin/sinatra-s3
55
+ - lib/sinatra-s3/base.rb
56
+ - lib/sinatra-s3/errors.rb
57
+ - lib/sinatra-s3/models/bit.rb
58
+ - lib/sinatra-s3/models/git_bucket.rb
59
+ - lib/sinatra-s3/models/slot.rb
60
+ - lib/sinatra-s3/models/torrent_peer.rb
61
+ - lib/sinatra-s3/models/file_info.rb
62
+ - lib/sinatra-s3/models/user.rb
63
+ - lib/sinatra-s3/models/bucket.rb
64
+ - lib/sinatra-s3/models/torrent.rb
65
+ - lib/sinatra-s3/helpers.rb
66
+ - lib/sinatra-s3/tasks.rb
67
+ - lib/sinatra-s3/admin.rb
68
+ - lib/sinatra-s3/ext.rb
69
+ - lib/sinatra-s3/tracker.rb
70
+ - lib/sinatra-s3/helpers/acp.rb
71
+ - lib/sinatra-s3/helpers/admin.rb
72
+ - lib/sinatra-s3/helpers/tracker.rb
73
+ - lib/sinatra-s3/helpers/versioning.rb
74
+ - lib/sinatra-s3/s3.rb
75
+ - lib/sinatra-s3.rb
76
+ - public/test.html
77
+ - public/images/external-link.gif
78
+ - public/css/wiki.css
79
+ - public/css/control.css
80
+ - public/js/prototype.js
81
+ - public/js/upload_status.js
82
+ - examples/wiki.ru
83
+ - examples/wiki.rb
84
+ - examples/README
85
+ - examples/wikicloth/wikicloth-0.1.3.gem
86
+ - examples/wikicloth/install.rb
87
+ - examples/wikicloth/wikicloth.gemspec
88
+ - examples/wikicloth/run_tests.rb
89
+ - examples/wikicloth/README
90
+ - examples/wikicloth/MIT-LICENSE
91
+ - examples/wikicloth/sample_documents/george_washington.wiki
92
+ - examples/wikicloth/sample_documents/pipe_trick.wiki
93
+ - examples/wikicloth/sample_documents/default.css
94
+ - examples/wikicloth/sample_documents/random.wiki
95
+ - examples/wikicloth/sample_documents/tv.wiki
96
+ - examples/wikicloth/sample_documents/air_force_one.wiki
97
+ - examples/wikicloth/sample_documents/lists.wiki
98
+ - examples/wikicloth/sample_documents/images.wiki
99
+ - examples/wikicloth/sample_documents/elements.wiki
100
+ - examples/wikicloth/sample_documents/wiki_tables.wiki
101
+ - examples/wikicloth/sample_documents/wiki.png
102
+ - examples/wikicloth/sample_documents/cheatsheet.wiki
103
+ - examples/wikicloth/init.rb
104
+ - examples/wikicloth/lib/wiki_buffer.rb
105
+ - examples/wikicloth/lib/wikicloth.rb
106
+ - examples/wikicloth/lib/wiki_cloth.rb
107
+ - examples/wikicloth/lib/core_ext.rb
108
+ - examples/wikicloth/lib/wiki_buffer/table.rb
109
+ - examples/wikicloth/lib/wiki_buffer/html_element.rb
110
+ - examples/wikicloth/lib/wiki_buffer/var.rb
111
+ - examples/wikicloth/lib/wiki_buffer/link.rb
112
+ - examples/wikicloth/lib/wiki_link_handler.rb
113
+ - examples/wikicloth/tasks/wikicloth_tasks.rake
114
+ - examples/wikicloth/uninstall.rb
115
+ - examples/wikicloth/Rakefile
116
+ - examples/wikicloth/test/wiki_cloth_test.rb
117
+ - examples/wikicloth/test/test_helper.rb
118
+ - db/migrate/001_create_bits.rb
119
+ - db/migrate/003_create_bits_users.rb
120
+ - db/migrate/004_create_torrents.rb
121
+ - db/migrate/002_create_users.rb
122
+ - db/migrate/005_create_torrent_peers.rb
123
+ - Rakefile
124
+ - s3.yml.example
125
+ - README
126
+ has_rdoc: true
127
+ homepage: http://github.com/nricciar/sinatra-s3
128
+ licenses: []
129
+
130
+ post_install_message:
131
+ rdoc_options: []
132
+
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: "0"
140
+ version:
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: "0"
146
+ version:
147
+ requirements: []
148
+
149
+ rubyforge_project:
150
+ rubygems_version: 1.3.5
151
+ signing_key:
152
+ specification_version: 3
153
+ summary: An implementation of the Amazon S3 API in Ruby
154
+ test_files:
155
+ - test/s3api_test.rb
156
+ - test/test_helper.rb