storify 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/storify.rb +52 -3
  3. data/lib/storify/agency.rb +17 -0
  4. data/lib/storify/agency/customerinfo.rb +22 -0
  5. data/lib/storify/agency/customerinfokeys.rb +17 -0
  6. data/lib/storify/agency/info.rb +17 -0
  7. data/lib/storify/attribution.rb +18 -0
  8. data/lib/storify/client.rb +72 -6
  9. data/lib/storify/comment.rb +19 -0
  10. data/lib/storify/coverphoto.rb +16 -0
  11. data/lib/storify/createdwith.rb +16 -0
  12. data/lib/storify/data.rb +18 -0
  13. data/lib/storify/data/image.rb +18 -0
  14. data/lib/storify/data/link.rb +20 -0
  15. data/lib/storify/data/oembed.rb +24 -0
  16. data/lib/storify/data/video.rb +19 -0
  17. data/lib/storify/dategroup.rb +21 -0
  18. data/lib/storify/element.rb +43 -34
  19. data/lib/storify/features.rb +23 -0
  20. data/lib/storify/identity.rb +18 -0
  21. data/lib/storify/quotable.rb +18 -0
  22. data/lib/storify/settings.rb +23 -0
  23. data/lib/storify/settings/colors.rb +18 -0
  24. data/lib/storify/settings/fonts.rb +17 -0
  25. data/lib/storify/settings/notifications.rb +27 -0
  26. data/lib/storify/settings/options.rb +21 -0
  27. data/lib/storify/settings/style.rb +18 -0
  28. data/lib/storify/settings/typekit.rb +16 -0
  29. data/lib/storify/source.rb +17 -0
  30. data/lib/storify/statselement.rb +19 -0
  31. data/lib/storify/statsembed.rb +17 -0
  32. data/lib/storify/story.rb +37 -24
  33. data/lib/storify/storymeta.rb +16 -0
  34. data/lib/storify/storystats.rb +21 -0
  35. data/lib/storify/user.rb +38 -0
  36. data/lib/storify/userstats.rb +18 -0
  37. data/spec/client_noauth_spec.rb +15 -0
  38. data/spec/client_spec.rb +58 -5
  39. data/spec/storify_spec.rb +12 -0
  40. metadata +47 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80ab1db50509835603c3e6c168b8e280609b56b8
4
- data.tar.gz: 8ee9e89be0fd86fb103359ed310a2b08b83d2ca4
3
+ metadata.gz: 1bc26cd7a6d0f18da904689a7765d52d75099d25
4
+ data.tar.gz: 5101109dee46ec2679dd36a84c959c189dc968c2
5
5
  SHA512:
6
- metadata.gz: d9150aaed0238077440089ff91343f388446662d2accf6a60764a30fe11ab36b14d3fa5f620b95111ee5d3470b0ebf795cfebb790cf5080adc8a7550d3e22185
7
- data.tar.gz: 7da411bd9aec3aff5a5b131b00cc446535e7f7a5d7aa19afb2d665d584af2de3c3df9b9fafd1dceddd8c3ade7f31ef85aea087a17324bdcc67e4bfbe1aaecb1a
6
+ metadata.gz: 648001b71e271feafa2abcc8e094b5a0941e35531028dbc4b06a8b8cf363012126be512c1404f4796214b2548e361091175a26d47188c7da961d38c51af82b22
7
+ data.tar.gz: b03312e0debb19881ee528d7b1c97a5472f3c0a49cdf55ad57e20bda7e855d30d18d620a6f02efb9aea5657ced4b06879d616fa62397292518aa1bfa5413f02c
data/lib/storify.rb CHANGED
@@ -16,7 +16,10 @@ module Storify
16
16
  :popular => '/stories/browse/popular',
17
17
  :topic => '/stories/browse/topic/:topic',
18
18
  :search => '/stories/search',
19
- :editslug => '/stories/:username/:slug/editslug'
19
+ :editslug => '/stories/:username/:slug/editslug',
20
+ :users => '/users',
21
+ :userprofile => '/users/:username',
22
+ :publish => '/stories/:username/:slug/publish'
20
23
  }
21
24
  }
22
25
 
@@ -43,8 +46,54 @@ module Storify
43
46
  end
44
47
  end
45
48
 
46
- require 'storify/story'
49
+
47
50
  require 'storify/client'
48
51
  require 'storify/pager'
49
- require 'storify/element'
50
52
  require 'storify/apierror'
