streama 0.3.2 → 0.3.4

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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
@@ -0,0 +1,2 @@
1
+ rvm:
2
+ - 1.9.2
data/Gemfile CHANGED
@@ -1,10 +1,4 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "activesupport", "~> 3.0"
4
- gem "mongoid", "~> 2.0"
5
-
6
- group :development do
7
- gem "rspec", "~> 2.3.0"
8
- gem "bundler", "~> 1.0.0"
9
- gem "jeweler", "~> 1.6.1"
10
- end
3
+ # Specify your gem's dependencies in streama.gemspec
4
+ gemspec
@@ -1,43 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ streama (0.3.3)
5
+
1
6
  GEM
2
7
  remote: http://rubygems.org/
3
8
  specs:
4
- activemodel (3.0.7)
5
- activesupport (= 3.0.7)
6
- builder (~> 2.1.2)
7
- i18n (~> 0.5.0)
8
- activesupport (3.0.7)
9
- bson (1.3.1)
10
- builder (2.1.2)
11
- diff-lcs (1.1.2)
12
- git (1.2.5)
13
- i18n (0.5.0)
14
- jeweler (1.6.1)
15
- bundler (~> 1.0.0)
16
- git (>= 1.2.5)
17
- rake
18
- mongo (1.3.1)
19
- bson (>= 1.3.1)
20
- mongoid (2.0.2)
21
- activemodel (~> 3.0)
9
+ activemodel (3.2.1)
10
+ activesupport (= 3.2.1)
11
+ builder (~> 3.0.0)
12
+ activesupport (3.2.1)
13
+ i18n (~> 0.6)
14
+ multi_json (~> 1.0)
15
+ bson (1.5.2)
16
+ bson_ext (1.5.2)
17
+ bson (= 1.5.2)
18
+ builder (3.0.0)
19
+ diff-lcs (1.1.3)
20
+ i18n (0.6.0)
21
+ mongo (1.5.2)
22
+ bson (= 1.5.2)
23
+ mongoid (2.4.3)
24
+ activemodel (~> 3.1)
22
25
  mongo (~> 1.3)
23
26
  tzinfo (~> 0.3.22)
24
- rake (0.9.0)
25
- rspec (2.3.0)
26
- rspec-core (~> 2.3.0)
27
- rspec-expectations (~> 2.3.0)
28
- rspec-mocks (~> 2.3.0)
29
- rspec-core (2.3.1)
30
- rspec-expectations (2.3.0)
27
+ multi_json (1.0.4)
28
+ rake (0.9.2.2)
29
+ rspec (2.6.0)
30
+ rspec-core (~> 2.6.0)
31
+ rspec-expectations (~> 2.6.0)
32
+ rspec-mocks (~> 2.6.0)
33
+ rspec-core (2.6.4)
34
+ rspec-expectations (2.6.0)
31
35
  diff-lcs (~> 1.1.2)
32
- rspec-mocks (2.3.0)
33
- tzinfo (0.3.27)
36
+ rspec-mocks (2.6.0)
37
+ tzinfo (0.3.31)
34
38
 
35
39
  PLATFORMS
36
40
  ruby
37
41
 
38
42
  DEPENDENCIES
