bustle 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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bustle.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,216 @@
1
+ # Bustle
2
+
3
+ Activities recording and retrieving using a simple Pub/Sub architecture.
4
+
5
+ The typical use cases are:
6
+
7
+ - Timeline (e.g. tracking activities such as posting and commenting for users)
8
+ - Logging
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'bustle'
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ### Configuration
21
+
22
+ First of all, you will need to configure Bustle. If you are using Rails, you can put the following code in an initializer (e.g. `config/initializers/bustle.rb`).
23
+
24
+ ```ruby
25
+ Bustle.config do |c|
26
+ # Specify an intepreter strategy for intepreting app data
27
+ # i.e. what your application uses for persistence
28
+ # Bustle ships with an ActiveRecord intepreter strategy
29
+ c.intepreter = Bustle::Intepreter::ActiveRecord
30
+
31
+ # Specify a storage strategy for storing activities
32
+ # Bustle ships with an ActiveRecord storage strategy
33
+ c.storage = Bustle::Storage::ActiveRecord
34
+ end
35
+ ```
36
+
37
+ For ActiveRecord, you will need the following migration file:
38
+
39
+ ```ruby
40
+ class CreateBustleTables < ActiveRecord::Migration
41
+ def change
42
+ create_table :bustle_activities do |t|
43
+ t.string :reference_class
44
+ t.integer :reference_id
45
+ t.string :action
46
+ t.integer :publisher_id, :null => false
47
+ t.timestamps
48
+ end
49
+
50
+ create_table :bustle_publishers do |t|
51
+ t.string :reference_class, :null => false
52
+ t.integer :reference_id, :null => false
53
+ t.timestamps
54
+ end
55
+
56
+ create_table :bustle_subscribers do |t|
57
+ t.string :reference_class, :null => false
58
+ t.integer :reference_id, :null => false
59
+ t.timestamps
60
+ end
61
+
62
+ create_table :bustle_subscriptions do |t|
63
+ t.integer :publisher_id, :null => false
64
+ t.string :subscriber_id, :null => false
65
+ t.timestamps
66
+ end
67
+
68
+ add_index :bustle_activities, :publisher_id
69
+ add_index :bustle_publishers, [:reference_class, :reference_id], :unique => true
70
+ add_index :bustle_subscribers, [:reference_class, :reference_id], :unique => true
71
+ add_index :bustle_subscriptions, :publisher_id
72
+ add_index :bustle_subscriptions, :subscriber_id
73
+ add_index :bustle_subscriptions, [:publisher_id, :subscriber_id], :unique => true
74
+ end
75
+ end
76
+ ```
77
+
78
+ ### Flow
79
+
80
+ Upon subscribing:
81
+
82
+ 1. Subscriber registers itself if not already registered
83
+ 2. Publisher registers itself if not already registered
84
+ 3. A Subscription is created for Subscriber and Publisher
85
+
86
+ When activities occur:
87
+
88
+ 1. Publisher registers itself if not already registered
89
+ 2. Publisher publishes activity
90
+
91
+ ### API
92
+
93
+ #### Register a Subscriber
94
+
95
+ ```ruby
96
+ Bustle::Subscribers.add subscriber
97
+
98
+ # example
99
+ user = User.find(1)
100
+ Bustle::Subscribers.add user
101
+ ```
102
+
103
+ #### Register a Publisher
104
+
105
+ ```ruby
106
+ Bustle::Publishers.add publisher
107
+
108
+ # example
109
+ post = Post.find(1)
110
+ Bustle::Publishers.add post
111
+ ```
112
+
113
+ #### Create a Subscription
114
+
115
+ ```ruby
116
+ Bustle::Subscriptions.add bustle_publisher, bustle_subscriber
117
+
118
+ # example
119
+ publisher = Bustle::Publishers.find(Post.first)
120
+ subscriber = Bustle::Subscribers.find(User.first)
121
+ Bustle::Subscriptions.add publisher, subscriber
122
+ ```
123
+
124
+ #### Find a Subscriber/Publisher/Subscription
125
+
126
+ ```ruby
127
+ Bustle::Subscribers.find subscriber
128
+ Bustle::Publishers.find publisher
129
+ Bustle::Subscriptions.find bustle_publisher, bustle_subscriber # => Bustle::Subscription
130
+ Bustle::Subscriptions.find bustle_publisher # => an array of Bustle::Subscription for the publisher
131
+ Bustle::Subscriptions.find bustle_subscriber # => an array of Bustle::Subscription for the subscriber
132
+ ```
133
+
134
+ #### Remove a Subscriber/Publisher/Subscription
135
+
136
+ ```ruby
137
+ Bustle::Subscribers.remove subscriber
138
+ Bustle::Publishers.remove publisher
139
+ Bustle::Subscriptions.remove bustle_publisher, bustle_subscriber
140
+ ```
141
+
142
+ Or:
143
+
144
+ ```ruby
145
+ Bustle::Subscribers.find(subscriber).destroy
146
+ Bustle::Publishers.find(publisher).destroy
147
+ Bustle::Subscriptions.find(bustle_publisher, bustle_subscriber).destroy
148
+ ```
149
+
150
+ #### Publish an Activity
151
+
152
+ ```ruby
153
+ Bustle::Activities.add bustle_publisher, action, activity
154
+ # or
155
+ Bustle::Publisher.publish action, activity
156
+
157
+ # example
158
+ post = Post.find(1)
159
+ comment = post.comments.add(:content => "I'm a comment")
160
+ Bustle::Publishers.add post
161
+ publisher = Bustle::Publishers.find post
162
+ publisher.publish 'new', comment
163
+ ```
164
+
165
+ #### Activities
166
+
167
+ ##### Retrieve Activities for a Subscriber
168
+
169
+ ```ruby
170
+ Bustle::Activities.for bustle_subscriber
171
+ # or
172
+ Bustle::Subscriber.activities
173
+
174
+ # example
175
+ subscriber = Bustle::Subscribers.find(User.first)
176
+ subscriber.activities
177
+ ```
178
+
179
+ ##### Retrieve Activities by a Publisher
180
+
181
+ ```ruby
182
+ Bustle::Activities.by bustle_publisher
183
+ # or
184
+ Bustle::Publisher.activities
185
+
186
+ # example
187
+ publisher = Bustle::Publishers.find(Post.first)
188
+ publisher.activities
189
+ ```
190
+
191
+ ##### Activities Filtering
192
+
193
+ ```ruby
194
+ Bustle::Activities.for(bustle_subscriber).filter :key => :value
195
+ # or
196
+ Bustle::Subscriber.activities.filter :key => :value
197
+
198
+ # example
199
+ subscriber = Bustle::Subscribers.find(User.first)
200
+ subscriber.activities.filter :action => 'new'
201
+ subscriber.activities.by(publisher).filter(:action => 'new')
202
+ ```
203
+
204
+ Activities are normal enumerable objects from your chosen storage, so in ActiveRecord's case, you may use any Arel methods to query the result:
205
+
206
+ ```ruby
207
+ subscriber.activities.filter(:action => 'new').order('created_at ASC').limit(10)
208
+ ```
209
+
210
+ ## License
211
+
212
+ This gem is released under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
213
+
214
+ ## Author
215
+
216
+ [Fred Wu](https://github.com/fredwu), originally built for [500 Startups](http://500.co).
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs.push 'lib'
7
+ t.test_files = FileList['specs/**/*_spec.rb']
8
+ t.verbose = true
9
+ end
10
+
11
+ task :default => :test
data/bustle.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/bustle/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Fred Wu"]
6
+ gem.email = ["ifredwu@gmail.com"]
7
+ gem.description = %q{Activities recording and retrieving using a simple Pub/Sub architecture.}
8
+ gem.summary = gem.description
9
+ gem.homepage = "https://github.com/fredwu/bustle"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "bustle"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Bustle::VERSION
17
+
18
+ gem.add_development_dependency 'rake'
19
+ gem.add_development_dependency 'simplecov'
20
+ gem.add_development_dependency 'minitest-colorize'
21
+ end
@@ -0,0 +1,3 @@
1
+ module Bustle
2
+ VERSION = "0.0.1"
3
+ end
data/lib/bustle.rb ADDED
@@ -0,0 +1 @@
1
+ require "bustle/version"
@@ -0,0 +1,8 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'minitest-colorize'
5
+ require 'minitest/autorun'
6
+ require 'minitest/spec'
7
+
8
+ require File.expand_path('../../lib/bustle', __FILE__)
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bustle
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Fred Wu
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: simplecov
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: minitest-colorize
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Activities recording and retrieving using a simple Pub/Sub architecture.
63
+ email:
64
+ - ifredwu@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - README.md
72
+ - Rakefile
73
+ - bustle.gemspec
74
+ - lib/bustle.rb
75
+ - lib/bustle/version.rb
76
+ - lib/specs/spec_helper.rb
77
+ homepage: https://github.com/fredwu/bustle
78
+ licenses: []
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ segments:
90
+ - 0
91
+ hash: 3392583862411400704
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ segments:
99
+ - 0
100
+ hash: 3392583862411400704
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 1.8.24
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Activities recording and retrieving using a simple Pub/Sub architecture.
107
+ test_files: []