53
+
54
+ # base types
55
+ require 'storify/features'
56
+ require 'storify/dategroup'
57
+ require 'storify/coverphoto'
58
+ require 'storify/identity'
59
+ require 'storify/userstats'
60
+ require 'storify/source'
61
+ require 'storify/attribution'
62
+
63
+ # story element data
64
+ require 'storify/data/link'
65
+ require 'storify/data/image'
66
+ require 'storify/data/video'
67
+ require 'storify/data/oembed'
68
+ require 'storify/data'
69
+
70
+ # story meta
71
+ require 'storify/quotable'
72
+ require 'storify/createdwith'
73
+ require 'storify/storymeta'
74
+
75
+ # story stats
76
+ require 'storify/statselement'
77
+ require 'storify/statsembed'
78
+ require 'storify/storystats'
79
+
80
+ # settings
81
+ require 'storify/settings/fonts'
82
+ require 'storify/settings/colors'
83
+ require 'storify/settings/options'
84
+ require 'storify/settings/notifications'
85
+ require 'storify/settings/typekit'
86
+ require 'storify/settings/style'
87
+ require 'storify/settings'
88
+
89
+ # agency
90
+ require 'storify/agency/info'
91
+ require 'storify/agency/customerinfokeys'
92
+ require 'storify/agency/customerinfo'
93
+ require 'storify/agency'
94
+
95
+ # user
96
+ require 'storify/user'
97
+ require 'storify/comment'
98
+ require 'storify/element'
99
+ require 'storify/story'
@@ -0,0 +1,17 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class UserAgency < OpenStruct
6
+
7
+ end
8
+
9
+ module UserAgencyRepresentable
10
+ include Representable::JSON
11
+
12
+ property :isAgency
13
+ property :agencyInfo, :class => Storify::Agency::Info, :extend => Storify::Agency::InfoRepresentable
14
+ property :isCustomer
15
+ property :customerInfo, :class => Storify::Agency::CustomerInfo, :extend => Storify::Agency::CustomerInfoRepresentable
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Agency
6
+ class CustomerInfo < OpenStruct
7
+
8
+ end
9
+
10
+ module CustomerInfoRepresentable
11
+ include Representable::JSON
12
+
13
+ property :approved
14
+ property :removalApproved
15
+ property :agencyId, :render_nil => true
16
+ property :agencyUsername, :render_nil => true
17
+ property :approved_at, :render_nil => true
18
+ property :paid_plan, :render_nil => true
19
+ property :keys, :class => Storify::Agency::CustomerInfoKeys, :extend => Storify::Agency::CustomerInfoKeysRepresentable
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Agency
6
+ class CustomerInfoKeys < OpenStruct
7
+
8
+ end
9
+
10
+ module CustomerInfoKeysRepresentable
11
+ include Representable::JSON
12
+
13
+ property :approve, :render_nil => true
14
+ property :remove, :render_nil => true
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Agency
6
+ class Info < OpenStruct
7
+
8
+ end
9
+
10
+ module InfoRepresentable
11
+ include Representable::JSON
12
+
13
+ property :maxCustomersNum
14
+ collection :customers
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class Attribution < OpenStruct
6
+
7
+ end
8
+
9
+ module AttributionRepresentable
10
+ include Representable::JSON
11
+
12
+ property :title
13
+ property :name
14
+ property :username
15
+ property :href
16
+ property :thumbnail
17
+ end
18
+ end
@@ -5,7 +5,7 @@ require 'rest-client'
5
5
  module Storify
6
6
  class Client
7
7
  # define end of content example
8
- EOC = {'content' => {'stories' => [], 'elements' => []}}
8
+ EOC = {'content' => {'stories' => [], 'elements' => [], 'users' => []}}
9
9
 
10
10
  attr_accessor :api_key, :username, :token
11
11
 
@@ -63,18 +63,25 @@ module Storify
63
63
  params: params)
64
64
 
65
65
  pager = pager ||= Pager.new
66
-
67
66
  story = nil
67
+ first = true
68
68
  elements = []
69
69
 
70
70
  begin
71
71
  data = call(endpoint, :GET, paging: pager.to_hash)
72
- story = Story.new(data['content']) if story.nil?
72
+ json = JSON.generate(data['content'])
73
+
74
+ if story.nil?
75
+ story = Story.new.extend(StoryRepresentable).from_json(json)
76
+ else
77
+ first = false
78
+ end
73
79
 
