browse-everything 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/.gitignore +19 -0
  2. data/.travis.yml +6 -0
  3. data/CONTRIBUTING.md +113 -0
  4. data/Gemfile +4 -0
  5. data/HISTORY.md +2 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +164 -0
  8. data/Rakefile +10 -0
  9. data/app/.DS_Store +0 -0
  10. data/app/assets/javascripts/browse_everything.js +3 -0
  11. data/app/assets/javascripts/browse_everything/behavior.js.coffee +110 -0
  12. data/app/assets/stylesheets/browse_everything.css.scss +82 -0
  13. data/app/controllers/browse_everything_controller.rb +74 -0
  14. data/app/helpers/browse_everything_helper.rb +11 -0
  15. data/app/views/.DS_Store +0 -0
  16. data/app/views/browse_everything/_auth.html.erb +3 -0
  17. data/app/views/browse_everything/_files.html.erb +12 -0
  18. data/app/views/browse_everything/_providers.html.erb +10 -0
  19. data/app/views/browse_everything/auth.html.erb +7 -0
  20. data/app/views/browse_everything/index.html.erb +28 -0
  21. data/app/views/browse_everything/resolve.html.erb +1 -0
  22. data/app/views/browse_everything/show.html.erb +9 -0
  23. data/app/views/layouts/browse_everything.html.erb +11 -0
  24. data/browse-everything.gemspec +40 -0
  25. data/config/locales/en_browse_everything.yml +13 -0
  26. data/config/routes.rb +6 -0
  27. data/lib/browse-everything.rb +1 -0
  28. data/lib/browse_everything.rb +37 -0
  29. data/lib/browse_everything/browser.rb +25 -0
  30. data/lib/browse_everything/driver/base.rb +55 -0
  31. data/lib/browse_everything/driver/box.rb +90 -0
  32. data/lib/browse_everything/driver/drop_box.rb +74 -0
  33. data/lib/browse_everything/driver/file_system.rb +62 -0
  34. data/lib/browse_everything/driver/google_drive.rb +103 -0
  35. data/lib/browse_everything/driver/sky_drive.rb +132 -0
  36. data/lib/browse_everything/engine.rb +6 -0
  37. data/lib/browse_everything/file_entry.rb +19 -0
  38. data/lib/browse_everything/version.rb +3 -0
  39. data/spec/fixtures/file_system/dir_1/dir_3/file_3.m4v +0 -0
  40. data/spec/fixtures/file_system/dir_1/file_2.txt +1 -0
  41. data/spec/fixtures/file_system/dir_2/file_4.docx +1 -0
  42. data/spec/fixtures/file_system/file_1.pdf +0 -0
  43. data/spec/fixtures/vcr_cassettes/dropbox.yml +231 -0
  44. data/spec/rake/app_spec.rb +121 -0
  45. data/spec/spec_helper.rb +56 -0
  46. data/spec/spec_helper.rb.orig +47 -0
  47. data/spec/support/app/controllers/file_handler_controller.rb +8 -0
  48. data/spec/support/app/views/file_handler/index.html.erb +22 -0
  49. data/spec/support/config/browse_everything_providers.yml.example +15 -0
  50. data/spec/support/lib/generators/test_app_generator.rb +50 -0
  51. data/spec/unit/base_spec.rb +28 -0
  52. data/spec/unit/browser_spec.rb +76 -0
  53. data/spec/unit/drop_box_spec.rb +119 -0
  54. data/spec/unit/file_entry_spec.rb +44 -0
  55. data/spec/unit/file_system_spec.rb +85 -0
  56. data/spec/unit/sky_drive_spec.rb +58 -0
  57. data/tasks/browse-everything-dev.rake +63 -0
  58. data/tasks/ci.rake +7 -0
  59. metadata +419 -0
