dallal 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +33 -0
  5. data/app/assets/javascripts/dallal/application.js +13 -0
  6. data/app/assets/stylesheets/dallal/application.css +15 -0
  7. data/app/controllers/dallal/application_controller.rb +5 -0
  8. data/app/helpers/dallal/application_helper.rb +4 -0
  9. data/app/jobs/dallal/dallal_job.rb +13 -0
  10. data/app/mailers/dallal/mailer.rb +36 -0
  11. data/app/views/layouts/dallal/application.html.erb +14 -0
  12. data/app/views/layouts/mailer.html.erb +5 -0
  13. data/app/views/layouts/mailer.text.erb +1 -0
  14. data/config/routes.rb +2 -0
  15. data/lib/dallal/abstract_interface.rb +30 -0
  16. data/lib/dallal/configuration.rb +54 -0
  17. data/lib/dallal/engine.rb +22 -0
  18. data/lib/dallal/events/event_publisher.rb +8 -0
  19. data/lib/dallal/events/event_subscriber.rb +33 -0
  20. data/lib/dallal/events/events.rb +5 -0
  21. data/lib/dallal/events/observer.rb +57 -0
  22. data/lib/dallal/events/publisher.rb +44 -0
  23. data/lib/dallal/events/subscriber.rb +16 -0
  24. data/lib/dallal/file_loader.rb +15 -0
  25. data/lib/dallal/notification.rb +79 -0
  26. data/lib/dallal/notifiers/email_notifier.rb +28 -0
  27. data/lib/dallal/notifiers/notifier.rb +33 -0
  28. data/lib/dallal/notifiers/sms_notifier.rb +15 -0
  29. data/lib/dallal/result.rb +21 -0
  30. data/lib/dallal/version.rb +3 -0
  31. data/lib/dallal.rb +41 -0
  32. data/lib/generators/dallal/install/USAGE +2 -0
  33. data/lib/generators/dallal/install/install_generator.rb +11 -0
  34. data/lib/generators/dallal/install/templates/dallal.rb +16 -0
  35. data/lib/generators/dallal/notification/USAGE +2 -0
  36. data/lib/generators/dallal/notification/notification_generator.rb +44 -0
  37. data/lib/generators/dallal/notification/templates/migration.rb +10 -0
  38. data/lib/generators/dallal/notification/templates/model.rb +2 -0
  39. data/lib/generators/dallal/notifiers/USAGE +2 -0
  40. data/lib/generators/dallal/notifiers/notifiers_generator.rb +56 -0
  41. data/lib/generators/dallal/notifiers/templates/email_notifier.rb +2 -0
  42. data/lib/generators/dallal/notifiers/templates/email_notifier_migration.rb +7 -0
  43. data/lib/generators/dallal/notifiers/templates/sms_notifier.rb +2 -0
  44. data/lib/generators/dallal/notifiers/templates/sms_notifier_migration.rb +7 -0
  45. data/lib/tasks/user_notification_tasks.rake +4 -0
  46. data/spec/dallal/configuration_spec.rb +56 -0
  47. data/spec/dallal/dallal_spec.rb +23 -0
  48. data/spec/dallal/events/event_publisher_spec.rb +7 -0
  49. data/spec/dallal/events/event_subscriber_spec.rb +92 -0
  50. data/spec/dallal/events/observer_spec.rb +117 -0
  51. data/spec/dallal/events/publisher_spec.rb +14 -0
  52. data/spec/dallal/events/subscriber_spec.rb +4 -0
  53. data/spec/dallal/notification_spec.rb +152 -0
  54. data/spec/dallal/notifiers/notifier_spec.rb +27 -0
  55. data/spec/dummy/README.rdoc +28 -0
  56. data/spec/dummy/Rakefile +6 -0
  57. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  58. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  59. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  60. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  61. data/spec/dummy/app/models/post.rb +4 -0
  62. data/spec/dummy/app/models/user.rb +4 -0
  63. data/spec/dummy/app/notifiers/comment_notifier.rb +0 -0
  64. data/spec/dummy/app/notifiers/post_notifier.rb +9 -0
  65. data/spec/dummy/app/notifiers/user_notifier.rb +2 -0
  66. data/spec/dummy/app/views/dallal/mailer/posts/register.html.erb +5 -0
  67. data/spec/dummy/app/views/dallal/mailer/posts/register_subject.html.erb +1 -0
  68. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  69. data/spec/dummy/bin/bundle +3 -0
  70. data/spec/dummy/bin/rails +4 -0
  71. data/spec/dummy/bin/rake +4 -0
  72. data/spec/dummy/bin/setup +29 -0
  73. data/spec/dummy/config/application.rb +32 -0
  74. data/spec/dummy/config/boot.rb +5 -0
  75. data/spec/dummy/config/database.yml +25 -0
  76. data/spec/dummy/config/environment.rb +5 -0
  77. data/spec/dummy/config/environments/development.rb +41 -0
  78. data/spec/dummy/config/environments/production.rb +79 -0
  79. data/spec/dummy/config/environments/test.rb +42 -0
  80. data/spec/dummy/config/initializers/assets.rb +11 -0
  81. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  82. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  83. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  84. data/spec/dummy/config/initializers/inflections.rb +16 -0
  85. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  86. data/spec/dummy/config/initializers/session_store.rb +3 -0
  87. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  88. data/spec/dummy/config/locales/en.yml +23 -0
  89. data/spec/dummy/config/routes.rb +4 -0
  90. data/spec/dummy/config/secrets.yml +22 -0
  91. data/spec/dummy/config.ru +4 -0
  92. data/spec/dummy/db/development.sqlite3 +0 -0
  93. data/spec/dummy/db/migrate/20160801191053_create_users.rb +10 -0
  94. data/spec/dummy/db/migrate/20160803174036_create_posts.rb +11 -0
  95. data/spec/dummy/db/schema.rb +38 -0
  96. data/spec/dummy/db/test.sqlite3 +0 -0
  97. data/spec/dummy/log/test.log +2057 -0
  98. data/spec/dummy/public/404.html +67 -0
  99. data/spec/dummy/public/422.html +67 -0
  100. data/spec/dummy/public/500.html +66 -0
  101. data/spec/dummy/public/favicon.ico +0 -0
  102. data/spec/dummy/spec/factories/posts.rb +7 -0
  103. data/spec/dummy/spec/factories/users.rb +6 -0
  104. data/spec/dummy/spec/models/post_spec.rb +5 -0
  105. data/spec/dummy/spec/models/user_spec.rb +5 -0
  106. data/spec/factories/posts.rb +7 -0
  107. data/spec/factories/users.rb +6 -0
  108. data/spec/jobs/dallal/dallal_job_spec.rb +14 -0
  109. data/spec/mailers/dallal/mailer_spec.rb +7 -0
  110. data/spec/mailers/previews/dallal/mailer_preview.rb +6 -0
  111. data/spec/rails_helper.rb +26 -0
  112. data/spec/spec_helper.rb +92 -0
  113. metadata +295 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ef7931f202a80463bfca59f1e2d4a32b74cf7114