74
80
  # create elements
75
81
  data['content']['elements'].each do |e|
76
- story.add_element(Element.new(e))
77
- end
82
+ je = JSON.generate(e)
83
+ story.elements << Element.new.extend(ElementRepresentable).from_json(je)
84
+ end unless first
78
85
 
79
86
  pager.next
80
87
  end while pager.has_pages?(data['content']['elements'])
@@ -93,6 +100,64 @@ module Storify
93
100
  data['content']['slug']
94
101
  end
95
102
 
103
+ def users(pager: nil, options: {})
104
+ endpoint = Storify::endpoint(version: options[:version],
105
+ protocol: options[:protocol],
106
+ method: :users)
107
+
108
+ pager = pager ||= Pager.new
109
+ users = []
110
+
111
+ begin
112
+ data = call(endpoint, :GET, paging: pager.to_hash, use_auth: false)
113
+ content = data['content']
114
+
115
+ content['users'].each do |s|
116
+ json = JSON.generate(s)
117
+ users << User.new.extend(UserRepresentable).from_json(json)
118
+ end
119
+
120
+ pager.next
121
+ end while pager.has_pages?(content['users'])
122
+
123
+ users
124
+ end
125
+
126
+ def profile(username = @usernmae, options: {})
127
+ endpoint = Storify::endpoint(version: options[:version],
128
+ protocol: options[:protocol],
129
+ method: :userprofile,
130
+ params: {':username' => username})
131
+
132
+ data = call(endpoint, :GET)
133
+ json = JSON.generate(data['content'])
134
+
135
+ User.new.extend(UserRepresentable).from_json(json)
136
+ end
137
+
138
+ def publish(story, options: {})
139
+ puts story.inspect
140
+ # ensure we have a story w/slug and author
141
+ raise "Not a Story" unless story.is_a?(Storify::Story)
142
+ raise "No slug found" if story.slug.nil?
143
+ raise "No author found" if (story.author.nil? || story.author.username.nil?)
144
+
145
+ # extract author and slug
146
+ slug = story.slug
147
+ username = story.author.username
148
+ endpoint = Storify::endpoint(version: options[:version],
149
+ protocol: options[:protocol],
150
+ method: :publish,
151
+ params: {':username' => username,
152
+ ':slug' => slug})
153
+
154
+ # attempt to publish
155
+ json = story.to_json
156
+ data = call(endpoint, :POST, params: {:data => json})
157
+ true
158
+ end
159
+
160
+
96
161
  def authenticated
97
162
  !@token.nil?
98
163
  end
@@ -114,7 +179,8 @@ module Storify
114
179
  content = data['content']
115
180
 
116
181
  content['stories'].each do |s|
117
- stories << Story.new(s)
182
+ json = JSON.generate(s)
183
+ stories << Story.new.extend(StoryRepresentable).from_json(json)
118
184
  end
119
185
 
120
186
  pager.next
