postrank-api 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ pkg
2
+ Gemfile.lock
data/.rspec ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Rakefile CHANGED
@@ -1,24 +1,9 @@
1
- require 'rake'
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
2
3
 
3
- begin
4
- require 'jeweler'
5
- Jeweler::Tasks.new do |gemspec|
6
- gemspec.name = "postrank-api"
7
- gemspec.summary = "PostRank API Wrapper"
8
- gemspec.description = gemspec.summary
9
- gemspec.email = "ilya@igvita.com"
10
- gemspec.homepage = "http://github.com/postrank/postrank-api"
11
- gemspec.authors = ["Ilya Grigorik"]
12
- gemspec.required_ruby_version = ">= 1.9.1"
13
- gemspec.add_dependency('eventmachine', '>= 0.12.9')
14
- gemspec.add_dependency('em-http-request')
15
- gemspec.add_dependency('em-synchrony')
16
- gemspec.add_dependency('yajl-ruby')
17
- gemspec.add_dependency('chronic')
18
- gemspec.rubyforge_project = "postrank-api"
19
- end
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
20
6
 
21
- Jeweler::GemcutterTasks.new
22
- rescue LoadError
23
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
24
- end
7
+ Rspec::Core::RakeTask.new do |t|
8
+ t.rspec_opts = '--color'
9
+ end
@@ -1,5 +1,6 @@
1
1
  require 'em-synchrony'
2
2
  require 'em-synchrony/em-http'
3
+ require 'postrank-uri'
3
4
 
4
5
  require 'digest/md5'
5
6
  require 'chronic'
@@ -7,8 +8,10 @@ require 'yajl'
7
8
 
8
9
  module PostRank
9
10
  class API
10
- V1_API_BASE = 'http://api.postrank.com/v1'
11
- V2_API_BASE = 'http://api.postrank.com/v2'
11
+ API_BASE = 'http://api.postrank.com'
12
+ V1_API_BASE = API_BASE + '/v1'
13
+ V2_API_BASE = API_BASE + '/v2'
14
+ V3_API_BASE = API_BASE + '/v3'
12
15
 
13
16
  def initialize(appkey)
14
17
  @appkey = appkey
@@ -41,20 +44,7 @@ module PostRank
41
44
  }
42
45
  }
43
46
 
44
- http = get("#{V2_API_BASE}/feed/", req)
45
- parse(http.response)
46
- end
47
-
48
- def recommendations(feeds, opts = {})
49
- req = {
50
- :query => {
51
- :appkey => @appkey,
52
- :num => opts[:num] || 10
53
- },
54
- :body => build_body(feeds, 'feed')
55
- }
56
-
57
- http = post("#{V2_API_BASE}/recommend", req)
47
+ http = get("#{V3_API_BASE}/feed/", req)
58
48
  parse(http.response)
59
49
  end
60
50
 
@@ -65,10 +55,10 @@ module PostRank
65
55
  req = {
66
56
  :query => {
67
57
  :appkey => @appkey,
68
- :min_time => Chronic.parse(opts[:start_time]).to_i,
69
- :max_time => Chronic.parse(opts[:start_time]).to_i
58
+ :start_time => Chronic.parse(opts[:start_time]).to_i,
59
+ :end_time => Chronic.parse(opts[:end_time]).to_i
70
60
  },
71
- :body => build_body( posts, 'post_hash')
61
+ :body => build_body(posts, 'post_hash')
72
62
  }
73
63
 
74
64
  http = post("#{V2_API_BASE}/entry/metrics/historic", req)
@@ -87,7 +77,6 @@ module PostRank
87
77
  parse(http.response)
88
78
  end
89
79
 
90
-
91
80
  def top_posts(feed, opts = {})
92
81
  req = {
93
82
  :query => {
@@ -98,7 +87,7 @@ module PostRank
98
87
  }
99
88
  }
100
89
 
101
- http = get("#{V2_API_BASE}/feed/topposts/", req)
90
+ http = get("#{V3_API_BASE}/feed/topposts/", req)
102
91
  parse(http.response)
103
92
  end
104
93
 
@@ -156,19 +145,39 @@ module PostRank
156
145
  :body => build_body(urls, 'url')
157
146
  }
158
147
 
159
- http = post("#{V2_API_BASE}/entry/metrics", req)
148
+ http = post("#{V3_API_BASE}/entry/metrics", req)
160
149
  parse(http.response).inject({}) do |hash, v|
161
150
  hash[reverse[v[0]]] = v[1]
162
151
  hash
163
152
  end
164
153
  end
165
154
 
