noticent 0.0.1.pre.pre → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile.lock +58 -0
- data/LICENSE +201 -0
- data/README.md +77 -12
- data/config.ru +9 -0
- data/lib/noticent.rb +2 -1
- data/lib/noticent/active_record_opt_in_provider.rb +10 -1
- data/lib/noticent/channel.rb +24 -31
- data/lib/noticent/config.rb +76 -17
- data/lib/noticent/definitions/alert.rb +80 -6
- data/lib/noticent/definitions/channel.rb +7 -2
- data/lib/noticent/definitions/scope.rb +10 -6
- data/lib/noticent/dispatcher.rb +16 -10
- data/lib/noticent/version.rb +1 -1
- data/lib/noticent/view.rb +16 -14
- data/noticent.gemspec +25 -21
- data/testing/channels/email.rb +1 -0
- data/testing/channels/exclusive.rb +9 -0
- data/testing/channels/simple.rb +9 -0
- data/testing/payloads/comment_payload.rb +10 -0
- data/testing/payloads/post_payload.rb +44 -0
- data/testing/views/email/some_event.html.erb +3 -0
- data/testing/views/email/some_event.txt.erb +2 -0
- data/testing/views/layouts/layout.html.erb +1 -1
- data/testing/views/simple/default.html.erb +1 -0
- metadata +66 -6
@@ -9,11 +9,17 @@ module Noticent
|
|
9
9
|
attr_reader :options
|
10
10
|
|
11
11
|
def initialize(config, name, group: :default, klass: nil)
|
12
|
+
raise BadConfiguration, 'name should be a symbol' unless name.is_a? Symbol
|
13
|
+
raise BadConfiguration, '\'_any_\' is a reserved channel name' if name == :_any_
|
14
|
+
raise BadConfiguration, '\'_none_\' is a reserved channel name' if name == :_none_
|
15
|
+
|
12
16
|
@name = name
|
13
17
|
@group = group
|
14
18
|
@config = config
|
15
19
|
|
16
|
-
|
20
|
+
sub_module = @config.use_sub_modules ? '::Channels::' : '::'
|
21
|
+
suggested_class_name = @config.base_module_name + sub_module + name.to_s.camelize
|
22
|
+
|
17
23
|
@klass = klass.nil? ? suggested_class_name.camelize.constantize : klass
|
18
24
|
rescue NameError
|
19
25
|
raise Noticent::BadConfiguration, "no class found for #{suggested_class_name}"
|
@@ -37,7 +43,6 @@ module Noticent
|
|
37
43
|
rescue ArgumentError
|
38
44
|
raise Noticent::BadConfiguration, "channel #{@klass} initializer arguments are mismatching."
|
39
45
|
end
|
40
|
-
|
41
46
|
end
|
42
47
|
end
|
43
48
|
end
|
@@ -5,22 +5,26 @@ module Noticent
|
|
5
5
|
class Scope
|
6
6
|
attr_reader :name
|
7
7
|
attr_reader :payload_class
|
8
|
+
attr_reader :check_constructor
|
8
9
|
|
9
|
-
def initialize(config, name, payload_class: nil)
|
10
|
+
def initialize(config, name, payload_class: nil, check_constructor: true)
|
10
11
|
@config = config
|
11
12
|
@name = name
|
12
|
-
|
13
|
-
|
13
|
+
@check_constructor = check_constructor
|
14
|
+
|
15
|
+
sub_module = @config.use_sub_modules ? '::Payloads::' : '::'
|
16
|
+
suggested_name = config.base_module_name + sub_module + "#{name.capitalize}Payload"
|
17
|
+
@payload_class = payload_class.nil? ? suggested_name.constantize : payload_class
|
14
18
|
rescue NameError
|
15
|
-
raise BadConfiguration, "scope #{
|
19
|
+
raise BadConfiguration, "scope #{suggested_name} class not found"
|
16
20
|
end
|
17
21
|
|
18
|
-
def alert(name, &block)
|
22
|
+
def alert(name, constructor_name: nil, &block)
|
19
23
|
alerts = @config.instance_variable_get(:@alerts) || {}
|
20
24
|
|
21
25
|
raise BadConfiguration, "alert '#{name}' already defined" if alerts.include? name
|
22
26
|
|
23
|
-
alert = Noticent::Definitions::Alert.new(@config, name: name, scope: self)
|
27
|
+
alert = Noticent::Definitions::Alert.new(@config, name: name, scope: self, constructor_name: constructor_name.nil? ? name : constructor_name)
|
24
28
|
@config.hooks&.run(:pre_alert_registration, alert)
|
25
29
|
alert.instance_eval(&block) if block_given?
|
26
30
|
@config.hooks&.run(:post_alert_registration, alert)
|
data/lib/noticent/dispatcher.rb
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module Noticent
|
4
4
|
class Dispatcher
|
5
|
-
def initialize(config, alert_name, payload,
|
5
|
+
def initialize(config, alert_name, payload, configuration = {})
|
6
6
|
@config = config
|
7
7
|
@alert_name = alert_name
|
8
8
|
@payload = payload
|
9
|
-
@
|
9
|
+
@configuration = configuration
|
10
10
|
|
11
11
|
validate!
|
12
12
|
|
@@ -34,8 +34,8 @@ module Noticent
|
|
34
34
|
|
35
35
|
# only returns recipients that have opted-in for this channel
|
36
36
|
def filter_recipients(recipients, channel)
|
37
|
-
raise ArgumentError,
|
38
|
-
raise ArgumentError,
|
37
|
+
raise ArgumentError, "channel should be a string or symbol" unless channel.is_a?(String) || channel.is_a?(Symbol)
|
38
|
+
raise ArgumentError, "recipients is nil" if recipients.nil?
|
39
39
|
|
40
40
|
recipients.select { |recipient| @config.opt_in_provider.opted_in?(recipient_id: recipient.id, scope: scope.name, entity_id: @entity_id, alert_name: alert.name, channel_name: channel) }
|
41
41
|
end
|
@@ -43,9 +43,15 @@ module Noticent
|
|
43
43
|
def dispatch
|
44
44
|
notifiers.values.each do |notifier|
|
45
45
|
recs = recipients(notifier.recipient)
|
46
|
-
|
46
|
+
notifier.applicable_channels.each do |channel|
|
47
47
|
to_send = filter_recipients(recs, channel.name)
|
48
|
-
|
48
|
+
|
49
|
+
if to_send.count == 0 && @config.skip_alert_with_no_subscribers
|
50
|
+
Noticent.configuration.logger.info "Skipping alert #{alert.name} as they are no subscribers"
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
channel_instance = channel.instance(@config, to_send, @payload, @configuration)
|
49
55
|
begin
|
50
56
|
raise Noticent::BadConfiguration, "channel #{channel.name} (#{channel.klass}) doesn't have a method called #{alert.name}" unless channel_instance.respond_to? alert.name
|
51
57
|
|
@@ -54,7 +60,7 @@ module Noticent
|
|
54
60
|
# log and move on
|
55
61
|
raise if @config.halt_on_error
|
56
62
|
|
57
|
-
Noticent.logger.error e
|
63
|
+
Noticent.configuration.logger.error e
|
58
64
|
end
|
59
65
|
end
|
60
66
|
end
|
@@ -63,12 +69,12 @@ module Noticent
|
|
63
69
|
private
|
64
70
|
|
65
71
|
def validate!
|
66
|
-
raise Noticent::BadConfiguration,
|
72
|
+
raise Noticent::BadConfiguration, "no base_dir defined" if @config.base_dir.nil?
|
67
73
|
raise Noticent::MissingConfiguration if @config.nil?
|
68
74
|
raise Noticent::BadConfiguration if @config.alerts.nil?
|
69
75
|
raise Noticent::InvalidAlert, "no alert #{@alert_name} found" if @config.alerts[@alert_name].nil?
|
70
|
-
raise ::ArgumentError,
|
71
|
-
raise ::ArgumentError,
|
76
|
+
raise ::ArgumentError, "payload is nil" if @payload.nil?
|
77
|
+
raise ::ArgumentError, "alert is not a symbol" unless @alert_name.is_a?(Symbol)
|
72
78
|
raise Noticent::BadConfiguration, "payload (#{@payload.class}) doesn't belong to this scope (#{scope.name}) as it requires #{scope.payload_class}" unless !scope.payload_class.nil? && @payload.is_a?(scope.payload_class)
|
73
79
|
raise Noticent::BadConfiguration, "payload doesn't have a #{scope.name}_id method" unless @payload.respond_to?("#{scope.name}_id")
|
74
80
|
end
|
data/lib/noticent/version.rb
CHANGED
data/lib/noticent/view.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "yaml"
|
4
4
|
|
5
5
|
module Noticent
|
6
6
|
class View
|
@@ -16,38 +16,40 @@ module Noticent
|
|
16
16
|
attr_reader :raw_data # frontmatter in their raw (pre render) format
|
17
17
|
attr_reader :rendered_data # frontmatter rendered in string format
|
18
18
|
|
19
|
-
def initialize(filename, template_filename:
|
19
|
+
def initialize(filename, template_filename: "", channel:)
|
20
20
|
raise ViewNotFound, "view #{filename} not found" unless File.exist?(filename)
|
21
|
-
raise ViewNotFound, "template #{template_filename} not found" if template_filename !=
|
22
|
-
raise ArgumentError,
|
21
|
+
raise ViewNotFound, "template #{template_filename} not found" if template_filename != "" && !File.exist?(template_filename)
|
22
|
+
raise ArgumentError, "channel is nil" if channel.nil?
|
23
23
|
|
24
24
|
@filename = filename
|
25
25
|
@view_content = File.read(filename)
|
26
|
-
@template_content = template_filename !=
|
27
|
-
@template_filename = template_filename !=
|
26
|
+
@template_content = template_filename != "" ? File.read(template_filename) : "<%= @content %>"
|
27
|
+
@template_filename = template_filename != "" ? template_filename : ""
|
28
28
|
@channel = channel
|
29
29
|
end
|
30
30
|
|
31
|
-
def process
|
31
|
+
def process(context)
|
32
32
|
parse
|
33
|
-
|
34
|
-
render_data
|
33
|
+
render_data(context)
|
35
34
|
read_data
|
35
|
+
# TODO this is nasty. we need to refactor to have an independent render context which somehow merges the binding with the channel.
|
36
|
+
@channel.data = @data
|
37
|
+
render_content(context)
|
36
38
|
end
|
37
39
|
|
38
40
|
private
|
39
41
|
|
40
|
-
def render_content
|
41
|
-
@content = @channel.render_within_context(@template_content, @
|
42
|
+
def render_content(context)
|
43
|
+
@content = @channel.render_within_context(template: @template_content, content: @raw_content, context: context)
|
42
44
|
end
|
43
45
|
|
44
|
-
def render_data
|
46
|
+
def render_data(context)
|
45
47
|
if @raw_data.nil?
|
46
48
|
@rendered_data = nil
|
47
49
|
return
|
48
50
|
end
|
49
51
|
|
50
|
-
@rendered_data = @channel.render_within_context(nil, @raw_data)
|
52
|
+
@rendered_data = @channel.render_within_context(template: nil, content: @raw_data, context: context)
|
51
53
|
end
|
52
54
|
|
53
55
|
def parse
|
@@ -70,7 +72,7 @@ module Noticent
|
|
70
72
|
if @raw_data.nil?
|
71
73
|
@data = nil
|
72
74
|
else
|
73
|
-
raise ArgumentError,
|
75
|
+
raise ArgumentError, "read_data was called before rendering" if @rendered_data.nil?
|
74
76
|
|
75
77
|
data = ::YAML.safe_load(@rendered_data)
|
76
78
|
@data = data.deep_symbolize_keys
|
data/noticent.gemspec
CHANGED
@@ -1,36 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require
|
5
|
+
require "noticent/version"
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name
|
9
|
-
spec.version
|
10
|
-
spec.authors
|
11
|
-
spec.email
|
8
|
+
spec.name = "noticent"
|
9
|
+
spec.version = Noticent::VERSION
|
10
|
+
spec.authors = ["Khash Sajadi"]
|
11
|
+
spec.email = ["khash@cloud66.com"]
|
12
12
|
|
13
|
-
spec.summary
|
13
|
+
spec.summary = "Act as Notified is a flexible framework to add notifications to a Rails application"
|
14
14
|
|
15
15
|
# Specify which files should be added to the gem when it is released.
|
16
16
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
17
17
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
18
18
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
19
|
end
|
20
|
-
spec.bindir
|
21
|
-
spec.executables
|
22
|
-
spec.require_paths = [
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.add_dependency
|
25
|
-
spec.add_dependency
|
24
|
+
spec.add_dependency "activerecord", "~> 5.2"
|
25
|
+
spec.add_dependency "activesupport", "~> 5.2"
|
26
|
+
spec.add_dependency "actionpack", "~> 5.2"
|
26
27
|
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_development_dependency
|
28
|
+
spec.add_development_dependency "combustion", "~> 1.1"
|
29
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
30
|
+
spec.add_development_dependency "factory_bot", "~> 5.0"
|
31
|
+
spec.add_development_dependency "generator_spec", "~> 0.9"
|
32
|
+
spec.add_development_dependency "rails", "~> 5.2"
|
33
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
+
spec.add_development_dependency "rspec", "~> 3.8"
|
35
|
+
spec.add_development_dependency "rubocop", "~> 0.69"
|
36
|
+
spec.add_development_dependency "rubocop-performance", "~> 1.3"
|
37
|
+
spec.add_development_dependency "rufo", "~> 0.7"
|
38
|
+
spec.add_development_dependency "sqlite3", "~> 1.4"
|
39
|
+
spec.add_development_dependency "byebug", "~> 11.0"
|
36
40
|
end
|
data/testing/channels/email.rb
CHANGED
@@ -3,6 +3,16 @@ module Noticent
|
|
3
3
|
# this is a example payload for comment as scope
|
4
4
|
class CommentPayload < Noticent::Testing::Payload
|
5
5
|
attr_accessor :comment_id
|
6
|
+
attr_reader :users
|
7
|
+
|
8
|
+
def self.three
|
9
|
+
# nop
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.new_signup
|
13
|
+
# nop
|
14
|
+
end
|
15
|
+
|
6
16
|
end
|
7
17
|
end
|
8
18
|
end
|
@@ -16,6 +16,50 @@ module Noticent
|
|
16
16
|
[]
|
17
17
|
end
|
18
18
|
|
19
|
+
def self.some_event(some_value)
|
20
|
+
# nop
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.foo(options)
|
24
|
+
# nop
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.boo
|
28
|
+
# nop
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.one
|
32
|
+
# nop
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.only_here
|
36
|
+
# nop
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.two
|
40
|
+
# nop
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.tfa_enabled
|
44
|
+
# nop
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.sign_up
|
48
|
+
# nop
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.new_signup
|
52
|
+
# nop
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.fuzz
|
56
|
+
# nop
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.buzz
|
60
|
+
# nop
|
61
|
+
end
|
62
|
+
|
19
63
|
end
|
20
64
|
end
|
21
65
|
end
|
@@ -4,3 +4,6 @@ fuzz: <%= @payload.some_attribute %>
|
|
4
4
|
This is normal test
|
5
5
|
Some non-context stuff <%= 1 + 1 %>
|
6
6
|
This comes from <%= @payload.some_attribute %>
|
7
|
+
This comes from an instance variable <%= @some_value %>
|
8
|
+
This is from Rails <%= @routes.hello_path %>
|
9
|
+
This is foo <%= @data[:foo] %> and this is bar <%= @data[:fuzz] %>
|
@@ -0,0 +1 @@
|
|
1
|
+
this is from the default view
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: noticent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khash Sajadi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '5.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: actionpack
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: combustion
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.1'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: bundler
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +108,20 @@ dependencies:
|
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '0.9'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rails
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '5.2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '5.2'
|
83
125
|
- !ruby/object:Gem::Dependency
|
84
126
|
name: rake
|
85
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +206,20 @@ dependencies:
|
|
164
206
|
- - "~>"
|
165
207
|
- !ruby/object:Gem::Version
|
166
208
|
version: '1.4'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: byebug
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '11.0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '11.0'
|
167
223
|
description:
|
168
224
|
email:
|
169
225
|
- khash@cloud66.com
|
@@ -178,10 +234,12 @@ files:
|
|
178
234
|
- ".vscode/settings.json"
|
179
235
|
- Gemfile
|
180
236
|
- Gemfile.lock
|
237
|
+
- LICENSE
|
181
238
|
- README.md
|
182
239
|
- Rakefile
|
183
240
|
- bin/console
|
184
241
|
- bin/setup
|
242
|
+
- config.ru
|
185
243
|
- lib/generators/noticent/noticent.rb
|
186
244
|
- lib/generators/noticent/templates/create_opt_ins.rb
|
187
245
|
- lib/generators/noticent/templates/noticent_initializer.rb
|
@@ -205,7 +263,9 @@ files:
|
|
205
263
|
- noticent.gemspec
|
206
264
|
- testing/channels/boo.rb
|
207
265
|
- testing/channels/email.rb
|
266
|
+
- testing/channels/exclusive.rb
|
208
267
|
- testing/channels/foo.rb
|
268
|
+
- testing/channels/simple.rb
|
209
269
|
- testing/channels/slack.rb
|
210
270
|
- testing/channels/webhook.rb
|
211
271
|
- testing/models/receipient.rb
|
@@ -215,6 +275,7 @@ files:
|
|
215
275
|
- testing/views/email/some_event.html.erb
|
216
276
|
- testing/views/email/some_event.txt.erb
|
217
277
|
- testing/views/layouts/layout.html.erb
|
278
|
+
- testing/views/simple/default.html.erb
|
218
279
|
homepage:
|
219
280
|
licenses: []
|
220
281
|
metadata: {}
|
@@ -229,12 +290,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
229
290
|
version: '0'
|
230
291
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
231
292
|
requirements:
|
232
|
-
- - "
|
293
|
+
- - ">="
|
233
294
|
- !ruby/object:Gem::Version
|
234
|
-
version:
|
295
|
+
version: '0'
|
235
296
|
requirements: []
|
236
|
-
|
237
|
-
rubygems_version: 2.7.6.2
|
297
|
+
rubygems_version: 3.0.4
|
238
298
|
signing_key:
|
239
299
|
specification_version: 4
|
240
300
|
summary: Act as Notified is a flexible framework to add notifications to a Rails application
|