copy-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +10 -0
- data/LICENSE +23 -0
- data/README.md +232 -0
- data/Rakefile +8 -0
- data/copy.gemspec +24 -0
- data/lib/copy.rb +85 -0
- data/lib/copy/base.rb +43 -0
- data/lib/copy/client.rb +70 -0
- data/lib/copy/file.rb +134 -0
- data/lib/copy/link.rb +52 -0
- data/lib/copy/operations/activity.rb +27 -0
- data/lib/copy/operations/all.rb +31 -0
- data/lib/copy/operations/base.rb +47 -0
- data/lib/copy/operations/create.rb +20 -0
- data/lib/copy/operations/delete.rb +25 -0
- data/lib/copy/operations/find.rb +21 -0
- data/lib/copy/operations/meta.rb +20 -0
- data/lib/copy/operations/show.rb +20 -0
- data/lib/copy/operations/update.rb +21 -0
- data/lib/copy/request/base.rb +41 -0
- data/lib/copy/request/connection.rb +120 -0
- data/lib/copy/request/helpers.rb +36 -0
- data/lib/copy/request/info.rb +41 -0
- data/lib/copy/request/validator.rb +53 -0
- data/lib/copy/revision.rb +25 -0
- data/lib/copy/session.rb +56 -0
- data/lib/copy/user.rb +24 -0
- data/lib/copy/version.rb +3 -0
- data/spec/copy/base_spec.rb +12 -0
- data/spec/copy/client_spec.rb +69 -0
- data/spec/copy/file_spec.rb +306 -0
- data/spec/copy/link_spec.rb +238 -0
- data/spec/copy/request/base_spec.rb +53 -0
- data/spec/copy/request/connection_spec.rb +73 -0
- data/spec/copy/request/info_spec.rb +27 -0
- data/spec/copy/request/validator_spec.rb +13 -0
- data/spec/copy/revision_spec.rb +42 -0
- data/spec/copy/user_spec.rb +119 -0
- data/spec/copy_spec.rb +52 -0
- data/spec/fixtures/hola.txt +1 -0
- data/spec/spec_helper.rb +12 -0
- metadata +170 -0
data/lib/copy/client.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
module Copy
|
2
|
+
class Client
|
3
|
+
RESOURCES = [:user, :file, :email, :link]
|
4
|
+
|
5
|
+
attr_reader :session
|
6
|
+
|
7
|
+
# Creates an client object using the given Copy session.
|
8
|
+
# existing account.
|
9
|
+
#
|
10
|
+
# @param [String] client object to use the copy api.
|
11
|
+
def initialize(session)
|
12
|
+
raise Copy::AuthenticationError unless session.valid?
|
13
|
+
@session = session
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
# Metaprograming of every resource to execute it over the perform!
|
18
|
+
# method just to add session tho the resource
|
19
|
+
#
|
20
|
+
# @param [String||Symbol] action name of the action to execute over
|
21
|
+
# @param [Hash] options for the execution
|
22
|
+
# @returns the execution return or nil
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# session = Copy::Session.new(api_key: '_your_api_key_', auth_token: '_aut_token_for_the_user')
|
26
|
+
# client = Copy::Client.new(session)
|
27
|
+
# client.user.show # returns user profile
|
28
|
+
# client.files.all
|
29
|
+
#
|
30
|
+
RESOURCES.each do |resource|
|
31
|
+
eval %{
|
32
|
+
def #{resource.to_s}(action, options={})
|
33
|
+
perform!(:#{resource.to_s}, action, options)
|
34
|
+
end
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Executes block with the access token
|
40
|
+
#
|
41
|
+
# @param [String||Symbol] resource_name name of the resource to execute over
|
42
|
+
# @param [String||Symbol] action name of the action to execute over
|
43
|
+
# @param [Hash] options for the execution
|
44
|
+
# @returns the execution return or nil
|
45
|
+
def perform!(resource_name, action, options={})
|
46
|
+
raise Copy::AuthenticationError unless session
|
47
|
+
resource(resource_name).send(action, options_with_session(options))
|
48
|
+
end
|
49
|
+
protected :perform!
|
50
|
+
|
51
|
+
# Merge the given options with the session for use the api
|
52
|
+
#
|
53
|
+
# @param [Hash] options options to merge with session
|
54
|
+
# @return [Hash]
|
55
|
+
def options_with_session(options={})
|
56
|
+
options.merge(session: @session)
|
57
|
+
end
|
58
|
+
protected :options_with_session
|
59
|
+
|
60
|
+
# Gest the api resource model class by his name
|
61
|
+
#
|
62
|
+
# @param [String||Symbol] name name of the resource
|
63
|
+
# @return [Copy::Base] resource to use the api
|
64
|
+
def resource(name)
|
65
|
+
eval('Copy::' + name.to_s.capitalize) rescue nil
|
66
|
+
end
|
67
|
+
protected :resource
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
data/lib/copy/file.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
|
2
|
+
module Copy
|
3
|
+
class File < Base
|
4
|
+
include Copy::Operations::Show
|
5
|
+
include Copy::Operations::Delete
|
6
|
+
include Copy::Operations::Activity
|
7
|
+
include Copy::Operations::Create
|
8
|
+
|
9
|
+
TYPES = [ :file, :dir, :root, :copy, :inbox ]
|
10
|
+
|
11
|
+
attr_accessor :id, :path, :name, :type, :stub,
|
12
|
+
:children_count, :size, :recipient_confirmed, :mime_type, :link_name, :token,
|
13
|
+
:creator_id, :permissions, :syncing, :public, :object_available, :url,
|
14
|
+
:thumb, :share, :children, :children_count, :revision_id,
|
15
|
+
:modified_time, :date_last_synced,
|
16
|
+
:children, :counts, :inbox_notifications, :links, :revisions
|
17
|
+
|
18
|
+
def initialize(attributes = {})
|
19
|
+
super(attributes)
|
20
|
+
parse_children
|
21
|
+
parse_revisions
|
22
|
+
parse_links
|
23
|
+
end
|
24
|
+
|
25
|
+
def is_dir?
|
26
|
+
type != 'file'
|
27
|
+
end
|
28
|
+
|
29
|
+
def stubbed?
|
30
|
+
stub
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse_children
|
34
|
+
return unless children
|
35
|
+
results = []
|
36
|
+
children.each do |obj|
|
37
|
+
results << self.class.new(obj)
|
38
|
+
end
|
39
|
+
@children = results
|
40
|
+
end
|
41
|
+
protected :parse_children
|
42
|
+
|
43
|
+
def parse_revisions
|
44
|
+
return unless revisions
|
45
|
+
results = []
|
46
|
+
revisions.each do |obj|
|
47
|
+
results << Copy::Revision.new(obj)
|
48
|
+
end
|
49
|
+
@revisions = results
|
50
|
+
end
|
51
|
+
protected :parse_revisions
|
52
|
+
|
53
|
+
def parse_links
|
54
|
+
return unless links
|
55
|
+
results = []
|
56
|
+
links.each do |obj|
|
57
|
+
results << Copy::Link.new(obj)
|
58
|
+
end
|
59
|
+
@links = results
|
60
|
+
end
|
61
|
+
protected :parse_revisions
|
62
|
+
|
63
|
+
class << self
|
64
|
+
# Create operation overwrite to parse file first
|
65
|
+
def create(attrs)
|
66
|
+
super(parse_file(attrs))
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
# Redefining the files api endpoint
|
72
|
+
#
|
73
|
+
def api_member_url(id=nil, method=nil)
|
74
|
+
url = api_resource_name(method)
|
75
|
+
url += "#{id}" if id
|
76
|
+
url
|
77
|
+
end
|
78
|
+
|
79
|
+
# Redefining the files api resource name
|
80
|
+
# depending on the interaction
|
81
|
+
#
|
82
|
+
def api_resource_name(method=nil)
|
83
|
+
case method
|
84
|
+
when :show, :activity
|
85
|
+
'meta'
|
86
|
+
else
|
87
|
+
super(method)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Parses the uploaded file to make the correct api request
|
92
|
+
#
|
93
|
+
# @param attributes [Hash] attributes to parse
|
94
|
+
# @return [Hash] parsed attributes hash
|
95
|
+
def parse_file(attrs)
|
96
|
+
return attrs unless attrs[:file]
|
97
|
+
attrs[:file_attrs] = {}
|
98
|
+
if attrs[:file].kind_of?(::File) or attrs[:file].kind_of?(::Tempfile) then
|
99
|
+
attrs[:file_attrs][:name] = attrs[:file].respond_to?(:original_filename) ? attrs[:file].original_filename : ::File.basename(attrs[:file].path)
|
100
|
+
attrs[:file_attrs][:local_path] = attrs[:file].path
|
101
|
+
elsif attrs[:file].kind_of?(String) then
|
102
|
+
attrs[:file_attrs][:local_path] = attrs[:file]
|
103
|
+
attrs[:file] = ::File.new(attrs[:file])
|
104
|
+
attrs[:file_attrs][:name] = ::File.basename(attrs[:file_attrs][:local_path])
|
105
|
+
elsif attrs[:file].kind_of?(StringIO) then
|
106
|
+
raise(ArgumentError, "Must specify the :as option when uploading from StringIO") unless attrs[:as]
|
107
|
+
attrs[:file_attrs][:local_path] = attrs[:as]
|
108
|
+
|
109
|
+
# hack for bug in UploadIO
|
110
|
+
class << file
|
111
|
+
attr_accessor :path
|
112
|
+
end
|
113
|
+
file.path = attrs[:file]
|
114
|
+
else
|
115
|
+
raise ArgumentError, "local_file must be a File, StringIO, or file path"
|
116
|
+
end
|
117
|
+
|
118
|
+
attrs[:file_attrs][:name] = ::File.basename(attrs.delete(:as)) if attrs[:as]
|
119
|
+
|
120
|
+
attrs
|
121
|
+
end
|
122
|
+
|
123
|
+
# Yiha! Api REST
|
124
|
+
#
|
125
|
+
def api_collection_url(attrs={})
|
126
|
+
path = attrs.delete(:path)
|
127
|
+
url = super(attrs)
|
128
|
+
url += '/' + path if path
|
129
|
+
url
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
data/lib/copy/link.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Copy
|
2
|
+
class Link < Base
|
3
|
+
include Copy::Operations::All
|
4
|
+
include Copy::Operations::Show
|
5
|
+
include Copy::Operations::Delete
|
6
|
+
include Copy::Operations::Create
|
7
|
+
include Copy::Operations::Meta
|
8
|
+
|
9
|
+
attr_accessor :id, :name, :public, :url, :url_short, :creator_id,
|
10
|
+
:created_time, :object_count, :confirmation_required, :status,
|
11
|
+
:permissions, :recipients
|
12
|
+
|
13
|
+
# Metadata fields
|
14
|
+
attr_accessor :children, :path, :token, :creator_id, :permissions,
|
15
|
+
:syncing, :public, :type, :size, :stub, :date_last_synced, :counts,
|
16
|
+
:children_count, :share
|
17
|
+
|
18
|
+
def initialize(attributes = {})
|
19
|
+
super(attributes)
|
20
|
+
parse_recipients
|
21
|
+
parse_children
|
22
|
+
end
|
23
|
+
|
24
|
+
def download_url
|
25
|
+
return unless url
|
26
|
+
"#{url}?download=1"
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def parse_recipients
|
32
|
+
return if @recipients.nil?
|
33
|
+
results = []
|
34
|
+
@recipients.each do |object|
|
35
|
+
case object['contact_type']
|
36
|
+
when 'user'
|
37
|
+
results << Copy::User.new(object)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@recipients = results
|
41
|
+
end
|
42
|
+
|
43
|
+
def parse_children
|
44
|
+
return if @children.nil?
|
45
|
+
results = []
|
46
|
+
@children.each do |object|
|
47
|
+
results << Copy::File.new(object)
|
48
|
+
end
|
49
|
+
@children = results
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Copy
|
2
|
+
module Operations
|
3
|
+
module Activity
|
4
|
+
module ClassMethods
|
5
|
+
# Retrieves all available objects from the Copy API
|
6
|
+
#
|
7
|
+
# @param [Hash] options Options to pass to the API
|
8
|
+
# @return [Array] The available objects
|
9
|
+
def activity(attributes={})
|
10
|
+
response = Copy.request(
|
11
|
+
:get,
|
12
|
+
nil,
|
13
|
+
api_member_url(attributes[:id], :activity ) + '/@activity',
|
14
|
+
{},
|
15
|
+
options_for_request(attributes)
|
16
|
+
)
|
17
|
+
self.new(response)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.included(base)
|
22
|
+
base.extend(ClassMethods)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Copy
|
2
|
+
module Operations
|
3
|
+
module All
|
4
|
+
module ClassMethods
|
5
|
+
# Retrieves all available objects from the Copy API
|
6
|
+
#
|
7
|
+
# @param [Hash] options Options to pass to the API
|
8
|
+
# @return [Array] The available objects
|
9
|
+
def all(attributes = {})
|
10
|
+
session = attributes.delete(:session)
|
11
|
+
response = Copy.request(:get, nil, api_collection_url , attributes, options_for_request(session: session))
|
12
|
+
results_from response
|
13
|
+
end
|
14
|
+
|
15
|
+
def results_from(response)
|
16
|
+
results = []
|
17
|
+
response.each do |obj|
|
18
|
+
results << self.new(obj)
|
19
|
+
end
|
20
|
+
results
|
21
|
+
end
|
22
|
+
private :results_from
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.included(base)
|
26
|
+
base.extend(ClassMethods)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Copy
|
2
|
+
module Operations
|
3
|
+
module Base
|
4
|
+
module ClassMethods
|
5
|
+
# Options for request
|
6
|
+
# overwrite this in the model to set security
|
7
|
+
#
|
8
|
+
# @return [Hash]
|
9
|
+
def options_for_request(attributes)
|
10
|
+
raise AuthenticationError unless attributes[:session]
|
11
|
+
{
|
12
|
+
session: attributes[:session]
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
# URl for the member endpoints
|
19
|
+
# overwrite this in the model if the api is not well named
|
20
|
+
#
|
21
|
+
def api_member_url(id=nil, method=nil)
|
22
|
+
url = api_resource_name(method)
|
23
|
+
url += "/#{id}" if id
|
24
|
+
url
|
25
|
+
end
|
26
|
+
|
27
|
+
# URl for the collection endpoints
|
28
|
+
# overwrite this in the model if the api is not well named
|
29
|
+
#
|
30
|
+
def api_collection_url(attrs={})
|
31
|
+
api_resource_name
|
32
|
+
end
|
33
|
+
|
34
|
+
# resource name
|
35
|
+
# overwrite this in the model if the api is not well named
|
36
|
+
#
|
37
|
+
def api_resource_name(method=nil)
|
38
|
+
"#{self.name.split("::").last.downcase}s"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.included(base)
|
43
|
+
base.extend(ClassMethods)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Copy
|
2
|
+
module Operations
|
3
|
+
module Create
|
4
|
+
module ClassMethods
|
5
|
+
# Creates a new object
|
6
|
+
#
|
7
|
+
# @param [Hash] attributes The attributes of the created object
|
8
|
+
def create(attributes)
|
9
|
+
session = attributes.delete(:session)
|
10
|
+
response = Copy.request(:post, nil, api_collection_url(attributes), attributes, options_for_request(session: session))
|
11
|
+
self.new(response)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.included(base)
|
16
|
+
base.extend(ClassMethods)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Copy
|
2
|
+
module Operations
|
3
|
+
module Delete
|
4
|
+
module ClassMethods
|
5
|
+
# Deletes the given object
|
6
|
+
#
|
7
|
+
# @param [Integer] id The id of the object that gets deleted
|
8
|
+
def delete(attributes={})
|
9
|
+
id = attributes.delete(:id)
|
10
|
+
response = Copy.request( :delete,
|
11
|
+
nil,
|
12
|
+
api_member_url(id, :delete),
|
13
|
+
{},
|
14
|
+
options_for_request(attributes)
|
15
|
+
)
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.included(base)
|
21
|
+
base.extend(ClassMethods)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Copy
|
2
|
+
module Operations
|
3
|
+
module Find
|
4
|
+
module ClassMethods
|
5
|
+
# Finds a given object
|
6
|
+
#
|
7
|
+
# @param [Integer] id The id of the object that should be found
|
8
|
+
# @return [Copy::Base] The found object
|
9
|
+
def find(attibutes)
|
10
|
+
id = attibutes.delete(:id)
|
11
|
+
response = Copy.request(:get, nil, api_member_url({id: id}), {}, options_for_request(attributes))
|
12
|
+
self.new(response["data"])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(base)
|
17
|
+
base.extend(ClassMethods)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Copy
|
2
|
+
module Operations
|
3
|
+
module Meta
|
4
|
+
module ClassMethods
|
5
|
+
# Shows a given object
|
6
|
+
#
|
7
|
+
# @param [Integer] id The id of the object that should be shown
|
8
|
+
# @return [Copy::Base] The found object
|
9
|
+
def meta(attributes={})
|
10
|
+
response = Copy.request(:get, nil, 'meta/' + api_member_url(attributes[:id], :meta), {}, options_for_request(attributes))
|
11
|
+
self.new(response)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.included(base)
|
16
|
+
base.extend(ClassMethods)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|