@@ -0,0 +1,6 @@
1
+ module BrowseEverything
2
+ class Engine < ::Rails::Engine
3
+ require 'bootstrap-sass'
4
+ require 'font-awesome-rails'
5
+ end
6
+ end
@@ -0,0 +1,19 @@
1
+ module BrowseEverything
2
+ class FileEntry
3
+ attr_reader :id, :location, :name, :size, :mtime, :type
4
+
5
+ def initialize(id, location, name, size, mtime, container, type=nil)
6
+ @id = id
7
+ @location = location
8
+ @name = name
9
+ @size = size
10
+ @mtime = mtime
11
+ @container = container
12
+ @type = type || @container ? 'directory' : Rack::Mime.mime_type(File.extname(name))
13
+ end
14
+
15
+ def container?
16
+ @container
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module BrowseEverything
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1 @@
1
+ M8?���Ot����y"Paľz/A]�"��=�P�"l��K��.� �%é�p�灵L����a��޷z4$>��H��;�� \�{�l�)S� �a@��{{�ukT�`YWf}ܟH���dK��81i
@@ -0,0 +1 @@
1
+ Uќ��و�X���
@@ -0,0 +1,231 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://DropBoxAppKey:DropBoxAppSecret@api.dropbox.com/1/oauth2/token
6
+ body:
7
+ encoding: UTF-8
8
+ string: grant_type=authorization_code&code=FakeDropboxAuthorizationCodeABCDEFG&redirect_uri=http%3A%2F%2Fbrowse.example.edu%2Fbrowse%2Fconnect
9
+ headers:
10
+ Accept: ! '*/*'
11
+ User-Agent: OfficialDropboxRubySDK/1.6.1
12
+ Content-Type: application/x-www-form-urlencoded
13
+ Connection: close
14
+ Host: api.dropbox.com
15
+ Content-Length: '140'
16
+ response:
17
+ status:
18
+ code: '200'
19
+ message: OK
20
+ headers:
21
+ Server: nginx
22
+ Date: Fri, 20 Sep 2013 15:38:46 GMT
23
+ Content-Type: text/javascript
24
+ Transfer-Encoding: chunked
25
+ Connection: close
26
+ x-server-response-time: '92'
27
+ x-dropbox-request-id: adb756ec7f02c3a142c9d43c479c2033
28
+ pragma: no-cache
29
+ cache-control: no-cache
30
+ x-dropbox-http-protocol: None
31
+ x-frame-options: SAMEORIGIN
32
+ X-RequestId: 9a70a92424860e2700a2f741b4d0dc6f
33
+ body:
34
+ encoding: UTF-8
35
+ string: ! '{"access_token": "FakeDropboxAccessToken01234567890ABCDEF_AAAAAAA987654321",
36
+ "token_type": "bearer", "uid": "1234567"}'
37
+ http_version: '1.1'
38
+ recorded_at: Fri, 20 Sep 2013 15:38:46 GMT
39
+ - request:
40
+ method: get
41
+ uri: https://api.dropbox.com/1/metadata/auto/?file_limit=25000&include_deleted=false&list=true
42
+ body:
43
+ encoding: UTF-8
44
+ string: ''
45
+ headers:
46
+ Accept: ! '*/*'
47
+ User-Agent: OfficialDropboxRubySDK/1.6.1
48
+ Authorization: Bearer FakeDropboxAccessToken01234567890ABCDEF_AAAAAAA987654321
49
+ Connection: close
50
+ Host: api.dropbox.com
51
+ response:
52
+ status:
53
+ code: '200'
54
+ message: OK
55
+ headers:
56
+ Server: nginx
57
+ Date: Fri, 20 Sep 2013 15:38:48 GMT
58
+ Content-Type: text/javascript
59
+ Transfer-Encoding: chunked
60
+ Connection: close
61
+ set-cookie: ! 'gvc=MjMzNzg4MzEzNTQ2Mzk1MzQ0NjcxNzY2ODI2MDkzODUzNzI5NTYw; expires=Wed,
62
+ 19 Sep 2018 15:38:48
63
+
64
+ GMT; Path=/; httponly'
65
+ x-server-response-time: '50'
66
+ x-dropbox-request-id: da19c8c6ca44a67e6c2db3f0254058d1
67
+ pragma: no-cache
68
+ cache-control: no-cache
69
+ x-dropbox-http-protocol: None
70
+ x-frame-options: SAMEORIGIN
71
+ X-RequestId: 057f2caf7291c8f9684a0626480afb30
72
+ body:
73
+ encoding: UTF-8
74
+ string: ! '{ "hash": "60657d5728ee9c36971c0c8269a1c5e8", "thumb_exists": false, "bytes":
75
+ 0, "path": "/", "is_dir": true, "size": "0 bytes", "root": "dropbox", "contents":
76
+ [ { "revision": 8743, "rev": "222700cbb190", "thumb_exists": false, "bytes": 0,
77
+ "modified": "Sun, 09 Dec 2012 20:30:45 +0000", "path": "/Apps", "is_dir": true,
78
+ "icon": "folder", "root": "dropbox", "size": "0 bytes" }, { "revision": 6944, "rev":
79
+ "1b2000cbb190", "thumb_exists": false, "bytes": 0, "modified": "Sun, 25 Mar 2012
80
+ 00:36:39 +0000", "path": "/Books", "is_dir": true, "icon": "folder", "root": "dropbox",
81
+ "size": "0 bytes" }, { "revision": 14, "rev": "e00cbb190", "thumb_exists": false,
82
+ "bytes": 0, "modified": "Mon, 28 Jun 2010 16:53:48 +0000", "path": "/Documents",
83
+ "is_dir": true, "icon": "folder", "root": "dropbox", "size": "0 bytes" }, { "revision":
84
+ 9, "rev": "900cbb190", "thumb_exists": false, "bytes": 127748, "modified": "Mon,
85
+ 28 Jun 2010 16:49:18 +0000", "client_mtime": "Mon, 28 Jun 2010 16:49:19 +0000",
86
+ "path": "/Getting Started.pdf", "is_dir": false, "icon": "page_white_acrobat", "root":
87
+ "dropbox", "mime_type": "application/pdf", "size": "124.8 KB" }, { "revision": 1975,
88
+ "rev": "7b700cbb190", "thumb_exists": false, "bytes": 208218, "modified": "Mon,
89
+ 28 Jun 2010 17:28:47 +0000", "client_mtime": "Mon, 28 Jun 2010 17:28:47 +0000",
90
+ "path": "/iPad intro.pdf", "is_dir": false, "icon": "page_white_acrobat", "root":
91
+ "dropbox", "mime_type": "application/pdf", "size": "203.3 KB" }, { "revision": 1973,
92
+ "rev": "7b500cbb190", "thumb_exists": false, "bytes": 315187, "modified": "Mon,
93
+ 28 Jun 2010 17:27:11 +0000", "client_mtime": "Mon, 28 Jun 2010 17:27:11 +0000",
94
+ "path": "/iPhone intro.pdf", "is_dir": false, "icon": "page_white_acrobat", "root":
95
+ "dropbox", "mime_type": "application/pdf", "size": "307.8 KB" }, { "revision": 2636,
96
+ "rev": "a4c00cbb190", "thumb_exists": false, "bytes": 0, "modified": "Thu, 23 Sep
97
+ 2010 06:30:15 +0000", "path": "/Writer", "is_dir": true, "icon": "folder", "root":
98
+ "dropbox", "size": "0 bytes" } ], "icon": "folder" }'
99
+ http_version: '1.1'
100
+ recorded_at: Fri, 20 Sep 2013 15:38:48 GMT
101
+ - request:
102
+ method: get
103
+ uri: https://api.dropbox.com/1/metadata/auto/Writer?file_limit=25000&include_deleted=false&list=true
104
+ body:
105
+ encoding: UTF-8
106
+ string: ''
107
+ headers:
108
+ Accept: ! '*/*'
109
+ User-Agent: OfficialDropboxRubySDK/1.6.1
110
+ Authorization: Bearer FakeDropboxAccessToken01234567890ABCDEF_AAAAAAA987654321
111
+ Connection: close
112
+ Host: api.dropbox.com
113
+ response:
114
+ status:
115
+ code: '200'
116
+ message: OK
117
+ headers:
118
+ Server: nginx
119
+ Date: Fri, 20 Sep 2013 15:38:55 GMT
120
+ Content-Type: text/javascript
121
+ Transfer-Encoding: chunked
122
+ Connection: close
123
+ set-cookie: ! 'gvc=Njg4MTEzOTAzNjIxMzA3Mzg0Nzk4ODMwMjc3ODE5Mjk1OTIyMjY%3D; expires=Wed,
124
+ 19 Sep 2018 15:38:55
125
+
126
+ GMT; Path=/; httponly'
127
+ x-server-response-time: '64'
128
+ x-dropbox-request-id: 349e4a2b10c59d22f4e686ddbd608b69
129
+ pragma: no-cache
130
+ cache-control: no-cache
131
+ x-dropbox-http-protocol: None
132
+ x-frame-options: SAMEORIGIN
133
+ X-RequestId: 83bc363934d5a5457cbcbd0fab8b4cfb
134
+ body:
135
+ encoding: UTF-8
136
+ string: ! '{ "hash": "c4a067b0bfef9feefca072bb14d9be93", "revision": 2636, "rev": "a4c00cbb190",
137
+ "thumb_exists": false, "bytes": 0, "modified": "Thu, 23 Sep 2010 06:30:15 +0000",
138
+ "path": "/Writer", "is_dir": true, "icon": "folder", "root": "dropbox", "contents":
139
+ [ { "revision": 4011, "rev": "fab00cbb190", "thumb_exists": false, "bytes": 11642,
140
+ "modified": "Sat, 09 Apr 2011 18:54:55 +0000", "client_mtime": "Sat, 09 Apr 2011
141
+ 18:54:55 +0000", "path": "/Writer/About Writer.txt", "is_dir": false, "icon": "page_white_text",
142
+ "root": "dropbox", "mime_type": "text/plain", "size": "11.4 KB" }, { "revision":
143
+ 2754, "rev": "ac200cbb190", "thumb_exists": false, "bytes": 988, "modified": "Thu,
144
+ 14 Oct 2010 08:32:20 +0000", "client_mtime": "Thu, 14 Oct 2010 08:32:20 +0000",
145
+ "path": "/Writer/Markdown Test.txt", "is_dir": false, "icon": "page_white_text",
146
+ "root": "dropbox", "mime_type": "text/plain", "size": "988 bytes" }, { "revision":
147
+ 4009, "rev": "fa900cbb190", "thumb_exists": false, "bytes": 20904, "modified": "Sat,
148
+ 09 Apr 2011 18:54:54 +0000", "client_mtime": "Sat, 09 Apr 2011 18:54:54 +0000",
149
+ "path": "/Writer/Writer FAQ.txt", "is_dir": false, "icon": "page_white_text", "root":
150
+ "dropbox", "mime_type": "text/plain", "size": "20.4 KB" } ], "size": "0 bytes" }'
151
+ http_version: '1.1'
152
+ recorded_at: Fri, 20 Sep 2013 15:38:55 GMT
153
+ - request:
154
+ method: get
155
+ uri: https://api.dropbox.com/1/media/auto/Writer/Writer%20FAQ.txt
156
+ body:
157
+ encoding: UTF-8
158
+ string: ''
159
+ headers:
160
+ Accept: ! '*/*'
161
+ User-Agent: OfficialDropboxRubySDK/1.6.1
162
+ Authorization: Bearer FakeDropboxAccessToken01234567890ABCDEF_AAAAAAA987654321
163
+ Connection: close
164
+ Host: api.dropbox.com
165
+ response:
166
+ status:
167
+ code: '200'
168
+ message: OK
169
+ headers:
170
+ Server: nginx
171
+ Date: Fri, 20 Sep 2013 15:39:01 GMT
172
+ Content-Type: text/javascript
173
+ Transfer-Encoding: chunked
174
+ Connection: close
175
+ set-cookie: ! 'gvc=MjEyNTM5NjUyNDAyMDIwODUzNTU0MTY0NzA0ODU4MzczNTU0NDI%3D; expires=Wed,
176
+ 19 Sep 2018 15:39:01
177
+
178
+ GMT; Path=/; httponly'
179
+ x-server-response-time: '68'
180
+ x-dropbox-request-id: d8dbc2e2080168d6e34d85165aa69c0e
181
+ pragma: no-cache
182
+ cache-control: no-cache
183
+ x-dropbox-http-protocol: None
184
+ x-frame-options: SAMEORIGIN
185
+ X-RequestId: e03a6c0ded5f7088ba59ecd9e97234a6
186
+ body:
187
+ encoding: UTF-8
188
+ string: ! '{"url": "https://dl.dropboxusercontent.com/1/view/FakeDropboxAccessPath/Writer/Writer%20FAQ.txt",
189
+ "expires": "Fri, 20 Sep 2013 19:39:01 +0000"}'
190
+ http_version: '1.1'
191
+ recorded_at: Fri, 20 Sep 2013 15:39:01 GMT
192
+ - request:
193
+ method: get
194
+ uri: https://api.dropbox.com/1/media/auto/Writer/Markdown%20Test.txt
195
+ body:
196
+ encoding: UTF-8
197
+ string: ''
198
+ headers:
199
+ Accept: ! '*/*'
200
+ User-Agent: OfficialDropboxRubySDK/1.6.1
201
+ Authorization: Bearer FakeDropboxAccessToken01234567890ABCDEF_AAAAAAA987654321
202
+ Connection: close
203
+ Host: api.dropbox.com
204
+ response:
205
+ status:
206
+ code: '200'
207
+ message: OK
208
+ headers:
209
+ Server: nginx
210
+ Date: Fri, 20 Sep 2013 15:39:02 GMT
211
+ Content-Type: text/javascript
212
+ Transfer-Encoding: chunked
213
+ Connection: close
214
+ set-cookie: ! 'gvc=NjgwODYwOTI2NTA5OTAyNzE3NzE4MDU3MzY0NTQ3NTYyNTYyNDE%3D; expires=Wed,
215
+ 19 Sep 2018 15:39:02
216
+
217
+ GMT; Path=/; httponly'
218
+ x-server-response-time: '78'
219
+ x-dropbox-request-id: b6fd9a3c039d2aea3def25f8f2f5ac3a
220
+ pragma: no-cache
221
+ cache-control: no-cache
222
+ x-dropbox-http-protocol: None
223
+ x-frame-options: SAMEORIGIN
224
+ X-RequestId: 30d2c0cf0122795ebce9bd5f26ce0c60
225
+ body:
226
+ encoding: UTF-8
227
+ string: ! '{"url": "https://dl.dropboxusercontent.com/1/view/FakeDropboxAccessPath/Writer/Markdown%20Test.txt",
228
+ "expires": "Fri, 20 Sep 2013 19:39:02 +0000"}'
229
+ http_version: '1.1'
230
+ recorded_at: Fri, 20 Sep 2013 15:39:02 GMT
231
+ recorded_with: Charles Proxy
@@ -0,0 +1,121 @@
1
+ require "spec_helper"
2
+ require 'rake'
3
+
4
+ # saves original $stdout in variable
5
+ # set $stdout as local instance of StringIO
6
+ # yields to code execution
7
+ # returns the local instance of StringIO
8
+ # resets $stdout to original value
9
+ def capture_stdout
10
+ out = StringIO.new
11
+ $stdout = out
12
+ yield
13
+ return out.string
14
+ ensure
15
+ $stdout = STDOUT
16
+ end
17
+
18
+ def loaded_files_excluding_current_rake_file
19
+ $".reject { |file| file.include? "tasks/sufia-fixtures" }
20
+ end
21
+
22
+ def attempts_max
23
+ 30
24
+ end
25
+
26
+ describe "Rake Tasks" do
27
+ before (:each) do
28
+ @rake = Rake::Application.new
29
+ Rake.application = @rake
30
+ Rake.application.rake_require("browse-everything-dev", ["#{BrowseEverything::Engine.root}/tasks/"], loaded_files_excluding_current_rake_file)
31
+ Rake::Task.define_task(:environment)
32
+ end
33
+
34
+ describe "start" do
35
+ after (:each) do
36
+ @rake['app:stop'].invoke
37
+ end
38
+ it "start an app" do
39
+ o = capture_stdout do
40
+ @rake['app:start'].invoke
41
+ end
42
+ o.should include "Starting"
43
+ attempts = 1
44
+ while ((!File.exists?('spec/internal/tmp/pids/server.pid')) && (attempts=+1 <attempts_max ))
45
+ sleep(0.01)
46
+ end
47
+
48
+ expect(File).to exist("spec/internal/tmp/pids/server.pid")
49
+ end
50
+ end
51
+
52
+ describe "stop" do
53
+ it "stop a started app" do
54
+
55
+ o = capture_stdout do
56
+ @rake['app:start'].invoke
57
+ end
58
+
59
+ #wait until the app has started
60
+ while (!File.exists?('spec/internal/tmp/pids/server.pid'))
61
+ sleep(0.01)
62
+ end
63
+
64
+ o = capture_stdout do
65
+ @rake['app:stop'].invoke
66
+ end
67
+ o.should include "Stopping"
68
+ attempts = 1
69
+ while ((File.exists?('spec/internal/tmp/pids/server.pid')) && (attempts=+1 <attempts_max ))
70
+ sleep(0.01)
71
+ end
72
+ expect(File).not_to exist("spec/internal/tmp/pids/server.pid")
73
+ end
74
+
75
+ it "not fail when stopping a stopped app" do
76
+
77
+ o = capture_stdout do
78
+ @rake['app:stop'].invoke
79
+ end
80
+ expect(File).not_to exist("spec/internal/tmp/pids/server.pid")
81
+ end
82
+ end
83
+
84
+ describe "clean" do
85
+ after (:each) do
86
+ @rake['app:generate'].invoke
87
+ #wait until the app has generated
88
+ while (!File.exists?('spec/internal/app/assets/stylesheets/'))
89
+ sleep(0.01)
90
+ end
91
+ end
92
+
93
+ it "remove spec internal app" do
94
+
95
+ o = capture_stdout do
96
+ @rake['app:clean'].invoke
97
+ end
98
+ expect(File).not_to exist("spec/internal/app")
99
+ end
100
+
101
+ it "stop server" do
102
+ o = capture_stdout do
103
+ @rake['app:start'].invoke
104
+ end
105
+
106
+ #wait until the app has started
107
+ while (!File.exists?('spec/internal/tmp/pids/server.pid'))
108
+ sleep(0.01)
109
+ end
110
+
111
+ o = capture_stdout do
112
+ @rake['app:clean'].invoke
113
+ end
114
+ o.should include "Stopping"
115
+ expect(File).not_to exist("spec/internal/app")
116
+
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path("config/environment", ENV['RAILS_ROOT'] || File.expand_path("../internal", __FILE__))
2
+ require 'rspec'
3
+ require 'webmock/rspec'
4
+ require 'simplecov'
5
+ require 'vcr'
6
+
7
+ SimpleCov.start do
8
+ add_filter "/spec/"
9
+ end
10
+
11
+ VCR.configure do |c|
12
+ c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
13
+ c.hook_into :webmock
14
+ c.configure_rspec_metadata!
15
+ end
16
+
17
+ RSpec.configure do |c|
18
+ c.treat_symbols_as_metadata_keys_with_true_values = true
19
+ end
20
+
21
+ module BrowserConfigHelper
22
+ def url_options
23
+ {
24
+ protocol: 'http://',
25
+ host: 'browse-everything.example.edu'
26
+ }
27
+ end
28
+
29
+ def stub_configuration
30
+ BrowseEverything.configure({
31
+ "file_system" => {
32
+ home: File.expand_path('../fixtures/file_system',__FILE__)
33
+ },
34
+ "box" => {
35
+ client_id: "BoxClientId",
36
+ client_secret: "BoxClientSecret"
37
+ },
38
+ "drop_box" => {
39
+ app_key: "DropBoxAppKey",
40
+ app_secret: "DropBoxAppSecret"
41
+ },
42
+ "google_drive" => {
43
+ client_id: "GoogleClientId",
44
+ client_secret: "GoogleClientSecret"
45
+ },
46
+ "sky_drive" => {
47
+ client_id: "SkyDriveClientId",
48
+ client_secret: "SkyDriveClientSecret"
49
+ }
50
+ })
51
+ end
52
+
53
+ def unstub_configuration
54
+ BrowseEverything.configure(nil)
55
+ end
56
+ end