storify 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8e5b35c38cdddf4afe33c92a7e6881ffaa67204a
4
- data.tar.gz: 8812500f6fd457cbab902acb867eb360594f211e
3
+ metadata.gz: ee651fbc8ced627f9d5711d772ac0d998c4cea5f
4
+ data.tar.gz: de03b76abd522d5992ac684e6446222a299bf2cc
5
5
  SHA512:
6
- metadata.gz: 5242d0dc6441c8f683fd1f29014454094c24b099921e40de4a12f15ca679bf9509ffa5ee1e3f77303acf249a064866142cfbcba4d2e65ef71bc48b048f8a3b09
7
- data.tar.gz: 0ae3995e36650a02fdddc67945dc00a29b4fc801abad24c477b84587fe5b1d95fec541f8eefbe3742b1e37de709f8b4ebf342aaf3880e223f17c7cd2cd0513e0
6
+ metadata.gz: b15afc86cbfda8cda37ca17da233df0b68065e8f0f107f445fc8f495747e77fa3fd49de10ef21629729460b3c372ea24da2074d2fea2e8f420442ec969e38dd0
7
+ data.tar.gz: ca3fff59c7a87850892817b60603dfbb26663a8516a1a0806d7b8b887a81d1eca198656dc5bff6f94f39aafbcc3508f9bb5d35dfdfad8f48509a40c0adb31096
@@ -1,13 +1,15 @@
1
- class Storify::ApiError < StandardError
2
- attr_reader :status, :type, :message
1
+ module Storify
2
+ class ApiError < StandardError
3
+ attr_reader :status, :type, :message
3
4
 
4
- def initialize(status, message, type = nil)
5
- @type = type
6
- @status = status
7
- @message = message
8
- end
5
+ def initialize(status, message, type = nil)
6
+ @type = type
7
+ @status = status
8
+ @message = message
9
+ end
9
10
 
10
- def to_s
11
- "#{self.status} #{self.type} #{self.message}"
11
+ def to_s
12
+ "#{self.status} #{self.type} #{self.message}"
13
+ end
12
14
  end
13
15
  end
@@ -2,101 +2,128 @@ require 'json'
2
2
  require 'rest-client'
3
3
  #RestClient.log = './restclient.log'
4
4
 
5
- class Storify::Client
6
- attr_reader :api_key, :username, :token
5
+ module Storify
6
+ class Client
7
+ # define end of content example
8
+ EOC = {'content' => {'stories' => [], 'elements' => []}}
7
9
 
8
- def initialize(api_key, username)
9
- @api_key = api_key
10
- @username = username
11
- end
10
+ attr_reader :api_key, :username, :token
12
11
 
13
- def auth(password, options: {})
14
- endpoint = Storify::endpoint(version: options[:version], method: :auth)
15
- data = call(endpoint, :POST, {password: password})
16
- @token = data['content']['_token']
12
+ def initialize(api_key, username)
13
+ @api_key = api_key
14
+ @username = username
15
+ end
17
16
 
18
- self
19
- end
17
+ def auth(password, options: {})
18
+ endpoint = Storify::endpoint(version: options[:version], method: :auth)
19
+ data = call(endpoint, :POST, params: {password: password})
20
+ @token = data['content']['_token']
20
21
 
21
- def userstories(username = @username, pager: nil, options: {})
22
- endpoint = Storify::endpoint(version: options[:version],
23
- protocol: options[:protocol],
24
- method: :userstories,
25
- params: {':username' => username})
22
+ self
23
+ end
26
24
 
27
- pager = Storify::Pager.new unless pager.is_a?(Storify::Pager)
28
- stories = []
25
+ def stories(pager: nil, options: {})
26
+ story_list(:stories, pager, options: options, use_auth: false)
27
+ end
29
28
 
