cloud_file 0.0.1
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/.document +5 -0
- data/.lre +1 -0
- data/.rspec +2 -0
- data/Gemfile +39 -0
- data/Gemfile.lock +128 -0
- data/Guardfile +11 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/cloud_file.gemspec +117 -0
- data/lib/cloud_file.rb +108 -0
- data/lib/cloud_file/address.rb +43 -0
- data/lib/cloud_file/cloud_uri.rb +10 -0
- data/lib/cloud_file/cloud_uri/dsl.rb +80 -0
- data/lib/cloud_file/convertors.rb +76 -0
- data/lib/cloud_file/copy.rb +15 -0
- data/lib/cloud_file/file.rb +28 -0
- data/lib/cloud_file/outer_service.rb +22 -0
- data/lib/cloud_file/providers/dropbox.rb +25 -0
- data/lib/cloud_file/providers/evernote.rb +78 -0
- data/lib/cloud_file/providers/gdrive.rb +39 -0
- data/lib/cloud_file/providers/local.rb +19 -0
- data/lib/cloud_file/providers/memory.rb +25 -0
- data/lib/cloud_file/service.rb +82 -0
- data/lib/cloud_file/services.rb +25 -0
- data/spec/cassettes/most.yml +307 -0
- data/spec/cloud_file_spec.rb +20 -0
- data/spec/cloud_uri_spec.rb +66 -0
- data/spec/providers/memory_spec.rb +24 -0
- data/spec/spec_helper.rb +104 -0
- data/vol/copy_test.rb +3 -0
- data/vol/gsub_test.rb +1 -0
- metadata +339 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
puts 'loading address'
|
2
|
+
|
3
|
+
module CloudFile
|
4
|
+
class Address
|
5
|
+
include FromHash
|
6
|
+
attr_accessor :user, :provider, :loc
|
7
|
+
|
8
|
+
def service
|
9
|
+
cls = ::CloudFile::Services.service_class(provider)
|
10
|
+
cls.for_user(user)
|
11
|
+
end
|
12
|
+
|
13
|
+
def open(&b)
|
14
|
+
service.open(loc,&b)
|
15
|
+
end
|
16
|
+
|
17
|
+
def files
|
18
|
+
service.files
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def parse(str)
|
23
|
+
raise "bad #{str}" unless str =~ /^(.+):\/\/(.+)$/
|
24
|
+
service_class = ::CloudFile::Services.service_class($1)
|
25
|
+
loc = service_class.uri_parser.parse(str)
|
26
|
+
provider = loc.delete('provider')
|
27
|
+
|
28
|
+
make(:provider => provider, :user => Tokens.user, :loc => loc)
|
29
|
+
end
|
30
|
+
def make(ops)
|
31
|
+
if ops[:loc]
|
32
|
+
new(ops)
|
33
|
+
else
|
34
|
+
res = new
|
35
|
+
res.user = ops.delete(:user)
|
36
|
+
res.provider = ops.delete(:provider)
|
37
|
+
res.loc = ops
|
38
|
+
res
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module CloudFile
|
2
|
+
class CloudUri
|
3
|
+
class Dsl
|
4
|
+
include FromHash
|
5
|
+
attr_accessor :service_class, :format
|
6
|
+
|
7
|
+
def self.regex
|
8
|
+
/^(.+):\/\/([^\/]+)((?:\/[^\/]+)*)/
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches(str)
|
12
|
+
raise "no matches" unless str =~ self.class.regex
|
13
|
+
|
14
|
+
res = [$1,$2]
|
15
|
+
if $3.present?
|
16
|
+
res += $3[1..-1].split("/")
|
17
|
+
end
|
18
|
+
res
|
19
|
+
end
|
20
|
+
|
21
|
+
def params
|
22
|
+
[':provider'] + format.split("/")
|
23
|
+
end
|
24
|
+
|
25
|
+
def result(str)
|
26
|
+
matches = matches(str)
|
27
|
+
res = {}
|
28
|
+
add = lambda do |k,i|
|
29
|
+
val = matches[i]
|
30
|
+
if val.kind_of?(Array)
|
31
|
+
raise "bad" if val.empty?
|
32
|
+
val = val.join("/")
|
33
|
+
else
|
34
|
+
raise "bad" unless val.present?
|
35
|
+
end
|
36
|
+
res[k] = val
|
37
|
+
end
|
38
|
+
|
39
|
+
params.each_with_index do |param,i|
|
40
|
+
if param =~ /^:/
|
41
|
+
k = param[1..-1]
|
42
|
+
add[k,i]
|
43
|
+
elsif param =~ /^*:/
|
44
|
+
k = param[2..-1]
|
45
|
+
add[k,(i..99)]
|
46
|
+
else
|
47
|
+
# do nothing
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
HashWithIndifferentAccess.new(res)
|
52
|
+
end
|
53
|
+
def parse(str)
|
54
|
+
result(str)
|
55
|
+
end
|
56
|
+
|
57
|
+
def run!
|
58
|
+
service_class.uri_parser = self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def process_route(route, pattern, keys, conditions, block = nil, values = [])
|
65
|
+
route = '/' if route.empty? and not settings.empty_path_info?
|
66
|
+
return unless match = pattern.match(route)
|
67
|
+
values += match.captures.to_a.map { |v| force_encoding URI.decode(v) if v }
|
68
|
+
|
69
|
+
if values.any?
|
70
|
+
original, @params = params, params.merge('splat' => [], 'captures' => values)
|
71
|
+
keys.zip(values) { |k,v| Array === @params[k] ? @params[k] << v : @params[k] = v if v }
|
72
|
+
end
|
73
|
+
|
74
|
+
catch(:pass) do
|
75
|
+
conditions.each { |c| throw :pass if c.bind(self).call == false }
|
76
|
+
block ? block[self, values] : yield(self, values)
|
77
|
+
end
|
78
|
+
ensure
|
79
|
+
@params = original if original
|
80
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module CloudFile
|
2
|
+
class Convertors
|
3
|
+
class << self
|
4
|
+
fattr(:instance) { new }
|
5
|
+
def method_missing(sym,*args,&b)
|
6
|
+
instance.send(sym,*args,&b)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
include FromHash
|
11
|
+
fattr(:list) { [] }
|
12
|
+
def register(ops,&b)
|
13
|
+
#puts "ops #{ops.inspect}"
|
14
|
+
self.list = list.reject { |x| x[:from].to_s == ops.keys.first.to_s && x[:to].to_s == ops.values.first.to_s }
|
15
|
+
self.list << {:from => ops.keys.first.to_s, :to => ops.values.first.to_s, :block => b}
|
16
|
+
end
|
17
|
+
def convert_inner(from,to,str)
|
18
|
+
block = list.find { |x| x[:from].to_s == from.to_s && x[:to].to_s == to.to_s }
|
19
|
+
raise "no convertor" unless block
|
20
|
+
block[:block][str]
|
21
|
+
end
|
22
|
+
def convert(from,to,str)
|
23
|
+
path = find_path(from,to)
|
24
|
+
raise "no path from #{from} to #{to}" unless path
|
25
|
+
if path.empty?
|
26
|
+
convert_inner(from,to,str)
|
27
|
+
else
|
28
|
+
str = convert_inner(from,path.first,str)
|
29
|
+
convert(path.first,to,str)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def graph
|
34
|
+
require 'rgl/adjacency'
|
35
|
+
a = []
|
36
|
+
list.each do |c|
|
37
|
+
a << c[:from]
|
38
|
+
a << c[:to]
|
39
|
+
end
|
40
|
+
RGL::DirectedAdjacencyGraph[*a]
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_path(source,target,prev=[])
|
44
|
+
raise "bad source: #{source} target: #{target}" if target.to_s == source.to_s
|
45
|
+
tos = list.select { |x| x[:from] == source.to_s }.map { |x| x[:to] }
|
46
|
+
puts "tos #{tos.inspect}"
|
47
|
+
if tos.any? { |x| x == target.to_s }
|
48
|
+
prev
|
49
|
+
elsif tos.empty?
|
50
|
+
nil
|
51
|
+
else
|
52
|
+
tos.each do |to|
|
53
|
+
p = prev + [to]
|
54
|
+
res = find_path(to,target,p)
|
55
|
+
return res if res
|
56
|
+
end
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
CloudFile::Convertors.register :html => :text do |str|
|
64
|
+
#str.gsub(/<[^>]+>/,"")
|
65
|
+
require 'nokogiri'
|
66
|
+
|
67
|
+
doc = Nokogiri::HTML(str)
|
68
|
+
if doc.css("body").length > 0
|
69
|
+
doc.css("body").text
|
70
|
+
else
|
71
|
+
doc.text
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module CloudFile
|
2
|
+
class Copy
|
3
|
+
include FromHash
|
4
|
+
attr_accessor :source, :target, :format
|
5
|
+
|
6
|
+
def run!
|
7
|
+
CloudFile.open(source) do |s|
|
8
|
+
CloudFile.open(target) do |t|
|
9
|
+
#t << s.read_format(format || t.service.class.format)
|
10
|
+
t << s.read
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class File
|
2
|
+
def self.crfate(file,val)
|
3
|
+
open(file,"w") do |f|
|
4
|
+
f << val
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module CloudFile
|
10
|
+
class File
|
11
|
+
include FromHash
|
12
|
+
attr_accessor :loc, :service
|
13
|
+
|
14
|
+
def read
|
15
|
+
service.read(loc)
|
16
|
+
end
|
17
|
+
def write(val)
|
18
|
+
service.write(loc,val)
|
19
|
+
end
|
20
|
+
def <<(*args)
|
21
|
+
write(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def read_format(format)
|
25
|
+
service.read_format(format,loc)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CloudFile
|
2
|
+
class OuterService
|
3
|
+
include FromHash
|
4
|
+
attr_accessor :service
|
5
|
+
|
6
|
+
def parse_loc(loc)
|
7
|
+
if loc.kind_of?(String)
|
8
|
+
loc = service.class.uri_parser.parse(loc)
|
9
|
+
end
|
10
|
+
loc
|
11
|
+
end
|
12
|
+
|
13
|
+
def read(loc)
|
14
|
+
raise 'foo'
|
15
|
+
service.read parse_loc(loc)
|
16
|
+
end
|
17
|
+
|
18
|
+
def write(loc,val)
|
19
|
+
service.write parse_loc(loc),val
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
::Dropbox::API::Config.app_key = "wncno17ygixgpy2"
|
2
|
+
::Dropbox::API::Config.app_secret = "om9yb57exzqb201"
|
3
|
+
::Dropbox::API::Config.mode = "dropbox"
|
4
|
+
|
5
|
+
module CloudFile
|
6
|
+
|
7
|
+
class Dropbox < Service
|
8
|
+
register :provider => "dropbox", :format => :text
|
9
|
+
uri_format "*:path"
|
10
|
+
fattr(:client) do
|
11
|
+
#puts "token #{access_token} secret #{access_secret}"
|
12
|
+
::Dropbox::API::Client.new :token => access_token, :secret => access_secret
|
13
|
+
end
|
14
|
+
def read(loc)
|
15
|
+
#puts "dropbox read #{loc.inspect}"
|
16
|
+
url = client.find(loc[:path]).direct_url
|
17
|
+
#puts url
|
18
|
+
#puts "about to read #{loc[:path]}"
|
19
|
+
client.download(loc[:path])
|
20
|
+
end
|
21
|
+
def write(loc,content)
|
22
|
+
client.upload loc[:path],content
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module CloudFile
|
2
|
+
class Evernote < Service
|
3
|
+
register :provider => "evernote", :format => :evernote_html
|
4
|
+
uri_format ":notebook/:title"
|
5
|
+
|
6
|
+
fattr(:client) do
|
7
|
+
EvernoteOAuth::Client.new(token: access_token)
|
8
|
+
end
|
9
|
+
fattr(:note_store) do
|
10
|
+
client.note_store
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_notebook(book)
|
14
|
+
note_store.listNotebooks.find { |x| x.name == book }
|
15
|
+
end
|
16
|
+
def get_note_shell(book,title)
|
17
|
+
book = get_notebook(book)
|
18
|
+
|
19
|
+
filter = ::Evernote::EDAM::NoteStore::NoteFilter.new
|
20
|
+
filter.notebookGuid = book.guid
|
21
|
+
#filter.words = title
|
22
|
+
notes = note_store.findNotes(filter,0,10)
|
23
|
+
|
24
|
+
notes.notes.find { |x| x.title == title }
|
25
|
+
end
|
26
|
+
def get_note(book,title)
|
27
|
+
shell = get_note_shell(book,title)
|
28
|
+
unless shell
|
29
|
+
raise "no note found"
|
30
|
+
end
|
31
|
+
|
32
|
+
note_store.getNote(shell.guid, true, true, false, false)
|
33
|
+
end
|
34
|
+
def create_note(book,title,content)
|
35
|
+
note = ::Evernote::EDAM::Type::Note.new
|
36
|
+
note.title = title
|
37
|
+
#note.content = ""
|
38
|
+
note.content = '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
|
39
|
+
<en-note>' + content + '</en-note>'
|
40
|
+
note.notebookGuid = get_notebook(book).guid
|
41
|
+
|
42
|
+
note_store.createNote(note)
|
43
|
+
end
|
44
|
+
def update_note(book,title,content)
|
45
|
+
note = get_note(book,title)
|
46
|
+
unless content =~ /DOCTYPE/
|
47
|
+
content = '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
|
48
|
+
<en-note>' + content + '</en-note>'
|
49
|
+
end
|
50
|
+
note.content = content
|
51
|
+
note_store.updateNote(note)
|
52
|
+
end
|
53
|
+
def write_note(book,title,content)
|
54
|
+
if get_note_shell(book,title)
|
55
|
+
update_note(book,title,content)
|
56
|
+
else
|
57
|
+
create_note(book,title,content)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def read(loc)
|
63
|
+
res = get_note(loc[:notebook],loc[:title]).content
|
64
|
+
#raise "no match" unless res =~ /<en-note>(.*)<\/en-note>/
|
65
|
+
#$1
|
66
|
+
end
|
67
|
+
def write(loc,content)
|
68
|
+
write_note(loc[:notebook],loc[:title],content)
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
register_converter :evernote_html => :html do |str|
|
73
|
+
raise "no match" unless str =~ /<en-note>(.*)<\/en-note>/
|
74
|
+
$1
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module CloudFile
|
2
|
+
class Gdrive < Service
|
3
|
+
register :provider => "google_oauth2", :format => :gdoc
|
4
|
+
uri_format ":title"
|
5
|
+
|
6
|
+
fattr(:client) do
|
7
|
+
GoogleDrive.login_with_oauth(access_token)
|
8
|
+
end
|
9
|
+
|
10
|
+
def temp_file
|
11
|
+
"/users/mharris717/multi.txt"
|
12
|
+
end
|
13
|
+
|
14
|
+
def read(loc)
|
15
|
+
file = client.file_by_title(loc[:title])
|
16
|
+
file.download_to_file temp_file
|
17
|
+
::File.read temp_file
|
18
|
+
end
|
19
|
+
|
20
|
+
def write(loc,val)
|
21
|
+
::File.create temp_file,val
|
22
|
+
client.upload_from_file(temp_file, loc[:title], :convert => true)
|
23
|
+
end
|
24
|
+
|
25
|
+
def list
|
26
|
+
client.files.map do |f|
|
27
|
+
if f.title.downcase =~ /interview/
|
28
|
+
::File.create "entry.xml",f.document_feed_entry.to_s
|
29
|
+
raise 'foo'
|
30
|
+
end
|
31
|
+
{:title => f.title}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
register_converter :gdoc => :html do |str|
|
36
|
+
str
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CloudFile
|
2
|
+
class Local < Service
|
3
|
+
register :provider => "local"
|
4
|
+
uri_format ":file"
|
5
|
+
|
6
|
+
def read(ops)
|
7
|
+
::File.read ops[:file]
|
8
|
+
end
|
9
|
+
def write(ops,val)
|
10
|
+
::File.create ops[:file],val
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def for_user(user)
|
15
|
+
new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|