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,82 @@
1
+ @import "bootstrap/variables";
2
+ @import "bootstrap/mixins";
3
+ @import "bootstrap";
4
+ @import "bootstrap-responsive";
5
+ @import "font-awesome";
6
+
7
+ @mixin border-highlight($color) {
8
+ $bl: 3;
9
+ @if $color == none {
10
+ $bl: 0
11
+ }
12
+ margin-left: #{4-$bl}px;
13
+ border-left: #{$bl}px solid $color;
14
+ padding-left: 4px;
15
+ }
16
+
17
+ @mixin ev-link {
18
+ cursor: pointer;
19
+ @include border-highlight(none);
20
+ &:hover {
21
+ @include border-highlight(gray);
22
+ }
23
+ a {
24
+ color: inherit;
25
+ background-color: inherit;
26
+ text-decoration: none;
27
+ }
28
+ }
29
+
30
+ .ev-body {
31
+ padding: 0;
32
+ }
33
+
34
+ .ev-providers {
35
+ padding: 4px;
36
+ background-color: lightgray;
37
+ }
38
+
39
+ .ev-providers, .ev-files {
40
+ li { @include ev-link; }
41
+ .ev-selected {
42
+ @include border-highlight(black);
43
+ }
44
+ }
45
+
46
+ .modal-body {
47
+ overflow: hidden;
48
+ }
49
+
50
+ .ev-files {
51
+ position: relative;
52
+ overflow-x: hidden;
53
+ overflow-y: auto;
54
+
55
+ li {
56
+ overflow: hidden;
57
+ text-overflow: ellipsis;
58
+ .ev-file-name {
59
+ // padding: 0px 6px;
60
+ white-space: nowrap;
61
+ }
62
+ border-top: none;
63
+ }
64
+
65
+ &.detail {
66
+ }
67
+
68
+ &.list ul {
69
+ @include content-columns(3);
70
+ }
71
+ }
72
+
73
+ .ev-container li {
74
+ cursor: pointer;
75
+ }
76
+
77
+ #browse-everything {
78
+ margin: 0 0 0 -37.5%;
79
+ left: 50%;
80
+ width: 75%;
81
+ height: 75%;
82
+ }
@@ -0,0 +1,74 @@
1
+ require File.expand_path('../../helpers/browse_everything_helper',__FILE__)
2
+
3
+ class BrowseEverythingController < ActionController::Base
4
+ layout 'browse_everything'
5
+ helper BrowseEverythingHelper
6
+
7
+ def index
8
+ render :layout => !request.xhr?
9
+ end
10
+
11
+ def show
12
+ render :layout => !request.xhr?
13
+ end
14
+
15
+ def auth
16
+ code = params[:code]
17
+ session["#{provider_name}_token"] = provider.connect(params,session["#{provider_name}_data"])
18
+ end
19
+
20
+ def resolve
21
+ selected_files = params[:selected_files] || []
22
+ @links = selected_files.collect { |file|
23
+ p,f = file.split(/:/)
24
+ (url,extra) = browser.providers[p].link_for(f)
25
+ result = { url: url }
26
+ result.merge!(extra) unless extra.nil?
27
+ result
28
+ }
29
+ respond_to do |format|
30
+ format.html { render :layout => false }
31
+ format.json { render :json => @links }
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def auth_link
38
+ @auth_link ||= if provider.present?
39
+ link, data = provider.auth_link
40
+ session["#{provider_name}_data"] = data
41
+ "#{link}&state=#{provider.key}"
42
+ else
43
+ nil
44
+ end
45
+ end
46
+
47
+ def browser
48
+ if @browser.nil?
49
+ @browser = BrowseEverything::Browser.new(url_options)
50
+ @browser.providers.values.each do |p|
51
+ p.token = session["#{p.key}_token"]
52
+ end
53
+ end
54
+ @browser
55
+ end
56
+
57
+ def browse_path
58
+ @path ||= params[:path] || ''
59
+ end
60
+
61
+ def provider
62
+ @provider ||= browser.providers[provider_name]
63
+ end
64
+
65
+ def provider_name
66
+ @provider_nane ||= params[:provider] || params[:state].to_s.split(/\|/).last
67
+ end
68
+
69
+ helper_method :auth_link
70
+ helper_method :browser
71
+ helper_method :browse_path
72
+ helper_method :provider
73
+ helper_method :provider_name
74
+ end
@@ -0,0 +1,11 @@
1
+ module BrowseEverythingHelper
2
+
3
+ def array_to_hidden_fields(array,key)
4
+ fields = array.to_query(key).split(Rack::Utils::DEFAULT_SEP).collect do |pair|
5
+ key,value=pair.split('=', 2).map { |str| Rack::Utils.unescape(str) }
6
+ hidden_field_tag(key,value)
7
+ end
8
+ fields.join("\n").html_safe
9
+ end
10
+
11
+ end
Binary file
@@ -0,0 +1,3 @@
1
+ <h2><%=t('browse_everything.auth_prompt.head', provider: provider.name)%></h2>
2
+ <p><%=t('browse_everything.auth_prompt.text', provider: provider.name)%></p>
3
+ <p><%= link_to t('browse_everything.auth_prompt.button_text', provider: provider.name), auth_link, class:"btn btn-primary ev-auth", target:'blank' %></p>
@@ -0,0 +1,12 @@
1
+ <% if provider.present? %>
2
+ <ul class="unstyled">
3
+ <% provider.contents(browse_path).each do |file| %>
4
+ <li data-ev-location="<%= file.location %>" title="<%= number_to_human_size(file.size).sub(/Bytes/,'bytes') %> • <%= file.mtime.strftime('%F %R') %>">
5
+ <span class="<%=file.container? ? 'ev-container' : 'ev-file'%> ev-file-name">
6
+ <%= link_to(file.name, browse_everything_engine.contents_path(provider_name,file.id)) %>
7
+ </span>
8
+ </li>
9
+ <% end %>
10
+ </table>
11
+ <% end %>
12
+
@@ -0,0 +1,10 @@
1
+ <ul class="unstyled">
2
+ <% browser.providers.each_pair do |key, provider| %>
3
+ <li>
4
+ <span class="ev-container">
5
+ <i class="icon-<%=provider.icon%>"></i>
6
+ <%= link_to(provider.name, browse_everything_engine.contents_path(key)) %>
7
+ </span>
8
+ </li>
9
+ <% end %>
10
+ </ul>
@@ -0,0 +1,7 @@
1
+ Authorized!
2
+
3
+ <script>
4
+ var caller = $($(window.opener).document)
5
+ $('.ev-providers .ev-selected',caller).click()
6
+ window.close()
7
+ </script>
@@ -0,0 +1,28 @@
1
+ <div class="modal-header"></div>
2
+ <div class="modal-body ev-body">
3
+ <div class="ev-browser row-fluid">
4
+ <div class="span2 ev-providers nav nav-list">
5
+ <%= render :partial => 'providers' %>
6
+ </div>
7
+ <div class="span10 ev-files list">
8
+ <%= render :partial => 'files' %>
9
+ </div>
10
+ </div>
11
+ </div>
12
+ <div class="modal-footer">
13
+ <span class="pull-left ev-status">0 files selected</span>
14
+ <%= form_tag browse_everything_file_handler_path, :method => "POST", :class => "ev-submit-form form-horizontal", :data => { :resolver => browse_everything_engine.resolver_path } do %>
15
+ <button class="ev-cancel btn btn-danger"><%= t('browse_everything.modal_form.cancel')%></button>
16
+ <button class="ev-submit btn btn-primary" data-loading-text="Loading..."><%= t('browse_everything.modal_form.submit')%></button>
17
+ <% end %>
18
+ </div>
19
+ <script>
20
+ $(window).resize(function() {
21
+ var be = $('#browse-everything').outerHeight();
22
+ var he = $('#browse-everything .modal-header').outerHeight();
23
+ var fo = $('#browse-everything .modal-footer').outerHeight();
24
+ $('#browse-everything .modal-body').css('max-height','none').height(be-(he+fo));
25
+ $('#browse-everything .ev-providers').height(be-(he+fo));
26
+ })
27
+ $(window).trigger('resize');
28
+ </script>
@@ -0,0 +1 @@
1
+ <%= array_to_hidden_fields(@links,'selected_files') %>
@@ -0,0 +1,9 @@
1
+ <% if provider.present? %>
2
+ <% if provider.authorized? %>
3
+ <%= render 'files' %>
4
+ <% else %>
5
+ <%= render 'auth' %>
6
+ <% end %>
7
+
8
+ <% end %>
9
+
@@ -0,0 +1,11 @@
1
+ <html>
2
+ <head>
3
+ <%= javascript_include_tag 'browse_everything' %>
4
+ <%= stylesheet_link_tag 'browse_everything' %>
5
+ </head>
6
+ <body>
7
+ <div class="browse-ev">
8
+ <%= yield %>
9
+ </div>
10
+ </body>
11
+ </html>
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'browse_everything/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "browse-everything"
8
+ spec.version = BrowseEverything::VERSION
9
+ spec.authors = ["Carolyn Cole", "Jessie Keck", "Michael B. Klein", "Thomas Scherz", "Xiaoming Wang"]
10
+ spec.email = ["cam156@psu.edu", "jkeck@stanford.edu", "mbklein@gmail.com", "scherztc@ucmail.uc.edu", "xw5d@virginia.edu"]
11
+ spec.description = %q{AJAX/Rails engine file browser for cloud storage services}
12
+ spec.summary = %q{AJAX/Rails engine file browser for cloud storage services}
13
+ spec.homepage = "https://github.com/mbklein/browse-everything"
14
+ spec.license = "Apache 2"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "rails", ">= 3.1"
22
+ spec.add_dependency "sass-rails"
23
+ spec.add_dependency "bootstrap-sass"
24
+ spec.add_dependency "font-awesome-rails"
25
+ spec.add_dependency "google_drive"
26
+ spec.add_dependency "dropbox-sdk"
27
+ spec.add_dependency "skydrive"
28
+ spec.add_dependency "ruby-box"
29
+ spec.add_dependency "google-api-client"
30
+ spec.add_development_dependency "rspec"
31
+ spec.add_development_dependency "rspec-rails"
32
+ spec.add_development_dependency "simplecov"
33
+ spec.add_development_dependency "bundler", "~> 1.3"
34
+ spec.add_development_dependency "pry"
35
+ spec.add_development_dependency "rake"
36
+ spec.add_development_dependency "webmock"
37
+ spec.add_development_dependency "vcr"
38
+ spec.add_development_dependency "sqlite3"
39
+
40
+ end
@@ -0,0 +1,13 @@
1
+ en:
2
+ browse_everything:
3
+ auth_prompt:
4
+ head: "%{provider}"
5
+ text: >
6
+ Please take a moment to authorize this application
7
+ to access your %{provider} files. You will be guided
8
+ through authorization in a popup window, and returned
9
+ here automatically when authorization is complete.
10
+ button_text: "Connect to %{provider}"
11
+ modal_form:
12
+ submit: "Submit"
13
+ cancel: "Cancel"
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ BrowseEverything::Engine.routes.draw do
2
+ get "connect", to: 'browse_everything#auth', as: 'connector_response'
3
+ match "resolve", to: 'browse_everything#resolve', as: 'resolver', via: [:get, :post]
4
+ get ":provider(/*path)", to: 'browse_everything#show', as: 'contents'
5
+ root to: 'browse_everything#index'
6
+ end
@@ -0,0 +1 @@
1
+ require 'browse_everything'
@@ -0,0 +1,37 @@
1
+ require "rails"
2
+ require "browse_everything/version"
3
+ require "browse_everything/engine"
4
+
5
+ module BrowseEverything
6
+ class InitializationError < RuntimeError; end
7
+
8
+ autoload :Browser, 'browse_everything/browser'
9
+ autoload :FileEntry, 'browse_everything/file_entry'
10
+ module Driver
11
+ autoload :Base, 'browse_everything/driver/base'
12
+ autoload :FileSystem, 'browse_everything/driver/file_system'
13
+ autoload :DropBox, 'browse_everything/driver/drop_box'
14
+ autoload :SkyDrive, 'browse_everything/driver/sky_drive'
15
+ autoload :Box, 'browse_everything/driver/box'
16
+ autoload :GoogleDrive, 'browse_everything/driver/google_drive'
17
+ end
18
+
19
+ class << self
20
+ def configure(value)
21
+ if value.nil? or value.kind_of?(Hash)
22
+ @config = value
23
+ elsif value.kind_of?(String)
24
+ @config = YAML.load(File.read(value))
25
+ else
26
+ raise InitializationError, "Unrecognized configuration: #{value.inspect}"
27
+ end
28
+ end
29
+
30
+ def config
31
+ if @config.nil?
32
+ configure(File.join(Rails.root.to_s,'config','browse_everything_providers.yml'))
33
+ end
34
+ @config
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ module BrowseEverything
2
+ class Browser
3
+ attr_reader :providers
4
+
5
+ def initialize(opts = {})
6
+ url_options = {}
7
+ if opts.has_key?(:url_options)
8
+ url_options = opts.delete(:url_options)
9
+ else
10
+ url_options = opts
11
+ opts = BrowseEverything.config
12
+ end
13
+
14
+ @providers = {}
15
+ opts.each_pair do |driver,config|
16
+ begin
17
+ driver_klass = BrowseEverything::Driver.const_get(driver.to_s.camelize.to_sym)
18
+ @providers[driver] = driver_klass.new(config.merge(url_options: url_options))
19
+ rescue
20
+ Rails.logger.warn "Unknown provider: #{driver.to_s}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
1
+ module BrowseEverything
2
+ module Driver
3
+ class Base
4
+ include BrowseEverything::Engine.routes.url_helpers
5
+
6
+ attr_reader :config
7
+ attr_accessor :token
8
+
9
+ def initialize(config,session_info={})
10
+ @config = config
11
+ validate_config
12
+ end
13
+
14
+ def key
15
+ self.class.name.split(/::/).last.underscore
16
+ end
17
+
18
+ def icon
19
+ 'unchecked'
20
+ end
21
+
22
+ def name
23
+ self.class.name.split(/::/).last.titleize
24
+ end
25
+
26
+ def validate_config
27
+ end
28
+
29
+ def contents(path)
30
+ []
31
+ end
32
+
33
+ def details(path)
34
+ nil
35
+ end
36
+
37
+ def link_for(path)
38
+ path
39
+ end
40
+
41
+ def authorized?
42
+ false
43
+ end
44
+
45
+ def auth_link
46
+ []
47
+ end
48
+
49
+ def connect(params,data)
50
+ nil
51
+ end
52
+
53
+ end
54
+ end
55
+ end