yodeler 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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +102 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/yodeler/application.js +13 -0
- data/app/assets/stylesheets/yodeler/application.css +13 -0
- data/app/controllers/yodeler/application_controller.rb +4 -0
- data/app/helpers/yodeler/application_helper.rb +4 -0
- data/app/views/layouts/yodeler/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/generators/yodeler/USAGE +2 -0
- data/lib/generators/yodeler/install_generator.rb +23 -0
- data/lib/generators/yodeler/templates/initializer.rb +3 -0
- data/lib/generators/yodeler/templates/migration.rb +50 -0
- data/lib/tasks/yodeler_tasks.rake +4 -0
- data/lib/yodeler/configuration.rb +6 -0
- data/lib/yodeler/engine.rb +10 -0
- data/lib/yodeler/listens_to_yodler.rb +26 -0
- data/lib/yodeler/models/event.rb +17 -0
- data/lib/yodeler/models/event_type.rb +6 -0
- data/lib/yodeler/models/event_types/base.rb +53 -0
- data/lib/yodeler/models/event_types/noop_event_type.rb +12 -0
- data/lib/yodeler/models/notification.rb +21 -0
- data/lib/yodeler/models/subscription.rb +9 -0
- data/lib/yodeler/version.rb +3 -0
- data/lib/yodeler.rb +122 -0
- metadata +222 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 530dac4896c916cff39b3290396117d2e03b9751
|
4
|
+
data.tar.gz: 4011479ed5dee9fb800330038a50613d2dd48da3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7bd42ef38e14b8b7945eeaf5f892cfd74d5be6d628bf5b7760b69ad39899f07c3d81bea1aa7973de10a012909a3f1dbe22bde601706105eefb795aefdfdc57b4
|
7
|
+
data.tar.gz: b99ceca1697e0546b238540ae19500177d3e99f8e460eb31392cedd9b95f1b8e124848bd57ba797ade4ed01503c6706a49ad33f12e0f55882b6fa482fd033bbb
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
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.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
Yodeler
|
2
|
+
=======
|
3
|
+
|
4
|
+
Spouting noise to whoever is listening.
|
5
|
+
|
6
|
+
Yodeler is an easy way to notify users of different events that occur in your app.
|
7
|
+
|
8
|
+
* Notify your marketing team on the 10,000 sign-up.
|
9
|
+
* Notify user's when their profile has been viewed
|
10
|
+
* Notify your dev team about events that are not quite exception worthy, but you don't want to dig through a bunch of logs to find.
|
11
|
+
|
12
|
+
|
13
|
+
Features
|
14
|
+
========
|
15
|
+
|
16
|
+
* store notifications via ActiveRecord
|
17
|
+
* benchmark event duration
|
18
|
+
* i18n support
|
19
|
+
* flexible payloads
|
20
|
+
|
21
|
+
|
22
|
+
What's wrong with XMPP?
|
23
|
+
=======================
|
24
|
+
|
25
|
+
Why don't you fly to Walmart on a rocket?
|
26
|
+
|
27
|
+
Don't even say it's because you don't have a rocket.
|
28
|
+
|
29
|
+
Why don't you kill ants with a bazooka?
|
30
|
+
|
31
|
+
Nevermind, you get it.
|
32
|
+
|
33
|
+
|
34
|
+
Usage
|
35
|
+
=====
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
# in config/initializers/yodeler.rb
|
39
|
+
Yodeler.register :another_thousand_users
|
40
|
+
|
41
|
+
Yodeler.register :view_user do
|
42
|
+
# Default states are unread: 0, read: 1
|
43
|
+
config.states = {
|
44
|
+
unread: 0,
|
45
|
+
read: 1,
|
46
|
+
ignored: 2
|
47
|
+
}
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# in a controller or Anywhere you want to hear some noise
|
53
|
+
class UserController < ApplicationController
|
54
|
+
around_action :track_user_view, only: :show
|
55
|
+
|
56
|
+
def show
|
57
|
+
# do your User#show as normal
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def track_user_view
|
63
|
+
# This will also benchmark the action since it is in a block
|
64
|
+
Yodeler.dispatch :view_user, {viewer_id: 3, viewee_id: 23} do |payload|
|
65
|
+
yield #yield the action dispatch, the payload is available
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
# off in some scorned rails-observer
|
73
|
+
class UserObserver
|
74
|
+
observers :user
|
75
|
+
|
76
|
+
def after_create
|
77
|
+
# let the marketing know another thousandth user has registered!
|
78
|
+
if (User.count % 1000).zero?
|
79
|
+
Yodeler.dispatch :another_thousand_users, {give_him_a_prize: @user.id}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
|
86
|
+
Getting around the objects
|
87
|
+
==========================
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
@event.subscriptions #=> Array<Yodeler::Subscription> all subscriber subscriptions
|
91
|
+
@event.notifications #=> Array<Yodeler::Notifications>
|
92
|
+
|
93
|
+
@notification.subscriber #=> Your 'subscriber' class, delegated to #subscription
|
94
|
+
@notification.subscription.subscriber
|
95
|
+
@notification.event #=> The subscriber to event, delegated to #subscription
|
96
|
+
@notification.message #=> i18n message interpolated w/ the payload
|
97
|
+
|
98
|
+
@subscription.subscriber #=> the 'subscriber' subscribed to this event
|
99
|
+
@subscription.notifications #=> all notifications of this event type for this subscriber
|
100
|
+
@subscription.event
|
101
|
+
|
102
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
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 = 'Yodeler'
|
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/test_app/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
@@ -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 vendor/assets/javascripts of plugins, if any, 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/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
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 vendor/assets/stylesheets of plugins, if any, 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 top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Yodeler</title>
|
5
|
+
<%= stylesheet_link_tag "yodeler/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "yodeler/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
module Yodeler
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
include ::Rails::Generators::Migration
|
7
|
+
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
desc 'Generates (but does not run) a migration to add yodeler tables and an initializer.'
|
10
|
+
|
11
|
+
def create_migration_file
|
12
|
+
migration_template 'migration.rb', 'db/migrate/create_yodeler_tables.rb'
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_initializer
|
16
|
+
copy_file 'initializer.rb', 'config/initializers/yodeler.rb'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.next_migration_number(dirname)
|
20
|
+
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class CreateYodelerTables < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :yodeler_event_types do |t|
|
4
|
+
t.string :name, null: false # Maps to registered name in DSL
|
5
|
+
t.string :type #STI
|
6
|
+
t.datetime :created_at
|
7
|
+
end
|
8
|
+
|
9
|
+
create_table :yodeler_events do |t|
|
10
|
+
t.integer :yodeler_event_type_id, null: false
|
11
|
+
t.datetime :started_at
|
12
|
+
t.datetime :finished_at
|
13
|
+
t.text :payload
|
14
|
+
t.datetime :created_at, null: false
|
15
|
+
end
|
16
|
+
|
17
|
+
create_table :yodeler_subscriptions do |t|
|
18
|
+
t.integer :yodeler_event_type_id, null: false
|
19
|
+
|
20
|
+
# polymorphic, support for whatever type of class is owning the subscription
|
21
|
+
t.string :subscriber_type, null: false
|
22
|
+
t.integer :subscriber_id, null: false
|
23
|
+
|
24
|
+
t.datetime :created_at
|
25
|
+
t.datetime :updated_at
|
26
|
+
end
|
27
|
+
|
28
|
+
create_table :yodeler_notifications do |t|
|
29
|
+
t.integer :yodeler_event_id, null: false
|
30
|
+
t.integer :yodeler_subscription_id, null: false
|
31
|
+
t.integer :state
|
32
|
+
t.datetime :created_at, null: false
|
33
|
+
t.datetime :updated_at, null: false
|
34
|
+
end
|
35
|
+
|
36
|
+
# sqlite3 has an index name length limitation of 62(?!) characters
|
37
|
+
unless Rails.env.test?
|
38
|
+
add_index :yodeler_event_types, :name
|
39
|
+
|
40
|
+
add_index :yodeler_events, :yodeler_event_type_id
|
41
|
+
|
42
|
+
add_index :yodeler_subscriptions, :yodeler_event_type_id
|
43
|
+
add_index :yodeler_subscriptions, [:subscriber_id, :subscriber_type]
|
44
|
+
|
45
|
+
add_index :yodeler_notifications, :yodeler_event_id
|
46
|
+
add_index :yodeler_notifications, :yodeler_subscription_id
|
47
|
+
add_index :yodeler_notifications, :state
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Yodeler
|
2
|
+
module ListensToYodler
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def listens_to_yodler(subscriptions_assocation_name = :yodeler_subscriptions)
|
10
|
+
cattr_accessor :yodeler_subscriptions_name
|
11
|
+
self.yodeler_subscriptions_name = subscriptions_assocation_name
|
12
|
+
|
13
|
+
has_many self.yodeler_subscriptions_name,
|
14
|
+
dependent: :destroy,
|
15
|
+
class_name: "Yodeler::Subscription",
|
16
|
+
foreign_key: :subscriber_id
|
17
|
+
|
18
|
+
include Yodeler::ListensToYodler::LocalInstanceMethods
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module LocalInstanceMethods;end;
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
ActiveRecord::Base.send :include, Yodeler::ListensToYodler
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Yodeler
|
2
|
+
class Event < ActiveRecord::Base
|
3
|
+
serialize :payload, Hash
|
4
|
+
|
5
|
+
validates_presence_of :event_type
|
6
|
+
|
7
|
+
belongs_to :event_type, class_name: "Yodeler::EventType::Base", foreign_key: :yodeler_event_type_id
|
8
|
+
has_many :notifications, class_name: "Yodeler::Notification", foreign_key: :yodeler_event_id
|
9
|
+
|
10
|
+
delegate :subscriptions, to: :event_type
|
11
|
+
delegate :name, to: :event_type
|
12
|
+
|
13
|
+
def duration
|
14
|
+
finished_at - started_at if finished_at.present? and started_at.present?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Yodeler
|
2
|
+
module EventType
|
3
|
+
class Base < ActiveRecord::Base
|
4
|
+
self.table_name= "yodeler_event_types"
|
5
|
+
|
6
|
+
class Configuration
|
7
|
+
include ActiveSupport::Configurable
|
8
|
+
config_accessor(:states) do
|
9
|
+
{ unread: 0, read: 1 }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.configuration
|
14
|
+
@configuration ||= Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
validates_presence_of :name
|
18
|
+
validates_uniqueness_of :name
|
19
|
+
|
20
|
+
has_many :events,
|
21
|
+
dependent: :destroy,
|
22
|
+
class_name: "Yodeler::Event",
|
23
|
+
foreign_key: :yodeler_event_type_id
|
24
|
+
|
25
|
+
has_many :subscriptions,
|
26
|
+
dependent: :destroy,
|
27
|
+
class_name: "Yodeler::Subscription",
|
28
|
+
foreign_key: :yodeler_event_type_id
|
29
|
+
|
30
|
+
|
31
|
+
# Logs the occurrence of a {Yodeler::Event} and dispatches notifications
|
32
|
+
#
|
33
|
+
# @param [Hash] params additional params to log
|
34
|
+
# @option params [String] :started_at Benchmark started at time
|
35
|
+
# @option params [String] :finished_at Benchmark finished at time
|
36
|
+
#
|
37
|
+
# @param [Hash] payload Serialized hash, anything you want
|
38
|
+
#
|
39
|
+
# @return [~Yodeler::EventType::Base] the logged event
|
40
|
+
def self.yodel!(params)
|
41
|
+
current_event_type = self.first
|
42
|
+
current_event = current_event_type.events.create(params)
|
43
|
+
|
44
|
+
current_event_type.subscriptions.each do |subscriber|
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
current_event
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Yodeler
|
2
|
+
module EventType
|
3
|
+
# The event that is dispatch if an Yodeler.dispatch is called on an event type that
|
4
|
+
# does not exist
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# Yodeler.dispatch :i_dont_exist, my_payload
|
8
|
+
# # => Yodeler.dispatch :noop, my_payload
|
9
|
+
class NoopEventType < Yodeler::EventType::Base
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Yodeler
|
2
|
+
class Notification < ActiveRecord::Base
|
3
|
+
validates_presence_of :subscription
|
4
|
+
validates_presence_of :event
|
5
|
+
|
6
|
+
belongs_to :event, class_name: "Yodeler::Event", foreign_key: :yodeler_event_id
|
7
|
+
belongs_to :subscription, class_name: "Yodeler::Subscription", foreign_key: :yodeler_subscription_id
|
8
|
+
|
9
|
+
delegate :event_type, to: :event
|
10
|
+
delegate :subscriber, to: :subscription
|
11
|
+
|
12
|
+
def message
|
13
|
+
I18n.t("yodeler.event_types.#{event_type_key}.message", event.payload)
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
def event_type_key
|
18
|
+
event_type.name.to_sym
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Yodeler
|
2
|
+
class Subscription < ActiveRecord::Base
|
3
|
+
validates_presence_of :subscriber, :event_type
|
4
|
+
belongs_to :event_type, class_name: "Yodeler::EventType::Base", foreign_key: :yodeler_event_type_id
|
5
|
+
belongs_to :subscriber, polymorphic: true
|
6
|
+
|
7
|
+
has_many :notifications, class_name: "Yodeler::Notification", foreign_key: :yodeler_subscription_id
|
8
|
+
end
|
9
|
+
end
|
data/lib/yodeler.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require "yodeler/engine"
|
2
|
+
|
3
|
+
module Yodeler
|
4
|
+
autoload :Configuration, 'yodeler/configuration'
|
5
|
+
autoload :EventType, 'yodeler/models/event_type'
|
6
|
+
autoload :Event, 'yodeler/models/event'
|
7
|
+
autoload :Subscription, 'yodeler/models/subscription'
|
8
|
+
autoload :Notification, 'yodeler/models/notification'
|
9
|
+
autoload :ListensToYodler, 'yodeler/listens_to_yodler'
|
10
|
+
autoload :EventType, 'yodeler/models/event_type'
|
11
|
+
|
12
|
+
mattr_accessor :registrations
|
13
|
+
self.registrations = {}
|
14
|
+
|
15
|
+
# Configuring the yodeler gem
|
16
|
+
def self.configuration
|
17
|
+
@configuration ||= Configuration.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.configure
|
21
|
+
yield configuration
|
22
|
+
end
|
23
|
+
|
24
|
+
# Set the ActiveRecord table name prefix to yodeler_
|
25
|
+
#
|
26
|
+
# This makes 'events' into 'yodeler_events' and also respects any
|
27
|
+
# 'global' table_name_prefix set on ActiveRecord::Base.
|
28
|
+
def self.table_name_prefix
|
29
|
+
"#{ActiveRecord::Base.table_name_prefix}yodeler_"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Creates an event_type model e.g.: Yodeler::#{event_type}EventType < Yodeler::EventType::Base
|
33
|
+
#
|
34
|
+
# @note
|
35
|
+
# you could also create your own class inheriting #{Yodeler::EventType::Base}
|
36
|
+
def self.register(event_type,&block)
|
37
|
+
event_type_klass = Yodeler.define_event_type(event_type)
|
38
|
+
|
39
|
+
if block_given?
|
40
|
+
yield event_type_klass.configuration
|
41
|
+
end
|
42
|
+
|
43
|
+
# Add the event type to the yodeler_event_types table
|
44
|
+
event_type_klass.first_or_create name: event_type
|
45
|
+
|
46
|
+
# keep track of the registrations
|
47
|
+
Yodeler.registrations[event_type] = event_type_klass
|
48
|
+
event_type_klass
|
49
|
+
end
|
50
|
+
|
51
|
+
# Dispatches an event
|
52
|
+
# @param [Symbol] event_type the registered event type
|
53
|
+
# @param [Hash] payload a hash of values to serialize with the event
|
54
|
+
#
|
55
|
+
def self.dispatch(event_type, payload={})
|
56
|
+
event_type_klass = Yodeler.registrations[event_type]
|
57
|
+
|
58
|
+
# If the class wasn't registered dispatch the default class noop
|
59
|
+
if event_type_klass.nil?
|
60
|
+
# Register it the first time
|
61
|
+
Yodeler.register(:noop) if Yodeler.registrations[:noop].nil?
|
62
|
+
|
63
|
+
event_type_klass = Yodeler::EventType::NoopEventType
|
64
|
+
end
|
65
|
+
|
66
|
+
started_at = nil
|
67
|
+
finished_at = nil
|
68
|
+
|
69
|
+
if block_given?
|
70
|
+
started_at = Time.now
|
71
|
+
yield payload
|
72
|
+
finished_at = Time.now
|
73
|
+
end
|
74
|
+
|
75
|
+
event_type_klass.yodel!({
|
76
|
+
started_at: started_at,
|
77
|
+
finished_at: finished_at,
|
78
|
+
payload: payload
|
79
|
+
})
|
80
|
+
end
|
81
|
+
|
82
|
+
# Clears all the registrations and removes the EventType classes
|
83
|
+
def self.flush_registrations!
|
84
|
+
Yodeler.registrations.keys.each do |event_type|
|
85
|
+
Yodeler.undefine_event_type(event_type)
|
86
|
+
end
|
87
|
+
Yodeler.registrations = {}
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
def self.event_type_class_name(event_type)
|
92
|
+
"#{event_type.to_s.classify}EventType"
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.undefine_event_type(event_type)
|
96
|
+
event_klass = Yodeler.registrations[event_type]
|
97
|
+
if event_klass && ( defined?( event_klass ) == 'constant' )
|
98
|
+
Yodeler::EventType.instance_eval{
|
99
|
+
remove_const( event_type.to_s.classify.to_sym )
|
100
|
+
}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.define_event_type(event_type)
|
105
|
+
undefine_event_type(event_type)
|
106
|
+
|
107
|
+
# Define an ancestor event type of Yodeler::EventType::Base and
|
108
|
+
# add AS Configurable to it
|
109
|
+
new_event_type_class = Class.new(Yodeler::EventType::Base) do
|
110
|
+
end
|
111
|
+
|
112
|
+
# Define the event type class, e.g.: Yodeler::EventType::UserViewedEventType
|
113
|
+
Yodeler::EventType.const_set(Yodeler.event_type_class_name(event_type), new_event_type_class)
|
114
|
+
end
|
115
|
+
|
116
|
+
# def self.cleanup!(hard=false)
|
117
|
+
# # defunct or delete any event_types, et al that aren't currently registered
|
118
|
+
# if hard
|
119
|
+
# else
|
120
|
+
# end
|
121
|
+
# end
|
122
|
+
end
|
metadata
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yodeler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cory O'Daniel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.0.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.0.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: railties
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: factory_girl_rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: generator_spec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: guard-bundler
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: shoulda-matchers
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: simplecov
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: database_cleaner
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description:
|
168
|
+
email:
|
169
|
+
- yodel@coryodaniel.com
|
170
|
+
executables: []
|
171
|
+
extensions: []
|
172
|
+
extra_rdoc_files: []
|
173
|
+
files:
|
174
|
+
- MIT-LICENSE
|
175
|
+
- README.md
|
176
|
+
- Rakefile
|
177
|
+
- app/assets/javascripts/yodeler/application.js
|
178
|
+
- app/assets/stylesheets/yodeler/application.css
|
179
|
+
- app/controllers/yodeler/application_controller.rb
|
180
|
+
- app/helpers/yodeler/application_helper.rb
|
181
|
+
- app/views/layouts/yodeler/application.html.erb
|
182
|
+
- config/routes.rb
|
183
|
+
- lib/generators/yodeler/USAGE
|
184
|
+
- lib/generators/yodeler/install_generator.rb
|
185
|
+
- lib/generators/yodeler/templates/initializer.rb
|
186
|
+
- lib/generators/yodeler/templates/migration.rb
|
187
|
+
- lib/tasks/yodeler_tasks.rake
|
188
|
+
- lib/yodeler.rb
|
189
|
+
- lib/yodeler/configuration.rb
|
190
|
+
- lib/yodeler/engine.rb
|
191
|
+
- lib/yodeler/listens_to_yodler.rb
|
192
|
+
- lib/yodeler/models/event.rb
|
193
|
+
- lib/yodeler/models/event_type.rb
|
194
|
+
- lib/yodeler/models/event_types/base.rb
|
195
|
+
- lib/yodeler/models/event_types/noop_event_type.rb
|
196
|
+
- lib/yodeler/models/notification.rb
|
197
|
+
- lib/yodeler/models/subscription.rb
|
198
|
+
- lib/yodeler/version.rb
|
199
|
+
homepage: http://github.com/coryodaniel/yodeler
|
200
|
+
licenses: []
|
201
|
+
metadata: {}
|
202
|
+
post_install_message:
|
203
|
+
rdoc_options: []
|
204
|
+
require_paths:
|
205
|
+
- lib
|
206
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
207
|
+
requirements:
|
208
|
+
- - '>='
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
version: '0'
|
211
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - '>='
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
requirements: []
|
217
|
+
rubyforge_project: yodeler
|
218
|
+
rubygems_version: 2.2.2
|
219
|
+
signing_key:
|
220
|
+
specification_version: 4
|
221
|
+
summary: Subscribable database-stored event notifications for Rails
|
222
|
+
test_files: []
|