@@ -0,0 +1,19 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class Comment < OpenStruct
6
+
7
+ end
8
+
9
+ module CommentRepresentable
10
+ include Representable::JSON
11
+
12
+ property :id
13
+ property :body
14
+ property :date, :class => Storify::DateGroup, :extend => Storify::DateGroupRepresentable
15
+ property :is_spam
16
+ property :author, :class => Storify::User, :extend => Storify::UserRepresentable
17
+ property :canEdit
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class CoverPhoto < OpenStruct
6
+
7
+ end
8
+
9
+ module CoverPhotoRepresentable
10
+ include Representable::JSON
11
+
12
+ property :url
13
+ property :width
14
+ property :height
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class CreatedWith < OpenStruct
6
+
7
+ end
8
+
9
+ module CreatedWithRepresentable
10
+ include Representable::JSON
11
+
12
+ property :href
13
+ property :appname
14
+ property :name
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class StoryData < OpenStruct
6
+
7
+ end
8
+
9
+ module StoryDataRepresentable
10
+ include Representable::JSON
11
+
12
+ property :image, :class => Storify::Data::Image, :extend => Storify::Data::ImageRepresentable
13
+ property :oembed, :class => Storify::Data::Oembed, :extend => Storify::Data::OembedRepresentable
14
+ property :link, :class => Storify::Data::Link, :extend => Storify::Data::LinkRepresentable
15
+ property :video, :class => Storify::Data::Video, :extend => Storify::Data::VideoRepresentable
16
+ property :text
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Data
6
+ class Image < OpenStruct
7
+
8
+ end
9
+
10
+ module ImageRepresentable
11
+ include Representable::JSON
12
+
13
+ property :src
14
+ property :caption
15
+ property :thumbnail
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Data
6
+ class Link < OpenStruct
7
+
8
+ end
9
+
10
+ module LinkRepresentable
11
+ include Representable::JSON
12
+
13
+ property :rest_api_url
14
+ property :oembed_url
15
+ property :thumbnail
16
+ property :description
17
+ property :title
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Data
6
+ class Oembed < OpenStruct
7
+
8
+ end
9
+
10
+ module OembedRepresentable
11
+ include Representable::JSON
12
+
13
+ property :type
14
+ property :html
15
+ property :thumbnail_url
16
+ property :title
17
+ property :provider_url
18
+ property :provider_name
19
+ property :url
20
+ property :author_url
21
+ property :author_name
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Data
6
+ class Video < OpenStruct
7
+
8
+ end
9
+
10
+ module VideoRepresentable
11
+ include Representable::JSON
12
+
13
+ property :src
14
+ property :title
15
+ property :description
16
+ property :thumbnail
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class DateGroup < OpenStruct
6
+ end
7
+
8
+ module DateGroupRepresentable
9
+ include Representable::JSON
10
+
11
+ property :updated
12
+ property :last_story
13
+ property :last_seen
14
+ property :last_email
15
+ property :last_digest
16
+ property :featured
17
+ property :created
18
+ property :modified
19
+ property :published
20
+ end
21
+ end
@@ -1,54 +1,63 @@
1
- require 'date'
1
+ require 'ostruct'
2
2
  require 'nokogiri'
3
+ require 'representable/json'
3
4
 
4
- # todo: split logic into separate source types
5
5
  module Storify
6
- class Storify::Element
7
- attr_reader :type, :source, :link, :published, :author
8
- attr_accessor :desc
6
+ class Element < OpenStruct
9
7
 
10
- def initialize(content)
11
- @type = content['type']
12
- @source = content['source']['name']
13
- @link = content['permalink']
14
- @published = DateTime.parse(content['posted_at'])
8
+ end
15
9
 
16
- case @type
17
- when 'image'
18
- @desc = content['data'][@type]['caption']
10
+ module ElementRepresentable
11
+ include Representable::JSON
12
+
13
+ property :id
14
+ property :eid
15
+ property :type
16
+ property :permalink
17
+ property :posted_at
18
+ property :updated_at
19
+ property :data, :class => Storify::StoryData, :extend => Storify::StoryDataRepresentable
20
+ property :source, :class => Storify::Source, :extend => Storify::SourceRepresentable
21
+ property :attribution, :class => Storify::Attribution, :extend => Storify::AttributionRepresentable
22
+ collection :comments, :class => Storify::Comment, :extend => Storify::CommentRepresentable
23
+ property :stats, :class => Storify::StoryStats, :extend => Storify::StoryStatsRepresentable
24
+ #meta.....highly variable
25
+
26
+ def to_s
27
+ out = ''
28
+ desc = ''
29
+ aut = ''
30
+ published = DateTime.parse(posted_at).to_date
19
31
 
20
- if content['data'].has_key?('oembed')
21
- @author = content['data']['oembed']['author_name']
22
- else
23
- @author = content['attribution']['name']
24
- end
32
+ case type
33
+ when 'image'
34
+ desc = data.image.caption
35
+ aut = data.respond_to?(:oembed) ? data.oembed.author_name : attribution.name
25
36
  when 'text'
26
- @desc = content['data']['text']
37
+ desc = data.text
27
38
 
28
- doc = Nokogiri::HTML(@desc)
29
- @desc = doc.xpath("//text()").to_s
39
+ doc = Nokogiri::HTML(desc)
40
+ desc = doc.xpath("//text()").to_s
41
+ desc = desc.gsub(/&[a-z]+;/,'')
30
42
  else
31
- @desc = content['data'][@type]['description']
32
- @author = content['source']['username']
33
- @author = "@" + @author if @source.downcase == 'twitter'
34
- end
35
- end
43
+ desc = data.send("#{type}".to_sym).description
36
44
 
37
- def to_s
38
- out = ''
39
- published = @published.to_date
45
+ aut = source.username
46
+ aut = "@" + aut if source.name.downcase == 'twitter'
47
+ end
40
48
 
