fotolia 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.
@@ -0,0 +1,15 @@
1
+ module Fotolia
2
+ #
3
+ # An interface to the representative categories at Fotolia.
4
+ #
5
+ # You should consider using Fotolia::Base#representative_categories as
6
+ # shortcut to an instance of this class.
7
+ #
8
+ class RepresentativeCategories < Categories
9
+ def initialize(fotolia_client)
10
+ @method = 'getCategories1'
11
+ @klass = RepresentativeCategory
12
+ super(fotolia_client)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ module Fotolia
2
+ #
3
+ # Represents a representative category at Fotolia.
4
+ #
5
+ class RepresentativeCategory < Category
6
+ #
7
+ # Returns an array of ConceptualCategory objects which are children of this
8
+ # category.
9
+ #
10
+ def child_categories
11
+ @fotolia.representative_categories.find(self)
12
+ end
13
+
14
+ #
15
+ # Searches for media in this category. For the options hash, see
16
+ # Fotolia::Base#search.
17
+ #
18
+ # Returns a Fotolia::SearchResultSet.
19
+ #
20
+ def media(options = {})
21
+ @fotolia.search(options.merge({:representative_category => self}))
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,244 @@
1
+ module Fotolia
2
+ #
3
+ # Holds all media returned by each method relying on Fotolia::Base#search.
4
+ #
5
+ # Acts like an Array as all missing methods are passed to the instance
6
+ # variable @media which is an Array in fact.
7
+ #
8
+ # Fotolia::Base#search doesn't return an Array but a SearchResultSet insteaad,
9
+ # because Fotolia's API restricts the number of media returned per search
10
+ # query to a maximum of 64. The SearchResultSet allows you to easily fetch all
11
+ # media -- the results are parted in pages.
12
+ #
13
+ # You may access these pages by calling +pages+ on the SearchResultSet. The
14
+ # pages are held in an Fotolia::SearchResultSet::Pages object.
15
+ #
16
+ class SearchResultSet
17
+
18
+ #
19
+ # Holds all pages for one search result. You may use all methods offered by
20
+ # Enumberable.
21
+ #
22
+ class Pages
23
+ include Enumerable
24
+
25
+ #
26
+ # == Parameters
27
+ # fotolia_client:: Fotolia::Base object
28
+ # options:: The options hash given to Base#search
29
+ # pages:: The total number of pages.
30
+ # result_set:: The SearchResultSet the call of Base#search returned.
31
+ #
32
+ def initialize(fotolia_client, options, pages, result_set)
33
+ @fotolia = fotolia_client
34
+ @options = options
35
+ @pages = pages
36
+ @result_sets = Array.new
37
+ @result_sets[result_set.page - 1] = result_set
38
+ end
39
+
40
+ #
41
+ # Access one page of a search result.
42
+ #
43
+ # Note that the numbering starts with 0.
44
+ #
45
+ # Returns a SearchResultSet.
46
+ #
47
+ def [] (n)
48
+ @result_sets[n] ||= Fotolia::SearchResultSet.new(@fotolia, @options.merge({:page => (n + 1)}), self)
49
+ end
50
+
51
+ #
52
+ # Yields the given block for every page.
53
+ #
54
+ def each
55
+ (0...@pages).each do |i|
56
+ yield @result_sets[i] ||= Fotolia::SearchResultSet.new(@fotolia, @options.merge({:page => (i + 1)}), self)
57
+ end
58
+ self
59
+ end
60
+
61
+ #
62
+ # Returns the number of pages.
63
+ #
64
+ def length
65
+ @pages
66
+ end
67
+
68
+ alias :count :length
69
+
70
+ end
71
+
72
+ # <Integer> The number of the current page.
73
+ attr_reader :page
74
+ # <Fotolia::SearchResultSet::Pages> The Pages object holding all pages for
75
+ # this search.
76
+ attr_reader :pages
77
+ # <Integer> The number of media per page.
78
+ attr_reader :per_page
79
+ # <Integer> The total number of found media for this search as returned by
80
+ # Fotolia. You shouldn't rely on this value too badly, Fotolia
81
+ # doesn't seem to be too correct about it...
82
+ attr_reader :total
83
+
84
+ #
85
+ # == Parameters
86
+ # fotolia_client:: A Fotolia::Base object
87
+ # options:: The options hash passed to Base#search
88
+ # pages_obj (optional):: Don't create a new Pages object, but use an existing one. Used internally for page caching.
89
+ #
90
+ def initialize(fotolia_client, options, pages_obj = nil)
91
+ @fotolia = fotolia_client
92
+ @options = options
93
+ @pages = pages_obj if(pages_obj.kind_of?(Pages))
94
+ search
95
+ end
96
+
97
+ #
98
+ # Returns the previous page for the current search or nil if any.
99
+ #
100
+ def previous_page
101
+ return nil unless(@media)
102
+ self.pages[@page - 2] if(@page > 1)
103
+ end
104
+
105
+ #
106
+ # Returns the next page for the current search or nil if any.
107
+ #
108
+ def next_page
109
+ return nil unless(@media)
110
+ self.pages[@page + 2] if(@page < @total)
111
+ end
112
+
113
+ def method_missing(method, *args, &block) #:nodoc:
114
+ @media.respond_to?(method) ? @media.send(method, *args, &block) : super
115
+ end
116
+
117
+ protected
118
+
119
+ def search #:nodoc:
120
+ #
121
+ # Other arguments (besides language_id and api_key) accepted by Fotolia API:
122
+ #
123
+ # *Argument* | *Type* | *Element (array)* | *Valid Values* | *Default* | *Details*
124
+ # ===============|========|===========================|====================|===========|=================================================================================================
125
+ # words | string | | list of words | none | keyword search. Words can also be media_id using # to search for some media ( ex : #20 #21 #22)
126
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
127
+ # creator_id | int | | valid creator id | none | Search by creator
128
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
129
+ # cat1_id | int | | valid category1 id | none | Search by representative category. Get valid categories1 ids width getCategories1
130
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
131
+ # cat2_id | int | | valid category2 id | none | Search by conceptual category. Get valid valid category2 id's width getCategories2
132
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
133
+ # gallery_id | int | | valid gallery id | none | Search by gallery. Get valid galleries id's with getGalleries
134
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
135
+ # color_name | string | | valid color name | none | Search by color. Get valid color names with getColors
136
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
137
+ # country_id | int | | valid country id | none | Search by country. Get valid country id's with getCountries
138
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
139
+ # media_id | int | | existing media id | none | Search by media id
140
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
141
+ # model_id | int | | existing media id | none | Search by same model
142
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
143
+ # serie_id | int | | existing media id | none | Search by same serie
144
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
145
+ # similia_id | int | | existing media id | none | Search by similar media (similia)
146
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
147
+ # filters | array | content_type:photo | 0 - 1 | 0 | Search for photos
148
+ # | | content_type:illustration | 0 - 1 | 0 | Search for illustration (jpg)
149
+ # | | content_type:vector | 0 - 1 | 0 | Search for illustration (svg)
150
+ # | | content_type:all | 0 - 1 | 1 | Search for all (default)
151
+ # | | offensive:2 | 0 - 1 | 0 | Explicit/Charm/Nudity/Violence excluded
152
+ # | | isolated:on | 0 - 1 | 0 | Isolated contents
153
+ # | | panoramic:on | 0 - 1 | 0 | Panoramic images
154
+ # | | license_L:on | 0 - 1 | 0 | L size available
155
+ # | | license_XL:on | 0 - 1 | 0 | XL size available
156
+ # | | license_XXL:on | 0 - 1 | 0 | XXL size available
157
+ # | | license_X:on | 0 - 1 | 0 | Extended licence availble
158
+ # | | licence_E:on | 0 - 1 | 0 | Exclusive buy out available
159
+ # | | orientation | horizontal | all | only horizontal image
160
+ # | | | vertical | | only vertical image
161
+ # | | | all | | all images (default)
162
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
163
+ # order | string | | relevance | relevance | Relevance
164
+ # | | | price_1 | | price ASC
165
+ # | | | creation | | creation date DESC
166
+ # | | | nb_views | | number of views DESC
167
+ # | | | nb_downloads | | number of downloads DESC
168
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
169
+ # limit | int | | 1 to 64 | 32 | maximum number of media returned
170
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
171
+ # offset | int | | 0 to max results | 0 | Start position in query
172
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
173
+ # thumbnail_size | int | | 30 | 110 | Small (30px)
174
+ # | | | 110 | | Medium (110px)
175
+ # | | | 400 | | Large (400px - watermarked)
176
+ # ---------------+--------+---------------------------+--------------------+-----------+-------------------------------------------------------------------------------------------------
177
+ # detail_level | int | | 1 | none | When this parameter is sent and set to 1, the method will return for each content :
178
+ # | | | | | * nb_downloads
179
+ # | | | | | * nb_views
180
+ # | | | | | * keywords (comma separated string, depends on the language_id)
181
+
182
+ @options = {
183
+ :per_page => 50,
184
+ :page => 1,
185
+ :detailed_results => true,
186
+ :language => @fotolia.language,
187
+ :content_types => [:all],
188
+ :only_licenses => []
189
+ }.merge(@options)
190
+
191
+ remote_opts = Hash.new
192
+
193
+ remote_opts['language_id'] = @options[:language].id
194
+ remote_opts['words'] = @options[:words] if(@options[:words])
195
+ remote_opts['creator_id'] = @options[:creator_id] if(@options[:creator_id])
196
+ remote_opts['cat1_id'] = @options[:representative_category].id if(@options[:representative_category] && @options[:representative_category].respond_to?(:id))
197
+ remote_opts['cat2_id'] = @options[:conceptual_category].id if(@options[:conceptual_category] && @options[:conceptual_category].respond_to?(:id))
198
+ remote_opts['gallery_id'] = @options[:gallery].id if(@options[:gallery].kind_of?(Fotolia::Gallery))
199
+ remote_opts['color_name'] = @options[:color].name if(@options[:color].kind_of?(Fotolia::Color))
200
+ remote_opts['country_id'] = @options[:country].id if(@options[:country].kind_of?(Fotolia::Country))
201
+ remote_opts['media_id'] = @options[:media_id] if(@options[:media_id])
202
+ remote_opts['model_id'] = @options[:model_id] if(@options[:model_id])
203
+ remote_opts['serie_id'] = @options[:serie_id] if(@options[:serie_id])
204
+ remote_opts['similia_id'] = @options[:similia_id] if(@options[:similia_id])
205
+ remote_opts['filters'] = {
206
+ 'content_type:photo' => @options[:content_types].include?(:photo) ? 1 : 0,
207
+ 'content_type:illustration' => @options[:content_types].include?(:illustration) ? 1 : 0,
208
+ 'content_type:vector' => @options[:content_types].include?(:vector) ? 1 : 0,
209
+ 'content_type:all' => @options[:content_types].include?(:all) ? 1 : 0,
210
+ 'offensive:2' => @options[:offensive] ? 1 : 0,
211
+ 'isolated:on' => @options[:isolated] ? 1 : 0,
212
+ 'panoramic:on' => @options[:panoramic] ? 1 : 0,
213
+ 'license_L:on' => @options[:only_licenses].include?('L') ? 1 : 0,
214
+ 'license_XL:on' => @options[:only_licenses].include?('XL') ? 1 : 0,
215
+ 'license_XXL:on' => @options[:only_licenses].include?('XXL') ? 1 : 0,
216
+ 'license_X:on' => @options[:only_licenses].include?('X') ? 1 : 0,
217
+ 'license_E:on' => @options[:only_licenses].include?('E') ? 1 : 0,
218
+ 'orientation' => @options[:orientation] || 'all'
219
+ }
220
+ remote_opts['order'] = @options[:order] if(@options[:order])
221
+ remote_opts['limit'] = @options[:per_page]
222
+ remote_opts['offset'] = ((@options[:page] - 1) * @options[:per_page]) + 1
223
+ remote_opts['thumbnail_size'] = @options[:thumbnail_size] if(@options[:thumbnail_size])
224
+ remote_opts['detail_level'] = 1 if(@options[:detailed_results])
225
+
226
+ parse_results(@fotolia.remote_call('getSearchResults', remote_opts))
227
+ end
228
+
229
+ def parse_results(api_response) #:nodoc:
230
+ @page = @options[:page]
231
+ @per_page = @options[:per_page]
232
+
233
+ @total = api_response['nb_results']
234
+
235
+ @media = Array.new
236
+
237
+ api_response.each{|k, v| @media << Fotolia::Medium.new(@fotolia, v) if(k =~ /^\d+$/)}
238
+
239
+ @pages = Pages.new(@fotolia, @options, (@total.to_f / @per_page.to_f).ceil, self) unless(@pages)
240
+
241
+ self
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,18 @@
1
+ module Fotolia
2
+ #
3
+ # Represents a tag at Fotolia.
4
+ #
5
+ class Tag
6
+ attr_reader :name
7
+ attr_reader :popularity
8
+
9
+ def initialize(attributes)
10
+ @name = attributes['name']
11
+ @popularity = attributes['popularity'].to_i
12
+ end
13
+
14
+ def to_s
15
+ @name.to_s
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ module Fotolia
2
+ #
3
+ # Interface to tags at Fotolia.
4
+ #
5
+ # Use Fotolia::Base#tags as shortcut to an instance of this class.
6
+ #
7
+ class Tags
8
+ def initialize(fotolia_client)
9
+ @fotolia = fotolia_client
10
+ end
11
+
12
+ #
13
+ # Returns an array of the most searched tags at Fotolia.
14
+ #
15
+ # The tags should be in the language the used Fotolia::Base object is set to.
16
+ #
17
+ def most_searched
18
+ self.find('Searched')
19
+ end
20
+
21
+ #
22
+ # Returns an array of the most used tags in media at Fotolia.
23
+ #
24
+ # The tags should be in the language the used Fotolia::Base object is set to.
25
+ #
26
+ def most_used
27
+ self.find('Used')
28
+ end
29
+
30
+ protected
31
+
32
+ def find(type) #:nodoc:
33
+ rsp = @fotolia.remote_call('getTags', @fotolia.language.id, type)
34
+
35
+ rsp.collect{|t| Fotolia::Tag.new(t)}
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,200 @@
1
+ module Fotolia
2
+ #
3
+ # Represents a Fotolia user.
4
+ #
5
+ # Won't yield sensible results in Partner API as the user methods are not
6
+ # available there. Note that Reseller and Business API are limited to the user
7
+ # the API key belongs to.
8
+ #
9
+ class User
10
+ attr_reader :login, :password
11
+
12
+ def initialize(fotolia_client, login, password)
13
+ @fotolia = fotolia_client
14
+ @login = login
15
+ @password = password
16
+ end
17
+
18
+ #
19
+ # reloads the statistical data when requested next time
20
+ #
21
+ def reload_data
22
+ @user_data = nil
23
+ @user_stats = nil
24
+ end
25
+
26
+ #
27
+ # the user's id
28
+ #
29
+ def id
30
+ self.user_data['id']
31
+ end
32
+
33
+ #
34
+ # the user's language
35
+ #
36
+ # returns a Fotolia::Language object
37
+ #
38
+ def language
39
+ Fotolia::Language.new(self.user_data['language_id'])
40
+ end
41
+
42
+ #
43
+ # the user's credits
44
+ #
45
+ def credits
46
+ user_data['nb_credits']
47
+ end
48
+
49
+ #
50
+ # how much is one of the user's credits worth?
51
+ #
52
+ def credit_value
53
+ user_data['credit_value']
54
+ end
55
+
56
+ #
57
+ # the name of the currency #credit_value is in
58
+ #
59
+ def currency_name
60
+ user_data['currency_name']
61
+ end
62
+
63
+ #
64
+ # the symbol of the currency #credit_value is in
65
+ #
66
+ def currency_symbol
67
+ user_data['currency_symbol']
68
+ end
69
+
70
+ #
71
+ # number of uploaded media
72
+ #
73
+ def count_media_uploaded
74
+ user_stats['nb_media_uploaded']
75
+ end
76
+
77
+ #
78
+ # number of accepted media
79
+ #
80
+ def count_media_accepted
81
+ user_stats['nb_media_accepted']
82
+ end
83
+
84
+ #
85
+ # number of purchased media
86
+ #
87
+ def count_media_purchased
88
+ user_stats['nb_media_purchased']
89
+ end
90
+
91
+ #
92
+ # number of sold media
93
+ #
94
+ def count_media_sold
95
+ user_stats['nb_media_sold']
96
+ end
97
+
98
+ #
99
+ # absolute ranking ( top sellers ever)
100
+ #
101
+ def absolute_ranking
102
+ user_stats['ranking_absolute']
103
+ end
104
+
105
+ #
106
+ # relative ranking ( top seller in 7 days)
107
+ #
108
+ def relative_ranking
109
+ user_stats['ranking_relative']
110
+ end
111
+
112
+ #
113
+ # See http://services.fotolia.com/Services/API/Method/getUserAdvancedStats
114
+ #
115
+ # ==Parameters
116
+ # time_range:: Group results by :day, :week, :month, :quarter or :year
117
+ # date_period:: The period for which the value shall be returned. Is optional. May be one of :all, :today, :yesterday, :one_day, :two_days, :three_days, :one_week, :one_month or an array of two Time objects: The first is taken as starting date, the latter as end.
118
+ #
119
+ def count_member_viewed_photos(time_range = :day, date_period = nil)
120
+ advanced_user_stats('member_viewed_photos', time_range, date_period)
121
+ end
122
+
123
+ #
124
+ # See http://services.fotolia.com/Services/API/Method/getUserAdvancedStats
125
+ #
126
+ # ==Parameters
127
+ # time_range:: Group results by :day, :week, :month, :quarter or :year
128
+ # date_period:: The period for which the value shall be returned. Is optional. May be one of :all, :today, :yesterday, :one_day, :two_days, :three_days, :one_week, :one_month or an array of two Time objects: The first is taken as starting date, the latter as end.
129
+ #
130
+ def count_member_downloaded_photos(time_range = :day, date_period = nil)
131
+ advanced_user_stats('member_downloaded_photos', time_range, date_period)
132
+ end
133
+
134
+ #
135
+ # See http://services.fotolia.com/Services/API/Method/getUserAdvancedStats
136
+ #
137
+ # ==Parameters
138
+ # time_range:: Group results by :day, :week, :month, :quarter or :year
139
+ # date_period:: The period for which the value shall be returned. Is optional. May be one of :all, :today, :yesterday, :one_day, :two_days, :three_days, :one_week, :one_month or an array of two Time objects: The first is taken as starting date, the latter as end.
140
+ #
141
+ def count_member_bought_photos(time_range = :day, date_period = nil)
142
+ advanced_user_stats('member_bought_photos', time_range, date_period)
143
+ end
144
+
145
+ #
146
+ # See http://services.fotolia.com/Services/API/Method/getUserAdvancedStats
147
+ #
148
+ # ==Parameters
149
+ # time_range:: Group results by :day, :week, :month, :quarter or :year
150
+ # date_period:: The period for which the value shall be returned. Is optional. May be one of :all, :today, :yesterday, :one_day, :two_days, :three_days, :one_week, :one_month or an array of two Time objects: The first is taken as starting date, the latter as end.
151
+ #
152
+ def count_member_earned_credits(time_range = :day, date_period = nil)
153
+ advanced_user_stats('member_earned_credits', time_range, date_period)
154
+ end
155
+
156
+ #
157
+ # Returns an array of galleries the user has created.
158
+ #
159
+ def galleries
160
+ raise Fotolia::LoginRequiredError unless @fotolia.logged_in?
161
+
162
+ res = @fotolia.remote_call('getUserGalleries', @fotolia.session_id)
163
+
164
+ res.collect{|g| Fotolia::Gallery.new(@fotolia, g)}
165
+ end
166
+
167
+ protected
168
+
169
+ def user_data #:nodoc:
170
+ raise Fotolia::LoginRequiredError unless @fotolia.logged_in?
171
+ @user_data ||= @fotolia.remote_call('getUserData', @fotolia.session_id)
172
+ end
173
+
174
+ def user_stats #:nodoc:
175
+ raise Fotolia::LoginRequiredError unless @fotolia.logged_in?
176
+ @user_stats ||= @fotolia.remote_call('getUserStats', @fotolia.session_id)
177
+ end
178
+
179
+ def advanced_user_stats(type, time_range = :year, date_period = nil) #:nodoc:
180
+ raise Fotolia::LoginRequiredError unless @fotolia.logged_in?
181
+ raise ArgumentError, 'time_range has to be one of :day, :week, :month, :quarter or :year' unless([:day, :week, :month, :quarter, :year].include?(time_range))
182
+
183
+ res = if(date_period.kind_of?(Symbol))
184
+ raise ArgumentError, 'only :all, :today, :yesterday, :one_day, :two_days, :three_days, :one_week or :one_month are allowed as symbols in date_period' unless([:all, :today, :yesterday, :one_day, :two_days, :three_days, :one_week, :one_month].include?(date_period))
185
+ @fotolia.remote_call('getUserAdvancedStats', @fotolia.session_id, type, time_range.to_s, date_period.to_s)
186
+ elsif(date_period.kind_of?(Array))
187
+ raise ArgumentError, 'Array elements have to be Time objects in date_period' unless(date_period[0] && date_period[1] && date_period[0].respond_to?(:strftime) && date_period[1].respond_to?(:strftime))
188
+ @fotolia.remote_call('getUserAdvancedStats', @fotolia.session_id, type, {'start_date' => date_period[0].strftime('%Y-%m-%d'), 'end_date' => date_period[1].strftime('%Y-%m-%d')})
189
+ elsif(date_period.nil?)
190
+ @fotolia.remote_call('getUserAdvancedStats', @fotolia.session_id, type, time_range.to_s)
191
+ else
192
+ raise ArgumentError, 'date_period has to be either Symbol, Array or nil'
193
+ end
194
+
195
+ # TODO:: parse response
196
+
197
+ end
198
+
199
+ end
200
+ end