fleakr 0.3.0 → 0.4.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.
- data/README.rdoc +114 -19
- data/Rakefile +1 -1
- data/lib/fleakr/api/file_parameter.rb +47 -0
- data/lib/fleakr/api/method_request.rb +57 -0
- data/lib/fleakr/api/parameter.rb +35 -0
- data/lib/fleakr/api/parameter_list.rb +96 -0
- data/lib/fleakr/api/response.rb +2 -2
- data/lib/fleakr/api/upload_request.rb +64 -0
- data/lib/fleakr/api/value_parameter.rb +36 -0
- data/lib/fleakr/api.rb +7 -0
- data/lib/fleakr/core_ext/hash.rb +22 -0
- data/lib/fleakr/core_ext.rb +1 -0
- data/lib/fleakr/objects/authentication_token.rb +43 -0
- data/lib/fleakr/objects/contact.rb +5 -5
- data/lib/fleakr/objects/error.rb +2 -2
- data/lib/fleakr/objects/group.rb +2 -2
- data/lib/fleakr/objects/image.rb +7 -7
- data/lib/fleakr/objects/photo.rb +69 -5
- data/lib/fleakr/objects/search.rb +3 -6
- data/lib/fleakr/objects/set.rb +11 -5
- data/lib/fleakr/objects/user.rb +14 -26
- data/lib/fleakr/objects.rb +9 -0
- data/lib/fleakr/support/attribute.rb +30 -12
- data/lib/fleakr/support/object.rb +20 -4
- data/lib/fleakr/support.rb +2 -0
- data/lib/fleakr/version.rb +1 -1
- data/lib/fleakr.rb +66 -7
- data/test/fixtures/auth.checkToken.xml +8 -0
- data/test/fixtures/auth.getFullToken.xml +8 -0
- data/test/fixtures/people.getInfo.xml +1 -1
- data/test/fixtures/photos.getInfo.xml +20 -0
- data/test/test_helper.rb +18 -3
- data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
- data/test/unit/fleakr/api/method_request_test.rb +103 -0
- data/test/unit/fleakr/api/parameter_list_test.rb +161 -0
- data/test/unit/fleakr/api/parameter_test.rb +34 -0
- data/test/unit/fleakr/api/upload_request_test.rb +133 -0
- data/test/unit/fleakr/api/value_parameter_test.rb +41 -0
- data/test/unit/fleakr/core_ext/hash_test.rb +32 -0
- data/test/unit/fleakr/objects/authentication_token_test.rb +47 -0
- data/test/unit/fleakr/objects/image_test.rb +10 -5
- data/test/unit/fleakr/objects/photo_test.rb +96 -36
- data/test/unit/fleakr/objects/search_test.rb +1 -1
- data/test/unit/fleakr/objects/set_test.rb +12 -1
- data/test/unit/fleakr/objects/user_test.rb +2 -16
- data/test/unit/fleakr/support/attribute_test.rb +82 -24
- data/test/unit/fleakr/support/object_test.rb +26 -3
- data/test/unit/fleakr_test.rb +65 -6
- metadata +28 -5
- data/lib/fleakr/api/request.rb +0 -58
- data/test/unit/fleakr/api/request_test.rb +0 -93
data/lib/fleakr/objects/image.rb
CHANGED
@@ -24,11 +24,11 @@ module Fleakr
|
|
24
24
|
|
25
25
|
include Fleakr::Support::Object
|
26
26
|
|
27
|
-
flickr_attribute :size, :
|
28
|
-
flickr_attribute :width
|
29
|
-
flickr_attribute :height
|
30
|
-
flickr_attribute :url, :
|
31
|
-
flickr_attribute :page, :
|
27
|
+
flickr_attribute :size, :from => '@label'
|
28
|
+
flickr_attribute :width
|
29
|
+
flickr_attribute :height
|
30
|
+
flickr_attribute :url, :from => '@source'
|
31
|
+
flickr_attribute :page, :from => '@url'
|
32
32
|
|
33
33
|
find_all :by_photo_id, :call => 'photos.getSizes', :path => 'sizes/size'
|
34
34
|
|
@@ -41,8 +41,8 @@ module Fleakr
|
|
41
41
|
# directory, the file will be created with the original filename from Flickr.
|
42
42
|
# If the target is a file, it will be saved with the specified name. In the
|
43
43
|
# case that the target file already exists, this method will overwrite it.
|
44
|
-
def save_to(target)
|
45
|
-
destination = File.directory?(target) ? "#{target}/#{self.filename}" : "#{target}"
|
44
|
+
def save_to(target, prefix = nil)
|
45
|
+
destination = File.directory?(target) ? "#{target}/#{prefix}#{self.filename}" : "#{target}"
|
46
46
|
File.open(destination, 'w') {|f| f << Net::HTTP.get(URI.parse(self.url)) }
|
47
47
|
end
|
48
48
|
|
data/lib/fleakr/objects/photo.rb
CHANGED
@@ -7,6 +7,10 @@ module Fleakr
|
|
7
7
|
#
|
8
8
|
# [id] The ID for this photo
|
9
9
|
# [title] The title of this photo
|
10
|
+
# [description] The description of this photo
|
11
|
+
# [secret] This photo's secret (used for sharing photo without permissions checking)
|
12
|
+
# [comment_count] Count of the comments attached to this photo
|
13
|
+
# [url] This photo's page on Flickr
|
10
14
|
# [square] The tiny square representation of this photo
|
11
15
|
# [thumbnail] The thumbnail for this photo
|
12
16
|
# [small] The small representation of this photo
|
@@ -25,18 +29,78 @@ module Fleakr
|
|
25
29
|
|
26
30
|
include Fleakr::Support::Object
|
27
31
|
|
28
|
-
flickr_attribute :
|
29
|
-
flickr_attribute :
|
30
|
-
flickr_attribute :
|
31
|
-
flickr_attribute :
|
32
|
-
flickr_attribute :
|
32
|
+
flickr_attribute :id, :from => ['@id', 'photoid']
|
33
|
+
flickr_attribute :title
|
34
|
+
flickr_attribute :description
|
35
|
+
flickr_attribute :farm_id, :from => '@farm'
|
36
|
+
flickr_attribute :server_id, :from => '@server'
|
37
|
+
flickr_attribute :secret
|
38
|
+
flickr_attribute :posted
|
39
|
+
flickr_attribute :taken
|
40
|
+
flickr_attribute :updated, :from => '@lastupdate'
|
41
|
+
flickr_attribute :comment_count, :from => 'comments'
|
42
|
+
flickr_attribute :url
|
43
|
+
|
44
|
+
# TODO:
|
45
|
+
# * owner (user)
|
46
|
+
# * visibility
|
47
|
+
# * editability
|
48
|
+
# * usage
|
49
|
+
# * notes
|
50
|
+
# * tags
|
33
51
|
|
34
52
|
find_all :by_photoset_id, :call => 'photosets.getPhotos', :path => 'photoset/photo'
|
35
53
|
find_all :by_user_id, :call => 'people.getPublicPhotos', :path => 'photos/photo'
|
36
54
|
find_all :by_group_id, :call => 'groups.pools.getPhotos', :path => 'photos/photo'
|
37
55
|
|
56
|
+
find_one :by_id, :using => :photo_id, :call => 'photos.getInfo', :authenticate? => true
|
57
|
+
|
58
|
+
lazily_load :posted, :taken, :updated, :comment_count, :url, :description, :with => :load_info
|
59
|
+
|
38
60
|
has_many :images
|
39
61
|
|
62
|
+
# Upload the photo specified by <tt>filename</tt> to the user's Flickr account. This
|
63
|
+
# call requires authentication.
|
64
|
+
#
|
65
|
+
def self.upload(filename)
|
66
|
+
response = Fleakr::Api::UploadRequest.with_response!(filename)
|
67
|
+
photo = Photo.new(response.body)
|
68
|
+
Photo.find_by_id(photo.id, :authenticate? => true)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Replace the current photo's image with the one specified by filename. This
|
72
|
+
# call requires authentication.
|
73
|
+
#
|
74
|
+
def replace_with(filename)
|
75
|
+
response = Fleakr::Api::UploadRequest.with_response!(filename, :photo_id => self.id, :type => :update)
|
76
|
+
self.populate_from(response.body)
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
# TODO: Refactor this to remove duplication w/ User#load_info - possibly in the lazily_load class method
|
81
|
+
def load_info # :nodoc:
|
82
|
+
response = Fleakr::Api::MethodRequest.with_response!('photos.getInfo', :photo_id => self.id)
|
83
|
+
self.populate_from(response.body)
|
84
|
+
end
|
85
|
+
|
86
|
+
# When was this photo posted?
|
87
|
+
#
|
88
|
+
def posted_at
|
89
|
+
Time.at(posted.to_i)
|
90
|
+
end
|
91
|
+
|
92
|
+
# When was this photo taken?
|
93
|
+
#
|
94
|
+
def taken_at
|
95
|
+
Time.parse(taken)
|
96
|
+
end
|
97
|
+
|
98
|
+
# When was this photo last updated? This includes addition of tags and other metadata.
|
99
|
+
#
|
100
|
+
def updated_at
|
101
|
+
Time.at(updated.to_i)
|
102
|
+
end
|
103
|
+
|
40
104
|
# Create methods to access image sizes by name
|
41
105
|
SIZES.each do |size|
|
42
106
|
define_method(size) do
|
@@ -9,13 +9,10 @@ module Fleakr
|
|
9
9
|
|
10
10
|
# Retrieve search results from the API
|
11
11
|
def results
|
12
|
-
|
13
|
-
response = Fleakr::Api::
|
14
|
-
|
15
|
-
Photo.new(flickr_photo)
|
16
|
-
end
|
12
|
+
@results ||= begin
|
13
|
+
response = Fleakr::Api::MethodRequest.with_response!('photos.search', parameters)
|
14
|
+
(response.body/'rsp/photos/photo').map {|p| Photo.new(p) }
|
17
15
|
end
|
18
|
-
@results
|
19
16
|
end
|
20
17
|
|
21
18
|
private
|
data/lib/fleakr/objects/set.rb
CHANGED
@@ -8,6 +8,7 @@ module Fleakr
|
|
8
8
|
# [id] The ID for this photoset
|
9
9
|
# [title] The title of this photoset
|
10
10
|
# [description] The description of this set
|
11
|
+
# [count] Count of photos in this set
|
11
12
|
#
|
12
13
|
# == Associations
|
13
14
|
#
|
@@ -19,26 +20,31 @@ module Fleakr
|
|
19
20
|
|
20
21
|
has_many :photos, :using => :photoset_id
|
21
22
|
|
22
|
-
flickr_attribute :id
|
23
|
+
flickr_attribute :id
|
23
24
|
flickr_attribute :title
|
24
25
|
flickr_attribute :description
|
26
|
+
flickr_attribute :count, :from => '@photos'
|
25
27
|
|
26
28
|
find_all :by_user_id, :call => 'photosets.getList', :path => 'photosets/photoset'
|
27
29
|
|
28
|
-
# Save all photos in this set to the specified directory
|
30
|
+
# Save all photos in this set to the specified directory for the specified size. Allowed
|
29
31
|
# Sizes include <tt>:square</tt>, <tt>:small</tt>, <tt>:thumbnail</tt>, <tt>:medium</tt>,
|
30
|
-
# <tt>:large</tt>, and <tt>:original</tt>. When saving the set, this
|
32
|
+
# <tt>:large</tt>, and <tt>:original</tt>. When saving the set, this method will create
|
31
33
|
# a subdirectory based on the set's title.
|
32
34
|
#
|
33
35
|
def save_to(path, size)
|
34
36
|
target = "#{path}/#{self.title}"
|
35
37
|
FileUtils.mkdir(target) unless File.exist?(target)
|
36
38
|
|
37
|
-
self.photos.
|
39
|
+
self.photos.each_with_index do |photo, index|
|
38
40
|
image = photo.send(size)
|
39
|
-
image.save_to(target) unless image.nil?
|
41
|
+
image.save_to(target, file_prefix(index)) unless image.nil?
|
40
42
|
end
|
41
43
|
end
|
44
|
+
|
45
|
+
def file_prefix(index) # :nodoc:
|
46
|
+
sprintf("%0#{self.count.length}d_", (index + 1))
|
47
|
+
end
|
42
48
|
|
43
49
|
end
|
44
50
|
end
|
data/lib/fleakr/objects/user.rb
CHANGED
@@ -11,6 +11,7 @@ module Fleakr
|
|
11
11
|
# [id] The ID for this user (also referred to as the NSID in the API docs)
|
12
12
|
# [username] This user's username
|
13
13
|
# [name] This user's full name (if entered)
|
14
|
+
# [location] This user's location (if entered)
|
14
15
|
# [photos_url] The direct URL to this user's photostream
|
15
16
|
# [profile_url] The direct URL to this user's profile
|
16
17
|
# [photos_count] The number of photos that this user has uploaded
|
@@ -42,37 +43,24 @@ module Fleakr
|
|
42
43
|
|
43
44
|
include Fleakr::Support::Object
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
flickr_attribute :id, :xpath => 'rsp/user', :attribute => 'nsid'
|
60
|
-
flickr_attribute :username, :xpath => 'rsp/user/username'
|
61
|
-
flickr_attribute :name, :xpath => 'rsp/person/realname'
|
62
|
-
flickr_attribute :photos_url, :xpath => 'rsp/person/photosurl'
|
63
|
-
flickr_attribute :profile_url, :xpath => 'rsp/person/profileurl'
|
64
|
-
flickr_attribute :photos_count, :xpath => 'rsp/person/photos/count'
|
65
|
-
flickr_attribute :icon_server, :xpath => 'rsp/person', :attribute => 'iconserver'
|
66
|
-
flickr_attribute :icon_farm, :xpath => 'rsp/person', :attribute => 'iconfarm'
|
67
|
-
flickr_attribute :pro, :xpath => 'rsp/person', :attribute => 'ispro'
|
68
|
-
flickr_attribute :admin, :xpath => 'rsp/person', :attribute => 'isadmin'
|
46
|
+
flickr_attribute :id, :from => 'user@nsid'
|
47
|
+
flickr_attribute :username
|
48
|
+
flickr_attribute :name, :from => 'person/realname'
|
49
|
+
flickr_attribute :location
|
50
|
+
flickr_attribute :photos_url, :from => 'person/photosurl'
|
51
|
+
flickr_attribute :profile_url, :from => 'person/profileurl'
|
52
|
+
flickr_attribute :photos_count, :from => 'person/photos/count'
|
53
|
+
flickr_attribute :icon_server, :from => 'person@iconserver'
|
54
|
+
flickr_attribute :icon_farm, :from => 'person@iconfarm'
|
55
|
+
flickr_attribute :pro, :from => 'person@ispro'
|
56
|
+
flickr_attribute :admin, :from => 'person@isadmin'
|
69
57
|
|
70
58
|
has_many :sets, :groups, :photos, :contacts
|
71
59
|
|
72
60
|
find_one :by_username, :call => 'people.findByUsername'
|
73
61
|
find_one :by_email, :using => :find_email, :call => 'people.findByEmail'
|
74
62
|
|
75
|
-
lazily_load :name, :photos_url, :profile_url, :photos_count, :with => :load_info
|
63
|
+
lazily_load :name, :photos_url, :profile_url, :photos_count, :location, :with => :load_info
|
76
64
|
lazily_load :icon_server, :icon_farm, :pro, :admin, :with => :load_info
|
77
65
|
|
78
66
|
scoped_search
|
@@ -97,7 +85,7 @@ module Fleakr
|
|
97
85
|
end
|
98
86
|
|
99
87
|
def load_info # :nodoc:
|
100
|
-
response = Fleakr::Api::
|
88
|
+
response = Fleakr::Api::MethodRequest.with_response!('people.getInfo', :user_id => self.id)
|
101
89
|
self.populate_from(response.body)
|
102
90
|
end
|
103
91
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'fleakr/objects/authentication_token'
|
2
|
+
require 'fleakr/objects/contact'
|
3
|
+
require 'fleakr/objects/error'
|
4
|
+
require 'fleakr/objects/group'
|
5
|
+
require 'fleakr/objects/image'
|
6
|
+
require 'fleakr/objects/photo'
|
7
|
+
require 'fleakr/objects/search'
|
8
|
+
require 'fleakr/objects/set'
|
9
|
+
require 'fleakr/objects/user'
|
@@ -2,25 +2,43 @@ module Fleakr
|
|
2
2
|
module Support # :nodoc:all
|
3
3
|
class Attribute
|
4
4
|
|
5
|
-
|
5
|
+
# TODO: Refactor the location / attribute logic into a Source class
|
6
6
|
|
7
|
-
|
7
|
+
attr_reader :name, :sources
|
8
|
+
|
9
|
+
def initialize(name, sources = nil)
|
8
10
|
@name = name.to_sym
|
9
|
-
|
11
|
+
|
12
|
+
@sources = Array(sources)
|
13
|
+
@sources << @name.to_s if @sources.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def split(source)
|
17
|
+
location, attribute = source.split('@')
|
18
|
+
location = self.name.to_s if location.blank?
|
19
|
+
|
20
|
+
[location, attribute]
|
21
|
+
end
|
22
|
+
|
23
|
+
def node_for(document, source)
|
24
|
+
document.at(location(source)) || document.search("//[@#{attribute(source)}]").first
|
25
|
+
end
|
10
26
|
|
11
|
-
|
12
|
-
|
27
|
+
def attribute(source)
|
28
|
+
location, attribute = source.split('@')
|
29
|
+
attribute || location
|
30
|
+
end
|
31
|
+
|
32
|
+
def location(source)
|
33
|
+
split(source).first
|
13
34
|
end
|
14
35
|
|
15
36
|
def value_from(document)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
node = document.at(self.xpath) if self.xpath
|
20
|
-
self.attribute.nil? ? node.inner_text : node[self.attribute]
|
21
|
-
rescue NoMethodError
|
22
|
-
nil
|
37
|
+
values = sources.map do |source|
|
38
|
+
node = node_for(document, source)
|
39
|
+
(node.attributes[attribute(source)] || node.inner_text) unless node.nil?
|
23
40
|
end
|
41
|
+
values.compact.first
|
24
42
|
end
|
25
43
|
|
26
44
|
end
|
@@ -9,7 +9,7 @@ module Fleakr
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def flickr_attribute(name, options = {})
|
12
|
-
self.attributes << Attribute.new(name, options)
|
12
|
+
self.attributes << Attribute.new(name, options[:from])
|
13
13
|
class_eval "attr_accessor :#{name}"
|
14
14
|
end
|
15
15
|
|
@@ -34,7 +34,7 @@ module Fleakr
|
|
34
34
|
|
35
35
|
class_eval <<-CODE
|
36
36
|
def self.find_all_#{condition}(value)
|
37
|
-
response = Fleakr::Api::
|
37
|
+
response = Fleakr::Api::MethodRequest.with_response!('#{options[:call]}', :#{attribute} => value)
|
38
38
|
(response.body/'rsp/#{options[:path]}').map {|e| #{target_class}.new(e) }
|
39
39
|
end
|
40
40
|
CODE
|
@@ -44,8 +44,10 @@ module Fleakr
|
|
44
44
|
attribute = options[:using].nil? ? condition.to_s.sub(/^by_/, '') : options[:using]
|
45
45
|
|
46
46
|
class_eval <<-CODE
|
47
|
-
def self.find_#{condition}(value)
|
48
|
-
|
47
|
+
def self.find_#{condition}(value, options = {})
|
48
|
+
options.merge!(:#{attribute} => value)
|
49
|
+
|
50
|
+
response = Fleakr::Api::MethodRequest.with_response!('#{options[:call]}', options)
|
49
51
|
#{self.name}.new(response.body)
|
50
52
|
end
|
51
53
|
CODE
|
@@ -60,6 +62,20 @@ module Fleakr
|
|
60
62
|
end
|
61
63
|
CODE
|
62
64
|
end
|
65
|
+
|
66
|
+
def lazily_load(*attributes)
|
67
|
+
options = attributes.extract_options!
|
68
|
+
|
69
|
+
attributes.each do |attribute|
|
70
|
+
class_eval <<-CODE
|
71
|
+
def #{attribute}_with_loading
|
72
|
+
self.send(:#{options[:with]}) if @#{attribute}.nil?
|
73
|
+
#{attribute}_without_loading
|
74
|
+
end
|
75
|
+
alias_method_chain :#{attribute}, :loading
|
76
|
+
CODE
|
77
|
+
end
|
78
|
+
end
|
63
79
|
|
64
80
|
end
|
65
81
|
|
data/lib/fleakr/version.rb
CHANGED
data/lib/fleakr.rb
CHANGED
@@ -6,13 +6,16 @@ require 'net/http'
|
|
6
6
|
require 'rubygems'
|
7
7
|
require 'hpricot'
|
8
8
|
require 'activesupport'
|
9
|
+
require 'md5'
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
require 'fleakr/api'
|
12
|
+
require 'fleakr/core_ext'
|
13
|
+
require 'fleakr/support'
|
14
|
+
require 'fleakr/objects'
|
14
15
|
|
15
|
-
# = Fleakr: A
|
16
|
+
# = Fleakr: A small, yet powerful, gem to interface with Flickr photostreams
|
17
|
+
#
|
18
|
+
# == Quick Start
|
16
19
|
#
|
17
20
|
# Getting started is easy, just make sure you have a valid API key from Flickr and you can
|
18
21
|
# then start making any non-authenticated request to pull back data for yours and others'
|
@@ -36,10 +39,42 @@ end
|
|
36
39
|
# user.groups
|
37
40
|
#
|
38
41
|
# To see what other associations and attributes are available, see the Fleakr::Objects::User class
|
42
|
+
#
|
43
|
+
# == Authentication
|
44
|
+
#
|
45
|
+
# If you want to do something more than just retrieve public photos (like upload your own),
|
46
|
+
# you'll need to generate an authentication token to use across requests and sessions.
|
47
|
+
#
|
48
|
+
# Assuming you've already applied for a key, go back and make sure you have the right settings
|
49
|
+
# to get your auth token. Click on the 'Edit key details' link and ensure that:
|
50
|
+
#
|
51
|
+
# 1. Your application description and notes are up-to-date
|
52
|
+
# 1. The value for 'Authentication Type' is set to 'Mobile Application'
|
53
|
+
# 1. The value for 'Mobile Permissions' is set to either 'write' or 'delete'
|
54
|
+
#
|
55
|
+
# Once this is set, you'll see your Authentication URL on the key details page (it will look
|
56
|
+
# something like http://www.flickr.com/auth-534525246245). Paste this URL into your browser and
|
57
|
+
# confirm access to get your mini-token. Now you're ready to make authenticated requests:
|
58
|
+
#
|
59
|
+
# require 'rubygems'
|
60
|
+
# require 'fleakr'
|
61
|
+
#
|
62
|
+
# Fleakr.api_key = 'ABC123'
|
63
|
+
# Fleakr.shared_secret = 'sekrit' # Available with your key details on the Flickr site
|
64
|
+
# Fleakr.mini_token = '362-133-214'
|
65
|
+
#
|
66
|
+
# Fleakr.upload('/path/to/my/photo.jpg')
|
67
|
+
# Fleakr.token.value # => "34132412341235-12341234ef34"
|
68
|
+
#
|
69
|
+
# Once you use the mini-token once, it is no longer available. To use the generated auth_token
|
70
|
+
# for future requests, just set Fleakr.auth_token to the generated value.
|
39
71
|
#
|
40
72
|
module Fleakr
|
41
73
|
|
42
|
-
|
74
|
+
# Generic catch-all exception for any API errors
|
75
|
+
class ApiError < StandardError; end
|
76
|
+
|
77
|
+
mattr_accessor :api_key, :shared_secret, :mini_token, :auth_token
|
43
78
|
|
44
79
|
# Find a user based on some unique user data. This method will try to find
|
45
80
|
# the user based on username and will fall back to email if that fails. Example:
|
@@ -51,7 +86,7 @@ module Fleakr
|
|
51
86
|
def self.user(user_data)
|
52
87
|
begin
|
53
88
|
Objects::User.find_by_username(user_data)
|
54
|
-
rescue
|
89
|
+
rescue ApiError
|
55
90
|
Objects::User.find_by_email(user_data)
|
56
91
|
end
|
57
92
|
end
|
@@ -71,4 +106,28 @@ module Fleakr
|
|
71
106
|
Objects::Search.new(params).results
|
72
107
|
end
|
73
108
|
|
109
|
+
# Upload one or more files to your Flickr account (requires authentication). Simply provide
|
110
|
+
# a filename or a pattern to upload one or more files:
|
111
|
+
#
|
112
|
+
# Fleakr.upload('/path/to/my/mug.jpg')
|
113
|
+
# Fleakr.upload('/User/Pictures/Party/*.jpg')
|
114
|
+
#
|
115
|
+
def self.upload(glob)
|
116
|
+
Dir[glob].each {|file| Fleakr::Objects::Photo.upload(file) }
|
117
|
+
end
|
118
|
+
|
119
|
+
# Get the authentication token needed for authenticated requests. Will either use
|
120
|
+
# a valid auth_token (if available) or a mini-token to generate the auth_token.
|
121
|
+
#
|
122
|
+
def self.token
|
123
|
+
@token ||= begin
|
124
|
+
if !Fleakr.auth_token.nil?
|
125
|
+
Fleakr::Objects::AuthenticationToken.from_auth_token(Fleakr.auth_token)
|
126
|
+
else
|
127
|
+
Fleakr::Objects::AuthenticationToken.from_mini_token(Fleakr.mini_token)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
74
133
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<username>frootpantz</username>
|
5
5
|
<realname>Sir Froot Pantz</realname>
|
6
6
|
<mbox_sha1sum>e52ed1e5b91c763694995460e9796fc2adc02019</mbox_sha1sum>
|
7
|
-
<location
|
7
|
+
<location>The Moon</location>
|
8
8
|
<photosurl>http://www.flickr.com/photos/frootpantz/</photosurl>
|
9
9
|
<profileurl>http://www.flickr.com/people/frootpantz/</profileurl>
|
10
10
|
<mobileurl>http://m.flickr.com/photostream.gne?id=34225</mobileurl>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<rsp stat="ok">
|
3
|
+
<photo id="1" secret="secret" server="3085" farm="4" dateuploaded="1230274722" isfavorite="0" license="0" rotation="0" originalsecret="sekrit" originalformat="jpg" media="photo">
|
4
|
+
<owner nsid="31066442@N69" username="frootpantz" realname="" location="" />
|
5
|
+
<title>Tree</title>
|
6
|
+
<description>A Tree</description>
|
7
|
+
<visibility ispublic="1" isfriend="0" isfamily="0" />
|
8
|
+
<dates posted="1230274722" taken="2008-12-25 18:26:55" takengranularity="0" lastupdate="1230276652" />
|
9
|
+
|
10
|
+
<editability cancomment="0" canaddmeta="0" />
|
11
|
+
<usage candownload="1" canblog="0" canprint="0" />
|
12
|
+
<comments>0</comments>
|
13
|
+
<notes />
|
14
|
+
<tags />
|
15
|
+
<urls>
|
16
|
+
<url type="photopage">http://www.flickr.com/photos/yes/1</url>
|
17
|
+
</urls>
|
18
|
+
|
19
|
+
</photo>
|
20
|
+
</rsp>
|
data/test/test_helper.rb
CHANGED
@@ -9,6 +9,19 @@ require File.dirname(__FILE__) + '/../lib/fleakr'
|
|
9
9
|
|
10
10
|
class Test::Unit::TestCase
|
11
11
|
|
12
|
+
def self.should_autoload_when_accessing(*attributes)
|
13
|
+
options = attributes.extract_options!
|
14
|
+
attributes.each do |accessor_name|
|
15
|
+
it "should load the additional user information when accessing the :#{accessor_name} attribute" do
|
16
|
+
klass = self.class.name.sub(/Test$/, '').constantize
|
17
|
+
|
18
|
+
object = klass.new
|
19
|
+
object.expects(options[:with]).with()
|
20
|
+
object.send(accessor_name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
12
25
|
def self.should_have_a_value_for(attribute_test)
|
13
26
|
it "should have a value for :#{attribute_test.keys.first}" do
|
14
27
|
@object.send(attribute_test.keys.first).should == attribute_test.values.first
|
@@ -64,12 +77,14 @@ class Test::Unit::TestCase
|
|
64
77
|
klass = "Fleakr::Objects::#{class_name}".constantize
|
65
78
|
object_type = class_name.downcase
|
66
79
|
|
80
|
+
condition_value = '1'
|
81
|
+
|
67
82
|
options[:with] = options[:by] if options[:with].nil?
|
83
|
+
params = {options[:with] => condition_value}
|
68
84
|
|
69
85
|
it "should be able to find a #{thing} by #{options[:by]}" do
|
70
|
-
condition_value = '1'
|
71
86
|
stub = stub()
|
72
|
-
response = mock_request_cycle :for => options[:call], :with =>
|
87
|
+
response = mock_request_cycle :for => options[:call], :with => params
|
73
88
|
|
74
89
|
klass.expects(:new).with(response.body).returns(stub)
|
75
90
|
klass.send("find_by_#{options[:by]}".to_sym, condition_value).should == stub
|
@@ -108,7 +123,7 @@ class Test::Unit::TestCase
|
|
108
123
|
|
109
124
|
def mock_request_cycle(options)
|
110
125
|
response = stub(:body => Hpricot.XML(read_fixture(options[:for])))
|
111
|
-
Fleakr::Api::
|
126
|
+
Fleakr::Api::MethodRequest.expects(:with_response!).with(options[:for], options[:with]).returns(response)
|
112
127
|
|
113
128
|
response
|
114
129
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
module Fleakr::Api
|
4
|
+
class FileParameterTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
describe "An instance of the FileParameter class" do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@temp_dir = File.expand_path(create_temp_directory)
|
10
|
+
@filename = "#{@temp_dir}/image.jpg"
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
FileUtils.rm_rf(@temp_dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should know not to include itself in the parameter signature" do
|
18
|
+
parameter = FileParameter.new('photo', @filename)
|
19
|
+
parameter.include_in_signature?.should be(false)
|
20
|
+
end
|
21
|
+
|
22
|
+
{'jpg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif'}.each do |ext, mime_type|
|
23
|
+
it "should know the correct MIME type for an extension of #{ext}" do
|
24
|
+
parameter = FileParameter.new('photo', "#{@temp_dir}/image.#{ext}")
|
25
|
+
parameter.mime_type.should == mime_type
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should retrieve the contents of the file when accessing the value" do
|
30
|
+
File.expects(:read).with(@filename).returns('bopbip')
|
31
|
+
|
32
|
+
parameter = FileParameter.new('photo', @filename)
|
33
|
+
parameter.value.should == 'bopbip'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should cache the file contents after retrieving them" do
|
37
|
+
File.expects(:read).with(@filename).once.returns('bopbip')
|
38
|
+
|
39
|
+
parameter = FileParameter.new('photo', @filename)
|
40
|
+
2.times { parameter.value }
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should know how to generate a form representation of itself" do
|
44
|
+
filename = 'image.jpg'
|
45
|
+
mime_type = 'image/jpeg'
|
46
|
+
|
47
|
+
parameter = FileParameter.new('photo', filename)
|
48
|
+
parameter.stubs(:mime_type).with().returns(mime_type)
|
49
|
+
parameter.stubs(:value).with().returns('data')
|
50
|
+
|
51
|
+
expected =
|
52
|
+
"Content-Disposition: form-data; name=\"photo\"; filename=\"#{filename}\"\r\n" +
|
53
|
+
"Content-Type: image/jpeg\r\n" +
|
54
|
+
"\r\n" +
|
55
|
+
"data\r\n"
|
56
|
+
|
57
|
+
parameter.to_form.should == expected
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|