poet_frost_API 0.0.4 → 0.1.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/poet_frost_API.rb +219 -13
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bc264446329a6b68234216a770d86e31b71475cd
4
- data.tar.gz: 5cdefd445cbbeac411c6d81a31dba838455921e2
3
+ metadata.gz: 0fd2ef7eac58feb61a71421ea6f855cb493d8cd5
4
+ data.tar.gz: cbf63c03b72a3695cf23cdc2890ef83b1a644d6b
5
5
  SHA512:
6
- metadata.gz: 594995c675c54b5724a45c17ec5b4d3d2fab931a3bf21d76f0e0d78c9058a69237f5c9212686a8c11927395cc6ca27547b41faccceaaf7bc57cf7745c8db1213
7
- data.tar.gz: 3a4e6703bc4bcf176a4a3200143b1e995e82ef34c55ebb0efdf89aea03d6c23ba29b36fcb97f916a175abf28c6b410a1876205a6dc3317a36da65ef572f5ed29
6
+ metadata.gz: e9c08eea8d46d6a08f4e4b4e5e1a0b7ec00b815237464e59ab0275416eb2e7e471f4c8a2b1e42d2dbeafb348885736323d47fc22f5eb11b05243a85d7f2a6762
7
+ data.tar.gz: c85aab788432bf0c4e54e4c9744bc88311150bab51725bf507f4749574b401b55f6aef2c8082e699898a5a1394f860d4c24161b18b5c5d8274d31c67834d56cf
@@ -2,28 +2,87 @@ require 'net/http'
2
2
  require 'json'
3
3
  require 'date'
4
4
 
5
+ # Configuration module for use when poet_frost_API is called with include.
6
+ #
7
+ # Include PoetFrostAPI and map the API fields to attributes of the local object.
8
+ # In the example below, the content field is mapped to the local object's
9
+ # body attribute.
10
+ #
11
+ # Usage example:
12
+ # include PoetFrostAPI
13
+ #
14
+ # poet_frost_configure do |config|
15
+ # config.name = :name # Required
16
+ # config.datePublished = :updated_at
17
+ # config.dateCreated = :created_at
18
+ # config.author = :author # Required
19
+ # config.tags = :tags
20
+ # config.content = :body # Required
21
+ # config.work_id = :workid
22
+ # config.api_key = :frost_api_key
23
+ # end
24
+ #
25
+ # API keys currently need to be manually registered at https://frost.po.et/
26
+ #
27
+ # In a Rails model like a blog post, you'll want to have :frost_api_key be a
28
+ # linked attribute belonging to the user making the post, unless it's a single
29
+ # user blog, in which case it might be easier to just set the FROST_TOKEN
30
+ # environment variable.
31
+ module PoetFrostConfig
32
+ attr_accessor :poet_frost_config
33
+
34
+ FROST_API_KEY = ENV['FROST_TOKEN']
35
+ FROST_URI = URI('https://api.frost.po.et/works/')
36
+ FROST_HTTP = Net::HTTP.new(FROST_URI.host, FROST_URI.port)
37
+ FROST_HTTP.use_ssl = true
38
+
39
+ def poet_frost_configuration
40
+ @poet_frost_config ||= OpenStruct.new(
41
+ name: nil,
42
+ datePublished: nil,
43
+ dateCreated: nil,
44
+ author: nil,
45
+ tags: nil,
46
+ content: nil,
47
+ api_key: nil,
48
+ work_id: nil
49
+ )
50
+ end
51
+
52
+ def poet_frost_configure
53
+ yield(poet_frost_configuration)
54
+ end
55
+ end
56
+
5
57
  # To use any of the methods, register an API key at https://frost.po.et/
6
58
  # and save it as the environment variable FROST_TOKEN.
7
- # For the current easiest way to integrate to Rails, see the github readme
8
- # here: https://github.com/minstrel/Poet-Frost-API-Wrapper
9
59
  module PoetFrostAPI
10
60
 
61
+ # When PoetFrostAPI is included, extend the base class with the
62
+ # PoetFrostConfig module.
63
+ def self.included(base)
64
+ base.extend(PoetFrostConfig)
65
+ end
66
+
11
67
  @@api_key = ENV['FROST_TOKEN']
12
68
  @@uri = URI('https://api.frost.po.et/works/')
13
69
  @@http = Net::HTTP.new(@@uri.host, @@uri.port)
14
70
  @@http.use_ssl = true
15
71
 
72
+
16
73
  # Register a work on Po.et.
17
74
  #
18
75
  # Usage:
19
76
  # PoetFrostAPI.create_work(name: 'Work Name',
20
77
  # datePublished: DateTime.now.iso8601,
21
78
  # dateCreated: DateTime.now.iso8601,
