browse-everything 0.1.0

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