30
- begin
31
- data = call(endpoint, :GET, pager.to_hash)
32
- content = data['content']
29
+ def latest(pager: nil, options: {})
30
+ story_list(:latest, pager, options: options, use_auth: false)
31
+ end
33
32
 
34
- content['stories'].each do |s|
35
- stories << Storify::Story.new(s)
36
- end
33
+ def featured(pager: nil, options: {})
34
+ story_list(:featured, pager, options: options, use_auth: false)
35
+ end
37
36
 
38
- pager.next
39
- end while pager.has_pages?(content['stories'])
37
+ def popular(pager: nil, options: {})
38
+ story_list(:popular, pager, options: options, use_auth: false)
39
+ end
40
40
 
41
- stories
42
- end
41
+ def userstories(username = @username, pager: nil, options: {})
42
+ params = {':username' => username}
43
+ story_list(:userstories, pager, options: options, params: params)
44
+ end
43
45
 
44
- def story(slug, username = @username, pager: nil, options: {})
45
- params = {':username' => username, ':slug' => slug}
46
- endpoint = Storify::endpoint(version: options[:version],
47
- protocol: options[:protocol],
48
- method: :userstory,
49
- params: params)
46
+ def story(slug, username = @username, pager: nil, options: {})
47
+ params = {':username' => username, ':slug' => slug}
48
+ endpoint = Storify::endpoint(version: options[:version],
49
+ protocol: options[:protocol],
50
+ method: :userstory,
51
+ params: params)
50
52
 
51
- pager = Storify::Pager.new unless pager.is_a?(Storify::Pager)
52
- story = nil
53
- elements = []
53
+ pager = pager ||= Pager.new
54
54
 
55
- begin
56
- data = call(endpoint, :GET, pager.to_hash)
57
- story = Storify::Story.new(data['content']) if story.nil?
55
+ story = nil
56
+ elements = []
58
57
 
59
- # create elements
60
- data['content']['elements'].each do |e|
61
- story.add_element(Storify::Element.new(e))
62
- end
58
+ begin
59
+ data = call(endpoint, :GET, paging: pager.to_hash)
60
+ story = Story.new(data['content']) if story.nil?
63
61
 
64
- pager.next
65
- end while pager.has_pages?(data['content']['elements'])
62
+ # create elements
63
+ data['content']['elements'].each do |e|
64
+ story.add_element(Element.new(e))
65
+ end
66
66
 
67
- story
68
- end
67
+ pager.next
68
+ end while pager.has_pages?(data['content']['elements'])
69
69
 
70
- def authenticated
71
- !@token.nil?
72
- end
70
+ story
71
+ end
73
72
 
73
+ def authenticated
74
+ !@token.nil?
75
+ end
74
76
 
75
- private
76
77
 
77
- def call(endpoint, verb, params = {}, opts = {})
78
- raw = nil
78
+ private
79
79
 
80
- begin
81
- # inject auth params automatically (if available)
82
- params[:username] = @username
83
- params[:api_key] = @api_key
84
- params[:_token] = @token if authenticated
80
+ def story_list(method, pager, params: {}, options: {}, use_auth: true)
81
+ endpoint = Storify::endpoint(version: options[:version],
82
+ protocol: options[:protocol],
83
+ method: method,
84
+ params: params)
85
85
 
86
- case verb
87
- when :POST
88
- raw = RestClient.post endpoint, params, {:accept => :json}
89
- when :GET
90
- raw = RestClient.get endpoint, {:params => params}
91
- end
92
- rescue => e
93
- raw = e.response
86
+ pager = pager ||= Pager.new
87
+ stories = []
88
+
89
+ begin
90
+ data = call(endpoint, :GET, paging: pager.to_hash, use_auth: use_auth)
91
+ content = data['content']
94
92
 
95
- data = JSON.parse(e.response)
96
- error = data['error']
97
- raise Storify::ApiError.new(data['code'], error['message'], error['type'])
93
+ content['stories'].each do |s|
94
+ stories << Story.new(s)
95
+ end
96
+
97
+ pager.next
98
+ end while pager.has_pages?(content['stories'])
99
+
100
+ stories
98
101
  end