39
- activesupport (~> 3.0)
40
- bundler (~> 1.0.0)
41
- jeweler (~> 1.6.1)
42
- mongoid (~> 2.0)
43
- rspec (~> 2.3.0)
43
+ bson_ext (~> 1.5)
44
+ mongoid (~> 2.4)
45
+ rake
46
+ rspec (~> 2.5)
47
+ streama!
@@ -0,0 +1,134 @@
1
+ # Streama
2
+
3
+ **ALPHA**
4
+
5
+ Streama is a simple Ruby activity stream gem for use with the Mongoid ODM framework.
6
+
7
+ [![travis](https://secure.travis-ci.org/christospappas/streama.png)](http://travis-ci.org/christospappas/streama)
8
+
9
+ ## Install
10
+
11
+ gem install streama
12
+
13
+ ## Usage
14
+
15
+ ### Define Activities
16
+
17
+ Create an Activity model and define the activities and the fields you would like to cache within the activity.
18
+
19
+ An activity consists of an actor, a verb, an object, and a target.
20
+
21
+ ``` ruby
22
+ class Activity
23
+ include Streama::Activity
24
+
25
+ activity :new_photo do
26
+ actor :user, :cache => [:full_name]
27
+ object :photo, :cache => [:subject, :comment]
28
+ target_object :album, :cache => [:title]
29
+ end
30
+
31
+ end
32
+ ```
33
+
34
+ The activity verb is implied from the activity name, in the above example the verb is :new_photo
35
+
36
+ The object may be the entity performing the activity, or the entity on which the activity was performed.
37
+ e.g John(actor) shared a video(object)
38
+
39
+ The target is the object that the verb is enacted on.
40
+ e.g. Geraldine(actor) posted a photo(object) to her album(target)
41
+
42
+ This is based on the Activity Streams 1.0 specification (http://activitystrea.ms)
43
+
44
+ ### Setup Actors
45
+
46
+ Include the Actor module in a class and override the default followers method.
47
+
48
+ ``` ruby
49
+ class User
50
+ include Mongoid::Document
51
+ include Streama::Actor
52
+
53
+ field :full_name, :type => String
54
+
55
+ def followers
56
+ User.excludes(:id => self.id).all
57
+ end
58
+ end
59
+ ```
60
+
61
+ ### Setup Indexes
62
+
63
+ Create the indexes for the Activities collection. You can do so by calling the create_indexes method.
64
+
65
+ ``` ruby
66
+ Activity.create_indexes
67
+ ```
68
+
69
+ ### Publishing Activity
70
+
71
+ In your controller or background worker:
72
+
73
+ ``` ruby
74
+ current_user.publish_activity(:new_photo, :object => @photo, :target_object => @album)
75
+ ```
76
+
77
+ This will publish the activity to the mongoid objects returned by the #followers method in the Actor.
78
+
79
+ To send your activity to different receievers, pass in an additional :receivers parameter.
80
+
81
+ ``` ruby
82
+ current_user.publish_activity(:new_photo, :object => @photo, :target_object => @album, :receivers => :friends) # calls friends method
83
+ ```
84
+
85
+ ``` ruby
86
+ current_user.publish_activity(:new_photo, :object => @photo, :target_object => @album, :receivers => current_user.find(:all, :conditions => {:group_id => mygroup}))
87
+ ```
88
+
89
+ ## Retrieving Activity
90
+
91
+ To retrieve all activity for an actor
92
+
93
+ ``` ruby
94
+ current_user.activity_stream
95
+ ```
96
+
97
+ To retrieve and filter to a particular activity type
98
+
99
+ ``` ruby
100
+ current_user.activity_stream(:type => :activity_verb)
101
+ ```
102
+ If you need to return the instance of an :actor, :object or :target_object from an activity call the Activity#load_instance method
103
+
104
+ ``` ruby
105
+ activity.load_instance(:actor)
106
+ ```
107
+
108
+ You can also refresh the cached activity data by calling the Activity#refresh_data method
109
+
110
+ ``` ruby
111
+ activity.refresh_data
112
+ ```
113
+
114
+ ## Upgrading
115
+
116
+ ### 0.3.3
117
+
118
+ The Activity "target" field was renamed to "target_object". If you are upgrading from a previous version of Streama you will need to rename the field in existing documents.
119
+
120
+ http://www.mongodb.org/display/DOCS/Updating#Updating-%24rename
121
+
122
+ ## Contributing
123
+
124
+ Once you've made your great commits
125
+
126
+ 1. Fork
127
+ 1. Create a topic branch - git checkout -b my_branch
128
+ 1. Push to your branch - git push origin my_branch
129
+ 1. Create a Pull Request from your branch
130
+ 1. That's it!
131
+
132
+ ## Contributors
133
+
134
+ * Christos Pappas (@christospappas)
data/Rakefile CHANGED
@@ -1,46 +1,6 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "streama"
16
- gem.homepage = "http://github.com/christospappas/streama"
17
- gem.license = "MIT"
18
- gem.summary = %Q{Streama is a simple activity stream gem for use with the Mongoid ODM framework.}
19
- gem.description = %Q{Streama is a simple activity stream gem for use with the Mongoid ODM framework.}
20
- gem.email = "christos.pappas@gmail.com"
21
- gem.authors = ["Christos Pappas"]
22
- end
23
- Jeweler::RubygemsDotOrgTasks.new
24
-
25
- require 'rspec/core'
1
+ require "bundler/gem_tasks"
26
2
  require 'rspec/core/rake_task'
27
- RSpec::Core::RakeTask.new(:spec) do |spec|
28
- spec.pattern = FileList['spec/**/*_spec.rb']
29
- end
30
-
31
- RSpec::Core::RakeTask.new(:rcov) do |spec|
32
- spec.pattern = 'spec/**/*_spec.rb'
33
- spec.rcov = true
34
- end
35
-
36
- task :default => :spec
37
3
 
38
- require 'rake/rdoctask'
39
- Rake::RDocTask.new do |rdoc|
40
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
4
+ RSpec::Core::RakeTask.new(:spec)
41
5
 
42
- rdoc.rdoc_dir = 'rdoc'
43
- rdoc.title = "streama #{version}"
44
- rdoc.rdoc_files.include('README*')
45
- rdoc.rdoc_files.include('lib/**/*.rb')
46
- end
6
+ task default: :spec
@@ -1,7 +1,7 @@
1
- require 'mongoid'
2
- require 'streama/actor'
3
- require 'streama/activity'
4
- require 'streama/definition'
5
- require 'streama/definition_dsl'
6
- require 'streama/errors'
7
-
1
+ require "mongoid"
2
+ require "streama/version"
3
+ require "streama/actor"
4
+ require "streama/activity"
5
+ require "streama/definition"
6
+ require "streama/definition_dsl"
7
+ require "streama/errors"
@@ -7,16 +7,16 @@ module Streama
7
7
  include Mongoid::Document
8
8
  include Mongoid::Timestamps
9
9
 
10
- field :verb, :type => Symbol
11
- field :actor, :type => Hash
12
- field :object, :type => Hash
13
- field :target, :type => Hash
14
- field :receivers, :type => Array
10
+ field :verb, :type => Symbol
11
+ field :actor, :type => Hash
12
+ field :object, :type => Hash
13
+ field :target_object, :type => Hash
14
+ field :receivers, :type => Array
15
15
 
16
16
  index :name
17
17
  index [['actor._id', Mongo::ASCENDING], ['actor._type', Mongo::ASCENDING]]
18
18
  index [['object._id', Mongo::ASCENDING], ['object._type', Mongo::ASCENDING]]
19
- index [['target._id', Mongo::ASCENDING], ['target._type', Mongo::ASCENDING]]
19
+ index [['target_object._id', Mongo::ASCENDING], ['target_object._type', Mongo::ASCENDING]]
20
20
  index [['receivers.id', Mongo::ASCENDING], ['receivers.type', Mongo::ASCENDING]]
21
21
 
22
22
  validates_presence_of :actor, :verb
@@ -34,7 +34,7 @@ module Streama
34
34
  # activity(:enquiry) do
35
35
  # actor :user, :cache => [:full_name]
36
36
  # object :enquiry, :cache => [:subject]
37
- # target :listing, :cache => [:title]
37
+ # target_object :listing, :cache => [:title]
38
38
  # end
39
39
  #
40
40
  # @return [Definition] Returns the registered definition
@@ -63,62 +63,58 @@ module Streama
63
63
 
64
64
  end
65
65
 
66
-
67
- module InstanceMethods
68
-
69
- # Publishes the activity to the receivers
70
- #
71
- # @param [ Hash ] options The options to publish with.
72
- #
73
- def publish(options = {})
74
- actor = load_instance(:actor)
75
- self.receivers = (options[:receivers] || actor.followers).map { |r| { :id => r.id, :type => r.class.to_s } }
76
- self.save
77
- self
78
- end
79
-
80
- # Returns an instance of an actor, object or target
81
- #
82
- # @param [ Symbol ] type The data type (actor, object, target) to return an instance for.
83
- #
84
- # @return [Mongoid::Document] document A mongoid document instance
85
- def load_instance(type)
86
- (data = self.send(type)).is_a?(Hash) ? data['type'].to_s.camelcase.constantize.find(data['id']) : data
87
- end
88
66
 
89
- def refresh_data
90
- assign_data
91
- save(:validate => false)
92
- end
67
+ # Publishes the activity to the receivers
68
+ #
69
+ # @param [ Hash ] options The options to publish with.
70
+ #
71
+ def publish(options = {})
72
+ actor = load_instance(:actor)
73
+ self.receivers = (options[:receivers] || actor.followers).map { |r| { :id => r.id, :type => r.class.to_s } }
74
+ self.save
75
+ self
76
+ end
93
77
 
94
- protected
95
-
96
- def assign_data
78
+ # Returns an instance of an actor, object or target
79
+ #
80
+ # @param [ Symbol ] type The data type (actor, object, target) to return an instance for.
81
+ #
82
+ # @return [Mongoid::Document] document A mongoid document instance
83
+ def load_instance(type)
84
+ (data = self.send(type)).is_a?(Hash) ? data['type'].to_s.camelcase.constantize.find(data['id']) : data
85
+ end
86
+
87
+ def refresh_data
88
+ assign_data
89
+ save(:validate => false)
90
+ end
91
+
92
+ protected
97
93
 
98
- [:actor, :object, :target].each do |type|
99
- next unless object = load_instance(type)
94
+ def assign_data
95
+
96
+ [:actor, :object, :target_object].each do |type|
97
+ next unless object = load_instance(type)
100
98
 
101
- class_sym = object.class.name.underscore.to_sym
99
+ class_sym = object.class.name.underscore.to_sym
102
100
 
103
- raise Streama::InvalidData.new(class_sym) unless definition.send(type).has_key?(class_sym)
104
-
105
- hash = {'id' => object.id, 'type' => object.class.name}
106
-
107
- if fields = definition.send(type)[class_sym][:cache]
108
- fields.each do |field|
109
- raise Streama::InvalidField.new(field) unless object.respond_to?(field)
110
- hash[field.to_s] = object.send(field)
111
- end
101
+ raise Streama::InvalidData.new(class_sym) unless definition.send(type).has_key?(class_sym)
102
+
103
+ hash = {'id' => object.id, 'type' => object.class.name}
104
+
105
+ if fields = definition.send(type)[class_sym].try(:[],:cache)
106
+ fields.each do |field|
107
+ raise Streama::InvalidField.new(field) unless object.respond_to?(field)
108
+ hash[field.to_s] = object.send(field)
112
109
  end
113
- write_attribute(type, hash)
114
110
  end
111
+ write_attribute(type, hash)
115
112
  end
116
-
117
- def definition
118
- @definition ||= Streama::Definition.find(verb)
119
- end
120
-
113
+ end
114
+
115
+ def definition
116
+ @definition ||= Streama::Definition.find(verb)
121
117
  end
122
118
 
123
119
  end
124
- end
120
+ end
@@ -15,29 +15,25 @@ module Streama
15
15
 
16
16
  end
17
17
 
18
- module InstanceMethods
19
-
20
- # Publishes the activity to the receivers
21
- #
22
- # @param [ Hash ] options The options to publish with.
23
- #
24
- # @example publish an activity with a object and target
25
- # current_user.publish_activity(:enquiry, :object => @enquiry, :target => @listing)
26
- #
27
- def publish_activity(name, options={})
28
- options[:receivers] = self.send(options[:receivers]) if options[:receivers].is_a?(Symbol)
29
- activity = activity_class.publish(name, {:actor => self}.merge(options))
30
- end
31
-
32
- def activity_stream(options = {})
33
- activity_class.stream_for(self, options)
34
- end
35
-
36
- def activity_class
37
- @activity_klass ||= activity_klass ? activity_klass.classify.constantize : ::Activity
38
- end
18
+ # Publishes the activity to the receivers
19
+ #
20
+ # @param [ Hash ] options The options to publish with.
21
+ #
22
+ # @example publish an activity with a object and target
23
+ # current_user.publish_activity(:enquiry, :object => @enquiry, :target => @listing)
24
+ #
25
+ def publish_activity(name, options={})
26
+ options[:receivers] = self.send(options[:receivers]) if options[:receivers].is_a?(Symbol)
27
+ activity = activity_class.publish(name, {:actor => self}.merge(options))
28
+ end
29
+
30
+ def activity_stream(options = {})
31
+ activity_class.stream_for(self, options)
39
32
  end
40
33
 
41
- end
34
+ def activity_class
35
+ @activity_klass ||= activity_klass ? activity_klass.classify.constantize : ::Activity
36
+ end
37
+ end
42
38
 
43
39
  end