41
- case @source.downcase
49
+ case source.name.downcase
42
50
  when 'storify'
43
- out << "\n#{@desc}\n"
44
- out << ('-' * @desc.length) + "\n\n" if @desc.length < 50
51
+ out << "\n#{desc}\n"
52
+ out << ('-' * desc.length) + "\n\n" if desc.length < 40
45
53
  when 'twitter'
46
- out << "[#{@published.to_s}] #{@author}: #{@link}\n"
54
+ out << "[#{published.to_s}] #{aut}: #{permalink}\n"
47
55
  else
48
- out << "#{@author} [#{@published.to_s}]: #{@link}\n"
56
+ out << "#{aut} [#{published.to_s}]: #{permalink}\n"
49
57
  end
50
58
 
51
59
  out
52
60
  end
61
+
53
62
  end
54
63
  end
@@ -0,0 +1,23 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class Features < OpenStruct
6
+
7
+ end
8
+
9
+ module FeaturesRepresentable
10
+ include Representable::JSON
11
+
12
+ property :custom_embed_style
13
+ property :private_stories
14
+ property :html_for_seo
15
+ property :no_advertising
16
+ property :business_options
17
+ property :headerless_embed
18
+ property :pdf
19
+ property :realtime_updates
20
+ property :storylock
21
+ property :maxEditors
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class Identity < OpenStruct
6
+ end
7
+
8
+ module IdentityRepresentable
9
+ include Representable::JSON
10
+
11
+ property :service
12
+ property :username
13
+ property :name
14
+ property :date, :class => Storify::DateGroup, :extend => Storify::DateGroupRepresentable
15
+ property :url
16
+ property :avatar
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class Quotable < OpenStruct
6
+
7
+ end
8
+
9
+ module QuotableRepresentable
10
+ include Representable::JSON
11
+
12
+ property :username
13
+ property :name
14
+ property :avatar
15
+ property :source
16
+ property :notified_at, :render_nil => true
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class UserSettings < OpenStruct
6
+
7
+ end
8
+
9
+ module UserSettingsRepresentable
10
+ include Representable::JSON
11
+
12
+ property :sxsw
13
+ property :comments
14
+ property :facebook_autoshare
15
+ property :facebook_quoteimg
16
+ property :facebook_post
17
+ property :twitter_post
18
+ property :ban_notify
19
+ property :options, :class => Storify::Settings::Options, :extend => Storify::Settings::OptionsRepresentable
20
+ property :notifications, :class => Storify::Settings::Notifications, :extend => Storify::Settings::NotificationsRepresentable
21
+ property :style, :class => Storify::Settings::Style, :extend => Storify::Settings::StyleRepresentable
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Settings
6
+ class Colors < OpenStruct
7
+
8
+ end
9
+
10
+ module ColorsRepresentable
11
+ include Representable::JSON
12
+
13
+ property :text
14
+ property :link
15
+ property :background
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Settings
6
+ class Fonts < OpenStruct
7
+
8
+ end
9
+
10
+ module FontsRepresentable
11
+ include Representable::JSON
12
+
13
+ property :title
14
+ property :body
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Settings
6
+ class Notifications < OpenStruct
7
+
8
+ end
9
+
10
+ module NotificationsRepresentable
11
+ include Representable::JSON
12
+
13
+ property :newsletter
14
+ property :digest
15
+ property :likes
16
+ property :comments
17
+ property :follower
18
+ property :quoted
19
+ property :friend_quoted
20
+ property :autoshare
21
+ property :element_comment
22
+ property :element_like
23
+ property :story_comment
24
+ property :story_like
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Settings
6
+ class Options < OpenStruct
7
+
8
+ end
9
+
10
+ module OptionsRepresentable
11
+ include Representable::JSON
12
+
13
+ property :infinite_scroll
14
+ property :hide_stats
15
+ property :allow_embedding
16
+ property :comments
17
+ property :related_stories
18
+ property :ga
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Settings
6
+ class Style < OpenStruct
7
+
8
+ end
9
+
10
+ module StyleRepresentable
11
+ include Representable::JSON
12
+
13
+ property :fonts, :class => Storify::Settings::Fonts, :extend => Storify::Settings::FontsRepresentable
14
+ property :colors, :class => Storify::Settings::Colors, :extend => Storify::Settings::ColorsRepresentable
15
+ property :typekit, :class => Storify::Settings::Typekit, :extend => Storify::Settings::TypekitRepresentable
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ module Settings
6
+ class Typekit < OpenStruct
7
+
8
+ end
9
+
10
+ module TypekitRepresentable
11
+ include Representable::JSON
12
+
13
+ property :kitId
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class Source < OpenStruct
6
+
7
+ end
8
+
9
+ module SourceRepresentable
10
+ include Representable::JSON
11
+
12
+ property :href
13
+ property :name
14
+ property :userid
15
+ property :username
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class StatsElement < OpenStruct
6
+
7
+ end
8
+
9
+ module StatsElementRepresentable
10
+ include Representable::JSON
11
+
12
+ property :text
13
+ property :quote
14
+ property :image
15
+ property :video
16
+ property :link
17
+ property :other
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class StatsEmbed < OpenStruct
6
+
7
+ end
8
+
9
+ module StatsEmbedRepresentable
10
+ include Representable::JSON
11
+
12
+ property :clicks
13
+ property :views
14
+ property :href
15
+ property :domain
16
+ end
17
+ end
data/lib/storify/story.rb CHANGED
@@ -1,36 +1,49 @@
1
+ require 'ostruct'
1
2
  require 'date'
