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