activity_stream 0.0.2 → 0.0.3

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/Gemfile CHANGED
@@ -3,4 +3,5 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in activity_stream.gemspec
4
4
  gemspec
5
5
 
6
- gem "sqlite3-ruby", :require => "sqlite3"
6
+ gem "sqlite3-ruby", :require => "sqlite3"
7
+ gem "ruby-debug"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- activity_stream (0.0.1)
4
+ activity_stream (0.0.3)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -28,10 +28,12 @@ GEM
28
28
  celerity (0.8.2)
29
29
  childprocess (0.1.3)
30
30
  ffi (~> 0.6.3)
31
+ columnize (0.3.1)
31
32
  culerity (0.2.12)
32
33
  ffi (0.6.3)
33
34
  rake (>= 0.8.7)
34
35
  json_pure (1.4.6)
36
+ linecache (0.43)
35
37
  mime-types (1.16)
36
38
  nokogiri (1.4.3.1)
37
39
  rack (1.1.0)
@@ -49,6 +51,11 @@ GEM
49
51
  rspec-rails (1.3.3)
50
52
  rack (>= 1.0.0)
51
53
  rspec (= 1.3.1)
54
+ ruby-debug (0.10.3)
55
+ columnize (>= 0.1)
56
+ ruby-debug-base (~> 0.10.3.0)
57
+ ruby-debug-base (0.10.3)
58
+ linecache (>= 0.3)
52
59
  rubyzip (0.9.4)
53
60
  selenium-webdriver (0.0.29)
54
61
  childprocess (>= 0.0.7)
@@ -67,4 +74,5 @@ DEPENDENCIES
67
74
  capybara
68
75
  rails (~> 2.3.10)
69
76
  rspec-rails (~> 1.3.0)
77
+ ruby-debug
70
78
  sqlite3-ruby
