outboxer 0.1.11 → 1.0.0.pre.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -47
  3. data/db/migrate/create_outboxer_exceptions.rb +20 -0
  4. data/db/migrate/create_outboxer_frames.rb +16 -0
  5. data/db/migrate/create_outboxer_messages.rb +19 -0
  6. data/generators/message_publisher_generator.rb +11 -0
  7. data/generators/{outboxer/install_generator.rb → schema_generator.rb} +4 -9
  8. data/lib/outboxer/database.rb +44 -0
  9. data/lib/outboxer/logger.rb +17 -0
  10. data/lib/outboxer/message.rb +262 -13
  11. data/lib/outboxer/messages.rb +232 -0
  12. data/lib/outboxer/models/exception.rb +15 -0
  13. data/lib/outboxer/models/frame.rb +14 -0
  14. data/lib/outboxer/models/message.rb +46 -0
  15. data/lib/outboxer/models.rb +3 -0
  16. data/lib/outboxer/railtie.rb +2 -4
  17. data/lib/outboxer/version.rb +1 -1
  18. data/lib/outboxer/web/public/css/bootstrap-icons.css +2078 -0
  19. data/lib/outboxer/web/public/css/bootstrap-icons.min.css +5 -0
  20. data/lib/outboxer/web/public/css/bootstrap.css +12071 -0
  21. data/lib/outboxer/web/public/css/bootstrap.min.css +6 -0
  22. data/lib/outboxer/web/public/css/fonts/bootstrap-icons.woff +0 -0
  23. data/lib/outboxer/web/public/css/fonts/bootstrap-icons.woff2 +0 -0
  24. data/lib/outboxer/web/public/favicon.svg +3 -0
  25. data/lib/outboxer/web/public/js/bootstrap.bundle.js +6306 -0
  26. data/lib/outboxer/web/public/js/bootstrap.bundle.min.js +7 -0
  27. data/lib/outboxer/web/views/error.erb +63 -0
  28. data/lib/outboxer/web/views/home.erb +172 -0
  29. data/lib/outboxer/web/views/layout.erb +80 -0
  30. data/lib/outboxer/web/views/message.erb +81 -0
  31. data/lib/outboxer/web/views/messages/index.erb +60 -0
  32. data/lib/outboxer/web/views/messages/show.erb +31 -0
  33. data/lib/outboxer/web/views/messages.erb +262 -0
  34. data/lib/outboxer/web.rb +430 -0
  35. data/lib/outboxer.rb +9 -5
  36. metadata +279 -22
  37. data/.rspec +0 -3
  38. data/.rubocop.yml +0 -229
  39. data/CHANGELOG.md +0 -5
  40. data/CODE_OF_CONDUCT.md +0 -84
  41. data/LICENSE.txt +0 -21
  42. data/Rakefile +0 -12
  43. data/generators/outboxer/templates/bin/publisher.rb +0 -11
  44. data/generators/outboxer/templates/migrations/create_outboxer_exceptions.rb +0 -15
  45. data/generators/outboxer/templates/migrations/create_outboxer_messages.rb +0 -13
  46. data/lib/outboxer/exception.rb +0 -9
  47. data/lib/outboxer/outboxable.rb +0 -21
  48. data/lib/outboxer/publisher.rb +0 -149
  49. data/lib/tasks/gem.rake +0 -58
  50. data/outboxer.gemspec +0 -33
  51. data/sig/outboxer.rbs +0 -19
