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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +10 -0
  6. data/LICENSE +23 -0
  7. data/README.md +232 -0
  8. data/Rakefile +8 -0
  9. data/copy.gemspec +24 -0
  10. data/lib/copy.rb +85 -0
  11. data/lib/copy/base.rb +43 -0
  12. data/lib/copy/client.rb +70 -0
  13. data/lib/copy/file.rb +134 -0
  14. data/lib/copy/link.rb +52 -0
  15. data/lib/copy/operations/activity.rb +27 -0
  16. data/lib/copy/operations/all.rb +31 -0
  17. data/lib/copy/operations/base.rb +47 -0
  18. data/lib/copy/operations/create.rb +20 -0
  19. data/lib/copy/operations/delete.rb +25 -0
  20. data/lib/copy/operations/find.rb +21 -0
  21. data/lib/copy/operations/meta.rb +20 -0
  22. data/lib/copy/operations/show.rb +20 -0
  23. data/lib/copy/operations/update.rb +21 -0
  24. data/lib/copy/request/base.rb +41 -0
  25. data/lib/copy/request/connection.rb +120 -0
  26. data/lib/copy/request/helpers.rb +36 -0
  27. data/lib/copy/request/info.rb +41 -0
  28. data/lib/copy/request/validator.rb +53 -0
  29. data/lib/copy/revision.rb +25 -0
  30. data/lib/copy/session.rb +56 -0
  31. data/lib/copy/user.rb +24 -0
  32. data/lib/copy/version.rb +3 -0
  33. data/spec/copy/base_spec.rb +12 -0
  34. data/spec/copy/client_spec.rb +69 -0
  35. data/spec/copy/file_spec.rb +306 -0
  36. data/spec/copy/link_spec.rb +238 -0
  37. data/spec/copy/request/base_spec.rb +53 -0
  38. data/spec/copy/request/connection_spec.rb +73 -0
  39. data/spec/copy/request/info_spec.rb +27 -0
  40. data/spec/copy/request/validator_spec.rb +13 -0
  41. data/spec/copy/revision_spec.rb +42 -0
  42. data/spec/copy/user_spec.rb +119 -0
  43. data/spec/copy_spec.rb +52 -0
  44. data/spec/fixtures/hola.txt +1 -0
  45. data/spec/spec_helper.rb +12 -0
  46. metadata +170 -0
@@ -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