activist 0.0.2

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,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ .rspec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in activist.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ activist (0.0.1)
5
+ activesupport (~> 3.0)
6
+ redis (~> 2.2)
7
+ redis-namespace (= 0.10.0)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activemodel (3.0.7)
13
+ activesupport (= 3.0.7)
14
+ builder (~> 2.1.2)
15
+ i18n (~> 0.5.0)
16
+ activerecord (3.0.7)
17
+ activemodel (= 3.0.7)
18
+ activesupport (= 3.0.7)
19
+ arel (~> 2.0.2)
20
+ tzinfo (~> 0.3.23)
21
+ activesupport (3.0.7)
22
+ arel (2.0.9)
23
+ builder (2.1.2)
24
+ diff-lcs (1.1.2)
25
+ i18n (0.5.0)
26
+ redis (2.2.0)
27
+ redis-namespace (0.10.0)
28
+ redis (< 3.0.0)
29
+ rspec (2.5.0)
30
+ rspec-core (~> 2.5.0)
31
+ rspec-expectations (~> 2.5.0)
32
+ rspec-mocks (~> 2.5.0)
33
+ rspec-core (2.5.1)
34
+ rspec-expectations (2.5.0)
35
+ diff-lcs (~> 1.1.2)
36
+ rspec-mocks (2.5.0)
37
+ sqlite3 (1.3.3)
38
+ sqlite3-ruby (1.3.3)
39
+ sqlite3 (>= 1.3.3)
40
+ tzinfo (0.3.27)
41
+
42
+ PLATFORMS
43
+ ruby
44
+
45
+ DEPENDENCIES
46
+ activerecord (~> 3.0)
47
+ activist!
48
+ bundler (~> 1.0)
49
+ rspec (~> 2.0)
50
+ sqlite3-ruby (~> 1.3.2)
data/LICENCE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Adrian Dulić
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.markdown ADDED
@@ -0,0 +1,49 @@
1
+ # Activist #
2
+
3
+ Activity stream in rails 3.0 applications
4
+
5
+ Based on http://activitystrea.ms/spec/1.0/atom-activity-01.html
6
+
7
+ ## Installation ##
8
+
9
+ Just run the following command :
10
+
11
+ gem install activist
12
+
13
+ Then in your Gemfile add the following line :
14
+
15
+ gem 'activist'
16
+
17
+ And run
18
+
19
+ bundle install
20
+
21
+ ## Usage ##
22
+
23
+ First generate a friendship model :
24
+
25
+ rails generate activist:install
26
+
27
+ This command creates a new model called __Action__ in *'app/models'* :
28
+
29
+ class Status < ActiveRecord::Base
30
+ serialize :data, Hash
31
+ end
32
+
33
+ It also creates a new migration for the Status model so don't forget to migrate your database :
34
+
35
+ rake db:migrate
36
+
37
+ Then add __activist__ in your user model :
38
+
39
+ class User < ActiveRecord::Base
40
+ include Activist::Actor
41
+
42
+ stream :public do
43
+ all
44
+ end
45
+
46
+ stream :private do
47
+ [user]
48
+ end
49
+ end
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
6
+
7
+ Rspec::Core::RakeTask.new(:spec)
data/activist.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "activist/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "activist"
7
+ s.version = Activist::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Adrian Dulić"]
10
+ s.email = ["adulic@gmail.com"]
11
+ s.homepage = "http://github.com/adriandulic/activist"
12
+ s.summary = %q{Activity stream in rails 3.0 application}
13
+ s.description = %q{Activity stream in rails 3.0 application}
14
+
15
+ s.extra_rdoc_files = ["README.markdown"]
16
+
17
+ s.required_rubygems_version = ">= 1.3.6"
18
+ s.rubyforge_project = s.name
19
+
20
+ s.add_dependency "redis", "~> 2.2"
21
+ s.add_dependency "redis-namespace", "0.10.0"
22
+ s.add_dependency "activesupport", "~> 3.0"
23
+
24
+ s.add_development_dependency "bundler", "~> 1.0"
25
+ s.add_development_dependency "rspec", "~> 2.0"
26
+ s.add_development_dependency "activerecord", "~> 3.0"
27
+ s.add_development_dependency "sqlite3-ruby", "~> 1.3.2"
28
+
29
+ s.files = `git ls-files`.split("\n")
30
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
31
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
32
+ s.require_paths = ["lib"]
33
+ end
data/lib/activist.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'active_support/configurable'
2
+ require 'active_support/concern'
3
+ require 'redis/namespace'
4
+ require 'redis'
5
+
6
+ module Activist
7
+ autoload :Redis, 'activist/redis'
8
+ autoload :Store, 'activist/store'
9
+ autoload :Actor, 'activist/actor'
10
+ autoload :Action, 'activist/action'
11
+ autoload :Stream, 'activist/stream'
12
+ end
@@ -0,0 +1,25 @@
1
+ module Activist
2
+ module Action
3
+ extend ActiveSupport::Concern
4
+ include Store
5
+
6
+ module ClassMethods
7
+ def activities(stream, options = {})
8
+ options.symbolize_keys!
9
+ callback = options[:when]
10
+
11
+ define_method "activist_#{stream}_#{callback}" do
12
+ store_activities(stream, options)
13
+ end
14
+
15
+ send(callback, "activist_#{stream}_#{callback}")
16
+ end
17
+ end
18
+
19
+ module InstanceMethods
20
+ def activity(stream, options = {})
21
+ store_activities(stream, options)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module Activist
2
+ module Actor
3
+ def self.included(receiver)
4
+ receiver.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def stream(stream, &block)
9
+ define_method "#{stream}_stream" do
10
+ Activist::Stream.new(stream, self, block)
11
+ end
12
+
13
+ after_destroy "delete_activist_#{stream}_stream"
14
+
15
+ private
16
+
17
+ define_method "delete_activist_#{stream}_stream" do
18
+ send("#{stream}_stream").destroy
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ module Activist
2
+ class Redis
3
+ include ActiveSupport::Configurable
4
+
5
+ config_accessor :host, :port, :db
6
+
7
+ def self.execute
8
+ @connection ||= ::Redis.new(:host => host || 'localhost', :port => port || 6379, :db => db || nil)
9
+ @redis ||= ::Redis::Namespace.new(:activist, :redis => @connection)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,53 @@
1
+ module Activist
2
+ module Store
3
+ extend ActiveSupport::Concern
4
+
5
+ module InstanceMethods
6
+ def store_activities(stream, options = {})
7
+ options.symbolize_keys!
8
+ callback = options.delete(:when)
9
+ actor = case options[:actor]
10
+ when nil
11
+ send(:user)
12
+ when Symbol
13
+ send(options[:actor])
14
+ when Proc
15
+ options[:actor].call(self)
16
+ else
17
+ options[:actor]
18
+ end
19
+ action = if options[:action].nil?
20
+ case callback
21
+ when :before_create, :after_create
22
+ options[:action] = :created
23
+ when :before_save, :after_save
24
+ options[:action] = :saved
25
+ when :before_update, :after_update
26
+ options[:action] = :updated
27
+ when :before_destroy, :after_destroy
28
+ options[:action] = :destroyed
29
+ else
30
+ options[:action] = :undefined
31
+ end
32
+ else
33
+ options[:action]
34
+ end
35
+ data = options[:data]
36
+
37
+ status = ::Status.create! do |s|
38
+ s.actor_class = actor.class.to_s
39
+ s.actor_id = actor.id
40
+ s.action = action
41
+ s.target_class = self.class.to_s
42
+ s.target_id = self.id
43
+ s.data = data
44
+ s.created_at = Time.now.utc
45
+ end
46
+
47
+ actor.send("#{stream}_stream").subscribers.each do |subscriber|
48
+ Redis.execute.lpush("#{subscriber.class}.#{subscriber.id}:#{stream}", status.id)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,34 @@
1
+ module Activist
2
+ class Stream
3
+ attr_reader :name, :actor, :subscribers
4
+
5
+ def initialize(name, actor, block)
6
+ @name = name.to_sym
7
+ @actor = actor
8
+ scoped = block.call(actor)
9
+ @subscribers = case scoped
10
+ when Symbol
11
+ actor.class.send(scoped)
12
+ when Array
13
+ scoped
14
+ end
15
+ end
16
+
17
+ def all(options={})
18
+ activities = Redis.execute.lrange(to_key, options[:offset] || 0, options[:limit] || size)
19
+ ::Status.where(:id => activities)
20
+ end
21
+
22
+ def size
23
+ @size ||= Redis.execute.llen(to_key)
24
+ end
25
+
26
+ def destroy
27
+ Redis.execute.del(to_key)
28
+ end
29
+
30
+ def to_key
31
+ "#{@actor.class}.#{@actor.id}:#{@name}"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module Activist
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,24 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module Activist
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+
9
+ def self.source_root
10
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
11
+ end
12
+
13
+ def self.next_migration_number
14
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
15
+ end
16
+
17
+ desc "This generator creates a status model and its migration file"
18
+ def create_friendship_model_files
19
+ template 'status.rb', 'app/models/status.rb'
20
+ template 'create_statuses.rb', "db/migrate/#{self.class.next_migration_number}_create_statuses.rb"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ class CreateStatuses < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :statuses do |t|
4
+ t.string :actor_class
5
+ t.integer :actor_id
6
+ t.string :action
7
+ t.string :target_class
8
+ t.integer :target_id
9
+ t.text :data
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+
15
+ def self.down
16
+ drop_table :statuses
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ class Status < ActiveRecord::Base
2
+ serialize :data, Hash
3
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Activist do
4
+ before do
5
+ @region = Region.create!(:name => "Mazovia")
6
+ @kate = User.create!(:name => "Kate", :regions => Region.all)
7
+ @john = User.create!(:name => "John", :regions => Region.all)
8
+ end
9
+
10
+ context "actor" do
11
+ it "should create streams for actor" do
12
+ @kate.public_stream.should be_kind_of Activist::Stream
13
+ @kate.regional_stream.should be_kind_of Activist::Stream
14
+ @kate.private_stream.should be_kind_of Activist::Stream
15
+ end
16
+ end
17
+
18
+ context "action" do
19
+ end
20
+
21
+ context "stream" do
22
+ end
23
+ end
data/spec/setup.rb ADDED
@@ -0,0 +1,85 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection(
4
+ :adapter => "sqlite3",
5
+ :database => ":memory:"
6
+ )
7
+ ActiveRecord::Migration.verbose = false
8
+
9
+ ActiveRecord::Schema.define do
10
+ create_table :statuses, :force => true do |t|
11
+ t.string :actor_class
12
+ t.integer :actor_id
13
+ t.string :action
14
+ t.string :target_class
15
+ t.integer :target_id
16
+ t.text :data
17
+ t.datetime :created_at
18
+ t.datetime :updated_at
19
+ end
20
+
21
+ create_table :regions, :force => true do |t|
22
+ t.string :name
23
+ end
24
+
25
+ create_table :regions_users, :id => false, :force => true do |t|
26
+ t.integer :user_id
27
+ t.integer :region_id
28
+ end
29
+
30
+ create_table :users, :force => true do |t|
31
+ t.string :name
32
+ end
33
+
34
+ create_table :notes, :force => true do |t|
35
+ t.integer :user_id
36
+ t.string :note
37
+ end
38
+ end
39
+
40
+ Activist::Redis.host = 'localhost'
41
+ Activist::Redis.port = 6379
42
+ Activist::Redis.execute.flushall
43
+
44
+ class Status < ActiveRecord::Base
45
+ serialize :data, Hash
46
+ end
47
+
48
+ class Region < ActiveRecord::Base
49
+ has_and_belongs_to_many :users
50
+ end
51
+
52
+ class User < ActiveRecord::Base
53
+ include Activist::Actor
54
+ has_many :notes
55
+ has_and_belongs_to_many :regions
56
+
57
+ stream :public do
58
+ all
59
+ end
60
+
61
+ stream :regional do |user|
62
+ User.joins(:regions).where(:'regions.id' => user.regions).all
63
+ end
64
+
65
+ stream :private do |user|
66
+ [user]
67
+ end
68
+ end
69
+
70
+ class Note < ActiveRecord::Base
71
+ include Activist::Action
72
+ belongs_to :user
73
+
74
+ activities :regional, :when => :after_create
75
+ activities :private, :when => :after_create
76
+
77
+ after_destroy do |note|
78
+ activity :private, :action => :deleted
79
+ end
80
+
81
+ def test
82
+ self.note = "#{self.note}. Tested."
83
+ activity :private, :action => :tested
84
+ end
85
+ end
@@ -0,0 +1,3 @@
1
+ require 'rspec'
2
+ require 'activist'
3
+ require 'setup'
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activist
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - "Adrian Duli\xC4\x87"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-29 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: redis
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: "2.2"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: redis-namespace
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - "="
33
+ - !ruby/object:Gem::Version
34
+ version: 0.10.0
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: activesupport
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: "3.0"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: bundler
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: "1.0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: rspec
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: "2.0"
68
+ type: :development
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: activerecord
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: "3.0"
79
+ type: :development
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: sqlite3-ruby
83
+ prerelease: false
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 1.3.2
90
+ type: :development
91
+ version_requirements: *id007
92
+ description: Activity stream in rails 3.0 application
93
+ email:
94
+ - adulic@gmail.com
95
+ executables: []
96
+
97
+ extensions: []
98
+
99
+ extra_rdoc_files:
100
+ - README.markdown
101
+ files:
102
+ - .gitignore
103
+ - Gemfile
104
+ - Gemfile.lock
105
+ - LICENCE
106
+ - README.markdown
107
+ - Rakefile
108
+ - activist.gemspec
109
+ - lib/activist.rb
110
+ - lib/activist/action.rb
111
+ - lib/activist/actor.rb
112
+ - lib/activist/redis.rb
113
+ - lib/activist/store.rb
114
+ - lib/activist/stream.rb
115
+ - lib/activist/version.rb
116
+ - lib/generators/activist/install/install_generator.rb
117
+ - lib/generators/activist/install/templates/create_statuses.rb
118
+ - lib/generators/activist/install/templates/status.rb
119
+ - spec/activist_spec.rb
120
+ - spec/setup.rb
121
+ - spec/spec_helper.rb
122
+ homepage: http://github.com/adriandulic/activist
123
+ licenses: []
124
+
125
+ post_install_message:
126
+ rdoc_options: []
127
+
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: "0"
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: 1.3.6
142
+ requirements: []
143
+
144
+ rubyforge_project: activist
145
+ rubygems_version: 1.7.2
146
+ signing_key:
147
+ specification_version: 3
148
+ summary: Activity stream in rails 3.0 application
149
+ test_files:
150
+ - spec/activist_spec.rb
151
+ - spec/setup.rb
152
+ - spec/spec_helper.rb