@@ -0,0 +1,430 @@
1
+ require 'bundler/setup'
2
+
3
+ require 'outboxer'
4
+ require 'sinatra/base'
5
+ require 'kaminari'
6
+ require 'uri'
7
+ require 'rack/flash'
8
+
9
+ require 'pry-byebug'
10
+
11
+ environment = ENV['RAILS_ENV'] || 'development'
12
+ config = Outboxer::Database.config(environment: environment)
13
+ Outboxer::Database.connect(config: config.merge('pool' => 5))
14
+
15
+ module Outboxer
16
+ class Web < Sinatra::Base
17
+ use Rack::Flash
18
+ set :views, File.expand_path('../web/views', __FILE__)
19
+ set :public_folder, File.expand_path('../web/public', __FILE__)
20
+ set :show_exceptions, false
21
+
22
+ helpers do
23
+ def outboxer_path(path)
24
+ "#{request.script_name}#{path}"
25
+ end
26
+ end
27
+
28
+ error StandardError do
29
+ error = env['sinatra.error']
30
+ status 500
31
+
32
+ puts "Error: #{error.class.name} - #{error.message}"
33
+
34
+ erb :error, locals: { error: error }, layout: false
35
+ end
36
+
37
+ get '/' do
38
+ denormalised_params = denormalise_params(
39
+ status: nil,
40
+ sort: :updated_at,
41
+ order: :asc,
42
+ page: 1,
43
+ per_page: params[:per_page]&.to_i)
44
+
45
+ message_status_counts = Messages.counts_by_status
46
+
47
+ messages_publishing = Messages.list(
48
+ status: :publishing,
49
+ sort: :updated_at,
50
+ order: :asc,
51
+ page: 1,
52
+ per_page: denormalised_params[:per_page])
53
+
54
+ messages_publishing_link = outboxer_path('/messages' + normalise_params(
55
+ status: :publishing,
56
+ sort: denormalised_params[:sort],
57
+ order: denormalised_params[:order],
58
+ page: denormalised_params[:page],
59
+ per_page: denormalised_params[:per_page]))
60
+
61
+ messages_queued = Messages.list(
62
+ status: :queued,
63
+ sort: :updated_at,
64
+ order: :asc,
65
+ page: 1,
66
+ per_page: denormalised_params[:per_page])
67
+
68
+ messages_queued_link = outboxer_path('/messages' + normalise_params(
69
+ status: :queued,
70
+ sort: denormalised_params[:sort],
71
+ order: denormalised_params[:order],
72
+ page: denormalised_params[:page],
73
+ per_page: denormalised_params[:per_page]))
74
+
75
+ messages_backlogged = Messages.list(
76
+ status: :backlogged,
77
+ sort: :updated_at,
78
+ order: :asc,
79
+ page: 1,
80
+ per_page: denormalised_params[:per_page])
81
+
82
+ messages_backlogged_link = outboxer_path('/messages' + normalise_params(
83
+ status: :backlogged,
84
+ sort: denormalised_params[:sort],
85
+ order: denormalised_params[:order],
86
+ page: denormalised_params[:page],
87
+ per_page: denormalised_params[:per_page]))
88
+
89
+ erb :home, locals: {
90
+ denormalised_params: denormalised_params,
91
+ message_status_counts: message_status_counts,
92
+ messages_publishing: messages_publishing,
93
+ messages_publishing_link: messages_publishing_link,
94
+ messages_queued: messages_queued,
95
+ messages_queued_link: messages_queued_link,
96
+ messages_backlogged: messages_backlogged,
97
+ messages_backlogged_link: messages_backlogged_link
98
+ }
99
+ end
100
+
101
+ post '/update_per_page' do
102
+ denormalised_params = denormalise_params(
103
+ status: params[:status],
104
+ sort: params[:sort],
105
+ order: params[:order],
106
+ page: params[:page]&.to_i,
107
+ per_page: params[:per_page]&.to_i)
108
+
109
+ normalised_params = normalise_params(
110
+ status: denormalised_params[:status],
111
+ sort: denormalised_params[:sort],
112
+ order: denormalised_params[:order],
113
+ page: denormalised_params[:page],
114
+ per_page: denormalised_params[:per_page])
115
+
116
+ redirect outboxer_path(normalised_params)
117
+ end
118
+
119
+ get '/messages' do
120
+ message_status_counts = Messages.counts_by_status
121
+
122
+ denormalised_params = denormalise_params(
123
+ status: params[:status],
124
+ sort: params[:sort],
125
+ order: params[:order],
126
+ page: params[:page]&.to_i,
127
+ per_page: params[:per_page]&.to_i)
128
+
129
+ normalised_params = normalise_params(
130
+ status: denormalised_params[:status],
131
+ sort: denormalised_params[:sort],
132
+ order: denormalised_params[:order],
133
+ page: denormalised_params[:page]&.to_i,
134
+ per_page: denormalised_params[:per_page]&.to_i)
135
+
136
+ paginated_messages = Messages.list(
137
+ status: denormalised_params[:status],
138
+ sort: denormalised_params[:sort],
139
+ order: denormalised_params[:order],
140
+ page: denormalised_params[:page]&.to_i,
141
+ per_page: denormalised_params[:per_page]&.to_i)
142
+
143
+ pagination = generate_pagination(
144
+ current_page: paginated_messages[:current_page],
145
+ total_pages: paginated_messages[:total_pages],
146
+ params: denormalised_params)
147
+
148
+ erb :messages, locals: {
149
+ message_status_counts: message_status_counts,
150
+ messages: paginated_messages[:messages],
151
+ headers: generate_headers(params: denormalised_params),
152
+ pagination: pagination,
153
+ denormalised_params: denormalised_params,
154
+ normalised_params: normalised_params,
155
+ per_page: params[:per_page]&.to_i || Messages::LIST_PER_PAGE_DEFAULT
156
+ }
157
+ end
158
+
159
+ HEADERS = {
160
+ 'id' => 'Id',
161
+ 'status' => 'Status',
162
+ 'messageable' => 'Messageable',
163
+ 'updated_at' => 'Updated At',
164
+ 'created_at' => 'Created At'
165
+ }
166
+
167
+ def generate_pagination(current_page:, total_pages:, params:)
168
+ previous_page = nil
169
+ pages = []
170
+ next_page = nil
171
+
172
+ if current_page > 1
173
+ previous_page = {
174
+ text: 'Previous',
175
+ href: outboxer_path("/messages" + normalise_params(
176
+ status: params[:status], sort: params[:sort], order: params[:order],
177
+ page: current_page - 1, per_page: params[:per_page]))
178
+ }
179
+ end
180
+
181
+ pages = (([current_page - 4, 1].max)..([current_page + 4, total_pages].min)).map do |page|
182
+ {
183
+ text: page,
184
+ href: outboxer_path("/messages" + normalise_params(
185
+ status: params[:status], sort: params[:sort], order: params[:order], page: page,
186
+ per_page: params[:per_page])),
187
+ is_active: current_page == page
188
+ }
189
+ end
190
+
191
+ if current_page < total_pages
192
+ next_page = {
193
+ text: 'Next',
194
+ href: outboxer_path("/messages" + normalise_params(
195
+ status: params[:status], sort: params[:sort], order: params[:order],
196
+ page: current_page + 1, per_page: params[:per_page]))
197
+ }
198
+ end
199
+
200
+ { previous_page: previous_page, pages: pages, next_page: next_page }
201
+ end
202
+
203
+ def generate_headers(params:)
204
+ HEADERS.map do |header_key, header_text|
205
+ if params[:sort] == header_key
206
+ if params[:order] == 'asc'
207
+ {
208
+ text: header_text,
209
+ icon_class: 'bi bi-arrow-up',
210
+ href: outboxer_path('/messages' + normalise_params(
211
+ status: params[:status],
212
+ order: 'desc',
213
+ sort: header_key,
214
+ page: 1,
215
+ per_page: params[:per_page]
216
+ ))
217
+ }
218
+ else
219
+ {
220
+ text: header_text,
221
+ icon_class: 'bi bi-arrow-down',
222
+ href: outboxer_path('/messages' + normalise_params(
223
+ status: params[:status],
224
+ order: 'asc',
225
+ sort: header_key,
226
+ page: 1,
227
+ per_page: params[:per_page]
228
+ ))
229
+ }
230
+ end
231
+ else
232
+ {
233
+ text: header_text,
234
+ icon_class: '',
235
+ href: outboxer_path('/messages' + normalise_params(
236
+ status: params[:status],
237
+ order: 'asc',
238
+ sort: header_key,
239
+ page: 1,
240
+ per_page: params[:per_page]))
241
+ }
242
+ end
243
+ end
244
+ end
245
+
246
+ def denormalise_params(status: Messages::LIST_STATUS_DEFAULT,
247
+ sort: Messages::LIST_SORT_DEFAULT,
248
+ order: Messages::LIST_ORDER_DEFAULT,
249
+ page: Messages::LIST_PAGE_DEFAULT,
250
+ per_page: Messages::LIST_PER_PAGE_DEFAULT)
251
+ {
252
+ status: params[:status] || Messages::LIST_STATUS_DEFAULT,
253
+ sort: params[:sort] || Messages::LIST_SORT_DEFAULT,
254
+ order: params[:order] || Messages::LIST_ORDER_DEFAULT,
255
+ page: params[:page]&.to_i || Messages::LIST_PAGE_DEFAULT,
256
+ per_page: params[:per_page]&.to_i || Messages::LIST_PER_PAGE_DEFAULT
257
+ }
258
+ end
259
+
260
+ def normalise_params(status: Messages::LIST_STATUS_DEFAULT,
261
+ sort: Messages::LIST_SORT_DEFAULT,
262
+ order: Messages::LIST_ORDER_DEFAULT,
263
+ page: Messages::LIST_PAGE_DEFAULT,
264
+ per_page: Messages::LIST_PER_PAGE_DEFAULT)
265
+ normalised_params = {
266
+ status: status == Messages::LIST_STATUS_DEFAULT ? nil : status,
267
+ sort: sort == Messages::LIST_SORT_DEFAULT ? nil : sort,
268
+ order: order == Messages::LIST_ORDER_DEFAULT ? nil : order,
269
+ page: page == Messages::LIST_PAGE_DEFAULT ? nil : page,
270
+ per_page: per_page == Messages::LIST_PER_PAGE_DEFAULT ? nil : per_page
271
+ }.compact
272
+
273
+ normalised_params.empty? ? '' : "?#{URI.encode_www_form(normalised_params)}"
274
+ end
275
+
276
+ post '/messages/update' do
277
+ ids = params[:selected_ids].map(&:to_i)
278
+
279
+ denormalised_params = denormalise_params(
280
+ status: params[:status],
281
+ sort: params[:sort],
282
+ order: params[:order],
283
+ page: params[:page]&.to_i,
284
+ per_page: params[:per_page]&.to_i)
285
+
286
+ normalised_params = normalise_params(
287
+ status: denormalised_params[:status],
288
+ sort: denormalised_params[:sort],
289
+ order: denormalised_params[:order],
290
+ page: denormalised_params[:page],
291
+ per_page: denormalised_params[:per_page])
292
+
293
+ result = case params[:action]
294
+ when 'republish_selected'
295
+ result = Messages.republish_selected(ids: ids)
296
+
297
+ message_text = result[:republished_count] == 1 ? 'message' : 'messages'
298
+
299
+ if result[:republished_count] > 0
300
+ flash[:primary] = "Backlogged #{result[:republished_count]} #{message_text}"
301
+ end
302
+
303
+ unless result[:not_republished_ids].empty?
304
+ flash[:warning] = "Could not republish #{message_text} with ids " +
305
+ "#{result[:not_republished_ids].join(', ')}"
306
+ end
307
+
308
+ result
309
+ when 'delete_selected'
310
+ result = Messages.delete_selected(ids: ids)
311
+
312
+ message_text = result[:deleted_count] == 1 ? 'message' : 'messages'
313
+
314
+ if result[:deleted_count] > 0
315
+ flash[:primary] = "Deleted #{result[:deleted_count]} #{message_text}"
316
+ end
317
+
318
+ unless result[:not_deleted_ids].empty?
319
+ flash[:warning] = "Could not delete #{message_text} with ids " +
320
+ "#{result[:not_deleted_ids].join(', ')}"
321
+ end
322
+
323
+ result
324
+ else
325
+ raise "Unknown action: #{params[:action]}"
326
+ end
327
+
328
+ redirect to("/messages#{normalised_params}")
329
+ end
330
+
331
+ post '/messages/republish_all' do
332
+ denormalised_params = denormalise_params(
333
+ status: params[:status],
334
+ sort: params[:sort],
335
+ order: params[:order],
336
+ page: params[:page]&.to_i,
337
+ per_page: params[:per_page]&.to_i)
338
+
339
+ normalised_params = normalise_params(
340
+ status: denormalised_params[:status],
341
+ sort: denormalised_params[:sort],
342
+ order: denormalised_params[:order],
343
+ page: denormalised_params[:page],
344
+ per_page: denormalised_params[:per_page])
345
+
346
+ result = Messages.republish_all(status: denormalised_params[:status])
347
+
348
+ message_text = result[:republished_count] == 1 ? 'message' : 'messages'
349
+ flash[:primary] = "#{result[:republished_count]} #{message_text} have been backlogged"
350
+
351
+ redirect to("/messages#{normalised_params}")
352
+ end
353
+
354
+ post '/messages/delete_all' do
355
+ denormalised_params = denormalise_params(
356
+ status: params[:status],
357
+ sort: params[:sort],
358
+ order: params[:order],
359
+ page: params[:page]&.to_i,
360
+ per_page: params[:per_page]&.to_i)
361
+
362
+ normalised_params = normalise_params(
363
+ status: denormalised_params[:status],
364
+ sort: denormalised_params[:sort],
365
+ order: denormalised_params[:order],
366
+ page: denormalised_params[:page],
367
+ per_page: denormalised_params[:per_page])
368
+
369
+ result = Messages.delete_all(status: denormalised_params[:status])
370
+
371
+ message_text = result[:deleted_count] == 1 ? 'message' : 'messages'
372
+ flash[:primary] = "#{result[:deleted_count]} #{message_text} have been deleted"
373
+
374
+ redirect to("/messages#{normalised_params}")
375
+ end
376
+
377
+ post '/messages/update_per_page' do
378
+ denormalised_params = denormalise_params(
379
+ status: params[:status],
380
+ sort: params[:sort],
381
+ order: params[:order],
382
+ page: params[:page]&.to_i,
383
+ per_page: params[:per_page]&.to_i)
384
+
385
+ normalised_params = normalise_params(
386
+ status: denormalised_params[:status],
387
+ sort: denormalised_params[:sort],
388
+ order: denormalised_params[:order],
389
+ page: denormalised_params[:page],
390
+ per_page: denormalised_params[:per_page])
391
+
392
+ redirect to("/messages#{normalised_params}")
393
+ end
394
+
395
+ get '/message/:id' do
396
+ message_status_counts = Messages.counts_by_status
397
+
398
+ message = Message.find_by_id(id: params[:id])
399
+
400
+ denormalised_params = denormalise_params(
401
+ status: params[:status],
402
+ sort: params[:sort],
403
+ order: params[:order],
404
+ page: params[:page]&.to_i,
405
+ per_page: params[:per_page]&.to_i)
406
+
407
+ erb :message, locals: {
408
+ message_status_counts: message_status_counts,
409
+ denormalised_params: denormalised_params,
410
+ message: message
411
+ }
412
+ end
413
+
414
+ post '/message/:id/republish' do
415
+ Message.republish(id: params[:id])
416
+
417
+ flash[:primary] = "Message #{params[:id]} was backlogged"
418
+
419
+ redirect to('/messages')
420
+ end
421
+
422
+ post '/message/:id/delete' do
423
+ Message.delete(id: params[:id])
424
+
425
+ flash[:primary] = "Message #{params[:id]} was deleted"
426
+
427
+ redirect to('/messages')
428
+ end
429
+ end
430
+ end
data/lib/outboxer.rb CHANGED
@@ -1,13 +1,17 @@
1
- require "active_support"
1
+ require "active_record"
2
+ require "kaminari"
2
3
 
3
4
  require_relative "outboxer/version"
4
5
  require_relative "outboxer/railtie" if defined?(Rails)
5
6
 
6
- require_relative "outboxer/outboxable"
7
- require_relative "outboxer/message"
8
- require_relative "outboxer/exception"
7
+ require_relative "outboxer/models/frame"
8
+ require_relative "outboxer/models/exception"
9
+ require_relative "outboxer/models/message"
9
10
 
10
- require_relative "outboxer/publisher"
11
+ require_relative "outboxer/logger"
12
+ require_relative "outboxer/database"
13
+ require_relative "outboxer/message"
14
+ require_relative "outboxer/messages"
11
15
 
12
16
  module Outboxer
13
17
  end