99
102
 
100
- JSON.parse(raw)
103
+ def call(endpoint, verb, params: {}, paging: {}, opts: {}, use_auth: true)
104
+ raw = nil
105
+
106
+ begin
107
+ # add paging and auth query params
108
+ params.merge!(paging)
109
+ params[:username] = @username
110
+ params[:api_key] = @api_key
111
+ params[:_token] = @token if (authenticated && use_auth)
112
+
113
+ case verb
114
+ when :POST
115
+ raw = RestClient.post endpoint, params, {:accept => :json}
116
+ when :GET
117
+ raw = RestClient.get endpoint, {:params => params}
118
+ end
119
+ rescue => e
120
+ data = JSON.parse(e.response)
121
+ error = data['error']
122
+
123
+ return Storify::error(data['code'], error['message'], error['type'], end_of_content: EOC)
124
+ end
125
+
126
+ JSON.parse(raw)
127
+ end
101
128
  end
102
129
  end
@@ -2,51 +2,53 @@ require 'date'
2
2
  require 'nokogiri'
3
3
 
4
4
  # todo: split logic into separate source types
5
- class Storify::Element
6
- attr_reader :type, :source, :link, :published, :author
7
- attr_accessor :desc
8
-
9
- def initialize(content)
10
- @type = content['type']
11
- @source = content['source']['name']
12
- @link = content['permalink']
13
- @published = DateTime.parse(content['posted_at'])
14
-
15
- case @type
16
- when 'image'
17
- @desc = content['data'][@type]['caption']
18
-
19
- if content['data'].has_key?('oembed')
20
- @author = content['data']['oembed']['author_name']
5
+ module Storify
6
+ class Storify::Element
7
+ attr_reader :type, :source, :link, :published, :author
8
+ attr_accessor :desc
9
+
10
+ def initialize(content)
11
+ @type = content['type']
12
+ @source = content['source']['name']
13
+ @link = content['permalink']
14
+ @published = DateTime.parse(content['posted_at'])
15
+
16
+ case @type
17
+ when 'image'
18
+ @desc = content['data'][@type]['caption']
19
+
20
+ if content['data'].has_key?('oembed')
21
+ @author = content['data']['oembed']['author_name']
22
+ else
23
+ @author = content['attribution']['name']
24
+ end
25
+ when 'text'
26
+ @desc = content['data']['text']
27
+
28
+ doc = Nokogiri::HTML(@desc)
29
+ @desc = doc.xpath("//text()").to_s
21
30
  else
22
- @author = content['attribution']['name']
31
+ @desc = content['data'][@type]['description']
32
+ @author = content['source']['username']
33
+ @author = "@" + @author if @source.downcase == 'twitter'
23
34
  end
24
- when 'text'
25
- @desc = content['data']['text']
26
-
27
- doc = Nokogiri::HTML(@desc)
28
- @desc = doc.xpath("//text()").to_s
29
- else
30
- @desc = content['data'][@type]['description']
31
- @author = content['source']['username']
32
- @author = "@" + @author if @source.downcase == 'twitter'
33
35
  end
34
- end
35
36
 
36
- def to_s
37
- out = ''
37
+ def to_s
38
+ out = ''
39
+ published = @published.to_date
38
40
 
39
- case @source.downcase
40
- when 'storify'
41
- out << "\n#{@desc}\n"
42
- out << ('-' * @desc.length) + "\n\n" if @desc.length < 50
43
- when 'twitter'
44
- out << "[#{@published.to_date.to_s}] #{@author}: #{@link}\n"
45
- else
41
+ case @source.downcase
42
+ when 'storify'
43
+ out << "\n#{@desc}\n"
44
+ out << ('-' * @desc.length) + "\n\n" if @desc.length < 50
45
+ when 'twitter'
46
+ out << "[#{@published.to_s}] #{@author}: #{@link}\n"
47
+ else
48
+ out << "#{@author} [#{@published.to_s}]: #{@link}\n"
49
+ end
46
50
 
