flickr 1.0.2 → 2.0.0
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/LICENSE +20 -0
- data/README.rdoc +185 -0
- data/examples/auth.rb +22 -0
- data/examples/interestingness.rb +7 -0
- data/examples/search.rb +20 -0
- data/examples/sinatra.rb +31 -0
- data/examples/upload.rb +16 -0
- data/examples/web_oauth.rb +47 -0
- data/flickr_rdoc.rb +128 -0
- data/lib/flickr.rb +281 -0
- data/lib/flickr/errors.rb +15 -0
- data/lib/flickr/oauth_client.rb +175 -0
- data/lib/flickr/request.rb +7 -0
- data/lib/flickr/response.rb +38 -0
- data/lib/flickr/response_list.rb +29 -0
- data/lib/flickr/util.rb +13 -0
- data/lib/flickr/version.rb +3 -0
- data/rakefile +22 -0
- data/test/test.rb +471 -0
- data/test/test_cache.rb +45 -0
- data/test/test_request.rb +36 -0
- data/test/test_response.rb +30 -0
- data/test/test_upload.rb +41 -0
- metadata +103 -53
- data/Rakefile +0 -36
- data/flickr.rb +0 -501
- data/index.html +0 -129
- data/test_flickr.rb +0 -173
data/test/test_cache.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.dirname(__FILE__)
|
4
|
+
$:.unshift lib unless $:.include?(lib)
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require 'tempfile'
|
8
|
+
require 'yaml'
|
9
|
+
require 'benchmark'
|
10
|
+
|
11
|
+
class TestCache < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def test_read_and_write
|
14
|
+
::Flickr.class_variable_set :@@initialized, false if ::Flickr.class_variable_get :@@initialized
|
15
|
+
|
16
|
+
file = Tempfile.new(['flickr-gem-test', '.yml'])
|
17
|
+
path = file.path
|
18
|
+
file.close
|
19
|
+
file.unlink
|
20
|
+
|
21
|
+
refute File.exist? path
|
22
|
+
|
23
|
+
::Flickr.cache = path
|
24
|
+
|
25
|
+
no_cache_timer = Benchmark.realtime do
|
26
|
+
::Flickr.new
|
27
|
+
end
|
28
|
+
|
29
|
+
assert File.exist? path
|
30
|
+
from_disk = YAML.load_file path
|
31
|
+
assert_equal Array, from_disk.class
|
32
|
+
assert_equal 222, from_disk.count
|
33
|
+
assert from_disk.all? { |x| /\Aflickr(\.(?i:[a-z]+))+\z/ === x }
|
34
|
+
|
35
|
+
cache_timer = Benchmark.realtime do
|
36
|
+
::Flickr.new
|
37
|
+
end
|
38
|
+
|
39
|
+
assert_operator no_cache_timer, :>, cache_timer
|
40
|
+
assert_operator 10, :<, no_cache_timer / cache_timer
|
41
|
+
|
42
|
+
ensure
|
43
|
+
File.unlink path
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.dirname(__FILE__)
|
4
|
+
$:.unshift lib unless $:.include?(lib)
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
class TestRequest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@flickr = ::Flickr.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_flickr_api_is_accessible_via_methods
|
15
|
+
Flickr.new.send :build_classes, ['flickr.fully.legal']
|
16
|
+
|
17
|
+
assert_equal true, @flickr.methods.include?(:fully)
|
18
|
+
assert_equal true, @flickr.fully.methods.include?(:legal)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_invalid_endpoint_definition
|
22
|
+
e = assert_raises(RuntimeError) do
|
23
|
+
Flickr.new.send :build_classes, ['not_flickr.something.method']
|
24
|
+
end
|
25
|
+
assert_equal "Invalid namespace", e.message
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_invalid_keys_are_skipped
|
29
|
+
assert_nothing_raised {
|
30
|
+
Flickr.new.send :build_classes, ["flickr.hacked; end; raise 'Pwned'; def x"]
|
31
|
+
}
|
32
|
+
|
33
|
+
assert_equal false, @flickr.methods.include?(:hacked)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.dirname(__FILE__)
|
4
|
+
$:.unshift lib unless $:.include?(lib)
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
class TestResponse < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def test_response_keys_are_turned_into_methods
|
11
|
+
subject = Flickr::Response.new({ 'le_gal' => 'ok', }, nil)
|
12
|
+
|
13
|
+
assert_equal true, subject.methods.include?(:le_gal)
|
14
|
+
assert_equal 'ok', subject.le_gal
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_invalid_keys_are_skipped
|
18
|
+
response_hash = {
|
19
|
+
'illegal; end; raise "Pwned"; def x' => 'skipped'
|
20
|
+
}
|
21
|
+
|
22
|
+
assert_nothing_raised {
|
23
|
+
Flickr::Response.new(response_hash, nil)
|
24
|
+
}
|
25
|
+
|
26
|
+
subject = Flickr::Response.new(response_hash, nil)
|
27
|
+
assert_equal false, subject.methods.include?(:illegal)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/test/test_upload.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.dirname(__FILE__)
|
4
|
+
$:.unshift lib unless $:.include?(lib)
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
class TestUpload < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@flickr = ::Flickr.new
|
12
|
+
|
13
|
+
@flickr.access_token = ENV['FLICKR_ACCESS_TOKEN']
|
14
|
+
@flickr.access_secret = ENV['FLICKR_ACCESS_SECRET']
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_upload
|
18
|
+
u = info = nil
|
19
|
+
path = File.dirname(__FILE__) + '/image testée.jpg'
|
20
|
+
title = "Titre de l'image testée"
|
21
|
+
description = "Ceci est la description de l'image testée"
|
22
|
+
|
23
|
+
assert File.exist? path
|
24
|
+
|
25
|
+
assert_nothing_raised do
|
26
|
+
u = @flickr.upload_photo path,
|
27
|
+
:title => title,
|
28
|
+
:description => description
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_nothing_raised do
|
32
|
+
info = @flickr.photos.getInfo :photo_id => u.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_equal title, info.title
|
36
|
+
assert_equal description, info.description
|
37
|
+
|
38
|
+
assert_nothing_raised {@flickr.photos.delete :photo_id => u.to_s}
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
metadata
CHANGED
@@ -1,57 +1,107 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.4
|
3
|
-
specification_version: 1
|
1
|
+
--- !ruby/object:Gem::Specification
|
4
2
|
name: flickr
|
5
|
-
version: !ruby/object:Gem::Version
|
6
|
-
version:
|
7
|
-
date: 2008-02-27 00:00:00 +01:00
|
8
|
-
summary: "An insanely easy interface to the Flickr photo-sharing service. By Scott Raymond. Maintainer: Patrick Plattes"
|
9
|
-
require_paths:
|
10
|
-
- .
|
11
|
-
email: patrick@erdbeere.net
|
12
|
-
homepage: http://flickr.rubyforge.org/
|
13
|
-
rubyforge_project: flickr
|
14
|
-
description:
|
15
|
-
autorequire: flickr
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: false
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
25
5
|
platform: ruby
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
6
|
+
authors:
|
7
|
+
- Mael Clerambault
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-03-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '12.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '12.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: nokogiri
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
description:
|
56
|
+
email: mael@clerambault.fr
|
42
57
|
executables: []
|
43
|
-
|
44
58
|
extensions: []
|
45
|
-
|
46
|
-
|
47
|
-
-
|
48
|
-
|
49
|
-
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- LICENSE
|
62
|
+
- README.rdoc
|
63
|
+
- examples/auth.rb
|
64
|
+
- examples/interestingness.rb
|
65
|
+
- examples/search.rb
|
66
|
+
- examples/sinatra.rb
|
67
|
+
- examples/upload.rb
|
68
|
+
- examples/web_oauth.rb
|
69
|
+
- flickr_rdoc.rb
|
70
|
+
- lib/flickr.rb
|
71
|
+
- lib/flickr/errors.rb
|
72
|
+
- lib/flickr/oauth_client.rb
|
73
|
+
- lib/flickr/request.rb
|
74
|
+
- lib/flickr/response.rb
|
75
|
+
- lib/flickr/response_list.rb
|
76
|
+
- lib/flickr/util.rb
|
77
|
+
- lib/flickr/version.rb
|
78
|
+
- rakefile
|
79
|
+
- test/test.rb
|
80
|
+
- test/test_cache.rb
|
81
|
+
- test/test_request.rb
|
82
|
+
- test/test_response.rb
|
83
|
+
- test/test_upload.rb
|
84
|
+
homepage: https://hanklords.github.io/flickraw/
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.3'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubygems_version: 3.0.3
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: Flickr library with a syntax close to the syntax described on https://www.flickr.com/services/api
|
107
|
+
test_files: []
|
data/Rakefile
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'rake/rdoctask'
|
4
|
-
require 'rake/gempackagetask'
|
5
|
-
require 'rubygems'
|
6
|
-
|
7
|
-
task :default => [ :gem, :rdoc ]
|
8
|
-
|
9
|
-
Rake::TestTask.new("test") { |t|
|
10
|
-
t.test_files = FileList['test*.rb']
|
11
|
-
}
|
12
|
-
|
13
|
-
Rake::RDocTask.new { |rdoc|
|
14
|
-
rdoc.rdoc_dir = 'doc'
|
15
|
-
rdoc.rdoc_files.include('flickr.rb')
|
16
|
-
}
|
17
|
-
|
18
|
-
spec = Gem::Specification.new do |s|
|
19
|
-
s.add_dependency('xml-simple', '>= 1.0.7')
|
20
|
-
s.name = 'flickr'
|
21
|
-
s.version = "1.0.2"
|
22
|
-
s.platform = Gem::Platform::RUBY
|
23
|
-
s.summary = "An insanely easy interface to the Flickr photo-sharing service. By Scott Raymond. Maintainer: Patrick Plattes"
|
24
|
-
s.requirements << 'Flickr developers API key'
|
25
|
-
s.files = Dir.glob("*").delete_if { |item| item.include?("svn") }
|
26
|
-
s.require_path = '.'
|
27
|
-
s.autorequire = 'flickr'
|
28
|
-
s.author = "Scott Raymond, Patrick Plattes"
|
29
|
-
s.email = "patrick@erdbeere.net"
|
30
|
-
s.rubyforge_project = "flickr"
|
31
|
-
s.homepage = "http://flickr.rubyforge.org/"
|
32
|
-
end
|
33
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
34
|
-
pkg.need_zip = true
|
35
|
-
pkg.need_tar = true
|
36
|
-
end
|
data/flickr.rb
DELETED
@@ -1,501 +0,0 @@
|
|
1
|
-
# = Flickr
|
2
|
-
# An insanely easy interface to the Flickr photo-sharing service. By Scott Raymond.
|
3
|
-
#
|
4
|
-
# Author:: Scott Raymond <sco@redgreenblu.com>
|
5
|
-
# Copyright:: Copyright (c) 2005 Scott Raymond <sco@redgreenblu.com>
|
6
|
-
# License:: MIT <http://www.opensource.org/licenses/mit-license.php>
|
7
|
-
#
|
8
|
-
# USAGE:
|
9
|
-
# require 'flickr'
|
10
|
-
# flickr = Flickr.new # create a flickr client
|
11
|
-
# user = flickr.users('sco@scottraymond.net') # lookup a user
|
12
|
-
# user.getInfo.name # get the user's name
|
13
|
-
# user.location # and location
|
14
|
-
# user.photos # grab their collection of Photo objects...
|
15
|
-
# user.groups # ...the groups they're in...
|
16
|
-
# user.contacts # ...their contacts...
|
17
|
-
# user.favorites # ...favorite photos...
|
18
|
-
# user.photosets # ...their photo sets...
|
19
|
-
# user.tags # ...and their tags
|
20
|
-
# recentphotos = flickr.photos # get the 100 most recent public photos
|
21
|
-
# photo = recent.first # or very most recent one
|
22
|
-
# photo.getInfo.url # see its URL,
|
23
|
-
# photo.title # title,
|
24
|
-
# photo.description # and description,
|
25
|
-
# photo.owner # and its owner.
|
26
|
-
# File.open(photo.filename, 'w') do |file|
|
27
|
-
# file.puts p.file # save the photo to a local file
|
28
|
-
# end
|
29
|
-
# flickr.photos.each do |p| # get the last 100 public photos...
|
30
|
-
# File.open(p.filename, 'w') do |f|
|
31
|
-
# f.puts p.file('Square') # ...and save a local copy of their square thumbnail
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
|
35
|
-
# TODO:
|
36
|
-
# - convert dates to ruby Dates
|
37
|
-
# - investigate xmlsimple caching
|
38
|
-
# - make to_s methods automatic?
|
39
|
-
|
40
|
-
# - complete tests
|
41
|
-
# - in tests, implement a MockFlickr object that has stored responses. automate the getting of the responses?
|
42
|
-
|
43
|
-
# - test on a few platforms
|
44
|
-
# - seek feedback from somebody
|
45
|
-
# - make a kickass demo, including autocompleting-ajax photo lookup ala http://mir.aculo.us/images/autocomplete1.mov
|
46
|
-
|
47
|
-
require 'cgi'
|
48
|
-
require 'net/http'
|
49
|
-
require 'xmlsimple'
|
50
|
-
|
51
|
-
# Flickr client class. Requires an API key, and optionally takes an email and password for authentication
|
52
|
-
class Flickr
|
53
|
-
|
54
|
-
attr_accessor :user
|
55
|
-
|
56
|
-
# Replace this API key with your own (see http://www.flickr.com/services/api/misc.api_keys.html)
|
57
|
-
def initialize(api_key=nil, email=nil, password=nil)
|
58
|
-
@api_key = api_key
|
59
|
-
@host = 'http://flickr.com'
|
60
|
-
@api = '/services/rest'
|
61
|
-
login(email, password) if email and password
|
62
|
-
end
|
63
|
-
|
64
|
-
# Takes a Flickr API method name and set of parameters; returns an XmlSimple object with the response
|
65
|
-
def request(method, *params)
|
66
|
-
response = XmlSimple.xml_in(http_get(request_url(method, params)), { 'ForceArray' => false })
|
67
|
-
raise response['err']['msg'] if response['stat'] != 'ok'
|
68
|
-
response
|
69
|
-
end
|
70
|
-
|
71
|
-
# Takes a Flickr API method name and set of parameters; returns the correct URL for the REST API.
|
72
|
-
# If @email and @password are present, authentication information is included
|
73
|
-
def request_url(method, *params)
|
74
|
-
url = "#{@host}#{@api}/?api_key=#{@api_key}&method=flickr.#{method}"
|
75
|
-
params[0][0].each_key do |key| url += "&#{key}=" + CGI::escape(params[0][0][key]) end if params[0][0]
|
76
|
-
url += "&email=#{@email}&password=#{@password}" if @email and @password
|
77
|
-
url
|
78
|
-
end
|
79
|
-
|
80
|
-
# Does an HTTP GET on a given URL and returns the response body
|
81
|
-
def http_get(url)
|
82
|
-
Net::HTTP.get_response(URI.parse(url)).body.to_s
|
83
|
-
end
|
84
|
-
|
85
|
-
# Stores authentication credentials to use on all subsequent calls.
|
86
|
-
# If authentication succeeds, returns a User object
|
87
|
-
def login(email='', password='')
|
88
|
-
@email = email
|
89
|
-
@password = password
|
90
|
-
user = request('test.login')['user'] rescue fail
|
91
|
-
@user = User.new(user['id'], @api_key)
|
92
|
-
end
|
93
|
-
|
94
|
-
# Implements flickr.urls.lookupGroup and flickr.urls.lookupUser
|
95
|
-
def find_by_url(url)
|
96
|
-
response = urls_lookupUser('url'=>url) rescue urls_lookupGroup('url'=>url) rescue nil
|
97
|
-
(response['user']) ? User.new(response['user']['id'], @api_key) : Group.new(response['group']['id'], @api_key) unless response.nil?
|
98
|
-
end
|
99
|
-
|
100
|
-
# Implements flickr.photos.getRecent and flickr.photos.search
|
101
|
-
def photos(*criteria)
|
102
|
-
photos = (criteria[0]) ? photos_search(criteria[0]) : photos_getRecent
|
103
|
-
# At this point, search criterias with pet_page => has structure
|
104
|
-
# {"photos => {"photo" => {...}}"}
|
105
|
-
# While per_page values with > 1 have
|
106
|
-
# {"photos => {"photo" => [{...}]}"}
|
107
|
-
collection = photos['photos']['photo']
|
108
|
-
collection = [collection] if collection.is_a? Hash
|
109
|
-
collection.collect { |photo| Photo.new(photo['id'], @api_key) }
|
110
|
-
end
|
111
|
-
|
112
|
-
# Gets public photos with a given tag
|
113
|
-
def tag(tag)
|
114
|
-
photos('tags'=>tag)
|
115
|
-
end
|
116
|
-
|
117
|
-
# Implements flickr.people.getOnlineList, flickr.people.findByEmail, and flickr.people.findByUsername
|
118
|
-
def users(lookup=nil)
|
119
|
-
if(lookup)
|
120
|
-
user = people_findByEmail('find_email'=>lookup)['user'] rescue people_findByUsername('username'=>lookup)['user']
|
121
|
-
return User.new(user['nsid'], @api_key)
|
122
|
-
else
|
123
|
-
return people_getOnlineList['online']['user'].collect { |person| User.new(person['nsid'], @api_key) }
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Implements flickr.groups.getActiveList
|
128
|
-
def groups
|
129
|
-
groups_getActiveList['activegroups']['group'].collect { |group| Group.new(group['nsid'], @api_key) }
|
130
|
-
end
|
131
|
-
|
132
|
-
# Implements flickr.tags.getRelated
|
133
|
-
def related_tags(tag)
|
134
|
-
tags_getRelated('tag_id'=>tag)['tags']['tag']
|
135
|
-
end
|
136
|
-
|
137
|
-
# Implements flickr.photos.licenses.getInfo
|
138
|
-
def licenses
|
139
|
-
photos_licenses_getInfo['licenses']['license']
|
140
|
-
end
|
141
|
-
|
142
|
-
# Implements everything else.
|
143
|
-
# Any method not defined explicitly will be passed on to the Flickr API,
|
144
|
-
# and return an XmlSimple document. For example, Flickr#test_echo is not defined,
|
145
|
-
# so it will pass the call to the flickr.test.echo method.
|
146
|
-
# e.g., Flickr#test_echo['stat'] should == 'ok'
|
147
|
-
def method_missing(method_id, *params)
|
148
|
-
request(method_id.id2name.gsub(/_/, '.'), params[0])
|
149
|
-
end
|
150
|
-
|
151
|
-
# Todo:
|
152
|
-
# logged_in?
|
153
|
-
# if logged in:
|
154
|
-
# flickr.blogs.getList
|
155
|
-
# flickr.favorites.add
|
156
|
-
# flickr.favorites.remove
|
157
|
-
# flickr.groups.browse
|
158
|
-
# flickr.photos.getCounts
|
159
|
-
# flickr.photos.getNotInSet
|
160
|
-
# flickr.photos.getUntagged
|
161
|
-
# flickr.photosets.create
|
162
|
-
# flickr.photosets.orderSets
|
163
|
-
# flickr.tags.getListUserPopular
|
164
|
-
# flickr.test.login
|
165
|
-
# uploading
|
166
|
-
class User
|
167
|
-
|
168
|
-
attr_reader :client, :id, :name, :location, :photos_url, :url, :count, :firstdate, :firstdatetaken
|
169
|
-
|
170
|
-
def initialize(id=nil, username=nil, email=nil, password=nil, api_key=nil)
|
171
|
-
@id = id
|
172
|
-
@username = username
|
173
|
-
@email = email
|
174
|
-
@password = password
|
175
|
-
@client = Flickr.new @api_key
|
176
|
-
@client.login(email, password) if email and password
|
177
|
-
@api_key = api_key
|
178
|
-
end
|
179
|
-
|
180
|
-
def username
|
181
|
-
@username.nil? ? getInfo.username : @username
|
182
|
-
end
|
183
|
-
def name
|
184
|
-
@name.nil? ? getInfo.name : @name
|
185
|
-
end
|
186
|
-
def location
|
187
|
-
@location.nil? ? getInfo.location : @location
|
188
|
-
end
|
189
|
-
def count
|
190
|
-
@count.nil? ? getInfo.count : @count
|
191
|
-
end
|
192
|
-
def firstdate
|
193
|
-
@firstdate.nil? ? getInfo.firstdate : @firstdate
|
194
|
-
end
|
195
|
-
def firstdatetaken
|
196
|
-
@firstdatetaken.nil? ? getInfo.firstdatetaken : @firstdatetaken
|
197
|
-
end
|
198
|
-
def photos_url
|
199
|
-
@photos_url.nil? ? getInfo.photos_url : @photos_url
|
200
|
-
end
|
201
|
-
def url
|
202
|
-
@url.nil? ? getInfo.url : @url
|
203
|
-
end
|
204
|
-
|
205
|
-
# Implements flickr.people.getPublicGroups
|
206
|
-
def groups
|
207
|
-
@client.people_getPublicGroups('user_id'=>@id)['groups']['group'].collect { |group| Group.new(group['nsid'], @api_key) }
|
208
|
-
end
|
209
|
-
|
210
|
-
# Implements flickr.people.getPublicPhotos
|
211
|
-
def photos
|
212
|
-
@client.people_getPublicPhotos('user_id'=>@id)['photos']['photo'].collect { |photo| Photo.new(photo['id'], @api_key) }
|
213
|
-
# what about non-public photos?
|
214
|
-
end
|
215
|
-
|
216
|
-
# Gets photos with a given tag
|
217
|
-
def tag(tag)
|
218
|
-
@client.photos('user_id'=>@id, 'tags'=>tag)
|
219
|
-
end
|
220
|
-
|
221
|
-
# Implements flickr.contacts.getPublicList and flickr.contacts.getList
|
222
|
-
def contacts
|
223
|
-
@client.contacts_getPublicList('user_id'=>@id)['contacts']['contact'].collect { |contact| User.new(contact['nsid'], @api_key) }
|
224
|
-
#or
|
225
|
-
end
|
226
|
-
|
227
|
-
# Implements flickr.favorites.getPublicList and flickr.favorites.getList
|
228
|
-
def favorites
|
229
|
-
@client.favorites_getPublicList('user_id'=>@id)['photos']['photo'].collect { |photo| Photo.new(photo['id'], @api_key) }
|
230
|
-
#or
|
231
|
-
end
|
232
|
-
|
233
|
-
# Implements flickr.photosets.getList
|
234
|
-
def photosets
|
235
|
-
@client.photosets_getList('user_id'=>@id)['photosets']['photoset'].collect { |photoset| Photoset.new(photoset['id'], @api_key) }
|
236
|
-
end
|
237
|
-
|
238
|
-
# Implements flickr.tags.getListUser
|
239
|
-
def tags
|
240
|
-
@client.tags_getListUser('user_id'=>@id)['who']['tags']['tag'].collect { |tag| tag }
|
241
|
-
end
|
242
|
-
|
243
|
-
# Implements flickr.photos.getContactsPublicPhotos and flickr.photos.getContactsPhotos
|
244
|
-
def contactsPhotos
|
245
|
-
@client.photos_getContactsPublicPhotos('user_id'=>@id)['photos']['photo'].collect { |photo| Photo.new(photo['id'], @api_key) }
|
246
|
-
# or
|
247
|
-
#@client.photos_getContactsPhotos['photos']['photo'].collect { |photo| Photo.new(photo['id'], @api_key) }
|
248
|
-
end
|
249
|
-
|
250
|
-
def to_s
|
251
|
-
@name
|
252
|
-
end
|
253
|
-
|
254
|
-
private
|
255
|
-
|
256
|
-
# Implements flickr.people.getInfo, flickr.urls.getUserPhotos, and flickr.urls.getUserProfile
|
257
|
-
def getInfo
|
258
|
-
info = @client.people_getInfo('user_id'=>@id)['person']
|
259
|
-
@username = info['username']
|
260
|
-
@name = info['realname']
|
261
|
-
@location = info['location']
|
262
|
-
@count = info['photos']['count']
|
263
|
-
@firstdate = info['photos']['firstdate']
|
264
|
-
@firstdatetaken = info['photos']['firstdatetaken']
|
265
|
-
@photos_url = @client.urls_getUserPhotos('user_id'=>@id)['user']['url']
|
266
|
-
@url = @client.urls_getUserProfile('user_id'=>@id)['user']['url']
|
267
|
-
self
|
268
|
-
end
|
269
|
-
|
270
|
-
end
|
271
|
-
|
272
|
-
class Photo
|
273
|
-
|
274
|
-
attr_reader :id, :client
|
275
|
-
|
276
|
-
def initialize(id=nil, api_key=nil)
|
277
|
-
@id = id
|
278
|
-
@api_key = api_key
|
279
|
-
@client = Flickr.new @api_key
|
280
|
-
end
|
281
|
-
|
282
|
-
def title
|
283
|
-
@title.nil? ? getInfo.title : @title
|
284
|
-
end
|
285
|
-
|
286
|
-
def owner
|
287
|
-
@owner.nil? ? getInfo.owner : @owner
|
288
|
-
end
|
289
|
-
|
290
|
-
def server
|
291
|
-
@server.nil? ? getInfo.server : @server
|
292
|
-
end
|
293
|
-
|
294
|
-
def isfavorite
|
295
|
-
@isfavorite.nil? ? getInfo.isfavorite : @isfavorite
|
296
|
-
end
|
297
|
-
|
298
|
-
def license
|
299
|
-
@license.nil? ? getInfo.license : @license
|
300
|
-
end
|
301
|
-
|
302
|
-
def rotation
|
303
|
-
@rotation.nil? ? getInfo.rotation : @rotation
|
304
|
-
end
|
305
|
-
|
306
|
-
def description
|
307
|
-
@description.nil? ? getInfo.description : @description
|
308
|
-
end
|
309
|
-
|
310
|
-
def notes
|
311
|
-
@notes.nil? ? getInfo.notes : @notes
|
312
|
-
end
|
313
|
-
|
314
|
-
# Returns the URL for the photo page (default or any specified size)
|
315
|
-
def url(size='Medium')
|
316
|
-
if size=='Medium'
|
317
|
-
"http://flickr.com/photos/#{owner.username}/#{@id}"
|
318
|
-
else
|
319
|
-
sizes(size)['url']
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
# Returns the URL for the image (default or any specified size)
|
324
|
-
def source(size='Medium')
|
325
|
-
sizes(size)['source']
|
326
|
-
end
|
327
|
-
|
328
|
-
# Returns the photo file data itself, in any specified size. Example: File.open(photo.title, 'w') { |f| f.puts photo.file }
|
329
|
-
def file(size='Medium')
|
330
|
-
Net::HTTP.get_response(URI.parse(source(size))).body
|
331
|
-
end
|
332
|
-
|
333
|
-
# Unique filename for the image, based on the Flickr NSID
|
334
|
-
def filename
|
335
|
-
"#{@id}.jpg"
|
336
|
-
end
|
337
|
-
|
338
|
-
# Implements flickr.photos.getContext
|
339
|
-
def context
|
340
|
-
context = @client.photos_getContext('photo_id'=>@id)
|
341
|
-
@previousPhoto = Photo.new(context['prevphoto']['id'], @api_key)
|
342
|
-
@nextPhoto = Photo.new(context['nextphoto']['id'], @api_key)
|
343
|
-
return [@previousPhoto, @nextPhoto]
|
344
|
-
end
|
345
|
-
|
346
|
-
# Implements flickr.photos.getExif
|
347
|
-
def exif
|
348
|
-
@client.photos_getExif('photo_id'=>@id)['photo']
|
349
|
-
end
|
350
|
-
|
351
|
-
# Implements flickr.photos.getPerms
|
352
|
-
def permissions
|
353
|
-
@client.photos_getPerms('photo_id'=>@id)['perms']
|
354
|
-
end
|
355
|
-
|
356
|
-
# Implements flickr.photos.getSizes
|
357
|
-
def sizes(size=nil)
|
358
|
-
sizes = @client.photos_getSizes('photo_id'=>@id)['sizes']['size']
|
359
|
-
sizes = sizes.find{|asize| asize['label']==size} if size
|
360
|
-
return sizes
|
361
|
-
end
|
362
|
-
|
363
|
-
# flickr.tags.getListPhoto
|
364
|
-
def tags
|
365
|
-
@client.tags_getListPhoto('photo_id'=>@id)['photo']['tags']
|
366
|
-
end
|
367
|
-
|
368
|
-
# Implements flickr.photos.notes.add
|
369
|
-
def add_note(note)
|
370
|
-
end
|
371
|
-
|
372
|
-
# Implements flickr.photos.setDates
|
373
|
-
def dates=(dates)
|
374
|
-
end
|
375
|
-
|
376
|
-
# Implements flickr.photos.setPerms
|
377
|
-
def perms=(perms)
|
378
|
-
end
|
379
|
-
|
380
|
-
# Implements flickr.photos.setTags
|
381
|
-
def tags=(tags)
|
382
|
-
end
|
383
|
-
|
384
|
-
# Implements flickr.photos.setMeta
|
385
|
-
def title=(title)
|
386
|
-
end
|
387
|
-
def description=(title)
|
388
|
-
end
|
389
|
-
|
390
|
-
# Implements flickr.photos.addTags
|
391
|
-
def add_tag(tag)
|
392
|
-
end
|
393
|
-
|
394
|
-
# Implements flickr.photos.removeTag
|
395
|
-
def remove_tag(tag)
|
396
|
-
end
|
397
|
-
|
398
|
-
# Implements flickr.photos.transform.rotate
|
399
|
-
def rotate
|
400
|
-
end
|
401
|
-
|
402
|
-
# Implements flickr.blogs.postPhoto
|
403
|
-
def postToBlog(blog_id, title='', description='')
|
404
|
-
@client.blogs_postPhoto('photo_id'=>@id, 'title'=>title, 'description'=>description)
|
405
|
-
end
|
406
|
-
|
407
|
-
# Implements flickr.photos.notes.delete
|
408
|
-
def deleteNote(note_id)
|
409
|
-
end
|
410
|
-
|
411
|
-
# Implements flickr.photos.notes.edit
|
412
|
-
def editNote(note_id)
|
413
|
-
end
|
414
|
-
|
415
|
-
# Converts the Photo to a string by returning its title
|
416
|
-
def to_s
|
417
|
-
getInfo.title
|
418
|
-
end
|
419
|
-
|
420
|
-
private
|
421
|
-
|
422
|
-
# Implements flickr.photos.getInfo
|
423
|
-
def getInfo
|
424
|
-
info = @client.photos_getInfo('photo_id'=>@id)['photo']
|
425
|
-
@title = info['title']
|
426
|
-
@owner = User.new(info['owner']['nsid'], @api_key)
|
427
|
-
@server = info['server']
|
428
|
-
@isfavorite = info['isfavorite']
|
429
|
-
@license = info['license']
|
430
|
-
@rotation = info['rotation']
|
431
|
-
@description = info['description']
|
432
|
-
@notes = info['notes']['note']#.collect { |note| Note.new(note.id) }
|
433
|
-
self
|
434
|
-
end
|
435
|
-
|
436
|
-
end
|
437
|
-
|
438
|
-
# Todo:
|
439
|
-
# flickr.groups.pools.add
|
440
|
-
# flickr.groups.pools.getContext
|
441
|
-
# flickr.groups.pools.getGroups
|
442
|
-
# flickr.groups.pools.getPhotos
|
443
|
-
# flickr.groups.pools.remove
|
444
|
-
class Group
|
445
|
-
attr_reader :id, :client, :name, :members, :online, :privacy, :chatid, :chatcount, :url
|
446
|
-
|
447
|
-
def initialize(id=nil, api_key=nil)
|
448
|
-
@id = id
|
449
|
-
@api_key = api_key
|
450
|
-
@client = Flickr.new @api_key
|
451
|
-
end
|
452
|
-
|
453
|
-
# Implements flickr.groups.getInfo and flickr.urls.getGroup
|
454
|
-
# private, once we can call it as needed
|
455
|
-
def getInfo
|
456
|
-
info = @client.groups_getInfo('group_id'=>@id)['group']
|
457
|
-
@name = info['name']
|
458
|
-
@members = info['members']
|
459
|
-
@online = info['online']
|
460
|
-
@privacy = info['privacy']
|
461
|
-
@chatid = info['chatid']
|
462
|
-
@chatcount = info['chatcount']
|
463
|
-
@url = @client.urls_getGroup('group_id'=>@id)['group']['url']
|
464
|
-
self
|
465
|
-
end
|
466
|
-
|
467
|
-
end
|
468
|
-
|
469
|
-
# Todo:
|
470
|
-
# flickr.photosets.delete
|
471
|
-
# flickr.photosets.editMeta
|
472
|
-
# flickr.photosets.editPhotos
|
473
|
-
# flickr.photosets.getContext
|
474
|
-
# flickr.photosets.getInfo
|
475
|
-
# flickr.photosets.getPhotos
|
476
|
-
class Photoset
|
477
|
-
|
478
|
-
attr_reader :id, :client, :owner, :primary, :photos, :title, :description, :url
|
479
|
-
|
480
|
-
def initialize(id=nil, api_key=nil)
|
481
|
-
@id = id
|
482
|
-
@api_key = api_key
|
483
|
-
@client = Flickr.new @api_key
|
484
|
-
end
|
485
|
-
|
486
|
-
# Implements flickr.photosets.getInfo
|
487
|
-
# private, once we can call it as needed
|
488
|
-
def getInfo
|
489
|
-
info = @client.photosets_getInfo('photosets_id'=>@id)['photoset']
|
490
|
-
@owner = User.new(info['owner'], @api_key)
|
491
|
-
@primary = info['primary']
|
492
|
-
@photos = info['photos']
|
493
|
-
@title = info['title']
|
494
|
-
@description = info['description']
|
495
|
-
@url = "http://www.flickr.com/photos/#{@owner.getInfo.username}/sets/#{@id}/"
|
496
|
-
self
|
497
|
-
end
|
498
|
-
|
499
|
-
end
|
500
|
-
|
501
|
-
end
|