3
+ require 'representable/json'
2
4
 
3
5
  module Storify
4
- class Story
5
- attr_reader :slug, :title, :desc, :link, :published, :author, :elements
6
+ class Story < OpenStruct
6
7
 
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 = []
19
- end
8
+ end
20
9
 
21
- def add_element(element)
22
- @elements << element
23
- end
10
+ module StoryRepresentable
11
+ include Representable::JSON
12
+
13
+ property :sid
14
+ property :title
15
+ property :slug
16
+ property :status
17
+ property :version
18
+ property :permalink
19
+ property :shortlink
20
+ property :description
21
+ property :thumbnail
22
+ property :date, :class => Storify::DateGroup, :extend => Storify::DateGroupRepresentable
23
+ property :private
24
+ property :not_indexed
25
+ property :is_spam
26
+ collection :topics
27
+ collection :siteposts
28
+ property :meta, :class => Storify::StoryMeta, :extend => Storify::StoryMetaRepresentable
29
+ property :stats, :class => Storify::StoryStats, :extend => Storify::StoryStatsRepresentable
30
+ property :modified
31
+ property :deleted
32
+ property :author, :class => Storify::User, :extend => Storify::UserRepresentable
33
+ property :canEdit
34
+ collection :comments, :class => Storify::Comment, :extend => Storify::CommentRepresentable
35
+ collection :elements, :class => Storify::Element, :extend => Storify::ElementRepresentable
24
36
 
25
37
  def to_s
26
- published = @published.nil? ? 'unpublished' : @published.to_date
38
+ published = DateTime.parse(date.published)
39
+ published = published.nil? ? 'unpublished' : published.to_date
27
40
 
28
- out = "\n#{@title}\n"
29
- out << ('-' * @title.length.to_i) + "\n"
41
+ out = "\n#{title}\n"
42
+ out << ('-' * title.length.to_i) + "\n"
30
43
  out << "Date: #{published.to_s}\n"
31
- out << "Author: #{@author}\n"
32
- out << "Link: #{@link}\n"
33
- out << "\n#{@desc} \n"
44
+ out << "Author: #{author.name}\n"
45
+ out << "Link: #{permalink}\n"
46
+ out << "\n#{description} \n"
34
47
 
35
48
  # serialize elements
36
49
  elements.each {|e| out << e.to_s }