47
- out << "#{@author} [#{@published.to_date.to_s}]: #{@link}\n"
51
+ out
48
52
  end
49
-
50
- out
51
53
  end
52
54
  end
data/lib/storify/pager.rb CHANGED
@@ -1,46 +1,48 @@
1
- class Storify::Pager
2
- MIN_PAGE = 1
3
- MAX_PER_PAGE = 50
1
+ module Storify
2
+ class Pager
3
+ MIN_PAGE = 1
4
+ MAX_PER_PAGE = 50
4
5
 
5
- attr_reader :page, :per_page, :max
6
+ attr_reader :page, :per_page, :max
6
7
 
7
- def initialize(page: 1, per_page: 20, max: 0)
8
- @max = max.to_i.abs
9
- self.page=(page)
10
- self.per_page=(per_page)
11
- end
8
+ def initialize(page: 1, per_page: 20, max: 0)
9
+ @max = max.to_i.abs
10
+ self.page=(page)
11
+ self.per_page=(per_page)
12
+ end
12
13
 
13
- def per_page=(value)
14
- @per_page = (value > MAX_PER_PAGE) ? MAX_PER_PAGE : value.to_i.abs
15
- end
14
+ def per_page=(value)
15
+ @per_page = (value > MAX_PER_PAGE) ? MAX_PER_PAGE : value.to_i.abs
16
+ end
16
17
 
17
- def next
18
- self.page=(@page + 1)
19
- self
20
- end
18
+ def next
19
+ self.page=(@page + 1)
20
+ self
21
+ end
21
22
 
22
- def prev
23
- self.page=(@page - 1)
24
- self
25
- end
23
+ def prev
24
+ self.page=(@page - 1)
25
+ self
26
+ end
26
27
 
27
- def to_hash
28
- {:page => @page, :per_page => @per_page}
29
- end
28
+ def to_hash
29
+ {:page => @page, :per_page => @per_page}
30
+ end
30
31
 
31
- def has_pages?(array = [])
32
- return false unless array.is_a?(Array)
33
- return false if (@page > @max && @max != 0)
32
+ def has_pages?(array = [])
33
+ return false unless array.is_a?(Array)
34
+ return false if (@page > @max && @max != 0)
34
35
 
35
- array.length != 0
36
- end
36
+ array.length != 0
37
+ end
37
38
 
38
- private
39
+ private
39
40
 
40
- def page=(value)
41
- return @page = MIN_PAGE if (value < MIN_PAGE)
42
- return @page = (@max + 1) if ((value > @max) && @max != 0)
41
+ def page=(value)
42
+ return @page = MIN_PAGE if (value < MIN_PAGE)
43
+ return @page = (@max + 1) if ((value > @max) && @max != 0)
43
44
 
44
- @page = value.to_i
45
+ @page = value.to_i
46
+ end
45
47
  end
46
48
  end
data/lib/storify/story.rb CHANGED
@@ -1,39 +1,41 @@
1
1
  require 'date'
2
2
 
3
- class Storify::Story
4
- attr_reader :slug, :title, :desc, :link, :published, :author, :elements
5
-
6
- def initialize(content)
7
- @slug = content['slug']
8
- @title = content['title']
9
- @desc = content['description']
10
- @link = content['permalink']
11
- @author = content['author']['username']
12
-
13
- unless content['date']['published'].nil?
14
- @published = DateTime.parse(content['date']['published'])
3
+ module Storify
4
+ class Story
5
+ attr_reader :slug, :title, :desc, :link, :published, :author, :elements
6
+
7
+ def initialize(content)
8
+ @slug = content['slug']
9
+ @title = content['title']
10
+ @desc = content['description']
11
+ @link = content['permalink']
12
+ @author = content['author']['username']
13
+
14
+ unless content['date']['published'].nil?
15
+ @published = DateTime.parse(content['date']['published'])
16
+ end
17
+
18
+ @elements = []
15
19
  end
