activity_stream 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/.gitignore +10 -0
  2. data/.yardopts +4 -0
  3. data/Gemfile +6 -0
  4. data/Gemfile.lock +70 -0
  5. data/Rakefile +10 -0
  6. data/Readme.md +71 -0
  7. data/activity_stream.gemspec +25 -0
  8. data/app/models/activity.rb +46 -0
  9. data/generators/activity_stream/activity_stream_generator.rb +28 -0
  10. data/generators/activity_stream/lib/insert_commands.rb +33 -0
  11. data/generators/activity_stream/templates/example_activity.rb +6 -0
  12. data/generators/activity_stream/templates/migration.rb +30 -0
  13. data/generators/activity_stream/templates/user.rb +5 -0
  14. data/lib/activity_stream.rb +9 -0
  15. data/lib/activity_stream/activities_helper.rb +15 -0
  16. data/lib/activity_stream/actor.rb +68 -0
  17. data/lib/activity_stream/definition.rb +80 -0
  18. data/lib/activity_stream/errors.rb +16 -0
  19. data/lib/activity_stream/metadata.rb +15 -0
  20. data/lib/activity_stream/stream.rb +38 -0
  21. data/lib/activity_stream/version.rb +3 -0
  22. data/rails/init.rb +5 -0
  23. data/spec/dummy/Gemfile +3 -0
  24. data/spec/dummy/Gemfile.lock +35 -0
  25. data/spec/dummy/README +243 -0
  26. data/spec/dummy/Rakefile +10 -0
  27. data/spec/dummy/app/controllers/application_controller.rb +10 -0
  28. data/spec/dummy/app/helpers/application_helper.rb +3 -0
  29. data/spec/dummy/app/models/activities/example_activity.rb +6 -0
  30. data/spec/dummy/app/models/user.rb +5 -0
  31. data/spec/dummy/config/boot.rb +128 -0
  32. data/spec/dummy/config/database.yml +22 -0
  33. data/spec/dummy/config/environment.rb +41 -0
  34. data/spec/dummy/config/environments/development.rb +17 -0
  35. data/spec/dummy/config/environments/production.rb +28 -0
  36. data/spec/dummy/config/environments/test.rb +28 -0
  37. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  38. data/spec/dummy/config/initializers/cookie_verification_secret.rb +7 -0
  39. data/spec/dummy/config/initializers/inflections.rb +10 -0
  40. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  41. data/spec/dummy/config/initializers/new_rails_defaults.rb +21 -0
  42. data/spec/dummy/config/initializers/session_store.rb +15 -0
  43. data/spec/dummy/config/locales/en.yml +5 -0
  44. data/spec/dummy/config/preinitializer.rb +20 -0
  45. data/spec/dummy/config/routes.rb +43 -0
  46. data/spec/dummy/db/migrate/20101101154941_create_activity_stream_tables.rb +30 -0
  47. data/spec/dummy/db/schema.rb +28 -0
  48. data/spec/dummy/db/seeds.rb +7 -0
  49. data/spec/dummy/public/404.html +30 -0
  50. data/spec/dummy/public/422.html +30 -0
  51. data/spec/dummy/public/500.html +30 -0
  52. data/spec/dummy/public/favicon.ico +0 -0
  53. data/spec/dummy/public/images/rails.png +0 -0
  54. data/spec/dummy/public/index.html +275 -0
  55. data/spec/dummy/public/javascripts/application.js +2 -0
  56. data/spec/dummy/public/javascripts/controls.js +963 -0
  57. data/spec/dummy/public/javascripts/dragdrop.js +973 -0
  58. data/spec/dummy/public/javascripts/effects.js +1128 -0
  59. data/spec/dummy/public/javascripts/prototype.js +4320 -0
  60. data/spec/dummy/public/robots.txt +5 -0
  61. data/spec/dummy/script/about +4 -0
  62. data/spec/dummy/script/console +3 -0
  63. data/spec/dummy/script/dbconsole +3 -0
  64. data/spec/dummy/script/destroy +3 -0
  65. data/spec/dummy/script/generate +3 -0
  66. data/spec/dummy/script/performance/benchmarker +3 -0
  67. data/spec/dummy/script/performance/profiler +3 -0
  68. data/spec/dummy/script/plugin +3 -0
  69. data/spec/dummy/script/runner +3 -0
  70. data/spec/dummy/script/server +3 -0
  71. data/spec/dummy/test/performance/browsing_test.rb +9 -0
  72. data/spec/dummy/test/test_helper.rb +38 -0
  73. data/spec/integration/activity_model_spec.rb +7 -0
  74. data/spec/lib/actor_spec.rb +5 -0
  75. data/spec/lib/definition_spec.rb +11 -0
  76. data/spec/lib/stream_spec.rb +9 -0
  77. data/spec/spec_helper.rb +26 -0
  78. metadata +243 -0
