fotolia 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/LICENSE +19 -0
- data/README.rdoc +76 -0
- data/Rakefile +35 -0
- data/TODO +3 -0
- data/VERSION +1 -0
- data/fotolia.gemspec +67 -0
- data/lib/fotolia.rb +161 -0
- data/lib/fotolia/base.rb +294 -0
- data/lib/fotolia/categories.rb +53 -0
- data/lib/fotolia/category.rb +23 -0
- data/lib/fotolia/color.rb +14 -0
- data/lib/fotolia/colors.rb +39 -0
- data/lib/fotolia/conceptual_categories.rb +15 -0
- data/lib/fotolia/conceptual_category.rb +24 -0
- data/lib/fotolia/countries.rb +21 -0
- data/lib/fotolia/country.rb +14 -0
- data/lib/fotolia/galleries.rb +36 -0
- data/lib/fotolia/gallery.rb +65 -0
- data/lib/fotolia/language.rb +58 -0
- data/lib/fotolia/medium.rb +348 -0
- data/lib/fotolia/representative_categories.rb +15 -0
- data/lib/fotolia/representative_category.rb +24 -0
- data/lib/fotolia/search_result_set.rb +244 -0
- data/lib/fotolia/tag.rb +18 -0
- data/lib/fotolia/tags.rb +38 -0
- data/lib/fotolia/user.rb +200 -0
- metadata +94 -0
data/.gitignore
ADDED
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
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
|
data/lib/fotolia/base.rb
ADDED
@@ -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
|