poet_frost_API 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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