22
- # author: 'Author Name'
23
- # tags: 'Tag1, Tag2'
24
- # content: 'Content body'
79
+ # author: 'Author Name',
80
+ # tags: 'Tag1, Tag2',
81
+ # content: 'Content body',
82
+ # api_key: 'API_key'
25
83
  # )
26
84
  #
85
+ # api_key will default to ENV['FROST_TOKEN'] if omitted
27
86
  # datePublished and dateCreated will default to current datetime if omitted
28
87
  # tags will default to blank string if omitted
29
88
  #
@@ -32,13 +91,14 @@ module PoetFrostAPI
32
91
 
33
92
  req = Net::HTTP::Post.new(@@uri.path)
34
93
  req.content_type = 'application/json'
35
- req['token'] = @@api_key
36
94
  args.keep_if { |k, v| [:name,
37
95
  :datePublished,
38
96
  :dateCreated,
39
97
  :author,
40
98
  :tags,
41
- :content].include?(k) }
99
+ :content,
100
+ :api_key].include?(k) }
101
+ req['token'] = args[:api_key] || @@api_key
42
102
  args[:datePublished] ||= DateTime.now.iso8601
43
103
  args[:dateCreated] ||= DateTime.now.iso8601
44
104
  args[:tags] ||= ''
@@ -53,14 +113,17 @@ module PoetFrostAPI
53
113
  # create_work.
54
114
  #
55
115
  # Usage:
56
- # PoetFrostAPI.get_work(workId)
116
+ # PoetFrostAPI.get_work(workId, api_key: 'API_key')
117
+ #
118
+ # api_key will default to ENV['FROST_TOKEN'] if omitted
57
119
  #
58
120
  # Returns a hash with the created fields.
59
- def PoetFrostAPI.get_work(workId)
121
+ def PoetFrostAPI.get_work(workId, args = {})
60
122
  uri = @@uri + workId
61
123
  req = Net::HTTP::Get.new(uri.path)
62
124
  req.content_type = 'application/json'
63
- req['token'] = @@api_key
125
+ args.keep_if { |k, v| [:api_key].include?(k) }
126
+ req['token'] = args[:api_key] || @@api_key
64
127
  res = @@http.request(req)
65
128
  JSON.parse(res.body)
66
129
  rescue => e
@@ -70,17 +133,160 @@ module PoetFrostAPI
70
133
  # Retrieve all works submitted by your Frost API Token.
71
134
  #
72
135
  # Usage:
73
- # PoetFrostAPI.get_all_works
136
+ # PoetFrostAPI.get_all_works(api_key: 'API_key')
137
+ #
138
+ # api_key will default to ENV['FROST_TOKEN'] if omitted
74
139
  #
75
140
  # Returns an array of individual works (hashes)
76
- def PoetFrostAPI.get_all_works
141
+ def PoetFrostAPI.get_all_works(args = {})
77
142
  req = Net::HTTP::Get.new(@@uri.path)
78
143
  req.content_type = 'application/json'
79
- req['token'] = @@api_key
144
+ args.keep_if { |k, v| [:api_key].include?(k) }
145
+ req['token'] = args[:api_key] || @@api_key
80
146
  res = @@http.request(req)
81
147
  JSON.parse(res.body)
82
148
  rescue => e
83
149
  "failed #{e}"
84
150
  end
85
151
 