155
+ def top_posts(feed, opts = {})
156
+ req = {
157
+ :query => {
158
+ :appkey => @appkey,
159
+ :q => opts[:q] || '',
160
+ :num => opts[:num] || 10,
161
+ :id => feed
162
+ }
163
+ }
164
+
165
+ http = get("#{V3_API_BASE}/feed/topposts/", req)
166
+ parse(http.response)
167
+ end
168
+
166
169
  private
167
170
 
168
171
  def parse(data)
169
172
  begin
170
- Yajl::Parser.parse(data)
171
- rescue Exception => e
173
+ data = Yajl::Parser.parse(data)
174
+
175
+ if msg = data['error']
176
+ raise Exception.new(msg)
177
+ end
178
+
179
+ data
180
+ rescue Yajl::ParseError => e
172
181
  puts "Failed to parse request:"
173
182
  puts e.message
174
183
  puts e.backtrace[0, 5].join("\n")
@@ -176,7 +185,13 @@ module PostRank
176
185
  end
177
186
 
178
187
  def build_body(urls, key)
179
- [urls].flatten.map { |e| "#{key}[]=#{e}" }.join("&")
188
+ [urls].flatten.map do |e|
189
+ if key == "url" && e !~ /\w{32}/
190
+ e = PostRank::URI.clean(e)
191
+ end
192
+
193
+ "#{key}[]=#{e}"
194
+ end.join("&")
180
195
  end
181
196
 
182
197
  def post(url, req)
@@ -187,14 +202,6 @@ module PostRank
187
202
  dispatch(:get, url, req)
188
203
  end
189
204
 
190
- def build_body(urls, key)
191
- [urls].flatten.map { |e| "#{key}[]=#{e}" }.join("&")
192
- end
193
-
194
- def post(url, req)
195
- dispatch(:post, url, req)
196
- end
197
-
198
205
  def dispatch(method, url, req)
199
206
  if EM.reactor_running?
200
207
  http = EM::HttpRequest.new(url).send(method, req)
