fotolia 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ nbproject/*
2
+ doc/*
3
+ pkg/*
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2009 Planquadrat Software-Integration, Torsten Schönebaum
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,76 @@
1
+ = fotolia
2
+
3
+ This is a client to the API of the royalty free stock image marketplace http://fotolia.com written in Ruby.
4
+
5
+ You will need to register for an API key at Fotolia to use it: http://www.fotolia.com/Services/API/Introduction
6
+
7
+ == Getting started
8
+ # install & configure gemcutter repos (skip if you already done this)
9
+ gem update --system
10
+ gem install gemcutter
11
+ gem tumble
12
+
13
+ # install gem
14
+ gem install fotolia
15
+
16
+ == Usage
17
+ require 'fotolia'
18
+
19
+ # get client instance
20
+ fotolia = Fotolia.new(:api_key => 'YOUR_API_KEY')
21
+ # => #<Fotolia::Base ...>
22
+
23
+ # search for media
24
+ search_results = fotolia.search(:words => 'ruby')
25
+ # => #<Fotolia::SearchResultSet ...>
26
+
27
+ search_results.total # number of results
28
+ # => 3978
29
+
30
+ # Take care, the result sets are paged!
31
+ search_results.length
32
+ # => 50
33
+
34
+ # You may access the pages in various ways:
35
+ search_results.next_page # get the next page of the current one
36
+ search_results.pages.length # get the total number of pages
37
+ search_results.pages[3] # Fotolia::SearchResultSet::Pages includes the
38
+ # Enumerable mixin!
39
+
40
+ # inspect a medium object
41
+ search_results.first
42
+ # => #<Fotolia::Medium ...>
43
+
44
+ search_results.first.id # get its id
45
+ # => 18432121
46
+ search_results.first.title # get its title
47
+ # => "Crowns"
48
+ search_results.first.licenses.collect{|l| {l.name => l.price}} # there are different licenses available at Fotolia
49
+ # => [{"XS"=>1}, {"S"=>2}, {"M"=>4}, {"L"=>5}, {"XL"=>6}, {"XXL"=>7}, {"V"=>6}, {"XV"=>80}]
50
+ search_results.first.creator_name # who published that image?
51
+ # => "antipathique"
52
+ search_results.first.thumbnail.url # get a thumbnail url
53
+ # => "http://static-p4.fotolia.com/jpg/....jpg"
54
+
55
+ # some basic fun with categories
56
+ categories = fotolia.representative_categories.root_level
57
+ # => [#<Fotolia::RepresentativeCategory..., ...]
58
+ {categories.first.id => categories.first.name}
59
+ # => {6000000=>"Transportation"}
60
+ categories.first.child_categories # there are three category levels, this
61
+ # gets the second one for the first
62
+ # category in our previously fetched array
63
+ # => [#<Fotolia::RepresentativeCategory..., ...]
64
+ categories.first.child_categories[2].child_categories # the third level
65
+ # => [#<Fotolia::RepresentativeCategory..., ...]
66
+ categories.first.child_categories[2].child_categories.first.media # get media in a category
67
+ # => #<Fotolia::SearchResultSet ...>
68
+
69
+ ...
70
+
71
+ == Author
72
+ Planquadrat Software-Integration GmbH <http://www.planquadrat-software.de>
73
+ Torsten Schönebaum <http://github.com/tosch>
74
+
75
+ == License
76
+ See LICENSE
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/rdoctask'
5
+ require 'rake/testtask'
6
+
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |gemspec|
10
+ gemspec.name = "fotolia"
11
+ gemspec.summary = "Fotolia API Client"
12
+ gemspec.description = "Provides a ruby interface to Fotolia via its XML-RPC api."
13
+ gemspec.email = "torsten.schoenebaum@planquadrat-software.de"
14
+ gemspec.homepage = "http://github.com/tosch/fotolia"
15
+ gemspec.authors = ["Torsten Schönebaum"]
16
+ gemspec.add_dependency('patron', '>= 0.4.4')
17
+ gemspec.rdoc_options << '--line-numbers' << '--main' << 'README.rdoc'
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
22
+ end
23
+
24
+ Rake::RDocTask.new do |rdoc|
25
+ files =['README.rdoc', 'LICENSE', 'VERSION', 'lib/**/*.rb']
26
+ rdoc.rdoc_files.add(files)
27
+ rdoc.main = "README.rdoc" # page to start on
28
+ rdoc.title = "Fotolia Client"
29
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
30
+ rdoc.options << '--line-numbers'
31
+ end
32
+
33
+ Rake::TestTask.new do |t|
34
+ t.test_files = FileList['test/**/*.rb']
35
+ end
data/TODO ADDED
@@ -0,0 +1,3 @@
1
+ - WRITE SOME TESTS
2
+ - implement Fotolia::Medium#buy_and_save
3
+ - implement ShoppingCart and Reseller API functions
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/fotolia.gemspec ADDED
@@ -0,0 +1,67 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{fotolia}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Torsten Sch\303\266nebaum"]
12
+ s.date = %q{2009-11-25}
13
+ s.description = %q{Provides a ruby interface to Fotolia via its XML-RPC api.}
14
+ s.email = %q{torsten.schoenebaum@planquadrat-software.de}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "TODO",
25
+ "VERSION",
26
+ "fotolia.gemspec",
27
+ "lib/fotolia.rb",
28
+ "lib/fotolia/base.rb",
29
+ "lib/fotolia/categories.rb",
30
+ "lib/fotolia/category.rb",
31
+ "lib/fotolia/color.rb",
32
+ "lib/fotolia/colors.rb",
33
+ "lib/fotolia/conceptual_categories.rb",
34
+ "lib/fotolia/conceptual_category.rb",
35
+ "lib/fotolia/countries.rb",
36
+ "lib/fotolia/country.rb",
37
+ "lib/fotolia/galleries.rb",
38
+ "lib/fotolia/gallery.rb",
39
+ "lib/fotolia/language.rb",
40
+ "lib/fotolia/medium.rb",
41
+ "lib/fotolia/representative_categories.rb",
42
+ "lib/fotolia/representative_category.rb",
43
+ "lib/fotolia/search_result_set.rb",
44
+ "lib/fotolia/tag.rb",
45
+ "lib/fotolia/tags.rb",
46
+ "lib/fotolia/user.rb"
47
+ ]
48
+ s.homepage = %q{http://github.com/tosch/fotolia}
49
+ s.rdoc_options = ["--charset=UTF-8", "--line-numbers", "--main", "README.rdoc"]
50
+ s.require_paths = ["lib"]
51
+ s.rubygems_version = %q{1.3.5}
52
+ s.summary = %q{Fotolia API Client}
53
+
54
+ if s.respond_to? :specification_version then
55
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
59
+ s.add_runtime_dependency(%q<patron>, [">= 0.4.4"])
60
+ else
61
+ s.add_dependency(%q<patron>, [">= 0.4.4"])
62
+ end
63
+ else
64
+ s.add_dependency(%q<patron>, [">= 0.4.4"])
65
+ end
66
+ end
67
+
data/lib/fotolia.rb ADDED
@@ -0,0 +1,161 @@
1
+ require 'xmlrpc/client'
2
+
3
+ [
4
+ 'language',
5
+ 'base',
6
+ 'category',
7
+ 'conceptual_category',
8
+ 'representative_category',
9
+ 'categories',
10
+ 'conceptual_categories',
11
+ 'representative_categories',
12
+ 'color',
13
+ 'colors',
14
+ 'country',
15
+ 'countries',
16
+ 'gallery',
17
+ 'galleries',
18
+ 'medium',
19
+ 'tag',
20
+ 'tags',
21
+ 'search_result_set',
22
+ 'user'
23
+ ].each {|file| require File.join(File.dirname(__FILE__), 'fotolia', file)}
24
+
25
+ require 'patron'
26
+
27
+ #
28
+ # Monkey patch XMLRPC::Client as Fotolia returns application/xml as content type
29
+ # instead of text/xml which XMLRPC expects
30
+ #
31
+ # Another monkey patch so that XMLRPC::Client will use the much faster Patron
32
+ # http client
33
+ #
34
+ class XMLRPC::HTTPException < Exception #:nodoc:
35
+ end
36
+ class XMLRPC::HTTPAuthenticationException < Exception #:nodoc:
37
+ end
38
+ module XMLRPC #:nodoc:
39
+ class Client #:nodoc:
40
+ def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil,
41
+ user=nil, password=nil, use_ssl=nil, timeout=nil)
42
+
43
+ @http_header_extra = nil
44
+ @http_last_response = nil
45
+ @cookie = nil
46
+
47
+ @host = host || "localhost"
48
+ @path = path || "/RPC2"
49
+ @proxy_host = proxy_host
50
+ @proxy_port = proxy_port
51
+ @proxy_host ||= 'localhost' if @proxy_port != nil
52
+ @proxy_port ||= 8080 if @proxy_host != nil
53
+ @use_ssl = use_ssl || false
54
+ @timeout = timeout || 30
55
+
56
+ @port = port || (use_ssl ? 443 : 80)
57
+
58
+ @user, @password = user, password
59
+
60
+ # convert ports to integers
61
+ @port = @port.to_i unless @port.nil?
62
+ @proxy_port = @proxy_port.to_i unless @proxy_port.nil?
63
+
64
+ # HTTP object for synchronous calls
65
+ @http = build_http_client
66
+ @http.handle_cookies
67
+
68
+ @parser = nil
69
+ @create = nil
70
+ end
71
+
72
+ def timeout=(new_timeout)
73
+ @timeout = new_timeout
74
+ @http.timeout = @timeout
75
+ end
76
+
77
+ private
78
+
79
+ def set_auth
80
+ if(@user.nil?)
81
+ @http.username = nil
82
+ @http.password = nil
83
+ else
84
+ @http.username = @user
85
+ @http.password = @password
86
+ end
87
+ end
88
+
89
+ def build_http_client
90
+ http = Patron::Session.new
91
+ require 'uri'
92
+ http.base_url = URI::HTTP.build(
93
+ :scheme => @use_ssl ? 'https' : 'http',
94
+ :host => @host,
95
+ :port => @port
96
+ ).to_s
97
+ http.timeout = @timeout
98
+ unless(@proxy_host.nil?)
99
+ http.proxy = URI::HTTP.build(:scheme => 'http', :host => @proxy_host, :port => @proxy_port).to_s
100
+ end
101
+ unless(@user.nil?)
102
+ http.username = @user
103
+ http.password = @password
104
+ end
105
+
106
+ http
107
+ end
108
+
109
+ def do_rpc(request, async=false) #:nodoc:
110
+ header = {
111
+ "User-Agent" => USER_AGENT,
112
+ "Content-Type" => "text/xml; charset=utf-8",
113
+ "Content-Length" => request.size.to_s,
114
+ "Connection" => (async ? "close" : "keep-alive")
115
+ }
116
+
117
+ header.update(@http_header_extra) if @http_header_extra
118
+
119
+ resp = nil
120
+ @http_last_response = nil
121
+
122
+ resp = if async
123
+ # use a new HTTP object for each call
124
+ http = build_http_client
125
+
126
+ # post request
127
+ http.post(@path, request, header)
128
+ else
129
+ # reuse the HTTP object for each call => connection alive is possible we
130
+
131
+ # post request
132
+ @http.post(@path, request, header)
133
+ end
134
+
135
+ @http_last_response = resp
136
+
137
+ data = resp.body
138
+
139
+ if resp.status == 401
140
+ # Authorization Required
141
+ raise XMLRPC::HTTPAuthenticationException, "Authorization failed.\nHTTP-Error: #{resp.status} #{resp.status_line}"
142
+ elsif resp.status < 200 or resp.status >= 300
143
+ raise XMLRPC::HTTPException, "HTTP-Error: #{resp.status} #{resp.message}"
144
+ end
145
+
146
+ ct = parse_content_type(resp.headers["Content-Type"]).first
147
+ if (ct != "text/xml") && (ct != "application/xml")
148
+ raise "Wrong content-type (received '#{ct}' but expected 'text/xml')"
149
+ end
150
+
151
+ expected = resp.headers["Content-Length"] || "<unknown>"
152
+ if data.nil? or data.size == 0
153
+ raise XMLRPC::HTTPException, "Wrong size. Was #{data.size}, should be #{expected}"
154
+ elsif expected != "<unknown>" and expected.to_i != data.size and resp["Transfer-Encoding"].nil?
155
+ raise XMLRPC::HTTPException, "Wrong size. Was #{data.size}, should be #{expected}"
156
+ end
157
+
158
+ return data
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,294 @@
1
+ module Fotolia
2
+ #
3
+ # See Fotolia::Base#new.
4
+ #
5
+ def self.new(*params)
6
+ Fotolia::Base.new(*params)
7
+ end
8
+
9
+ #
10
+ # This error is raised if Fotolia's Api returns an error
11
+ #
12
+ class CommunicationError < StandardError; end
13
+
14
+ #
15
+ # Raised if no api key is given to the initializer
16
+ #
17
+ class ApiKeyRequiredError < StandardError; end
18
+
19
+ #
20
+ # Raised if an user login via Fotolia's API fails
21
+ #
22
+ class UserLoginError < StandardError; end
23
+
24
+ #
25
+ # Raised if a function is called which requires a user login
26
+ #
27
+ class LoginRequiredError < StandardError; end
28
+
29
+ #
30
+ # == Example Usage
31
+ #
32
+ # 0. Require the lib:
33
+ # <tt>require 'fotolia'</tt>
34
+ #
35
+ # 1. Get a new instance of the base class:
36
+ # <tt>fotolia = Fotolia::Base.new :api_key => 'AAAAA'</tt>
37
+ #
38
+ # Note: You may also use the shortcut <tt>Fotolia.new</tt>.
39
+ #
40
+ # 2. Search for some media:
41
+ # <tt>search_results = fotolia.search :words => 'nitpick'</tt>
42
+ #
43
+ # +search_result+ now contains an array of Fotolia media containing the
44
+ # word 'nitpick' somewhere. Note that the array won't have more than 50
45
+ # items per default as Fotolia limits the number of media returned (the max
46
+ # is 64). However, the array is extended in some ways as it is not a plain
47
+ # Array object, but a SearchResultSet instead. So you can call
48
+ # <tt>search_results.total</tt> to get the total number of all results or
49
+ # <tt>search_results.next_page</tt> to get the next set of results. See
50
+ # SearchResultSet for more information.
51
+ #
52
+ # Each medium is represented by the class Fotolia::Medium, so check its
53
+ # documentation for further info.
54
+ #
55
+ # 3. Get all representative categories in root level (Fotolia has two types of
56
+ # categories, representative and conceptual ones. Each root category may
57
+ # have children and grand-children):
58
+ # <tt>r_cats = fotolia.representative_categories</tt>
59
+ #
60
+ # This gives you an array of all root-level representative categories. You
61
+ # may get the children of the first cat by calling
62
+ # <tt>r_cats.first.children</tt>
63
+ #
64
+ # You can fetch a category's media by calling
65
+ # <tt>r_cats.first.media</tt>
66
+ # Note that this method takes the same options hash as parameter as
67
+ # Base#search.
68
+ #
69
+ # 4. You may change the language used in all returns of Fotolia's API. Default
70
+ # is <tt>:en_us</tt>. Also available are <tt>:en_uk</tt>, <tt>:fr</tt>,
71
+ # <tt>:de</tt>, <tt>:es</tt>, <tt>:it</tt>, <tt>:pt_pt</tt>,
72
+ # <tt>:pt_br</tt>, <tt>:jp</tt> and <tt>:pl</tt>. To use one of them, pass
73
+ # the initializer of Base an Fotolia::Language instance:
74
+ #
75
+ # <tt>fotolia = Fotolia.new :api_key => 'A...', :language => Fotolia::Language.new(:de)</tt>
76
+ #
77
+ # Category names, tags and some other items will be returned in German now.
78
+ # If it's not translated, it's Fotolia's fault, not this gem's ;-)
79
+ #
80
+ # 5. Get a Fotolia medium by its ID
81
+ #
82
+ # You may use the :media_id option of Base#search, but calling
83
+ #
84
+ # <tt>medium = Fotolia::Medium.new fotolia, :id => 12334567</tt>
85
+ #
86
+ # is just more intuitive. The class will try to fetch all missing data from
87
+ # Fotolia. You should catch CommunicationErrors when using any medium
88
+ # object generated this way as an of those will be raised if the given
89
+ # media id is unknown to Fotolia.
90
+ #
91
+ # 6. Login a user and get its galleries and add a medium to the first.
92
+ #
93
+ # <tt>fotolia.login 'username', 'password'</tt>
94
+ # <tt>galleries = fotolia.logged_in_user.galleries</tt>
95
+ # <tt>medium = Fotolia::Medium.new fotolia, :id => 12345678</tt>
96
+ # <tt>medium.add_to_user_gallery galleries.first</tt>
97
+ # <tt>fotolia.logout</tt>
98
+ #
99
+ #
100
+ class Base
101
+ DEFAULT_API_URI = 'http://api.fotolia.com/Xmlrpc/rpc'
102
+ DEFAULT_LANGUAGE = :en_us
103
+
104
+ # <String> The API key the client is set to.
105
+ attr_reader :api_key
106
+ # <Fotolia::Language> The language for all requests which return i18n'd results.
107
+ attr_reader :language
108
+ # <String> The URI of the API.
109
+ attr_reader :api_uri
110
+ # <mixed> A string containing the user session id or nil if any.
111
+ attr_reader :session_id
112
+ # <mixed> A Fotolia::User object if there is a user session or nil.
113
+ attr_reader :logged_in_user
114
+
115
+ #
116
+ # ==options hash
117
+ # :api_key <String>:: Your Fotolia API key (an exception is raised if not included)
118
+ # :language <Fotolia::Language>:: The language the client should submit to the API if applicable. Defaults to Fotolia::Language.new(DEFAULT_LANGUAGE).
119
+ # :api_uri <String>:: The URI of the Fotolia API. Defaults to DEFAULT_API_URI.
120
+ #
121
+ def initialize(options = {})
122
+ @api_key = options[:api_key]
123
+ @language = options[:language] || Fotolia::Language.new(DEFAULT_LANGUAGE)
124
+ @api_uri = options[:api_uri] || DEFAULT_API_URI
125
+ @xmlrpc_client = XMLRPC::Client.new2(@api_uri)
126
+
127
+ raise ApiKeyRequiredError unless(@api_key)
128
+ end
129
+
130
+ #
131
+ # Returns a Fotolia::Colors object.
132
+ #
133
+ # ==Example
134
+ # f = Fotolia.new(:api_key => YOUR_API_KEY)
135
+ # f.colors.find_all
136
+ #
137
+ def colors
138
+ @colors ||= Fotolia::Colors.new(self)
139
+ end
140
+
141
+ #
142
+ # Returns a Fotolia::ConceptualCategories object.
143
+ #
144
+ # ==Example
145
+ # f = Fotolia.new(:api_key => YOUR_API_KEY)
146
+ # f.conceptual_categories.find
147
+ #
148
+ def conceptual_categories
149
+ @conceptual_categories ||= Fotolia::ConceptualCategories.new(self)
150
+ end
151
+
152
+ #
153
+ # Returns a Fotolia::RepresentativeCategories object.
154
+ #
155
+ # ==Example
156
+ # f = Fotolia.new(:api_key => YOUR_API_KEY)
157
+ # f.representative_categories.find
158
+ #
159
+ def representative_categories
160
+ @representative_categories ||= Fotolia::RepresentativeCategories.new(self)
161
+ end
162
+
163
+ #
164
+ # Returns a Fotolia::Countries object.
165
+ #
166
+ # ==Example
167
+ # f = Fotolia.new(:api_key => YOUR_API_KEY)
168
+ # f.countries.find_all
169
+ #
170
+ def countries
171
+ @countries ||= Fotolia::Countries.new(self)
172
+ end
173
+
174
+ #
175
+ # Returns a Fotolia::Galleries object.
176
+ #
177
+ # ==Example
178
+ # f = Fotolia.new(:api_key => YOUR_API_KEY)
179
+ # f.galleries.find_all
180
+ #
181
+ def galleries
182
+ @galleries ||= Fotolia::Galleries.new(self)
183
+ end
184
+
185
+ #
186
+ # Returns a Fotolia::Tags object.
187
+ #
188
+ # ==Example
189
+ # f = Fotolia.new(:api_key => YOUR_API_KEY)
190
+ # f.tags.most_used
191
+ # f.tags.most_searched
192
+ #
193
+ def tags
194
+ @tags ||= Fotolia::Tags.new(self)
195
+ end
196
+
197
+ #
198
+ # Searches for media in Fotolia's DB.
199
+ #
200
+ # ==options hash
201
+ # :language <Fotolia::Language>:: Return results in this language. Defaults to language set in Fotolia::Base#new.
202
+ # :per_page <Fixnum>:: Number of results per page. Defaults to 50. Fotolia API limits this to values from 1 to 64.
203
+ # :page <Fixnum>:: Page to show. Defaults to 1.
204
+ # :detailed_results <Boolean>:: Whether to fetch keywords, number of views and downloads of the media in the result set. Defaults to true.
205
+ # :content_types <Array>:: Limit search to certain content types. Valid values are :photo, :illustration, :vector and :all. These types may be mixed together.
206
+ # :only_licenses <Array>:: Only return media offering the listed licenses. Valid values may be 'L', 'XL', 'XXL', 'X' and 'E'. Values may be mixed, but unsure if Fotolia API combines them by AND or OR.
207
+ # :words <String>:: Keyword search. Words can also be media_id using # to search for some media ( ex : #20 #21 #22)
208
+ # :creator_id <Fixnum>:: Search by creator.
209
+ # :representative_category <Fotolia::RepresentativeCategory>:: Search by representative category.
210
+ # :conceptual_category <Fotolia::ConceptualCategory>:: Search by conceptual category.
211
+ # :gallery <Fotolia::Galery>:: Search by gallery.
212
+ # :color <Fotolia::Color>:: Search by color.
213
+ # :country <Fotolia::Country>:: Search by country.
214
+ # :media_id <Fixnum>:: Search by media id -- fetch a medium by its known media id.
215
+ # :model_id <Fixnum>:: Search by same model. Value must be a valid media id.
216
+ # :serie_id <Fixnum>:: Search by same serie. Value must be a valid media id.
217
+ # :similia_id <Fixnum>:: Search similar media. Value must be a valid media id.
218
+ # :offensive <Boolean>:: Include Explicit/Charm/Nudity/Violence media. Defaults to false.
219
+ # :panoramic <Boolean>:: Only fetch panoramic media. Defaults to false.
220
+ # :isolated <Boolean>:: Only fetch isolated media. Defaults to false.
221
+ # :orientation <String>:: Only fetch media in given orientation. Valid values are 'horizontal', 'vertical' and 'all'. Defaults to the latter.
222
+ # :order <String>:: Order the result set. Valid values are 'relevance', 'price_1', 'creation', 'nb_views' and 'nb_downloads'. Defaults to 'relevance'.
223
+ # :thumbnail_size <Fixnum>:: The size of the thumbnail images included in the result set. Valid values are 30, 110 and 400. Defaults to 110. Thumbs in 400px size are watermarked by Fotolia.
224
+ #
225
+ # ==returns
226
+ # Fotolia::SearchResultSet
227
+ #
228
+ def search(options)
229
+ Fotolia::SearchResultSet.new(self, options)
230
+ end
231
+
232
+ #
233
+ # Start an user authenticated session which is needed for some functions,
234
+ # especially user related ones.
235
+ #
236
+ # Won't work in Fotolia's Partner API! Business and Reseller API are limited
237
+ # to login the user the API key belongs to. Only Developer API allows login
238
+ # of all users.
239
+ #
240
+ def login(login, pass)
241
+ @logged_in_user = Fotolia::User.new(self, login, pass)
242
+ res = self.remote_call('loginUser', login, pass)
243
+ raise UserLoginError unless(res['session_id'])
244
+ @session_id = res['session_id']
245
+ end
246
+
247
+ #
248
+ # Ends an user authenticated session.
249
+ #
250
+ def logout
251
+ return false unless self.logged_in?
252
+ self.remote_call('logoutUser', self.session_id)
253
+ @session_id = nil
254
+ @logged_in_user = nil
255
+ true
256
+ end
257
+
258
+ #
259
+ # Returns true if there is a valid user authenticated session.
260
+ #
261
+ def logged_in?
262
+ !@session_id.nil?
263
+ end
264
+
265
+ #
266
+ # The number of media objects in Fotolia's DB.
267
+ #
268
+ def count_media
269
+ general_data['nb_media']
270
+ end
271
+
272
+ #
273
+ # Does an API call and returns the response. Useful if you like to call
274
+ # methods not implemented by this library.
275
+ #
276
+ def remote_call(method, *args)
277
+ begin
278
+ @xmlrpc_client.call('xmlrpc.' + method.to_s, @api_key, *args)
279
+ rescue XMLRPC::FaultException => e
280
+ raise Fotolia::CommunicationError, e.message
281
+ end
282
+ end
283
+
284
+ def inspect #:nodoc:
285
+ "#<#{self.class} api_key=#{@api_key.inspect} language=#{@language.inspect} session_id=#{@session_id.inspect} logged_in_user=#{@logged_in_user.inspect}>"
286
+ end
287
+
288
+ protected
289
+
290
+ def general_data #:nodoc:
291
+ @general_data ||= self.remote_call('getData')
292
+ end
293
+ end
294
+ end