16
20
 
17
- @elements = []
18
- end
19
-
20
- def add_element(element)
21
- @elements << element
22
- end
21
+ def add_element(element)
22
+ @elements << element
23
+ end
23
24
 
24
- def to_s
25
- published = @published.nil? ? 'unpublished' : @published.to_date.to_s
25
+ def to_s
26
+ published = @published.nil? ? 'unpublished' : @published.to_date
26
27
 
27
- out = "\n#{@title}\n"
28
- out << ('-' * @title.length.to_i) + "\n"
29
- out << "Date: #{published}\n"
30
- out << "Author: #{@author}\n"
31
- out << "Link: #{@link}\n"
32
- out << "\n#{@desc} \n"
28
+ out = "\n#{@title}\n"
29
+ out << ('-' * @title.length.to_i) + "\n"
30
+ out << "Date: #{published.to_s}\n"
31
+ out << "Author: #{@author}\n"
32
+ out << "Link: #{@link}\n"
33
+ out << "\n#{@desc} \n"
33
34
 
34
- # serialize elements
35
- elements.each {|e| out << e.to_s }
35
+ # serialize elements
36
+ elements.each {|e| out << e.to_s }
36
37
 
37
- out
38
+ out
39
+ end
38
40
  end
39
41
  end
data/lib/storify.rb CHANGED
@@ -8,8 +8,12 @@ module Storify
8
8
  :v1 => {
9
9
  :base => 'api.storify.com/v1',
10
10
  :auth => '/auth',
11
+ :stories => '/stories',
11
12
  :userstories => '/stories/:username',
12
- :userstory => '/stories/:username/:slug'
13
+ :userstory => '/stories/:username/:slug',
14
+ :latest => '/stories/browse/latest',
15
+ :featured => '/stories/browse/featured',
16
+ :popular => '/stories/browse/popular'
13
17
  }
14
18
  }
15
19
 
@@ -26,6 +30,14 @@ module Storify
26
30
 
27
31
  uri
28
32
  end
33
+
34
+ def self.error(code, message, type, end_of_content: {})
35
+ unless message.downcase.include?('max')
36
+ raise Storify::ApiError.new(code, message, type)
37
+ end
38
+
39
+ end_of_content
40
+ end
29
41
  end
30
42
 
