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 ADDED
@@ -0,0 +1,10 @@
1
+ task :app do
2
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift File.dirname($LOAD_PATH.first)
4
+ require 'app'
5
+ end
6
+
7
+ task :clear => :app do
8
+ items = CachedInstagram.cache.clear
9
+ puts "#{items.size} removed"
10
+ end
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 self.popular(params = {})
13
- url = Popular.dup
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 self.by_user(user_id, params = {})
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 self.user_info(user_id, params = {})
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
- def self.parse_response(url, params, parser)
28
+ private
29
+
30
+ def parse_response(url, params, parser = nil)
28
31
  url.query_values = params
29
- body = Net::HTTP.get url
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
@@ -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
- - 1
7
+ - 2
9
8
  - 0
10
- version: 0.1.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-11-30 00:00:00 +01:00
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: false
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"