instagram 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +10 -0
- data/lib/instagram.rb +25 -10
- data/lib/instagram/cached.rb +25 -0
- data/lib/instagram/failsafe_store.rb +52 -0
- data/lib/instagram/models.rb +6 -0
- metadata +7 -10
data/Rakefile
ADDED
data/lib/instagram.rb
CHANGED
@@ -5,29 +5,44 @@ require 'instagram/models'
|
|
5
5
|
|
6
6
|
module Instagram
|
7
7
|
|
8
|
+
extend self
|
9
|
+
|
8
10
|
Popular = Addressable::URI.parse 'http://instagr.am/api/v1/feed/popular/'
|
9
11
|
UserFeed = Addressable::Template.new 'http://instagr.am/api/v1/feed/user/{user_id}/'
|
10
12
|
UserInfo = Addressable::Template.new 'http://instagr.am/api/v1/users/{user_id}/info/'
|
11
13
|
|
12
|
-
def
|
13
|
-
|
14
|
-
parse_response(url, params, Timeline)
|
14
|
+
def popular(params = {}, options = {})
|
15
|
+
parse_response(Popular.dup, params, options.fetch(:parse_with, Timeline))
|
15
16
|
end
|
16
17
|
|
17
|
-
def
|
18
|
+
def by_user(user_id, params = {}, options = {})
|
18
19
|
url = UserFeed.expand :user_id => user_id
|
19
|
-
parse_response(url, params, Timeline)
|
20
|
+
parse_response(url, params, options.fetch(:parse_with, Timeline))
|
20
21
|
end
|
21
22
|
|
22
|
-
def
|
23
|
+
def user_info(user_id, params = {}, options = {})
|
23
24
|
url = UserInfo.expand :user_id => user_id
|
24
|
-
parse_response(url, params, UserWrap)
|
25
|
+
parse_response(url, params, options.fetch(:parse_with, UserWrap))
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
+
private
|
29
|
+
|
30
|
+
def parse_response(url, params, parser = nil)
|
28
31
|
url.query_values = params
|
29
|
-
body =
|
30
|
-
parser.parse body
|
32
|
+
body = get_url url
|
33
|
+
parser ? parser.parse(body) : body
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_url(url)
|
37
|
+
response = Net::HTTP.start(url.host, url.port) { |http|
|
38
|
+
http.get url.request_uri
|
39
|
+
}
|
40
|
+
|
41
|
+
if Net::HTTPSuccess === response
|
42
|
+
response.body
|
43
|
+
else
|
44
|
+
response.error!
|
45
|
+
end
|
31
46
|
end
|
32
47
|
|
33
48
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'instagram'
|
2
|
+
require 'instagram/failsafe_store'
|
3
|
+
|
4
|
+
module Instagram
|
5
|
+
module Cached
|
6
|
+
extend Instagram
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :cache
|
10
|
+
|
11
|
+
def setup(cache_dir, options = {})
|
12
|
+
self.cache = FailsafeStore.new(cache_dir, {
|
13
|
+
namespace: 'instagram',
|
14
|
+
exceptions: [Net::HTTPServerException, JSON::ParserError]
|
15
|
+
}.update(options))
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def get_url(url)
|
20
|
+
cache.fetch(url.to_s) { super }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'active_support/cache'
|
2
|
+
|
3
|
+
module Instagram
|
4
|
+
class FailsafeStore < ActiveSupport::Cache::FileStore
|
5
|
+
# Reuses the stale cache if a known exception occurs while yielding to the block.
|
6
|
+
# The list of exception classes is read from the ":exceptions" array.
|
7
|
+
def fetch(name, options = nil)
|
8
|
+
options = merged_options(options)
|
9
|
+
key = namespaced_key(name, options)
|
10
|
+
entry = unless options[:force]
|
11
|
+
instrument(:read, name, options) do |payload|
|
12
|
+
payload[:super_operation] = :fetch if payload
|
13
|
+
read_entry(key, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if entry and not entry.expired?
|
18
|
+
instrument(:fetch_hit, name, options) { |payload| }
|
19
|
+
entry.value
|
20
|
+
else
|
21
|
+
reusing_stale = false
|
22
|
+
|
23
|
+
result = begin
|
24
|
+
instrument(:generate, name, options) do |payload|
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
rescue
|
28
|
+
if entry and ignore_exception?($!)
|
29
|
+
reusing_stale = true
|
30
|
+
instrument(:reuse_stale, name, options) do |payload|
|
31
|
+
payload[:exception] = $! if payload
|
32
|
+
entry.value
|
33
|
+
end
|
34
|
+
else
|
35
|
+
# TODO: figure out if deleting entries is ever necessary
|
36
|
+
# delete_entry(key, options) if entry
|
37
|
+
raise
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
write(name, result, options) unless reusing_stale
|
42
|
+
result
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def ignore_exception?(ex)
|
49
|
+
options[:exceptions] && options[:exceptions].any? { |klass| ex.is_a? klass }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/instagram/models.rb
CHANGED
@@ -52,6 +52,8 @@ module Instagram
|
|
52
52
|
element :type
|
53
53
|
element :width
|
54
54
|
element :height
|
55
|
+
|
56
|
+
alias to_s url
|
55
57
|
end
|
56
58
|
|
57
59
|
def caption
|
@@ -60,6 +62,10 @@ module Instagram
|
|
60
62
|
comments.first.text
|
61
63
|
end
|
62
64
|
end
|
65
|
+
|
66
|
+
def image_url(size = 150)
|
67
|
+
self.images.find { |img| img.width == size }.to_s
|
68
|
+
end
|
63
69
|
end
|
64
70
|
|
65
71
|
class Timeline < NibblerJSON
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instagram
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 27
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
|
-
-
|
7
|
+
- 2
|
9
8
|
- 0
|
10
|
-
version: 0.
|
9
|
+
version: 0.2.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- "Mislav Marohni\xC4\x87"
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-
|
17
|
+
date: 2010-12-07 00:00:00 +01:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -26,7 +25,6 @@ dependencies:
|
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
28
|
segments:
|
31
29
|
- 0
|
32
30
|
version: "0"
|
@@ -40,7 +38,6 @@ dependencies:
|
|
40
38
|
requirements:
|
41
39
|
- - ">="
|
42
40
|
- !ruby/object:Gem::Version
|
43
|
-
hash: 3
|
44
41
|
segments:
|
45
42
|
- 0
|
46
43
|
version: "0"
|
@@ -54,7 +51,6 @@ dependencies:
|
|
54
51
|
requirements:
|
55
52
|
- - ">="
|
56
53
|
- !ruby/object:Gem::Version
|
57
|
-
hash: 31
|
58
54
|
segments:
|
59
55
|
- 1
|
60
56
|
- 2
|
@@ -71,11 +67,14 @@ extensions: []
|
|
71
67
|
extra_rdoc_files: []
|
72
68
|
|
73
69
|
files:
|
70
|
+
- Rakefile
|
71
|
+
- lib/instagram/cached.rb
|
72
|
+
- lib/instagram/failsafe_store.rb
|
74
73
|
- lib/instagram/models.rb
|
75
74
|
- lib/instagram.rb
|
76
75
|
- README.md
|
77
76
|
- MIT-LICENSE
|
78
|
-
has_rdoc:
|
77
|
+
has_rdoc: true
|
79
78
|
homepage: http://github.com/mislav/instagram
|
80
79
|
licenses: []
|
81
80
|
|
@@ -89,7 +88,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
88
|
requirements:
|
90
89
|
- - ">="
|
91
90
|
- !ruby/object:Gem::Version
|
92
|
-
hash: 3
|
93
91
|
segments:
|
94
92
|
- 0
|
95
93
|
version: "0"
|
@@ -98,7 +96,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
96
|
requirements:
|
99
97
|
- - ">="
|
100
98
|
- !ruby/object:Gem::Version
|
101
|
-
hash: 3
|
102
99
|
segments:
|
103
100
|
- 0
|
104
101
|
version: "0"
|