copy-ruby 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.
- 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
|