instagram 0.1.0 → 0.2.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/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"
|