152
+ # Post the work to Po.et
153
+ # Usage example:
154
+ # @blog_post.post_to_poet
155
+ #
156
+ # This will post the object's linked fields to Po.et (see the module
157
+ # PoetFrostConfig for configuration)
158
+ #
159
+ # If the class is an ActiveRecord object, and the work_id field is present,
160
+ # the object will be updated with the work_id returned (without altering
161
+ # timestamps). Otherwise, the method will return the work_id.
162
+ #
163
+ # If the configuration includes an API key field, that will be used when
164
+ # posting. Otherwise, it will look for and use the environment variable
165
+ # FROST_TOKEN.
166
+ #
167
+ # Dates will default to the current time if not set in config.
168
+ def post_to_poet
169
+ req = Net::HTTP::Post.new(PoetFrostConfig::FROST_URI.path)
170
+ req.content_type = 'application/json'
171
+ args = self.class.poet_frost_config.to_h
172
+ # Go through the config args and pass them on appropriately.
173
+ args.each do |k,v|
174
+ # Ignore undefined values
175
+ if v == nil
176
+ args.delete(k)
177
+ # If the value is a model field, instance_eval it so we can pull in the actual value from the object.
178
+ elsif self.class.method_defined? v
179
+ # Check if the field is a date field and, if so, do .iso8601 on it.
180
+ # If not, pass the field value in as-is.
181
+ if self.instance_eval(v.to_s).class.method_defined? :iso8601
182
+ args[k] = self.instance_eval(v.to_s).iso8601
183
+ else
184
+ args[k] = self.instance_eval(v.to_s)
185
+ end
186
+ # If it isn't a model field, pass the value in directly (as a string)
187
+ # TODO test this
188
+ else
189
+ args[k] = v.to_s
190
+ end
191
+ end
192
+ # Can do away with this after the api starts accepting arbitrary fields
193
+ # Replace it with delete_if to take out work_id.
194
+ args.keep_if { |k, v| [:name,
195
+ :datePublished,
196
+ :dateCreated,
197
+ :author,
198
+ :tags,
199
+ :content,
200
+ :api_key].include?(k) }
201
+ # Use the referenced model field, if set. Else use the string value, if it exists. Else use
202
+ # the environment variable.
203
+ # TODO test, such as with a Blog model that belongs_to User, and has user.frost_key set in the config.
204
+ frost_config = self.class.poet_frost_config
205
+ req['token'] = if self.class.method_defined? frost_config[:api_key].to_s
206
+ self.instance_eval(frost_config[:api_key])
207
+ elsif frost_config[:api_key]
208
+ frost_config[:api_key]
209
+ else
210
+ PoetFrostConfig::FROST_API_KEY
211
+ end
212
+ args.delete(:api_key) if args[:api_key]
213
+ args[:datePublished] ||= DateTime.now.iso8601
214
+ args[:dateCreated] ||= DateTime.now.iso8601
215
+ args[:tags] ||= ''
216
+ req.body = args.to_json
217
+ res = PoetFrostConfig::FROST_HTTP.request(req)
218
+ workid = JSON.parse(res.body)['workId']
219
+ # Check if we're running ActiveRecord, and post_to_poet is being run on an
220
+ # ActiveRecord object.
221
+ if defined?(ActiveRecord::Base) && self.is_a?(ActiveRecord::Base)
222
+ # Check if work_id is defined
223
+ if self.class.poet_frost_config.work_id
224
+ # Update the work_id column with the workId, preserve original timestamps.
225
+ work_id_column = self.class.poet_frost_config.work_id
226
+ self.update_column(work_id_column, workid)
227
+ end
228
+ # If we're not running ActiveRecord, return the workid.
229
+ else
230
+ workid
231
+ end
232
+ rescue => e
233
+ "failed #{e}"
234
+ end
235
+
236
+ # Retrieve a specific work from Po.et, using the workId returned from
237
+ # create_work.
238
+ #
239
+ # Usage example:
240
+ # @blog_post.get_work
241
+ #
242
+ # Returns a hash with the created fields.
243
+ def get_work
244
+ frost_config = self.class.poet_frost_config
245
+ work_id_column = frost_config.work_id
246
+ uri = PoetFrostConfig::FROST_URI + self[work_id_column].to_s
247
+ req = Net::HTTP::Get.new(uri.path)
248
+ req.content_type = 'application/json'
249
+ # Use the referenced model field, if set. Else use the string value, if it exists. Else use
250
+ # the environment variable.
251
+ # TODO test, such as with a Blog model that belongs_to User, and has user.frost_key set in the config.
252
+ req['token'] = if self.class.method_defined? frost_config[:api_key].to_s
253
+ self.instance_eval(frost_config[:api_key])
254
+ elsif frost_config[:api_key]
255
+ frost_config[:api_key]
256
+ else
257
+ PoetFrostConfig::FROST_API_KEY
258
+ end
259
+ res = PoetFrostConfig::FROST_HTTP.request(req)
260
+ res.body
261
+ rescue => e
262
+ "failed #{e}"
263
+ end
264
+
265
+ # Retrieve all works submitted by your Frost API Token.
266
+ #
267
+ # Usage example:
268
+ # @user.get_all_works
269
+ #
270
+ # Returns an array of individual works (hashes)
271
+ def get_all_works
272
+ frost_config = self.class.poet_frost_config
273
+ req = Net::HTTP::Get.new(PoetFrostConfig::FROST_URI.path)
274
+ req.content_type = 'application/json'
275
+ # Use the referenced model field, if set. Else use the string value, if it exists. Else use
276
+ # the environment variable.
277
+ # TODO test, such as with a Blog model that belongs_to User, and has user.frost_key set in the config.
278
+ req['token'] = if self.class.method_defined? frost_config[:api_key].to_s
279
+ self.instance_eval(frost_config[:api_key])
280
+ elsif frost_config[:api_key]
281
+ frost_config[:api_key]
282
+ else
283
+ PoetFrostConfig::FROST_API_KEY
284
+ end
285
+ res = PoetFrostConfig::FROST_HTTP.request(req)
286
+ res.body
287
+ rescue => e
288
+ "failed #{e}"
289
+ end
290
+
86
291
  end
292
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: poet_frost_API
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Donald Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-12 00:00:00.000000000 Z
11
+ date: 2018-03-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A Ruby wrapper for the Po.et Frost API
14
14
  email: donald@sinbissquare.com