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.
- data/.gitignore +19 -0
- data/.travis.yml +6 -0
- data/CONTRIBUTING.md +113 -0
- data/Gemfile +4 -0
- data/HISTORY.md +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +164 -0
- data/Rakefile +10 -0
- data/app/.DS_Store +0 -0
- data/app/assets/javascripts/browse_everything.js +3 -0
- data/app/assets/javascripts/browse_everything/behavior.js.coffee +110 -0
- data/app/assets/stylesheets/browse_everything.css.scss +82 -0
- data/app/controllers/browse_everything_controller.rb +74 -0
- data/app/helpers/browse_everything_helper.rb +11 -0
- data/app/views/.DS_Store +0 -0
- data/app/views/browse_everything/_auth.html.erb +3 -0
- data/app/views/browse_everything/_files.html.erb +12 -0
- data/app/views/browse_everything/_providers.html.erb +10 -0
- data/app/views/browse_everything/auth.html.erb +7 -0
- data/app/views/browse_everything/index.html.erb +28 -0
- data/app/views/browse_everything/resolve.html.erb +1 -0
- data/app/views/browse_everything/show.html.erb +9 -0
- data/app/views/layouts/browse_everything.html.erb +11 -0
- data/browse-everything.gemspec +40 -0
- data/config/locales/en_browse_everything.yml +13 -0
- data/config/routes.rb +6 -0
- data/lib/browse-everything.rb +1 -0
- data/lib/browse_everything.rb +37 -0
- data/lib/browse_everything/browser.rb +25 -0
- data/lib/browse_everything/driver/base.rb +55 -0
- data/lib/browse_everything/driver/box.rb +90 -0
- data/lib/browse_everything/driver/drop_box.rb +74 -0
- data/lib/browse_everything/driver/file_system.rb +62 -0
- data/lib/browse_everything/driver/google_drive.rb +103 -0
- data/lib/browse_everything/driver/sky_drive.rb +132 -0
- data/lib/browse_everything/engine.rb +6 -0
- data/lib/browse_everything/file_entry.rb +19 -0
- data/lib/browse_everything/version.rb +3 -0
- data/spec/fixtures/file_system/dir_1/dir_3/file_3.m4v +0 -0
- data/spec/fixtures/file_system/dir_1/file_2.txt +1 -0
- data/spec/fixtures/file_system/dir_2/file_4.docx +1 -0
- data/spec/fixtures/file_system/file_1.pdf +0 -0
- data/spec/fixtures/vcr_cassettes/dropbox.yml +231 -0
- data/spec/rake/app_spec.rb +121 -0
- data/spec/spec_helper.rb +56 -0
- data/spec/spec_helper.rb.orig +47 -0
- data/spec/support/app/controllers/file_handler_controller.rb +8 -0
- data/spec/support/app/views/file_handler/index.html.erb +22 -0
- data/spec/support/config/browse_everything_providers.yml.example +15 -0
- data/spec/support/lib/generators/test_app_generator.rb +50 -0
- data/spec/unit/base_spec.rb +28 -0
- data/spec/unit/browser_spec.rb +76 -0
- data/spec/unit/drop_box_spec.rb +119 -0
- data/spec/unit/file_entry_spec.rb +44 -0
- data/spec/unit/file_system_spec.rb +85 -0
- data/spec/unit/sky_drive_spec.rb +58 -0
- data/tasks/browse-everything-dev.rake +63 -0
- data/tasks/ci.rake +7 -0
- 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
|
data/app/views/.DS_Store
ADDED
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,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,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
|