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,47 @@
1
+ require File.expand_path("config/environment", ENV['RAILS_ROOT'] || File.expand_path("../internal", __FILE__))
2
+ <<<<<<< HEAD
3
+ require 'rspec/rails'
4
+ require 'webmock/rspec'
5
+ =======
6
+ require 'simplecov'
7
+ SimpleCov.start do
8
+ add_filter "/spec/"
9
+ end
10
+
11
+ module BrowserConfigHelper
12
+ def url_options
13
+ {
14
+ protocol: 'http://',
15
+ host: 'browse-everything.example.edu'
16
+ }
17
+ end
18
+
19
+ def stub_configuration
20
+ BrowseEverything.configure({
21
+ "file_system" => {
22
+ home: File.expand_path('../fixtures/file_system',__FILE__)
23
+ },
24
+ "box" => {
25
+ client_id: "BoxClientId",
26
+ client_secret: "BoxClientSecret"
27
+ },
28
+ "drop_box" => {
29
+ app_key: "DropBoxAppKey",
30
+ app_secret: "DropBoxAppSecret"
31
+ },
32
+ "google_drive" => {
33
+ client_id: "GoogleClientId",
34
+ client_secret: "GoogleClientSecret"
35
+ },
36
+ "sky_drive" => {
37
+ client_id: "SkyDriveClientId",
38
+ client_secret: "SkyDriveClientSecret"
39
+ }
40
+ })
41
+ end
42
+
43
+ def unstub_configuration
44
+ BrowseEverything.configure(nil)
45
+ end
46
+ end
47
+ >>>>>>> Add coverage and configuration stubs
@@ -0,0 +1,8 @@
1
+ class FileHandlerController < ApplicationController
2
+ def index
3
+ end
4
+
5
+ def update
6
+ render :json => params[:selected_files].to_json
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ <div class="hero-unit">
2
+ <h1>Welcome!</h1>
3
+
4
+ <p>Please click the button below to start pickin' files!</p>
5
+
6
+ <%= form_tag(browse_everything_file_handler_path, id: 'main_form', method: 'post') do %>
7
+ <%= button_tag("Browse", type: 'button', class: 'btn btn-large btn-success', id: "browse-btn",
8
+ 'data-toggle' => 'browse-everything', 'data-route' => browse_everything_engine.root_path,
9
+ 'data-target' => '#main_form' ) %>
10
+ <%= button_tag("Submit", type: 'submit', class: 'btn btn-large btn-primary', id: "submit-btn") %>
11
+ <% end %>
12
+
13
+ <p id="status">0 items selected</p>
14
+
15
+ <script>
16
+ $(document).ready(function() {
17
+ $('#browse-btn').browseEverything()
18
+ .done(function(data) { $('#status').html(data.length.toString() + " items selected") })
19
+ .cancel(function() { window.alert('Canceled!') });
20
+ });
21
+ </script>
22
+ </div>
@@ -0,0 +1,15 @@
1
+ ---
2
+ file_system:
3
+ :home: SERVER_SIDE_BROWSE_ROOT
4
+ box:
5
+ :client_id: YOUR_BOX_CLIENT_ID
6
+ :client_secret: YOUR_BOX_CLIENT_SECRET
7
+ drop_box:
8
+ :app_key: YOUR_DROPBOX_APP_KEY
9
+ :app_secret: YOUR_DROPBOX_APP_SECRET
10
+ google_drive:
11
+ :client_id: YOUR_GOOGLE_API_CLIENT_ID
12
+ :client_secret: YOUR_GOOGLE_API_CLIENT_SECRET
13
+ sky_drive:
14
+ :client_id: YOUR_MS_LIVE_CONNECT_CLIENT_ID
15
+ :client_secret: YOUR_MS_LIVE_CONNECT_CLIENT_SECRET
@@ -0,0 +1,50 @@
1
+ require 'rails/generators'
2
+
3
+ class TestAppGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../../../../support", __FILE__)
5
+ def inject_css
6
+ copy_file "../internal/app/assets/stylesheets/application.css", "app/assets/stylesheets/application.css.scss"
7
+ remove_file "app/assets/stylesheets/application.css"
8
+ insert_into_file "app/assets/stylesheets/application.css.scss", :after => '*/' do
9
+ %{\n\n@import "browse_everything"}
10
+ end
11
+ end
12
+
13
+ def inject_javascript
14
+ insert_into_file "app/assets/javascripts/application.js", :after => '//= require_tree .' do
15
+ "\n//= require browse_everything"
16
+ end
17
+ end
18
+
19
+ def inject_application
20
+ insert_into_file "config/application.rb", :after => 'Rails::Application' do
21
+ "\nconfig.autoload_paths+=[File.join(Rails.root,'../../lib')]"
22
+ end
23
+ end
24
+
25
+ def inject_routes
26
+ insert_into_file "config/routes.rb", :after => ".draw do" do
27
+ %{
28
+
29
+ mount BrowseEverything::Engine => '/browse'
30
+ root :to => "file_handler#index"
31
+ post '/file', :to => "file_handler#update", :as => "browse_everything_file_handler"
32
+ }
33
+ end
34
+ end
35
+
36
+ def create_bev_configuration
37
+ create_file "config/browse_everything_providers.yml" do
38
+ YAML.dump({ 'file_system' => { :home => Rails.root.to_s }})
39
+ end
40
+ end
41
+
42
+ def create_test_route
43
+ copy_file "app/controllers/file_handler_controller.rb", "app/controllers/file_handler_controller.rb"
44
+ copy_file "app/views/file_handler/index.html.erb", "app/views/file_handler/index.html.erb"
45
+ end
46
+
47
+ def copy_example_config
48
+ copy_file "config/browse_everything_providers.yml.example", "config/browse_everything_providers.yml.example"
49
+ end
50
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path('../../spec_helper',__FILE__)
2
+
3
+ include BrowserConfigHelper
4
+
5
+ describe BrowseEverything::Driver::Base do
6
+ subject { BrowseEverything::Driver::Base.new({}) }
7
+
8
+ describe "simple properties" do
9
+ its(:name) { should == 'Base' }
10
+ its(:key) { should == 'base' }
11
+ its(:icon) { should be_a(String) }
12
+ its(:auth_link) { should be_empty }
13
+ specify { should_not be_authorized }
14
+ end
15
+ context "#connect" do
16
+ specify { subject.connect({},{}).should be_blank }
17
+ end
18
+ context "#contents" do
19
+ specify { subject.contents('').should be_empty }
20
+ end
21
+ context "#details" do
22
+ specify { subject.details('/path/to/foo.txt').should be_nil }
23
+ end
24
+ context "#link_for" do
25
+ specify { subject.link_for('/path/to/foo.txt').should == '/path/to/foo.txt' }
26
+ end
27
+ end
28
+
@@ -0,0 +1,76 @@
1
+ require File.expand_path('../../spec_helper',__FILE__)
2
+
3
+ include BrowserConfigHelper
4
+
5
+ describe BrowseEverything::Browser do
6
+ let(:file_config) {
7
+ {
8
+ file_system: { home: '/file/config/home' },
9
+ drop_box: { app_key: 'FileConfigKey', app_secret: 'FileConfigSecret' }
10
+ }.to_yaml
11
+ }
12
+
13
+ let(:global_config) {
14
+ {
15
+ file_system: { home: '/global/config/home' },
16
+ drop_box: { app_key: 'GlobalConfigKey', app_secret: 'GlobalConfigSecret' }
17
+ }
18
+ }
19
+
20
+ let(:local_config) {
21
+ {
22
+ file_system: { home: '/local/config/home' },
23
+ drop_box: { app_key: 'LocalConfigKey', app_secret: 'LocalConfigSecret' },
24
+ url_options: url_options
25
+ }
26
+ }
27
+
28
+ describe "file config" do
29
+ before(:each) { File.stub(:read).and_return(file_config) }
30
+ subject { BrowseEverything::Browser.new(url_options) }
31
+
32
+ it "should have 2 providers" do
33
+ expect(subject.providers.keys).to eq([:file_system,:drop_box])
34
+ end
35
+
36
+ it "should use the file configuration" do
37
+ expect(subject.providers[:drop_box].config[:app_key]).to eq('FileConfigKey')
38
+ end
39
+ end
40
+
41
+ describe "global config" do
42
+ before(:each) { BrowseEverything.configure(global_config) }
43
+ subject { BrowseEverything::Browser.new(url_options) }
44
+
45
+ it "should have 2 providers" do
46
+ expect(subject.providers.keys).to eq([:file_system,:drop_box])
47
+ end
48
+
49
+ it "should use the global configuration" do
50
+ expect(subject.providers[:drop_box].config[:app_key]).to eq('GlobalConfigKey')
51
+ end
52
+ end
53
+
54
+ describe "local config" do
55
+ subject { BrowseEverything::Browser.new(local_config) }
56
+
57
+ it "should have 2 providers" do
58
+ expect(subject.providers.keys).to eq([:file_system,:drop_box])
59
+ end
60
+
61
+ it "should use the local configuration" do
62
+ expect(subject.providers[:drop_box].config[:app_key]).to eq('LocalConfigKey')
63
+ end
64
+ end
65
+
66
+ describe "unknown provider" do
67
+ subject {
68
+ BrowseEverything::Browser.new(local_config.merge(foo: { key: 'bar', secret: 'baz' }))
69
+ }
70
+
71
+ it "should complain but continue" do
72
+ Rails.logger.should_receive(:warn).with('Unknown provider: foo')
73
+ expect(subject.providers.keys).to eq([:file_system,:drop_box])
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,119 @@
1
+ require File.expand_path('../../spec_helper',__FILE__)
2
+
3
+ include BrowserConfigHelper
4
+
5
+ describe BrowseEverything::Driver::DropBox, vcr: { cassette_name: 'dropbox', record: :none } do
6
+ before(:all) { stub_configuration }
7
+ after(:all) { unstub_configuration }
8
+
9
+ let(:browser) { BrowseEverything::Browser.new(url_options) }
10
+ let(:provider) { browser.providers['drop_box'] }
11
+ let(:auth_params) { {
12
+ 'code' => 'FakeDropboxAuthorizationCodeABCDEFG',
13
+ 'state' => 'GjDcUhPNZrZzdsw%2FghBy2A%3D%3D|drop_box'
14
+ } }
15
+ let(:csrf_data) { {token: 'GjDcUhPNZrZzdsw%2FghBy2A%3D%3D'} }
16
+
17
+ it "#validate_config" do
18
+ expect { BrowseEverything::Driver::DropBox.new({}) }.to raise_error(BrowseEverything::InitializationError)
19
+ end
20
+
21
+ describe "simple properties" do
22
+ subject { provider }
23
+ its(:name) { should == 'Drop Box' }
24
+ its(:key) { should == 'drop_box' }
25
+ its(:icon) { should be_a(String) }
26
+ end
27
+
28
+ context "authorization" do
29
+ subject { provider }
30
+
31
+ specify { should_not be_authorized }
32
+
33
+ context "#auth_link" do
34
+ specify { subject.auth_link[0].should start_with('https://www.dropbox.com/1/oauth2/authorize') }
35
+ end
36
+
37
+ it "should authorize" do
38
+ subject.connect(auth_params,csrf_data)
39
+ expect(subject).to be_authorized
40
+ end
41
+ end
42
+
43
+ describe "#contents" do
44
+ before(:each) { provider.connect(auth_params,csrf_data) }
45
+
46
+ context "root directory" do
47
+ let(:contents) { provider.contents('') }
48
+ context "[0]" do
49
+ subject { contents[0] }
50
+ its(:name) { should == 'Apps' }
51
+ specify { should be_container }
52
+ end
53
+ context "[1]" do
54
+ subject { contents[1] }
55
+ its(:name) { should == 'Books' }
56
+ specify { should be_container }
57
+ end
58
+ context "[4]" do
59
+ subject { contents[4] }
60
+ its(:name) { should == 'iPad intro.pdf' }
61
+ its(:size) { should == '203.3 KB' }
62
+ its(:location) { should == "drop_box:/iPad intro.pdf" }
63
+ its(:type) { should == "application/pdf" }
64
+ specify { should_not be_container }
65
+ end
66
+ end
67
+
68
+ context "subdirectory" do
69
+ let(:contents) { provider.contents('/Writer') }
70
+ context "[0]" do
71
+ subject { contents[0] }
72
+ its(:name) { should == '..' }
73
+ specify { should be_container }
74
+ end
75
+ context "[1]" do
76
+ subject { contents[1] }
77
+ its(:name) { should == 'About Writer.txt' }
78
+ its(:location) { should == "drop_box:/Writer/About Writer.txt" }
79
+ its(:type) { should == "text/plain" }
80
+ specify { should_not be_container }
81
+ end
82
+ context "[2]" do
83
+ subject { contents[2] }
84
+ its(:name) { should == 'Markdown Test.txt' }
85
+ its(:location) { should == "drop_box:/Writer/Markdown Test.txt" }
86
+ its(:type) { should == "text/plain" }
87
+ specify { should_not be_container }
88
+ end
89
+ context "[3]" do
90
+ subject { contents[3] }
91
+ its(:name) { should == 'Writer FAQ.txt' }
92
+ its(:location) { should == "drop_box:/Writer/Writer FAQ.txt" }
93
+ its(:type) { should == "text/plain" }
94
+ specify { should_not be_container }
95
+ end
96
+ end
97
+
98
+ context "#details" do
99
+ subject { provider.details('') }
100
+ its(:name) { should == 'Apps' }
101
+ end
102
+ end
103
+
104
+ describe "#link_for" do
105
+ before(:each) { provider.connect(auth_params,csrf_data) }
106
+
107
+ context "[0]" do
108
+ subject { provider.link_for('/Writer/Writer FAQ.txt') }
109
+ specify { subject[0].should == "https://dl.dropboxusercontent.com/1/view/FakeDropboxAccessPath/Writer/Writer%20FAQ.txt" }
110
+ specify { subject[1].should have_key(:expires) }
111
+ end
112
+
113
+ context "[1]" do
114
+ subject { provider.link_for('/Writer/Markdown Test.txt') }
115
+ specify { subject[0].should == "https://dl.dropboxusercontent.com/1/view/FakeDropboxAccessPath/Writer/Markdown%20Test.txt" }
116
+ specify { subject[1].should have_key(:expires) }
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path('../../spec_helper',__FILE__)
2
+
3
+ describe BrowseEverything::FileEntry do
4
+ let(:mtime) { Time.now }
5
+ subject {
6
+ BrowseEverything::FileEntry.new(
7
+ 'file_id_01234', 'my_provider:/location/pa/th/file.m4v',
8
+ 'file.m4v', '1.2 GB', mtime, false
9
+ )
10
+ }
11
+
12
+ it "should be a BrowseEverything::FileEntry" do
13
+ expect(subject).to be_a BrowseEverything::FileEntry
14
+ end
15
+
16
+ it "#id" do
17
+ expect(subject.id).to eq("file_id_01234")
18
+ end
19
+
20
+ it "#location" do
21
+ expect(subject.location).to eq("my_provider:/location/pa/th/file.m4v")
22
+ end
23
+
24
+ it "#name" do
25
+ expect(subject.name).to eq("file.m4v")
26
+ end
27
+
28
+ it "#size" do
29
+ expect(subject.size).to eq("1.2 GB")
30
+ end
31
+
32
+ it "#mtime" do
33
+ expect(subject.mtime).to eq(mtime)
34
+ end
35
+
36
+ it "#type" do
37
+ expect(subject.type).to eq("video/mp4")
38
+ end
39
+
40
+ it "#container?" do
41
+ expect(subject.container?).to be_false
42
+ end
43
+
44
+ end
@@ -0,0 +1,85 @@
1
+ require File.expand_path('../../spec_helper',__FILE__)
2
+
3
+ include BrowserConfigHelper
4
+
5
+ describe BrowseEverything::Driver::FileSystem do
6
+ before(:all) { stub_configuration }
7
+ after(:all) { unstub_configuration }
8
+ let(:home) { File.expand_path(BrowseEverything.config['file_system'][:home]) }
9
+ let(:browser) { BrowseEverything::Browser.new(url_options) }
10
+ let(:provider) { browser.providers['file_system'] }
11
+
12
+ it "#validate_config" do
13
+ expect { BrowseEverything::Driver::FileSystem.new({}) }.to raise_error(BrowseEverything::InitializationError)
14
+ end
15
+
16
+ describe "simple properties" do
17
+ subject { provider }
18
+ its(:name) { should == 'File System' }
19
+ its(:key) { should == 'file_system' }
20
+ its(:icon) { should be_a(String) }
21
+ specify { should be_authorized }
22
+ end
23
+
24
+ describe "#contents" do
25
+ context "root directory" do
26
+ let(:contents) { provider.contents('/') }
27
+ context "[0]" do
28
+ subject { contents[0] }
29
+ its(:name) { should == 'dir_1' }
30
+ specify { should be_container }
31
+ end
32
+ context "[1]" do
33
+ subject { contents[1] }
34
+ its(:name) { should == 'dir_2' }
35
+ specify { should be_container }
36
+ end
37
+ context "[2]" do
38
+ subject { contents[2] }
39
+ its(:name) { should == 'file_1.pdf' }
40
+ its(:size) { should == 2256 }
41
+ its(:location) { should == "file_system:#{File.join(home,'file_1.pdf')}" }
42
+ its(:type) { should == "application/pdf" }
43
+ specify { should_not be_container }
44
+ end
45
+ end
46
+
47
+ context "subdirectory" do
48
+ let(:contents) { provider.contents('/dir_1') }
49
+ context "[0]" do
50
+ subject { contents[0] }
51
+ its(:name) { should == '..' }
52
+ specify { should be_container }
53
+ end
54
+ context "[1]" do
55
+ subject { contents[1] }
56
+ its(:name) { should == 'dir_3' }
57
+ specify { should be_container }
58
+ end
59
+ context "[2]" do
60
+ subject { contents[2] }
61
+ its(:name) { should == 'file_2.txt' }
62
+ its(:location) { should == "file_system:#{File.join(home,'dir_1/file_2.txt')}" }
63
+ its(:type) { should == "text/plain" }
64
+ specify { should_not be_container }
65
+ end
66
+ end
67
+
68
+ context "single file" do
69
+ let(:contents) { provider.contents('/dir_1/dir_3/file_3.m4v') }
70
+ context "[0]" do
71
+ subject { contents[0] }
72
+ its(:name) { should == 'file_3.m4v' }
73
+ its(:location) { should == "file_system:#{File.join(home,'dir_1/dir_3/file_3.m4v')}" }
74
+ its(:size) { should == 3879 }
75
+ its(:type) { should == "video/mp4" }
76
+ specify { should_not be_container }
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#link_for('/path/to/file')" do
82
+ subject { provider.link_for('/path/to/file') }
83
+ it { should == "file:///path/to/file" }
84
+ end
85
+ end