@@ -0,0 +1,16 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class StoryMeta < OpenStruct
6
+
7
+ end
8
+
9
+ module StoryMetaRepresentable
10
+ include Representable::JSON
11
+
12
+ collection :quoted, :class => Storify::Quotable, :extend => Storify::QuotableRepresentable
13
+ collection :hashtags
14
+ property :created_with, :class => Storify::CreatedWith, :extend => Storify::CreatedWithRepresentable
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class StoryStats < OpenStruct
6
+
7
+ end
8
+
9
+ module StoryStatsRepresentable
10
+ include Representable::JSON
11
+
12
+ property :views
13
+ property :popularity
14
+ property :likes
15
+ collection :embeds, :class => StatsEmbed, :extend => StatsEmbedRepresentable
16
+ property :elements, :class => StatsElement, :extend => StatsElementRepresentable
17
+ property :elementComments
18
+ property :comments
19
+ property :clicks
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class User < OpenStruct
6
+
7
+ end
8
+
9
+ module UserRepresentable
10
+ include Representable::JSON
11
+
12
+ property :_id
13
+ property :username
14
+ property :_access
15
+ property :name
16
+ property :bio
17
+ property :location
18
+ property :website
19
+ property :avatar
20
+ property :permalink
21
+ property :settings, :class => Storify::UserSettings, :extend => Storify::UserSettingsRepresentable
22
+ property :lang
23
+ property :stats, :class => Storify::UserStats, :extend => Storify::UserStatsRepresentable
24
+ property :date, :class => Storify::DateGroup, :extend => Storify::DateGroupRepresentable
25
+ property :coverPhoto, :class => Storify::CoverPhoto, :extend => Storify::CoverPhotoRepresentable
26
+ property :canFeatureStories
27
+ collection :featuredStories
28
+ property :paid_plan
29
+ property :email_verified
30
+ property :features_enabled, :class => Storify::Features, :extend => Storify::FeaturesRepresentable
31
+ property :agency, :class => Storify::UserAgency, :extend => Storify::UserAgencyRepresentable
32
+ property :category
33
+ property :is_spam
34
+ collection :subscribers, :class => Storify::User, :extend => Storify::UserRepresentable
35
+ collection :subscriptions, :class => Storify::User, :extend => Storify::UserRepresentable
36
+ collection :identities, :class => Storify::Identity, :extend => Storify::IdentityRepresentable
37
+ end
38
+ end
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+ require 'representable/json'
3
+
4
+ module Storify
5
+ class UserStats < OpenStruct
6
+
7
+ end
8
+
9
+ module UserStatsRepresentable
10
+ include Representable::JSON
11
+
12
+ property :views
13
+ property :subscriptions
14
+ property :subscribers
15
+ property :stories
16
+ property :embeds
17
+ end
18
+ end
@@ -102,4 +102,19 @@ describe "Storify::Client -- Unauthenticated" do
102
102
  @client.search('startups', pager: p).length.should == 5
103
103
  end
104
104
  end
105
+
106
+ context "GET /users" do
107
+ it "should get all users until the maximum" do
108
+ @client.users.length.should > 100
109
+ end
110
+
111
+ it "should accept endpoint options (version, protocol)" do
112
+ @client.users(options: @options).length.should > 100
113
+ end
114
+
115
+ it "should support paging options" do
116
+ p = Storify::Pager.new(page: 1, max: 1, per_page: 10)
117
+ @client.users(pager: p).length.should == 10
118
+ end
119
+ end
105
120
  end
data/spec/client_spec.rb CHANGED
@@ -36,12 +36,12 @@ describe Storify::Client do
36
36
 
37
37
  context "GET /stories/:username" do
38
38
  it "should get all stories for a specific user" do
39
- @client.userstories(@username).length.should == 2
39
+ @client.userstories(@username).length.should >= 2
40
40
  end
41
41
 
42
42
  it "should accept endpoint options (version, protocol)" do
43
43
  options = {:version => :v1, :protocol => :insecure}
44
- @client.userstories(@username, options: options).length.should == 2
44
+ @client.userstories(@username, options: options).length.should >= 2
45
45
  end
46
46
 
47
47
  it "should accept paging options (Pager)" do
@@ -96,8 +96,61 @@ describe Storify::Client do
96
96
  end
97
97
  end
98
98
 