@@ -0,0 +1,10 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ .yardoc
5
+ doc
6
+ *.swp
7
+ spec/dummy/db/*.sqlite3
8
+ spec/dummy/log/*.log
9
+ spec/dummy/tmp/
10
+ *.DS_Store
@@ -0,0 +1,4 @@
1
+ 'app/**/*.rb'
2
+ 'lib/**/*.rb'
3
+ -
4
+ Readme.md
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in activity_stream.gemspec
4
+ gemspec
5
+
6
+ gem "sqlite3-ruby", :require => "sqlite3"
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ activity_stream (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ actionmailer (2.3.10)
10
+ actionpack (= 2.3.10)
11
+ actionpack (2.3.10)
12
+ activesupport (= 2.3.10)
13
+ rack (~> 1.1.0)
14
+ activerecord (2.3.10)
15
+ activesupport (= 2.3.10)
16
+ activeresource (2.3.10)
17
+ activesupport (= 2.3.10)
18
+ activesupport (2.3.10)
19
+ capybara (0.4.0)
20
+ celerity (>= 0.7.9)
21
+ culerity (>= 0.2.4)
22
+ mime-types (>= 1.16)
23
+ nokogiri (>= 1.3.3)
24
+ rack (>= 1.0.0)
25
+ rack-test (>= 0.5.4)
26
+ selenium-webdriver (>= 0.0.27)
27
+ xpath (~> 0.1.2)
28
+ celerity (0.8.2)
29
+ childprocess (0.1.3)
30
+ ffi (~> 0.6.3)
31
+ culerity (0.2.12)
32
+ ffi (0.6.3)
33
+ rake (>= 0.8.7)
34
+ json_pure (1.4.6)
35
+ mime-types (1.16)
36
+ nokogiri (1.4.3.1)
37
+ rack (1.1.0)
38
+ rack-test (0.5.6)
39
+ rack (>= 1.0)
40
+ rails (2.3.10)
41
+ actionmailer (= 2.3.10)
42
+ actionpack (= 2.3.10)
43
+ activerecord (= 2.3.10)
44
+ activeresource (= 2.3.10)
45
+ activesupport (= 2.3.10)
46
+ rake (>= 0.8.3)
47
+ rake (0.8.7)
48
+ rspec (1.3.1)
49
+ rspec-rails (1.3.3)
50
+ rack (>= 1.0.0)
51
+ rspec (= 1.3.1)
52
+ rubyzip (0.9.4)
53
+ selenium-webdriver (0.0.29)
54
+ childprocess (>= 0.0.7)
55
+ ffi (~> 0.6.3)
56
+ json_pure
57
+ rubyzip
58
+ sqlite3-ruby (1.3.2)
59
+ xpath (0.1.2)
60
+ nokogiri (~> 1.3)
61
+
62
+ PLATFORMS
63
+ ruby
64
+
65
+ DEPENDENCIES
66
+ activity_stream!
67
+ capybara
68
+ rails (~> 2.3.10)
69
+ rspec-rails (~> 1.3.0)
70
+ sqlite3-ruby
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake'
5
+ require 'spec/rake/spectask'
6
+
7
+ desc "Run all examples"
8
+ Spec::Rake::SpecTask.new('rspec') do |t|
9
+ t.spec_files = FileList['spec/**/*_spec.rb']
10
+ end
@@ -0,0 +1,71 @@
1
+ # ActivityStream (early alpha) #
2
+
3
+ Activity Stream provides a simple DSL to define, create,
4
+ and retrieve user activities.
5
+
6
+ ## Installation ##
7
+
8
+ Add it to your Gemfile:
9
+
10
+ gem 'activity_stream'
11
+
12
+ Run the generator:
13
+
14
+ script/generate activity_stream
15
+
16
+ And migrate the database:
17
+
18
+ rake db:migrate
19
+
20
+ ## Usage ##
21
+
22
+ ### Defining Activities ###
23
+
24
+ In `app/models/activities/example_action_activity.rb`:
25
+
26
+ Activity.define(:example_action) do
27
+ metadata(:target, :default => :actor)
28
+ metadata(:referrer)
29
+ icon('example_activity_icon.png')
30
+ end
31
+
32
+ ### Extending User ###
33
+
34
+ In your User model:
35
+
36
+ class User < ActiveRecord::Base
37
+
38
+ include ActivityStream::Actor
39
+
40
+ def activity_stream_actors
41
+ [[User, 13], [User, 14], [Page, 9]]
42
+ end
43
+
44
+ end
45
+
46
+ ### Retrieving Activities ###
47
+
48
+ In your dashboard controller:
49
+
50
+ @activity_stream = current_user.activity_stream
51
+
52
+ ### Creating Activies ###
53
+
54
+ When you want to create an activity:
55
+
56
+ current_user.create_activity(:example_action,
57
+ :target => @friend,
58
+ :referrer => @referrer)
59
+
60
+
61
+ ## Notes ##
62
+
63
+ Currently designed for Rails 2.3.10, because the project
64
+ that prompted its creation is that version. I can't guarantee
65
+ that it will work in any other version of Rails.
66
+
67
+ However, I do have other projects, that are Rails 3, that will
68
+ benefit from a Rails 3 compatible version of activity_stream.
69
+ Be on the lookout for updates!
70
+
71
+
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "activity_stream/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "activity_stream"
7
+ s.version = ActivityStream::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Andrew Smith"]
10
+ s.email = ["andrew@envylabs.com"]
11
+ s.homepage = "http://rubygems.org/gems/activity_stream"
12
+ s.summary = %q{Rails plugin to add activity streams for your users}
13
+ s.description = %q{Rails plugin to add activity streams for your users, highly opinionated.}
14
+
15
+ s.rubyforge_project = "activity_stream"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency "rspec-rails", "~> 1.3.0"
23
+ s.add_development_dependency "rails", "~> 2.3.10"
24
+ s.add_development_dependency "capybara"
25
+ end
@@ -0,0 +1,46 @@
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
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
2
+ # require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
3
+
4
+ class ActivityStreamGenerator < Rails::Generator::Base
5
+
6
+ def manifest
7
+ record do |m|
8
+
9
+ m.directory(File.join('app','models','activities'))
10
+ m.template('example_activity.rb', 'app/models/activities/example_activity.rb')
11
+
12
+ user_model = 'app/models/user.rb'
13
+ if File.exists?(user_model)
14
+ m.insert_into(user_model, "include ActivityStream::Actor")
15
+ else
16
+ m.directory(File.join('app', 'models'))
17
+ m.file('user.rb', user_model)
18
+ end
19
+
20
+ m.migration_template('migration.rb',
21
+ 'db/migrate',
22
+ :migration_file_name => 'create_activity_stream_tables',
23
+ :assigns => {:has_users => ActiveRecord::Base.connection.table_exists?(:users)})
24
+
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,33 @@
1
+ # Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
2
+
3
+ Rails::Generator::Commands::Base.class_eval do
4
+ def file_contains?(relative_destination, line)
5
+ File.read(destination_path(relative_destination)).include?(line)
6
+ end
7
+ end
8
+
9
+ Rails::Generator::Commands::Create.class_eval do
10
+ def insert_into(file, line)
11
+ logger.insert "#{line} into #{file}"
12
+ unless options[:pretend] || file_contains?(file, line)
13
+ gsub_file file, /^(class|module|.*Routes).*$/ do |match|
14
+ "#{match}\n #{line}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ Rails::Generator::Commands::Destroy.class_eval do
21
+ def insert_into(file, line)
22
+ logger.remove "#{line} from #{file}"
23
+ unless options[:pretend]
24
+ gsub_file file, "\n #{line}", ''
25
+ end
26
+ end
27
+ end
28
+
29
+ Rails::Generator::Commands::List.class_eval do
30
+ def insert_into(file, line)
31
+ logger.insert "#{line} into #{file}"
32
+ end
33
+ end
@@ -0,0 +1,6 @@
1
+ # Activity.define(:example_activity) do
2
+ # icon 'example_activity_icon.png'
3
+ # metadata :detail
4
+ # metadata :target
5
+ # end
6
+ #
@@ -0,0 +1,30 @@
1
+ class CreateActivityStreamTables < ActiveRecord::Migration
2
+ def self.up
3
+
4
+ create_table :activities do |t|
5
+ t.integer :actor_id
6
+ t.string :actor_type
7
+ t.string :kind
8
+ t.text :metadata
9
+ t.datetime :occurred_at
10
+ end
11
+
12
+ add_index :activities, [:actor_id, :actor_type]
13
+
14
+ <% unless has_users %>
15
+ create_table :users do |t|
16
+ t.string :name
17
+ end
18
+
19
+ <% end %>
20
+ end
21
+
22
+ def self.down
23
+ <% unless has_users %>
24
+ drop_table :users
25
+ <% end %>
26
+
27
+ drop_table :activities
28
+
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ include ActivityStream::Actor
4
+
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'activity_stream/definition'
2
+ require 'activity_stream/actor'
3
+ require 'activity_stream/metadata'
4
+ require 'activity_stream/stream'
5
+ require 'activity_stream/version'
6
+
7
+ module ActivityStream
8
+ # Your code goes here...
9
+ end
@@ -0,0 +1,15 @@
1
+ module ActivityStream
2
+
3
+ module ActivitiesHelper
4
+
5
+ def render_activities(activities)
6
+ return nil if activities.empty?
7
+ activities.map do |activity|
8
+ _partial_name = activity.template
9
+ template = self.view_paths.find_template(%{activities/_#{_partial_name}}, :html)
10
+ template.render_partial(self, activity)
11
+ end.join('').html_safe
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,68 @@
1
+ module ActivityStream
2
+
3
+ # @example Definition
4
+ # class User < ActiveRecord::Base
5
+ #
6
+ # include ActivityStream::Actor
7
+ #
8
+ # activity_stream(:friends, :actors => :friend_actors)
9
+ #
10
+ # def friend_actors
11
+ # friend_ids.map{|id| [User, id]}
12
+ # end
13
+ #
14
+ # def friend_ids
15
+ # # get friend ids
16
+ # end
17
+ #
18
+ # end
19
+ #
20
+ # @example Usage
21
+ # @user.activity_stream(:friends) # => <ActivityStream::Stream>
22
+ module Actor
23
+
24
+ def self.included(base)
25
+ base.extend(ClassMethods)
26
+ base.class_eval do
27
+ has_many :activities, :as => :actor
28
+ activity_stream(:all, :actors => :activity_stream_actors)
29
+ end
30
+ end
31
+
32
+ # @param name [Symbol] An activity identifer defined by Activity.define
33
+ def create_activity(name)
34
+
35
+ end
36
+
37
+ # Creates and returns an ActivityStream::Stream for the predefined
38
+ # list of actors.
39
+ # @param name [Symbol] The key of a defined activity stream
40
+ def activity_stream(name)
41
+ ActivityStream::Stream.new(name, self, self.class.defined_streams[name])
42
+ end
43
+
44
+ def activity_stream_actors
45
+ self.class.all.map{|actor| [actor.class, actor.id]}
46
+ end
47
+
48
+ module ClassMethods
49
+
50
+ # @attr_accessor defined_streams
51
+ attr_accessor :defined_streams
52
+
53
+ # Creates an activity_stream instance method that fetches
54
+ # all recent activity
55
+ #
56
+ # @param name [Symbol] the name for the sub stream you wish to access
57
+ # @option opts (see ActivityStream::Stream#new)
58
+ def activity_stream(name, opts = {})
59
+ self.defined_streams ||= {}
60
+ self.defined_streams[name.to_sym] = opts
61
+ return nil
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end