4
+ data.tar.gz: 8c243ab925cdab39f98c364b92994bd260244da5
5
+ SHA512:
6
+ metadata.gz: 283eff9f49bacda0ce3a827515adc71c821b792b6bbd8a3e8c8a5264da389890feae70026fa9ad81f8335538ac59499fbf6b5be6e259bb5539ac6d5539804149
7
+ data.tar.gz: 4258db0fff6f2ba0a416cbd9cdaec87a7cc0cac597cc8e9f6de030e4258ba985fed2aa713d25e52970cb46ea13354a1518768d79a63d5b159642bfddfe4fc1db
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 Laertis Pappas
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = Dallal
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Dallal'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+ Bundler::GemHelper.install_tasks
24
+
25
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
26
+ require 'rspec/core'
27
+ require 'rspec/core/rake_task'
28
+
29
+ desc "Run all specs in spec directory (excluding plugin specs)"
30
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
31
+
32
+ task :default => :spec
33
+
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ module Dallal
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Dallal
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,13 @@
1
+ module Dallal
2
+ class DallalJob < ActiveJob::Base
3
+ queue_as :default
4
+
5
+ # TODO This is tricky. Event is string here. Is transformed in
6
+ # event_subscriber from sym to string. we transform here egain to
7
+ # sym. Rethink this
8
+ # or user.notify....
9
+ def perform(klass, id, event)
10
+ "#{klass}_notifier".classify.constantize.create_notification(id: id, event: event.to_sym)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ module Dallal
2
+ class Mailer < ActionMailer::Base
3
+ layout Dallal.configuration.email_layout
4
+
5
+ # TODO add mailer specs
6
+ def notify(notification)
7
+ @notification = notification
8
+ mail(mail_attrs)
9
+ end
10
+
11
+ private
12
+ def mail_attrs
13
+ {
14
+ from: address_format(@notification.from_email, @notification.from_name),
15
+ reply_to: address_format(@notification.from_email, @notification.from_name),
16
+ to: @notification.user.email,
17
+ cc: nil,
18
+ subject: subject,
19
+ template_name: "#{object_plural_name}/#{@notification.template_name}"
20
+ }
21
+ end
22
+
23
+ def subject
24
+ render_to_string(template: "dallal/mailer/#{object_plural_name}/#{@notification.template_name}_subject")
25
+ end
26
+
27
+ def address_format email, name
28
+ address = Mail::Address.new email
29
+ address.display_name = name
30
+ address.format
31
+ end
32
+ def object_plural_name
33
+ @notification._object.class.name.underscore.pluralize
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dallal</title>
5
+ <%= stylesheet_link_tag "dallal/application", media: "all" %>
6
+ <%= javascript_include_tag "dallal/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,5 @@
1
+ <html>
2
+ <body>
3
+ <%= yield %>
4
+ </body>
5
+ </html>
@@ -0,0 +1 @@
1
+ <%= yield %>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Dallal::Engine.routes.draw do
2
+ end
@@ -0,0 +1,30 @@
1
+ module Dallal
2
+ module AbstractInterface
3
+ class InterfaceNotImplementedError < NotImplementedError
4
+ end
5
+
6
+ def self.included(klass)
7
+ klass.send(:include, AbstractInterface::Methods)
8
+ klass.send(:extend, AbstractInterface::Methods)
9
+ klass.send(:extend, AbstractInterface::ClassMethods)
10
+ end
11
+
12
+ module Methods
13
+ def api_not_implemented(klass)
14
+ caller.first.match(/in \`(.+)\'/)
15
+ method_name = $1
16
+ raise AbstractInterface::InterfaceNotImplementedError.new("#{klass.class.name} needs to implement '#{method_name}' for interface #{self.name}!")
17
+ end
18
+ end
19
+
20
+ module ClassMethods
21
+ def needs_implementation(name, *args)
22
+ self.class_eval do
23
+ define_method(name) do |*args|
24
+ raise NotImplemented
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,54 @@
1
+ require 'ostruct'
2
+
3
+ module Dallal
4
+ module Configuration
5
+ CURRENT_ATTRS = [:user_class_name, :dallal_class_name,
6
+ :enabled, :email_layout, :from_email, :from_name].freeze
7
+ DEPRECATED_ATTRS = [].freeze
8
+ CONFIG_ATTRS = (CURRENT_ATTRS + DEPRECATED_ATTRS).freeze
9
+
10
+ def config
11
+ @config ||= Configuration.new
12
+ end
13
+ private :config
14
+
15
+ def configure
16
+ return unless block_given?
17
+ yield config if block_given?
18
+ end
19
+
20
+ def configuration
21
+ config
22
+ end
23
+
24
+ def options
25
+ config.options
26
+ end
27
+
28
+ class Configuration < Struct.new(*CONFIG_ATTRS)
29
+ def initialize
30
+ super
31
+
32
+ set_default_values
33
+ end
34
+
35
+ def options
36
+ Hash[ * CONFIG_ATTRS.map { |key| [key, send(key)] }.flatten ]
37
+ end
38
+
39
+ def enabled?
40
+ self.enabled
41
+ end
42
+
43
+ private
44
+ def set_default_values
45
+ self.user_class_name = 'User'
46
+ self.dallal_class_name = 'Dallal'
47
+ self.enabled = true
48
+ self.email_layout = 'mailer'
49
+ self.from_email = 'foo@bar.xyz'
50
+ self.from_name = 'just a name'
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,22 @@
1
+ module Dallal
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Dallal
4
+
5
+ initializer "Include Dallal after rails boot" do
6
+ # ...
7
+ require 'dallal/file_loader'
8
+
9
+ # Run before every request in dev and before the first request in production
10
+ ActionDispatch::Callbacks.to_prepare do
11
+ Dallal::FileLoader.load_notifiers
12
+ end
13
+ end
14
+
15
+ config.generators do |g|
16
+ g.test_framework :rspec, :fixture => false
17
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
18
+ g.assets false
19
+ g.helper false
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ module Dallal
2
+ module Events
3
+ class EventPublisher
4
+ include Dallal::Events::Publisher
5
+ self.pub_sub_namespace = 'dallals'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ module Dallal
2
+ module Events
3
+ class EventSubscriber
4
+ include Dallal::Events::Subscriber
5
+
6
+ #TODO Refactor this
7
+ ActiveSupport::Notifications.subscribe('dallals') do |_,_,_,_,payload|
8
+ new(payload).execute
9
+ end
10
+
11
+ def initialize(payload)
12
+ @payload = payload
13
+ end
14
+
15
+ def execute
16
+ if should_create_notifications?
17
+ # Trigger an ActiJob for this notification
18
+ DallalJob.perform_later payload[:class], payload[:id], payload[:event].to_s
19
+ end
20
+ end
21
+
22
+ private
23
+ attr_reader :payload
24
+
25
+ # TODO This silently ignores creating a notification
26
+ # add a warning here or raise exception if not applicable
27
+ def should_create_notifications?
28
+ # Are notifications enabled? && is class in Notifiables?
29
+ Dallal.configuration.enabled? && Observer::NOTIFIABLES.include?(payload[:class])
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ require 'dallal/events/subscriber'
2
+ require 'dallal/events/publisher'
3
+ require 'dallal/events/event_publisher'
4
+ require 'dallal/events/event_subscriber'
5
+ require 'dallal/events/observer'
@@ -0,0 +1,57 @@
1
+ # TODO Move to other module
2
+ module Dallal
3
+ module Events
4
+ class Observer
5
+ NOTIFIABLES = []
6
+
7
+ def self.inherited(base)
8
+ model_name = base.name.gsub('Notifier', '')
9
+ validate_model_exists!(model_name)
10
+
11
+ NOTIFIABLES << model_name
12
+ end
13
+
14
+ def self.callbacks
15
+ @__notification_callbacks ||= []
16
+ end
17
+
18
+ def self.on *args, &block
19
+ opts = args.extract_options!
20
+ callbacks << { on: args, opts: opts, block: block }
21
+ end
22
+
23
+ # TODO Rethink this. Currently one worker executes all notifications
24
+ # rethink moving to multiple concrete notifications so
25
+ # we can have one worker per notification.
26
+ def self.create_notification(id:, event:)
27
+ # TODO This loops on all callbacks. Rethink this
28
+ # method and implement it differently. Add listeners?
29
+ callbacks.each do |callback|
30
+ next unless callback[:on].include?(event)
31
+ obj = model_class.constantize.find(id)
32
+ notification = Dallal::Notification.new(event: event, model_class: model_class, opts: callback[:opts], _object: obj)
33
+ notification.define_singleton_method(model_class.underscore) do
34
+ obj
35
+ end
36
+ notification.instance_eval(&callback[:block])
37
+ notification.dispatch!
38
+ end
39
+ end
40
+
41
+
42
+ private
43
+
44
+ def self.model_class
45
+ self.name.gsub('Notifier', '')
46
+ end
47
+
48
+ def self.validate_model_exists!(model)
49
+ unless Object.const_defined?(model)
50
+ # TODO add more descriptive error
51
+ # also fix this
52
+ # raise "Model #{model} is not defined."
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,44 @@
1
+ module Dallal
2
+ module Events
3
+ module Publisher
4
+ extend ::ActiveSupport::Concern
5
+
6
+ included do
7
+ class_attribute :pub_sub_namespace
8
+
9
+ self.pub_sub_namespace = 'dallals'
10
+ end
11
+
12
+ #def broadcast_event(name, payload = {})
13
+ # if block_given?
14
+ # self.class.broadcast_event(name, payload) do
15
+ # yield
16
+ # end
17
+ # else
18
+ # self.class.broadcast_event(name, payload)
19
+ # end
20
+ #end
21
+
22
+ def broadcast(info)
23
+ self.class.broadcast(info)
24
+ end
25
+
26
+ module ClassMethods
27
+ # Broadcast to dallals
28
+ def broadcast(info)
29
+ ActiveSupport::Notifications.instrument(self.pub_sub_namespace, info)
30
+ end
31
+
32
+ def broadcast_event(name, payload = {})
33
+ if block_given?
34
+ ActiveSupport::Notifications.instrument(name, payload) do
35
+ yield
36
+ end
37
+ else
38
+ ActiveSupport::Notifications.instrument(name, payload)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ module Dallal
2
+ module Events
3
+ module Subscriber
4
+
5
+ # TODO remove dallals from this module. Implement sub chanel on
6
+ # event_subscriber
7
+
8
+ #def subscribe(event_name)
9
+ # ActiveSupport::Notifications.subscribe(event_name) do |*args|
10
+ # event = ActiveSupport::Notifications::Event.new(*args)
11
+ # yield(event)
12
+ # end
13
+ #end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Dallal
2
+ class FileLoader
3
+ def self.load_notifiers
4
+ if directory_exists?
5
+ Dir[Rails.root.join("app/notifiers/**/*.rb")].each do |file|
6
+ require_dependency file
7
+ end
8
+ end
9
+ end
10
+
11
+ def self.directory_exists?
12
+ File.directory?(Rails.root.join("app/notifiers"))
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,79 @@
1
+ module Dallal
2
+ class Notification
3
+ attr_accessor :event, :model_class, :opts, :_object
4
+ attr_reader :template_name
5
+
6
+ def initialize args = {}
7
+ args.each do |k, v|
8
+ send("#{k}=", v)
9
+ end
10
+
11
+ @notifiers = {}
12
+ end
13
+
14
+ def notify target, &block
15
+ @target = Array(target).flatten.compact.uniq
16
+ instance_eval(&block)
17
+ end
18
+
19
+ def with *args, &block
20
+ opts = args.extract_options!
21
+ if should_send?(opts[:if])
22
+ instance_eval(&block)
23
+ args.each { |arg| @notifiers[arg] = get_notifier(arg) }
24
+ end
25
+ end
26
+
27
+ def user
28
+ @target.first
29
+ end
30
+
31
+ # TODO !!! Watch out same payload for multiple notifers that
32
+ # require payload
33
+ def payload payload
34
+ @payload = payload
35
+ end
36
+
37
+ # Same here as payload
38
+ def template template
39
+ @template_name = template
40
+ end
41
+
42
+ def persist?
43
+ opts[:persist].present?
44
+ end
45
+
46
+ def dispatch!
47
+ validate!
48
+ @notifiers.each { |_, n| n.notify! }
49
+ @notifiers.each { |_, n| n.persist! } if persist?
50
+ end
51
+
52
+ private
53
+ # TODO Implement this
54
+ # when target is nil throw error
55
+ # on email notification when template is nil throw error
56
+ # on sms notification when payload is nil throw an error
57
+ # on any other notifiers add a validation logic here
58
+ def validate!
59
+ if false
60
+ raise "You have not defined \'notify\' in \'with\' block for #{class_name} notifier"
61
+ end
62
+ end
63
+
64
+ def get_notifier(name)
65
+ # TODO Pass concrete notifications to notifiers. Ex, EmailNotification, JsonPayloadNotification, SmsNotification ...
66
+ Dallal::Notifiers::Notifier.send(name, self)
67
+ end
68
+
69
+ def should_send?(condition)
70
+ return true if condition.blank?
71
+
72
+ if condition.is_a?(Proc)
73
+ _object.instance_exec(&condition)
74
+ else
75
+ _object.send(condition)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,28 @@
1
+ module Dallal
2
+ module Notifiers
3
+ class EmailNotifier < Notifier
4
+ def notify!
5
+ # TODO please pass a email notification instead
6
+ define_email_methods
7
+ mailer.notify(notification).deliver_now
8
+ end
9
+
10
+ def persist!
11
+ end
12
+
13
+ private
14
+
15
+ def define_email_methods
16
+ [:from_email, :from_name].each do |name|
17
+ notification.define_singleton_method(name) do
18
+ Dallal.configuration.send(name)
19
+ end
20
+ end
21
+ end
22
+
23
+ def mailer
24
+ Dallal::Mailer
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+ require 'dallal/abstract_interface'
2
+
3
+ module Dallal
4
+ module Notifiers
5
+ class Notifier
6
+ attr_reader :notification
7
+
8
+ include AbstractInterface
9
+ def initialize(notification)
10
+ @notification = notification
11
+ end
12
+
13
+ def self.email(notification)
14
+ Dallal::Notifiers::EmailNotifier.new(notification)
15
+ end
16
+
17
+ def self.sms(notification)
18
+ Dallal::Notifiers::SmsNotifier.new(notification)
19
+ end
20
+
21
+ def notify!(*args)
22
+ Notifier.api_not_implemented(self)
23
+ end
24
+
25
+ def persist!
26
+ Notifier.api_not_implemented(self)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ require 'dallal/notifiers/email_notifier'
33
+ require 'dallal/notifiers/sms_notifier'
@@ -0,0 +1,15 @@
1
+
2
+ module Dallal
3
+ module Notifiers
4
+ class SmsNotifier < Notifier
5
+
6
+ def notify!
7
+ end
8
+
9
+
10
+ def persist!
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module Dallal
2
+ module Result
3
+ class Success
4
+ attr_reader :success, :data
5
+ def initialize(data = nil)
6
+ @success = true
7
+ @data = data
8
+ end
9
+ end
10
+
11
+ class Error
12
+ attr_reader :success, :message, :data
13
+
14
+ def initialize(message, data = nil)
15
+ @success = false
16
+ @message = message
17
+ @data = data
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Dallal
2
+ VERSION = "0.0.1"
3
+ end