dallal 0.0.1

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 (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