flickr-objects 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +49 -63
- data/lib/flickr/api/abstract/params_processor.rb +68 -0
- data/lib/flickr/api/abstract.rb +113 -0
- data/lib/flickr/api/general.rb +75 -0
- data/lib/flickr/api/person.rb +91 -39
- data/lib/flickr/api/photo.rb +213 -108
- data/lib/flickr/api/set.rb +114 -55
- data/lib/flickr/api/upload_ticket.rb +17 -6
- data/lib/flickr/api.rb +90 -35
- data/lib/flickr/attributes.rb +200 -0
- data/lib/flickr/base_converter.rb +29 -0
- data/lib/flickr/client/data.rb +47 -0
- data/lib/flickr/client/oauth.rb +44 -0
- data/lib/flickr/client/upload.rb +55 -0
- data/lib/flickr/client.rb +77 -33
- data/lib/flickr/configuration.rb +85 -14
- data/lib/flickr/error.rb +58 -0
- data/lib/flickr/middleware.rb +52 -28
- data/lib/flickr/oauth.rb +89 -74
- data/lib/flickr/object/attribute_locations/list.rb +25 -0
- data/lib/flickr/object/attribute_locations/location.rb +29 -0
- data/lib/flickr/object/attribute_locations/permissions.rb +31 -0
- data/lib/flickr/object/attribute_locations/person/upload_status.rb +32 -0
- data/lib/flickr/object/attribute_locations/person.rb +78 -0
- data/lib/flickr/object/attribute_locations/photo/exif.rb +29 -0
- data/lib/flickr/object/attribute_locations/photo/note.rb +36 -0
- data/lib/flickr/object/attribute_locations/photo/tag.rb +23 -0
- data/lib/flickr/object/attribute_locations/photo.rb +164 -0
- data/lib/flickr/object/attribute_locations/set.rb +53 -0
- data/lib/flickr/object/attribute_locations/upload_ticket.rb +30 -0
- data/lib/flickr/object/attribute_locations/visibility.rb +24 -0
- data/lib/flickr/object/list/kaminari.rb +30 -0
- data/lib/flickr/object/list/normal.rb +27 -0
- data/lib/flickr/object/list/will_paginate.rb +31 -0
- data/lib/flickr/object/list.rb +87 -0
- data/lib/flickr/object/location.rb +35 -0
- data/lib/flickr/object/permissions.rb +18 -0
- data/lib/flickr/object/person/upload_status.rb +22 -0
- data/lib/flickr/object/person.rb +93 -0
- data/lib/flickr/object/photo/exif.rb +35 -0
- data/lib/flickr/object/photo/note.rb +20 -0
- data/lib/flickr/object/photo/size.rb +67 -0
- data/lib/flickr/object/photo/tag.rb +23 -0
- data/lib/flickr/object/photo.rb +349 -0
- data/lib/flickr/object/set.rb +114 -0
- data/lib/flickr/object/upload_ticket.rb +31 -0
- data/lib/flickr/object/visibility.rb +16 -0
- data/lib/flickr/object.rb +118 -27
- data/lib/flickr/sanitized_file.rb +70 -0
- data/lib/flickr/version.rb +4 -2
- data/lib/flickr.rb +69 -15
- metadata +89 -103
- data/lib/flickr/api/api_methods/flickr.rb +0 -5
- data/lib/flickr/api/api_methods/person.rb +0 -14
- data/lib/flickr/api/api_methods/photo.rb +0 -26
- data/lib/flickr/api/api_methods/set.rb +0 -18
- data/lib/flickr/api/api_methods/upload_ticket.rb +0 -5
- data/lib/flickr/api/flickr.rb +0 -35
- data/lib/flickr/api_caller.rb +0 -98
- data/lib/flickr/client/methods_client.rb +0 -22
- data/lib/flickr/client/upload_client.rb +0 -62
- data/lib/flickr/errors.rb +0 -19
- data/lib/flickr/helpers/base_58.rb +0 -15
- data/lib/flickr/helpers/boolean.rb +0 -4
- data/lib/flickr/helpers/core_ext.rb +0 -5
- data/lib/flickr/object/attribute/converter.rb +0 -49
- data/lib/flickr/object/attribute/finder.rb +0 -32
- data/lib/flickr/object/attribute.rb +0 -45
- data/lib/flickr/objects/attribute_values/list.rb +0 -10
- data/lib/flickr/objects/attribute_values/location.rb +0 -14
- data/lib/flickr/objects/attribute_values/note.rb +0 -11
- data/lib/flickr/objects/attribute_values/permissions.rb +0 -12
- data/lib/flickr/objects/attribute_values/person/upload_status.rb +0 -16
- data/lib/flickr/objects/attribute_values/person.rb +0 -24
- data/lib/flickr/objects/attribute_values/photo.rb +0 -84
- data/lib/flickr/objects/attribute_values/set.rb +0 -17
- data/lib/flickr/objects/attribute_values/tag.rb +0 -9
- data/lib/flickr/objects/attribute_values/upload_ticket.rb +0 -9
- data/lib/flickr/objects/attribute_values/visibility.rb +0 -10
- data/lib/flickr/objects/list.rb +0 -86
- data/lib/flickr/objects/location.rb +0 -26
- data/lib/flickr/objects/note.rb +0 -14
- data/lib/flickr/objects/permissions.rb +0 -14
- data/lib/flickr/objects/person/upload_status.rb +0 -14
- data/lib/flickr/objects/person.rb +0 -43
- data/lib/flickr/objects/photo.rb +0 -113
- data/lib/flickr/objects/set.rb +0 -29
- data/lib/flickr/objects/tag.rb +0 -17
- data/lib/flickr/objects/upload_ticket.rb +0 -18
- data/lib/flickr/objects/visibility.rb +0 -12
- data/lib/flickr/objects.rb +0 -25
data/lib/flickr/object.rb
CHANGED
@@ -1,49 +1,140 @@
|
|
1
|
-
require "flickr/
|
2
|
-
require "flickr/api_caller"
|
1
|
+
require "flickr/attributes"
|
3
2
|
|
4
|
-
|
3
|
+
module Flickr
|
4
|
+
|
5
|
+
##
|
6
|
+
# Every Flickr object inherits from this class. It provides interface for defining
|
7
|
+
# attributes and some helper methods.
|
8
|
+
#
|
5
9
|
class Object
|
6
|
-
|
7
|
-
|
10
|
+
|
11
|
+
extend Flickr::Attributes
|
12
|
+
extend Flickr::AutoloadHelper
|
13
|
+
|
14
|
+
autoload_names \
|
15
|
+
:List, :Photo, :Person, :Set, :UploadTicket, :Permissions, :Location,
|
16
|
+
:Visibility
|
17
|
+
|
18
|
+
##
|
19
|
+
# @private
|
20
|
+
#
|
21
|
+
def self.api_class
|
22
|
+
Flickr::Api.const_get(name.match(/^Flickr::Object::/).post_match)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Overriding Flickr::Attributes#attribute to add a default location.
|
27
|
+
# This means that `:<attribute>` will always first be searched in
|
28
|
+
# `@attributes["<attribute>"]`.
|
29
|
+
#
|
30
|
+
# @!macro [attach] attribute
|
31
|
+
# @attribute [r] $1
|
32
|
+
# @return [$2]
|
33
|
+
#
|
34
|
+
# @private
|
35
|
+
#
|
36
|
+
def self.attribute(name, type)
|
37
|
+
new_attribute = super
|
38
|
+
new_attribute.add_locations([-> { @attributes[name.to_s] }])
|
8
39
|
end
|
9
40
|
|
10
|
-
|
11
|
-
|
12
|
-
|
41
|
+
##
|
42
|
+
# @private
|
43
|
+
#
|
44
|
+
def initialize(attributes, access_token = [])
|
45
|
+
raise ArgumentError, "attributes should not be nil" if attributes.nil?
|
13
46
|
|
14
|
-
|
47
|
+
@attributes = attributes
|
48
|
+
@access_token = access_token
|
15
49
|
end
|
16
50
|
|
17
|
-
|
18
|
-
|
51
|
+
##
|
52
|
+
# @private
|
53
|
+
#
|
54
|
+
attr_reader :access_token
|
55
|
+
##
|
56
|
+
# The raw hash of attributes returned from Flickr.
|
57
|
+
#
|
58
|
+
# @return [Hash]
|
59
|
+
# @see #[]
|
60
|
+
#
|
61
|
+
attr_reader :attributes
|
62
|
+
|
63
|
+
##
|
64
|
+
# Shorthand for accessing the raw hash of attributes returned
|
65
|
+
# from Flickr.
|
66
|
+
#
|
67
|
+
# @see #attributes
|
68
|
+
#
|
69
|
+
def [](key)
|
70
|
+
@attributes[key]
|
19
71
|
end
|
20
72
|
|
21
|
-
|
22
|
-
|
73
|
+
##
|
74
|
+
# Compares by ID (if that object has an ID), otherwise compares by attributes.
|
75
|
+
#
|
76
|
+
def ==(other)
|
77
|
+
if not other.is_a?(Flickr::Object)
|
78
|
+
raise ArgumentError "can't compare Flickr::Object with #{other.class}"
|
79
|
+
end
|
80
|
+
|
81
|
+
if [self, other].all? { |object| object.respond_to?(:id) && object.id }
|
82
|
+
self.id == other.id
|
83
|
+
else
|
84
|
+
self.attributes == other.attributes
|
85
|
+
end
|
23
86
|
end
|
87
|
+
alias eql? ==
|
24
88
|
|
89
|
+
##
|
90
|
+
# Displays all the attributes and their values.
|
91
|
+
#
|
25
92
|
def inspect
|
26
|
-
attribute_values =
|
27
|
-
|
28
|
-
|
29
|
-
|
93
|
+
attribute_values = self.class.attributes
|
94
|
+
.inject({}) { |hash, attribute| hash.update(attribute.name => send(attribute.name)) }
|
95
|
+
.reject { |name, value| value.nil? or (value.respond_to?(:empty?) and value.empty?) }
|
96
|
+
attributes = attribute_values
|
97
|
+
.map { |name, value| "#{name}=#{value.inspect}" }
|
98
|
+
.join(" ")
|
99
|
+
|
30
100
|
class_name = self.class.name
|
31
|
-
|
101
|
+
hex_code = "0x#{(object_id >> 1).to_s(16)}"
|
102
|
+
|
103
|
+
"#<#{class_name}:#{hex_code} #{attributes}>"
|
32
104
|
end
|
33
105
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
106
|
+
##
|
107
|
+
# Tests if the object matches a hash of attributes. Supports nesting
|
108
|
+
# (see the example).
|
109
|
+
#
|
110
|
+
# @param attributes [Hash]
|
111
|
+
# @return [Boolean]
|
112
|
+
# @example
|
113
|
+
# photo.matches?(owner: {username: "janko"})
|
114
|
+
#
|
115
|
+
def matches?(attributes)
|
116
|
+
attributes.all? do |name, value|
|
117
|
+
if send(name).is_a?(Flickr::Object) and value.is_a?(Hash)
|
118
|
+
send(name).matches?(value)
|
119
|
+
else
|
120
|
+
send(name) == value
|
121
|
+
end
|
39
122
|
end
|
40
123
|
end
|
41
124
|
|
42
|
-
|
125
|
+
##
|
126
|
+
# @private
|
127
|
+
#
|
128
|
+
def update(attributes)
|
129
|
+
@attributes.update(attributes)
|
130
|
+
self
|
131
|
+
end
|
43
132
|
|
44
|
-
|
45
|
-
|
46
|
-
|
133
|
+
private
|
134
|
+
|
135
|
+
def api
|
136
|
+
self.class.api_class.new(@access_token)
|
47
137
|
end
|
48
138
|
end
|
139
|
+
|
49
140
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "delegate"
|
2
|
+
|
3
|
+
module Flickr
|
4
|
+
|
5
|
+
##
|
6
|
+
# File that users provide for uploading can come from various sources (Rails, Sinatra
|
7
|
+
# etc). This class attempts to sanitize it, pulling out the path, content type,
|
8
|
+
# and the actual file.
|
9
|
+
#
|
10
|
+
# @private
|
11
|
+
#
|
12
|
+
class SanitizedFile < SimpleDelegator
|
13
|
+
|
14
|
+
attr_reader :file, :content_type, :path
|
15
|
+
|
16
|
+
##
|
17
|
+
# @param original [String, File, Rails, Sinatra]
|
18
|
+
#
|
19
|
+
def initialize(original)
|
20
|
+
@original = original
|
21
|
+
sanitize!
|
22
|
+
super(@file)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
##
|
28
|
+
# Extracts the tempfile, content type and path.
|
29
|
+
#
|
30
|
+
def sanitize!
|
31
|
+
if rails_file?
|
32
|
+
@file = @original
|
33
|
+
@content_type = @original.content_type
|
34
|
+
@path = @original.tempfile
|
35
|
+
elsif sinatra_file?
|
36
|
+
@file = @original[:tempfile]
|
37
|
+
@content_type = @original[:type]
|
38
|
+
@path = @original[:tempfile].path
|
39
|
+
elsif file?
|
40
|
+
@file = @original
|
41
|
+
@content_type = @original.content_type if @original.respond_to?(:content_type)
|
42
|
+
@path = @original.path
|
43
|
+
elsif string?
|
44
|
+
@file = File.open(@original)
|
45
|
+
@content_type = nil
|
46
|
+
@path = @original
|
47
|
+
else
|
48
|
+
raise ArgumentError, "invalid file format"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def rails_file?
|
53
|
+
defined?(Rails) and @original.is_a?(ActionDispatch::Http::UploadedFile)
|
54
|
+
end
|
55
|
+
|
56
|
+
def sinatra_file?
|
57
|
+
defined?(Sinatra) and @original.is_a?(Hash)
|
58
|
+
end
|
59
|
+
|
60
|
+
def file?
|
61
|
+
@original.respond_to?(:read) and @original.respond_to?(:path)
|
62
|
+
end
|
63
|
+
|
64
|
+
def string?
|
65
|
+
@original.is_a?(String)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/lib/flickr/version.rb
CHANGED
data/lib/flickr.rb
CHANGED
@@ -1,26 +1,80 @@
|
|
1
|
-
|
2
|
-
require "flickr/configuration"
|
1
|
+
module Flickr
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
##
|
4
|
+
# @private
|
5
|
+
#
|
6
|
+
module AutoloadHelper
|
7
|
+
def autoload_dir(directory, mappings)
|
8
|
+
mappings.each do |const_name, path|
|
9
|
+
autoload const_name, File.join(directory, path)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Flickr::Object and Flickr::Api contain too many constants, so rather than
|
15
|
+
# providing an explicit filename we rather use the underscored constant name.
|
16
|
+
#
|
17
|
+
def autoload_names(*class_names)
|
18
|
+
mappings = class_names.inject({}) do |mappings, class_name|
|
19
|
+
mappings.update(class_name => Flickr.underscore(class_name.to_s))
|
20
|
+
end
|
21
|
+
directory = Flickr.underscore(name)
|
22
|
+
|
23
|
+
autoload_dir directory, mappings
|
24
|
+
end
|
7
25
|
end
|
8
26
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
configuration
|
27
|
+
extend AutoloadHelper
|
28
|
+
|
29
|
+
autoload_dir "flickr",
|
30
|
+
:Configuration => "configuration",
|
31
|
+
:Api => "api",
|
32
|
+
:OAuth => "oauth",
|
33
|
+
:Object => "object",
|
34
|
+
:Client => "client"
|
35
|
+
|
36
|
+
##
|
37
|
+
# ActiveSupport's `underscore` (simpler version), used in
|
38
|
+
# Flickr::AutoloadHelper#autoload_names
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# Flickr.underscore("Foo::Bar::Baz") # => "foo/bar/baz"
|
42
|
+
# @private
|
43
|
+
#
|
44
|
+
def self.underscore(class_name)
|
45
|
+
class_name
|
46
|
+
.split("::")
|
47
|
+
.map { |s| s.split(/(?=[A-Z])/).map(&:downcase).join("_") }
|
48
|
+
.join("/")
|
13
49
|
end
|
14
50
|
|
15
|
-
|
16
|
-
|
51
|
+
extend Flickr::Configuration
|
52
|
+
|
53
|
+
##
|
54
|
+
# If you're obtaining the access token dynamically, then you can't set it in
|
55
|
+
# the global configuration. This method allows you to create a temporary
|
56
|
+
# instance with the access token.
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# flickr = Flickr.new("KEY", "SECRET")
|
60
|
+
# flickr.photos.get_recent
|
61
|
+
# # ...
|
62
|
+
# @return [Flickr]
|
63
|
+
#
|
64
|
+
def self.new(access_token_key, access_token_secret)
|
65
|
+
dup.configure do |config|
|
66
|
+
config.access_token_key = access_token_key
|
67
|
+
config.access_token_secret = access_token_secret
|
68
|
+
end
|
17
69
|
end
|
18
70
|
|
71
|
+
extend Flickr::Api
|
72
|
+
|
73
|
+
##
|
74
|
+
# @private
|
75
|
+
#
|
19
76
|
def self.deprecation_warn(message)
|
20
77
|
warn "[FLICKR OBJECTS] #{message}"
|
21
78
|
end
|
22
|
-
end
|
23
79
|
|
24
|
-
|
25
|
-
require "flickr/api"
|
26
|
-
require "flickr/oauth"
|
80
|
+
end
|