99
- it "should allow a story to be serialized as text" do
100
- story = @client.story('austin-startup-digest-for-december-9-2014', 'joshuabaer')
101
- story.should_not eql ""
99
+ context "GET /users/:username" do
100
+ it "should get a specific user's profile" do
101
+ @client.profile(@username).username.should == @username
102
+ end
103
+ end
104
+
105
+ context "POST /stories/:username/:slug/publish" do
106
+ it "should raise an exception if a story is not provided" do
107
+ expect{@client.publish(nil)}.to raise_exception
108
+ end
109
+
110
+ it "should raise an exception if the story is not found" do
111
+ story = Storify::Story.new.extend(Storify::StoryRepresentable)
112
+ author = Storify::User.new.extend(Storify::UserRepresentable)
113
+ author.username = 'rtejpar'
114
+ story.author = author
115
+ story.slug = 'does-not-exist-story'
116
+
117
+ expect{@client.publish(story)}.to raise_exception(Storify::ApiError)
118
+ end
119
+
120
+ it "should raise an exception if you do not have permission to publish" do
121
+ story = Storify::Story.new.extend(Storify::StoryRepresentable)
122
+ author = Storify::User.new.extend(Storify::UserRepresentable)
123
+ author.username = 'storify'
124
+ story.author = author
125
+ story.slug = 'storify-acquired-by-livefyre'
126
+
127
+ expect{@client.publish(story)}.to raise_exception(Storify::ApiError)
128
+ end
129
+
130
+ it "should publish an existing story" do
131
+ story = @client.story('test-story', @username)
132
+ @client.publish(story).should == true
133
+ end
134
+
135
+ it "should ignore any changes to the story during a publish" do
136
+ story = @client.story('no-embeds', @username)
137
+ new_desc = "New Description #{Random.new(Random.new_seed).to_s}"
138
+ old_desc = story.description
139
+
140
+ story.description = new_desc
141
+ story.description.should == new_desc
142
+ @client.publish(story).should == true
143
+
144
+ revised = @client.story('no-embeds', @username)
145
+ revised.description.should == old_desc
146
+ end
147
+
148
+ end
149
+
150
+ context "Serialization" do
151
+ it "should allow a story to be serialized as text" do
152
+ story = @client.story('austin-startup-digest-for-december-9-2014', 'joshuabaer')
153
+ story.should_not eql ""
154
+ end
102
155
  end
103
156
  end
data/spec/storify_spec.rb CHANGED
@@ -73,6 +73,18 @@ describe Storify do
73
73
  it "should support the Search Story endpoint" do
74
74
  Storify::ENDPOINTS[:v1][:search].should == "/stories/search"
75
75
  end
76
+
77
+ it "should support the Users endpoint" do
78
+ Storify::ENDPOINTS[:v1][:users].should == "/users"
79
+ end
80
+
81
+ it "should support the User Profile endpoint" do
82
+ Storify::ENDPOINTS[:v1][:userprofile].should == "/users/:username"
83
+ end
84
+
85
+ it "should support the Publish Story endpoint" do
86
+ Storify::ENDPOINTS[:v1][:publish].should == "/stories/:username/:slug/publish"
87
+ end
76
88
  end
77
89
 
78
90
  context "API Endpoint URI Builder:" do
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.10
4
+ version: 0.0.11
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-12 00:00:00.000000000 Z
11
+ date: 2013-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.6.7
41
+ - !ruby/object:Gem::Dependency
42
+ name: representable
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: 1.7.3
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.7.3
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: nokogiri
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,11 +100,42 @@ executables: []
86
100
  extensions: []
87
101
  extra_rdoc_files: []
88
102
  files:
103
+ - lib/storify/agency/customerinfo.rb
104
+ - lib/storify/agency/customerinfokeys.rb
105
+ - lib/storify/agency/info.rb
106
+ - lib/storify/agency.rb
89
107
  - lib/storify/apierror.rb
108
+ - lib/storify/attribution.rb
90
109
  - lib/storify/client.rb
110
+ - lib/storify/comment.rb
111
+ - lib/storify/coverphoto.rb
112
+ - lib/storify/createdwith.rb
113
+ - lib/storify/data/image.rb
114
+ - lib/storify/data/link.rb
115
+ - lib/storify/data/oembed.rb
116
+ - lib/storify/data/video.rb
117
+ - lib/storify/data.rb
118
+ - lib/storify/dategroup.rb
91
119
  - lib/storify/element.rb
120
+ - lib/storify/features.rb
121
+ - lib/storify/identity.rb
92
122
  - lib/storify/pager.rb
123
+ - lib/storify/quotable.rb
124
+ - lib/storify/settings/colors.rb
125
+ - lib/storify/settings/fonts.rb
126
+ - lib/storify/settings/notifications.rb
127
+ - lib/storify/settings/options.rb
128
+ - lib/storify/settings/style.rb
129
+ - lib/storify/settings/typekit.rb
130
+ - lib/storify/settings.rb
131
+ - lib/storify/source.rb
132
+ - lib/storify/statselement.rb
133
+ - lib/storify/statsembed.rb
93
134
  - lib/storify/story.rb
135
+ - lib/storify/storymeta.rb
136
+ - lib/storify/storystats.rb
137
+ - lib/storify/user.rb
138
+ - lib/storify/userstats.rb
94
139
  - lib/storify.rb
95
140
  - spec/client_auth_spec.rb
96
141
  - spec/client_noauth_spec.rb