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 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"