@@ -0,0 +1,77 @@
1
+ module ActivityStream
2
+
3
+ class Activity < ActiveRecord::Base
4
+
5
+ belongs_to :actor, :polymorphic => true
6
+
7
+ before_save :ensure_occurred_at_set
8
+
9
+ # @param name [Symbol] (see ActivityStream::Definition#new)
10
+ # @return [ActivityStream::Definition] the new definitions
11
+ #
12
+ def self.define(name, &block)
13
+ definition = ActivityStream::DefinitionProxy.new(name)
14
+ definition.instance_eval(&block)
15
+ ActivityStream::Definition.register(definition)
16
+ end
17
+
18
+ def self.new_with_name_and_metadata(name, metadata = {})
19
+ new(:kind => name.to_s, :metadata => metadata)
20
+ end
21
+
22
+ named_scope :in_reverse_chronological_order, :order => 'occurred_at DESC'
23
+
24
+ named_scope :in_chronological_order, :order => 'occurred_at ASC'
25
+
26
+ # @param actors [Array] An array of [ActorClass, actor_id] sets
27
+ # or [ActorClass, [actor_id, actor_id, actor_id...]
28
+ #
29
+ named_scope :by_actors, lambda { |actors|
30
+ if actors.first.is_a?(Array)
31
+ conditions = actors.map do |(actor_type, actor_id)|
32
+ %{("activities"."actor_id" = #{actor_id.to_param} AND "activities"."actor_type" = '#{actor_type.to_param}')}
33
+ end
34
+ {:conditions => conditions.join(' OR ') }
35
+ elsif actors.first.is_a?(Class)
36
+ {:conditions => {:actor_id => actors.last, :actor_type => actors.first.to_param}}
37
+ else
38
+ {} # Not sure what to do here.
39
+ end
40
+ }
41
+
42
+ serialize :metadata, ActivityStream::Metadata
43
+
44
+ delegate :template, :icon_path, :to => :definition
45
+
46
+ def metadata
47
+ self[:metadata] ||= ActivityStream::Metadata.new(self[:kind])
48
+ end
49
+
50
+ def metadata=(new_data = {})
51
+ new_data = new_data.presence || {}
52
+ occurred_at = new_data.delete(:occurred_at)
53
+ new_data.each do |key, value|
54
+ metadata.store(key, value)
55
+ end
56
+ end
57
+
58
+ def definition
59
+ ActivityStream::Definition.find_by_name(self[:kind])
60
+ end
61
+
62
+ def kind=(val)
63
+ write_attribute(:kind, val.to_s)
64
+ end
65
+
66
+ def kind
67
+ read_attribute(:kind).to_sym
68
+ end
69
+
70
+ private
71
+
72
+ def ensure_occurred_at_set
73
+ self.occurred_at ||= Time.now
74
+ end
75
+
76
+ end
77
+ end
@@ -6,8 +6,8 @@ class ActivityStreamGenerator < Rails::Generator::Base
6
6
  def manifest
7
7
  record do |m|
8
8
 
9
- m.directory(File.join('app','models','activities'))
10
- m.template('example_activity.rb', 'app/models/activities/example_activity.rb')
9
+ m.directory(File.join('config','initializers'))
10
+ m.template('initializer.rb', 'config/initializers/activity_stream.rb')
11
11
 
12
12
  user_model = 'app/models/user.rb'
13
13
  if File.exists?(user_model)
@@ -25,23 +25,25 @@ module ActivityStream
25
25
  base.extend(ClassMethods)
26
26
  base.class_eval do
27
27
  has_many :activities, :as => :actor
28
- activity_stream(:all, :actors => :activity_stream_actors)
28
+ activity_stream(:default, :actors => :followed_actors)
29
29
  end
30
30
  end
31
31
 
32
32
  # @param name [Symbol] An activity identifer defined by Activity.define
33
- def create_activity(name)
34
-
33
+ def publish_activity(name, metadata = {})
34
+ activity = ::Activity.new_with_name_and_metadata(name, metadata)
35
+ self.activities << activity
36
+ activity
35
37
  end
36
38
 
37
39
  # Creates and returns an ActivityStream::Stream for the predefined
38
40
  # list of actors.
39
41
  # @param name [Symbol] The key of a defined activity stream
40
- def activity_stream(name)
42
+ def activity_stream(name = :default)
41
43
  ActivityStream::Stream.new(name, self, self.class.defined_streams[name])
42
44
  end
43
-
44
- def activity_stream_actors
45
+ # Override this to change the default actors
46
+ def followed_actors
45
47
  self.class.all.map{|actor| [actor.class, actor.id]}
46
48
  end
47
49
 
@@ -2,51 +2,35 @@ require 'active_support/core_ext/array/extract_options'
2
2
 
3
3
  module ActivityStream
4
4
 
5
- def definitions
6
- @@definitions ||= []
7
- end
8
-
5
+ # Defines a type of activity. You don't actually interact with this class directly.
9
6
  class Definition
10
7
 
11
- attr_reader :name
12
-
13
- # @param name [Symbol] the unique name of the Activity
14
- def initialize(name)
15
- @name = name.to_sym
16
- @metadata = {}
17
- end
18
-
19
- # @param filename [String] the icon's name inside of the
20
- # `public/images/activity_stream/icons` directory
21
- def icon(filename)
22
- @icon = filename
23
- end
24
-
25
- # @overload metadata
26
- # @return [Hash] A hash of defined metadata
27
- # @overload metadata(name, opts = {})
28
- # @param name [Symbol] the unique name for the metadata attribute
29
- # @option opts :default The default value for that metadata
30
- def metadata(*args)
31
- if args.empty?
32
- @metadata
33
- else
34
- opts = args.extract_options!
35
- @metadata[args.first.to_sym] = opts
36
- end
8
+ attr_reader :name, :icon, :metadata, :template
9
+
10
+ # @param proxy [ActivityStream::DefinitionProxy] A constructed proxy that
11
+ # will set the values for this Definition
12
+ def initialize(proxy)
13
+ @name = proxy[:name]
14
+ @metadata = proxy[:metadata] || {}
15
+ @template = proxy[:template] || 'activity'
16
+ @icon = proxy[:icon] || 'activity_icon.png'
37
17
  end
38
18
 
39
- #
40
- def template
41
- 'activity'
19
+ def icon_path
20
+ 'activity_stream/icons/%s' % self.icon
42
21
  end
43
-
22
+
44
23
  class << self
45
24
  # @param definition [Definition] The definition to be made available
46
25
  # @return [Definition] Returns the registered definition
47
26
  def register(definition)
48
- self.all << definition
49
- definition
27
+ definition = new(definition) if definition.is_a? DefinitionProxy
28
+ if definition.is_a? Definition
29
+ self.all << definition
30
+ definition
31
+ else
32
+ false
33
+ end
50
34
  end
51
35
 
52
36
  # List of registered definitions
@@ -58,15 +42,15 @@ module ActivityStream
58
42
  # end
59
43
  # ActivityStream::Definition.all
60
44
  def all
61
- @@definitions ||= []
45
+ @definitions ||= []
62
46
  end
63
47
 
64
48
  # Find a registered definition by its symbolic name
65
49
  # @param name [Symbol] the name to find
66
50
  # @return [ActivityStream::Definition]
67
51
  def find_by_name(name)
68
- unless definition = all.find{|d| d.name == name.to_sym}
69
- raise ActivityStream::UndefinedActivity, "Could not find a definition for `#{name}`"
52
+ unless definition = all.find{|definition| definition.name == name.to_sym}
53
+ raise UndefinedActivity, "Could not find a definition for `#{name}`"
70
54
  else
71
55
  definition
72
56
  end
@@ -0,0 +1,49 @@
1
+ module ActivityStream
2
+
3
+ # Provides a DSL to define an Activity. It is used in Activity.define
4
+ class DefinitionProxy
5
+
6
+ # @param name [Symbol] The name of the activity
7
+ def initialize(name)
8
+ @attributes = {
9
+ :name => name.to_sym,
10
+ :icon => 'activity_icon.png',
11
+ :metadata => {},
12
+ :template => 'activity'
13
+ }
14
+ end
15
+
16
+ # Define the activity's icon
17
+ # @param filename [String] the icon's name inside of the
18
+ # `public/images/activity_stream/icons` directory
19
+ def icon(filename)
20
+ @attributes.store(:icon, filename)
21
+ end
22
+
23
+ # Define metadata for the activity
24
+ # @param name [Symbol] the unique name for the metadata attribute
25
+ # @option opts :default The default value for that metadata
26
+ # @option opts [Boolean] :required (false) Mark this metadata as required
27
+ def metadata(*args)
28
+ opts = args.extract_options!
29
+ args.each do |name|
30
+ self.add_metadata(name, opts)
31
+ end
32
+ end
33
+
34
+ # Define a custom template
35
+ # @param name [String] the name of the template for this Activity.
36
+ # Should be located in `app/views/activities/*`
37
+ def template(template_name)
38
+ @attributes.store(template_name)
39
+ end
40
+
41
+ delegate :[], :to => :@attributes
42
+
43
+ def add_metadata(name, opts = {})
44
+ @attributes[:metadata][name] = opts
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -1,15 +1,56 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+ require 'active_support/core_ext/object/singleton_class'
3
+
1
4
  module ActivityStream
2
5
 
6
+ # Storage for an activities metadata.
3
7
  class Metadata
4
8
 
9
+ attr_reader :data
10
+
5
11
  def initialize(definition_name)
6
-
12
+ @definition_name = definition_name
13
+ @data = {}
14
+ end
15
+
16
+ delegate :merge, :store, :to => :data
17
+
18
+ def definition
19
+ @definition ||= Definition.find_by_name(@definition_name)
20
+ end
21
+
22
+ def to_yaml_properties
23
+ ["@data","@definition_name"]
24
+ end
25
+
26
+ def valid?
27
+ # TODO: Check definition for required keys, and loop through the
28
+ # values in @data to see what is missing
29
+ true
30
+ end
31
+
32
+ def method_missing(method_name)
33
+ case method_name
34
+ when *definition.metadata.keys
35
+ @data[method_name]
36
+ else
37
+ super
38
+ end
7
39
  end
40
+
41
+ private
8
42
 
9
- def store
10
- @store ||= {}
43
+ def define_metadata_method(name)
44
+ self.singleton_class.class_eval do
45
+ define_method(name) do
46
+ self.data[name]
47
+ end
48
+ define_method(:"#{name.to_s}=") do |value|
49
+ self.data[name]= value
50
+ end
51
+ end
11
52
  end
12
53
 
13
54
  end
14
55
 
15
- end
56
+ end
@@ -12,11 +12,13 @@ module ActivityStream
12
12
  @collection = initialize_collection(opts[:actors])
13
13
  end
14
14
 
15
+ # @param reload [Boolean] Return to the database for new activities
16
+ # @return the activities for the collection of actors
15
17
  def activities(reload = false)
16
18
  if @activities && !reload
17
19
  @activities
18
20
  else
19
- @activities = Activity.by_actors(@collection)
21
+ @activities = ::Activity.by_actors(@collection)
20
22
  end
21
23
  end
22
24
 
@@ -1,3 +1,3 @@
1
1
  module ActivityStream
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActivityStream::Metadata do
4
+
5
+ let(:metadata) { ActivityStream::Metadata.new(:example_action) }
6
+
7
+ before(:each) do
8
+ Activity.define(:example_action) do
9
+ metadata(:one_data)
10
+ metadata(:two_data)
11
+ end
12
+ end
13
+
14
+ after(:each) do
15
+ ActivityStream::Definition.all.delete(:example_action)
16
+ end
17
+
18
+ it 'should be initialized with a definition name' do
19
+ ActivityStream::Metadata.new(:example_action)
20
+ end
21
+
22
+ context 'data storage' do
23
+
24
+ it 'should accept new data' do
25
+ metadata.store(:one_data, 1)
26
+ end
27
+
28
+ it 'should retrieve previously set data' do
29
+ metadata.store(:two_data, 2)
30
+ metadata.data[:two_data].should be(2)
31
+ end
32
+
33
+ end
34
+
35
+ context 'definition' do
36
+
37
+ it 'should return one' do
38
+ metadata.definition.should be_a(ActivityStream::Definition)
39
+ end
40
+
41
+ end
42
+
43
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activity_stream
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andrew Smith
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-02 00:00:00 -04:00
18
+ date: 2010-11-06 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -81,16 +81,17 @@ files:
81
81
  - Rakefile
82
82
  - Readme.md
83
83
  - activity_stream.gemspec
84
- - app/models/activity.rb
84
+ - app/models/activity_stream/activity.rb
85
85
  - generators/activity_stream/activity_stream_generator.rb
86
86
  - generators/activity_stream/lib/insert_commands.rb
87
- - generators/activity_stream/templates/example_activity.rb
87
+ - generators/activity_stream/templates/initializer.rb
88
88
  - generators/activity_stream/templates/migration.rb
89
89
  - generators/activity_stream/templates/user.rb
90
90
  - lib/activity_stream.rb
91
91
  - lib/activity_stream/activities_helper.rb
92
92
  - lib/activity_stream/actor.rb
93
93
  - lib/activity_stream/definition.rb
94
+ - lib/activity_stream/definition_proxy.rb
94
95
  - lib/activity_stream/errors.rb
95
96
  - lib/activity_stream/metadata.rb
96
97
  - lib/activity_stream/stream.rb
@@ -149,6 +150,7 @@ files:
149
150
  - spec/integration/activity_model_spec.rb
150
151
  - spec/lib/actor_spec.rb
151
152
  - spec/lib/definition_spec.rb
153
+ - spec/lib/metadata_spec.rb
152
154
  - spec/lib/stream_spec.rb
153
155
  - spec/spec_helper.rb
154
156
  has_rdoc: true
@@ -239,5 +241,6 @@ test_files:
239
241
  - spec/integration/activity_model_spec.rb
240
242
  - spec/lib/actor_spec.rb
241
243
  - spec/lib/definition_spec.rb
244
+ - spec/lib/metadata_spec.rb
242
245
  - spec/lib/stream_spec.rb
243
246
  - spec/spec_helper.rb
@@ -1,46 +0,0 @@
1
- class Activity < ActiveRecord::Base
2
-
3
- belongs_to :actor, :polymorphic => true
4
-
5
- # @param name [Symbol] (see ActivityStream::Definition#new)
6
- # @return [ActivityStream::Definition] the new definitions
7
- #
8
- def self.define(name, &block)
9
- definition = ActivityStream::Definition.new(name)
10
- definition.instance_eval(&block)
11
- ActivityStream::Definition.register(definition)
12
- end
13
-
14
- named_scope :in_reverse_chronological_order, :order => 'occurred_at DESC'
15
-
16
- named_scope :in_chronological_order, :order => 'occurred_at ASC'
17
-
18
- # @param actors [Array] An array of [ActorClass, actor_id] sets
19
- # or [ActorClass, [actor_id, actor_id, actor_id...]
20
- #
21
- named_scope :by_actors, lambda { |actors|
22
- if actors.first.is_a?(Array)
23
- conditions = actors.map do |(actor_type, actor_id)|
24
- %{("activities"."actor_id" = #{actor_id.to_param} AND "activities"."actor_type" = '#{actor_type.to_param}')}
25
- end
26
- {:conditions => conditions.join(' OR ') }
27
- elsif actors.first.is_a?(Class)
28
- {:conditions => {:actor_id => actors.last, :actor_type => actors.first.to_param}}
29
- else
30
- {} # Not sure what to do here.
31
- end
32
- }
33
-
34
- serialize :metadata, ActivityStream::Metadata
35
-
36
- delegate :template, :icon, :to => :definition
37
-
38
- def metadata
39
- self[:metadata] ||= ActivityStream::Metadata.new(self[:kind])
40
- end
41
-
42
- def definition
43
- ActivityStream::Definition.find_by_name(self[:kind])
44
- end
45
-
46
- end