31
43
  require 'storify/story'
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ # These methods did not work with authentication,
4
+ # so they have been forced to not use the auth token
5
+
6
+ describe "Storify::Client -- Unauthenticated" do
7
+ before(:each) do
8
+ @client = Storify::Client.new(@api_key, @username)
9
+ @options = {:version => :v1, :protocol => :insecure}
10
+ end
11
+
12
+ context "GET /stories" do
13
+ it "should get all stories until the maximum" do
14
+ @client.stories.length.should > 400
15
+ end
16
+
17
+ it "should accept endpoint options (version, protocol)" do
18
+ @client.stories(options: @options).length.should > 400
19
+ end
20
+
21
+ it "should accept paging options (Pager)" do
22
+ pager = Storify::Pager.new(page: 1, max: 2, per_page: 20)
23
+ @client.stories(pager: pager).length.should == 40
24
+ end
25
+ end
26
+
27
+ context "GET /stories/browse/latest" do
28
+ it "should get all the latest stories until the maximum" do
29
+ @client.latest.length.should > 400
30
+ end
31
+
32
+ it "should accept endpoint options (version, protocol)" do
33
+ @client.latest(options: @options).length > 400
34
+ end
35
+
36
+ it "should get the top 20 stories" do
37
+ pager = Storify::Pager.new(page: 1, max: 1, per_page: 20)
38
+ @client.latest(pager: pager).length.should == 20
39
+ end
40
+ end
41
+
42
+ context "GET /stories/browse/featured" do
43
+ it "should get all the featured stories until the maximum" do
44
+ @client.featured.length.should > 400
45
+ end
46
+
47
+ it "should accept endpoint options (version, protocol)" do
48
+ @client.featured(options: @options).length > 400
49
+ end
50
+
51
+ it "should get the top 20 featured stories" do
52
+ pager = Storify::Pager.new(page: 1, max: 1, per_page: 20)
53
+ @client.featured(pager: pager).length.should == 20
54
+ end
55
+ end
56
+
57
+ context "GET /stories/browse/popular" do
58
+ it "should get all the popular stories until the maximum" do
59
+ @client.popular.length.should > 400
60
+ end
61
+
62
+ it "should accept endpoint options (version, protocol)" do
63
+ @client.popular(options: @options).length > 400
64
+ end
65
+
66
+ it "should get the top 15 popular stories" do
67
+ p = Storify::Pager.new(page: 1, max: 1, per_page: 15)
68
+ @client.popular(pager: p).length.should == 15
69
+ end
70
+ end
71
+ end
data/spec/storify_spec.rb CHANGED
@@ -38,6 +38,22 @@ describe Storify do
38
38
  Storify::ENDPOINTS[:v1][:auth].should == "/auth"
39
39
  end
40
40
 
41
+ it "should support the Stories endpoint" do
42
+ Storify::ENDPOINTS[:v1][:stories].should == "/stories"
43
+ end
44
+
45
+ it "should support the Latest Stories endpoint" do
46
+ Storify::ENDPOINTS[:v1][:latest].should == "/stories/browse/latest"
47
+ end
48
+
49
+ it "should support the Featured Stories endpoint" do
50
+ Storify::ENDPOINTS[:v1][:featured].should == "/stories/browse/featured"
51
+ end
52
+
53
+ it "should support the Popular Stories endpoint" do
54
+ Storify::ENDPOINTS[:v1][:popular].should == "/stories/browse/popular"
55
+ end
56
+
41
57
  it "should support the User Stories endpoint" do
42
58
  Storify::ENDPOINTS[:v1][:userstories].should == "/stories/:username"
43
59
  end
@@ -76,4 +92,17 @@ describe Storify do
76
92
  uri.should == 'http://api.storify.com/v1/stories/rtejpar'
77
93
  end
78
94
  end
95
+
96
+ context "API v1 Error Handling" do
97
+ it "should return an empty content block (if api max reached)" do
98
+ eoc = Storify::Client::EOC
99
+ content = Storify::error(400, '...Max...', 'bad request', end_of_content: eoc)
100
+ content.should == eoc
101
+ end
102
+
103
+ it "should return an API error for a non-max case" do
104
+ eoc = Storify::Client::EOC
105
+ expect{Storify::error(400, '...', 'bad request', end_of_content: eoc)}.to raise_error(Storify::ApiError)
106
+ end
107
+ end
79
108
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: storify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rizwan Tejpar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-11 00:00:00.000000000 Z
11
+ date: 2013-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -93,6 +93,7 @@ files:
93
93
  - lib/storify/story.rb
94
94
  - lib/storify.rb
95
95
  - spec/client_auth_spec.rb
96
+ - spec/client_noauth_spec.rb
96
97
  - spec/client_spec.rb
97
98
  - spec/pager_spec.rb
98
99
  - spec/spec_helper.rb
@@ -123,6 +124,7 @@ specification_version: 4
123
124
  summary: Storify API
124
125
  test_files:
125
126
  - spec/client_auth_spec.rb
127
+ - spec/client_noauth_spec.rb
126
128
  - spec/client_spec.rb
127
129
  - spec/pager_spec.rb
128
130
  - spec/spec_helper.rb