@@ -0,0 +1,5 @@
1
+ module PostRank
2
+ class API
3
+ VERSION = "0.4.0"
4
+ end
5
+ end
@@ -1,63 +1,30 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "postrank-api/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
- s.name = %q{postrank-api}
8
- s.version = "0.2.0"
6
+ s.name = "postrank-api"
7
+ s.version = PostRank::API::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Ilya Grigorik"]
10
+ s.email = ["ilya@igvita.com"]
11
+ s.homepage = "http://github.com/postrank-labs/postrank-api"
12
+ s.summary = "Ruby 1.9 PostRank API Wrapper"
13
+ s.description = s.summary
9
14
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Ilya Grigorik"]
12
- s.date = %q{2010-12-15}
13
- s.description = %q{PostRank API Wrapper}
14
- s.email = %q{ilya@igvita.com}
15
- s.extra_rdoc_files = [
16
- "README.md"
17
- ]
18
- s.files = [
19
- "README.md",
20
- "Rakefile",
21
- "VERSION",
22
- "lib/postrank-api.rb",
23
- "lib/postrank-api/api.rb",
24
- "postrank-api.gemspec",
25
- "spec/api_spec.rb"
26
- ]
27
- s.homepage = %q{http://github.com/postrank/postrank-api}
28
- s.rdoc_options = ["--charset=UTF-8"]
29
- s.require_paths = ["lib"]
30
- s.required_ruby_version = Gem::Requirement.new(">= 1.9.1")
31
- s.rubyforge_project = %q{postrank-api}
32
- s.rubygems_version = %q{1.3.7}
33
- s.summary = %q{PostRank API Wrapper}
34
- s.test_files = [
35
- "spec/api_spec.rb"
36
- ]
15
+ s.rubyforge_project = "postrank-api"
37
16
 
38
- if s.respond_to? :specification_version then
39
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
- s.specification_version = 3
17
+ s.add_dependency "postrank-uri"
18
+ s.add_dependency "eventmachine"
19
+ s.add_dependency "em-http-request"
20
+ s.add_dependency "em-synchrony"
21
+ s.add_dependency "yajl-ruby"
22
+ s.add_dependency "chronic"
41
23
 
42
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
- s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.9"])
44
- s.add_runtime_dependency(%q<em-http-request>, [">= 0"])
45
- s.add_runtime_dependency(%q<em-synchrony>, [">= 0"])
46
- s.add_runtime_dependency(%q<yajl-ruby>, [">= 0"])
47
- s.add_runtime_dependency(%q<chronic>, [">= 0"])
48
- else
49
- s.add_dependency(%q<eventmachine>, [">= 0.12.9"])
50
- s.add_dependency(%q<em-http-request>, [">= 0"])
51
- s.add_dependency(%q<em-synchrony>, [">= 0"])
52
- s.add_dependency(%q<yajl-ruby>, [">= 0"])
53
- s.add_dependency(%q<chronic>, [">= 0"])
54
- end
55
- else
56
- s.add_dependency(%q<eventmachine>, [">= 0.12.9"])
57
- s.add_dependency(%q<em-http-request>, [">= 0"])
58
- s.add_dependency(%q<em-synchrony>, [">= 0"])
59
- s.add_dependency(%q<yajl-ruby>, [">= 0"])
60
- s.add_dependency(%q<chronic>, [">= 0"])
61
- end
62
- end
24
+ s.add_development_dependency "rspec"
63
25
 
26
+ s.files = `git ls-files`.split("\n")
27
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
28
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
29
+ s.require_paths = ["lib"]
30
+ end
@@ -1,4 +1,4 @@
1
- require 'spec'
1
+ require 'rspec'
2
2
  require 'lib/postrank-api'
3
3
  require 'pp'
4
4
 
@@ -70,28 +70,6 @@ describe PostRank::API do
70
70
  end
71
71
  end
72
72
 
73
- describe "Recommendations API" do
74
-
75
- it "should fetch recommendations for a single feed" do
76
- EM.synchrony do
77
- resp = api.recommendations(IGVITA)
78
- resp.class.should == Array
79
- EM.stop
80
- end
81
- end
82
-
83
- it "should fetch recommendation for a set of feeds" do
84
- EM.synchrony do
85
- resp = api.recommendations([IGVITA, EVERBURNING], :num => 1)
86
-
87
- resp.class.should == Array
88
- resp.size.should == 1
89
-
90
- EM.stop
91
- end
92
- end
93
- end
94
-
95
73
  describe "Top Posts API" do
96
74
  it "should fetch top posts for a feed" do
97
75
  EM.synchrony do
@@ -106,18 +84,19 @@ describe PostRank::API do
106
84
  end
107
85
  end
108
86
 
109
- describe "Metrics Versioned API" do
87
+ describe "Metrics Versioned API" do
110
88
  it "should fetch metrics for a single post" do
111
89
  EM.synchrony do
112
- met = api.metrics_versioned('b0432f947bc0d44766d046bfc3c15043', {:start => '5 years ago', :end => 'today'})
90
+ met = api.metrics_versioned('cd116fcfb7df471e3a2ba2065b3499bb', {:start_time => '5 years ago'})
113
91
  met.class.should == Hash
114
92
  met.keys.size.should == 1
115
93
  EM.stop
116
94
  end
117
95
  end
96
+
118
97
  it "should fetch metrics for multiple posts" do
119
98
  EM.synchrony do
120
- met = api.metrics_versioned(['b0432f947bc0d44766d046bfc3c15043', 'a020c1c3a5b2aef1ab4a7307cf3d2cb6'], {:start => '5 years ago', :end => 'today'})
99
+ met = api.metrics_versioned(['b0432f947bc0d44766d046bfc3c15043', 'a020c1c3a5b2aef1ab4a7307cf3d2cb6'], {:start_time => '5 years ago', :end_time => 'today'})
121
100
  met.class.should == Hash
122
101
  met.keys.size.should == 2
123
102
  EM.stop
@@ -128,18 +107,19 @@ describe PostRank::API do
128
107
  describe "Postrank API" do
129
108
  it "should fetch postrank with respect to provided urls" do
130
109
  EM.synchrony do
131
- pr = api.postrank(['http://www.igvita.com/2008/06/19/splunk-your-distributed-logs-in-ec2/', 'http://www.igvita.com/2008/02/11/nginx-and-memcached-a-400-boost/'])
132
- pr.class.should == Hash
133
- pr.keys.size.should == 2
110
+ pr = api.postrank(['http://www.igvita.com/2008/06/19/splunk-your-distributed-logs-in-ec2/', 'http://www.igvita.com/2008/02/11/nginx-and-memcached-a-400-boost/'])
111
+ pr.class.should == Hash
112
+ pr.keys.size.should == 2
134
113
  EM.stop
135
- end
114
+ end
136
115
  end
116
+
137
117
  it "should fetch postrank with respect specific feeds" do
138
118
  EM.synchrony do
139
119
  pr = api.postrank(['http://www.igvita.com/2008/06/19/splunk-your-distributed-logs-in-ec2/', 'http://www.igvita.com/2008/02/11/nginx-and-memcached-a-400-boost/'], ['421df2d86ab95100de7dcc2e247a08ab'])
140
120
  pr.class.should == Hash
141
121
  pr.keys.size.should == 2
142
- EM.stop
122
+ EM.stop
143
123
  end
144
124
  end
145
125
  end
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postrank-api
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 2
8
- - 0
9
- version: 0.2.0
4
+ prerelease:
5
+ version: 0.4.0
10
6
  platform: ruby
11
7
  authors:
12
8
  - Ilya Grigorik
@@ -14,99 +10,114 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2010-12-15 00:00:00 -05:00
13
+ date: 2011-03-31 00:00:00 -04:00
18
14
  default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
21
- name: eventmachine
17
+ name: postrank-uri
22
18
  prerelease: false
23
19
  requirement: &id001 !ruby/object:Gem::Requirement
24
20
  none: false
25
21
  requirements:
26
22
  - - ">="
27
23
  - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- - 12
31
- - 9
32
- version: 0.12.9
24
+ version: "0"
33
25
  type: :runtime
34
26
  version_requirements: *id001
35
27
  - !ruby/object:Gem::Dependency
36
- name: em-http-request
28
+ name: eventmachine
37
29
  prerelease: false
38
30
  requirement: &id002 !ruby/object:Gem::Requirement
39
31
  none: false
40
32
  requirements:
41
33
  - - ">="
42
34
  - !ruby/object:Gem::Version
43
- segments:
44
- - 0
45
35
  version: "0"
46
36
  type: :runtime
47
37
  version_requirements: *id002
48
38
  - !ruby/object:Gem::Dependency
49
- name: em-synchrony
39
+ name: em-http-request
50
40
  prerelease: false
51
41
  requirement: &id003 !ruby/object:Gem::Requirement
52
42
  none: false
53
43
  requirements:
54
44
  - - ">="
55
45
  - !ruby/object:Gem::Version
56
- segments:
57
- - 0
58
46
  version: "0"
59
47
  type: :runtime
60
48
  version_requirements: *id003
61
49
  - !ruby/object:Gem::Dependency
62
- name: yajl-ruby
50
+ name: em-synchrony
63
51
  prerelease: false
64
52
  requirement: &id004 !ruby/object:Gem::Requirement
65
53
  none: false
66
54
  requirements:
67
55
  - - ">="
68
56
  - !ruby/object:Gem::Version
69
- segments:
70
- - 0
71
57
  version: "0"
72
58
  type: :runtime
73
59
  version_requirements: *id004
74
60
  - !ruby/object:Gem::Dependency
75
- name: chronic
61
+ name: yajl-ruby
76
62
  prerelease: false
77
63
  requirement: &id005 !ruby/object:Gem::Requirement
78
64
  none: false
79
65
  requirements:
80
66
  - - ">="
81
67
  - !ruby/object:Gem::Version
82
- segments:
83
- - 0
84
68
  version: "0"
85
69
  type: :runtime
86
70
  version_requirements: *id005
87
- description: PostRank API Wrapper
88
- email: ilya@igvita.com
71
+ - !ruby/object:Gem::Dependency
72
+ name: chronic
73
+ prerelease: false
74
+ requirement: &id006 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ type: :runtime
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ prerelease: false
85
+ requirement: &id007 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id007
93
+ description: Ruby 1.9 PostRank API Wrapper
94
+ email:
95
+ - ilya@igvita.com
89
96
  executables: []
90
97
 
91
98
  extensions: []
92
99
 
93
- extra_rdoc_files:
94
- - README.md
100
+ extra_rdoc_files: []
101
+
95
102
  files:
103
+ - .gitignore
104
+ - .rspec
105
+ - Gemfile
96
106
  - README.md
97
107
  - Rakefile
98
108
  - VERSION
99
109
  - lib/postrank-api.rb
100
110
  - lib/postrank-api/api.rb
111
+ - lib/postrank-api/version.rb
101
112
  - postrank-api.gemspec
102
113
  - spec/api_spec.rb
103
114
  has_rdoc: true
104
- homepage: http://github.com/postrank/postrank-api
115
+ homepage: http://github.com/postrank-labs/postrank-api
105
116
  licenses: []
106
117
 
107
118
  post_install_message:
108
- rdoc_options:
109
- - --charset=UTF-8
119
+ rdoc_options: []
120
+
110
121
  require_paths:
111
122
  - lib
112
123
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -114,25 +125,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
125
  requirements:
115
126
  - - ">="
116
127
  - !ruby/object:Gem::Version
117
- segments:
118
- - 1
119
- - 9
120
- - 1
121
- version: 1.9.1
128
+ version: "0"
122
129
  required_rubygems_version: !ruby/object:Gem::Requirement
123
130
  none: false
124
131
  requirements:
125
132
  - - ">="
126
133
  - !ruby/object:Gem::Version
127
- segments:
128
- - 0
129
134
  version: "0"
130
135
  requirements: []
131
136
 
132
137
  rubyforge_project: postrank-api
133
- rubygems_version: 1.3.7
138
+ rubygems_version: 1.6.2
134
139
  signing_key:
135
140
  specification_version: 3
136
- summary: PostRank API Wrapper
141
+ summary: Ruby 1.9 PostRank API Wrapper
137
142
  test_files:
138
143
  - spec/api_spec.rb