cloud_file 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|