muck-services 0.1.14 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/VERSION +1 -1
  2. data/app/controllers/muck/feeds_controller.rb +1 -1
  3. data/app/helpers/muck_services_service_helper.rb +1 -2
  4. data/app/models/aggregation.rb +9 -5
  5. data/app/models/aggregation_feed.rb +1 -0
  6. data/app/models/attention.rb +4 -3
  7. data/app/models/attention_type.rb +9 -0
  8. data/app/models/entry.rb +3 -12
  9. data/app/models/oai_endpoint.rb +17 -0
  10. data/app/models/personal_recommendation.rb +23 -1
  11. data/app/models/service.rb +2 -2
  12. data/app/views/feeds/_feed_row.html.erb +1 -1
  13. data/app/views/services/_personal_recommendations.html.erb +3 -3
  14. data/db/migrate/20091118203605_add_default_feed_type_to_aggregation_feed.rb +10 -0
  15. data/lib/active_record/acts/muck_recommendations.rb +24 -0
  16. data/lib/muck_services.rb +1 -1
  17. data/muck-services.gemspec +8 -3
  18. data/rails/init.rb +1 -1
  19. data/test/rails_root/app/models/user.rb +2 -0
  20. data/test/rails_root/config/environment.rb +3 -3
  21. data/test/rails_root/db/migrate/20090602191243_create_muck_raker.rb +19 -4
  22. data/test/rails_root/db/migrate/20090703175825_denormalize_entries_subjects.rb +29 -3
  23. data/test/rails_root/db/migrate/20090717175825_normalize_entries_subjects.rb +32 -3
  24. data/test/rails_root/db/migrate/20091115011828_add_aggregations_for_personal_recs.rb +9 -0
  25. data/test/rails_root/db/migrate/20091116094447_rename_action_table.rb +38 -0
  26. data/test/rails_root/db/migrate/20091118203605_add_default_feed_type_to_aggregation_feed.rb +10 -0
  27. data/test/rails_root/db/schema.rb +25 -17
  28. data/test/rails_root/test/unit/aggregation_feed_test.rb +1 -0
  29. data/test/rails_root/test/unit/aggregation_test.rb +2 -1
  30. data/test/rails_root/test/unit/entry_test.rb +1 -12
  31. data/test/rails_root/test/unit/oai_endpoint_test.rb +17 -0
  32. data/test/rails_root/test/unit/personal_recommendation_test.rb +78 -0
  33. data/test/rails_root/test/unit/service_test.rb +3 -1
  34. data/test/rails_root/test/unit/user_test.rb +1 -0
  35. metadata +8 -3
  36. data/db/migrate/20090704220055_create_slugs.rb +0 -18
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.14
1
+ 0.1.16
@@ -161,7 +161,7 @@ class Muck::FeedsController < ApplicationController
161
161
  end
162
162
 
163
163
  def get_layout_by_params
164
- if params[:layout].empty?
164
+ if params[:layout].blank?
165
165
  true
166
166
  else
167
167
  params[:layout]
@@ -8,8 +8,7 @@ module MuckServicesServiceHelper
8
8
 
9
9
  # Render personal recommendations
10
10
  def personal_recommendations(user, limit = 5)
11
- recommendations = user.recommended_resources
12
- render :partial => 'services/personal_recommendations', :locals => { :recommendations => recommendations }
11
+ render :partial => 'services/personal_recommendations', :locals => { :recommendations => user.personal_recommendations.limit(5) }
13
12
  end
14
13
 
15
14
  # Render a view with all services in categories.
@@ -3,7 +3,7 @@
3
3
  # Table name: aggregations
4
4
  #
5
5
  # id :integer(4) not null, primary key
6
- # terms :string(255)
6
+ # terms :string(255)
7
7
  # title :string(255)
8
8
  # description :text
9
9
  # top_tags :text
@@ -11,6 +11,7 @@
11
11
  # updated_at :datetime
12
12
  # ownable_id :integer(4)
13
13
  # ownable_type :string(255)
14
+ # feed_count :integer(4) default(0)
14
15
  #
15
16
 
16
17
  class Aggregation < ActiveRecord::Base
@@ -19,9 +20,11 @@ class Aggregation < ActiveRecord::Base
19
20
  has_friendly_id :terms, :use_slug => true
20
21
 
21
22
  belongs_to :ownable, :polymorphic => true
23
+
22
24
  has_many :aggregation_feeds, :conditions => ['feed_type = ?', 'Feed']
23
- has_many :aggregation_oai_endpoints, :conditions => ['feed_type = ?', 'OaiEndpoint']
25
+ has_many :aggregation_oai_endpoints, :conditions => ['feed_type = ?', 'OaiEndpoint'], :source => 'aggregation_feeds'
24
26
  has_many :feeds, :through => :aggregation_feeds
27
+ has_many :oai_endpoints, :through => :aggregation_feeds
25
28
 
26
29
  named_scope :by_title, :order => "title ASC"
27
30
  named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } }
@@ -41,11 +44,12 @@ class Aggregation < ActiveRecord::Base
41
44
  safe_add_feeds(Feed.create_tag_feeds(user, uris))
42
45
  end
43
46
 
44
- # Only add feeds that aren't already part of the aggregation
45
- def safe_add_feeds(new_feeds)
47
+ # Only add feeds that aren't already part of the aggregation. This will setup the feed
48
+ # as type 'Feed'. It is important to add feeds using this method or the type won't be set.
49
+ def safe_add_feeds(new_feeds, type = 'Feed')
46
50
  new_feeds.each do |feed|
47
51
  begin
48
- self.feeds << feed
52
+ self.aggregation_feeds.create(:feed => feed, :feed_type => type)
49
53
  rescue ActiveRecord::RecordInvalid => ex
50
54
  # Throw away exception. Feed already exists so we don't need to do anything.
51
55
  end
@@ -5,6 +5,7 @@
5
5
  # id :integer(4) not null, primary key
6
6
  # aggregation_id :integer(4)
7
7
  # feed_id :integer(4)
8
+ # feed_type :string(255) default("Feed")
8
9
  #
9
10
 
10
11
  class AggregationFeed < ActiveRecord::Base
@@ -4,10 +4,11 @@
4
4
  #
5
5
  # id :integer(4) not null, primary key
6
6
  # attentionable_id :integer(4)
7
- # attentionable_type :string(255)
7
+ # attentionable_type :string(255) default("User")
8
8
  # entry_id :integer(4)
9
- # action_type :string(255)
10
- # weight :float
9
+ # attention_type_id :integer(4)
10
+ # weight :integer(4) default(5)
11
+ # created_at :datetime
11
12
  #
12
13
 
13
14
  class Attention < ActiveRecord::Base
@@ -1,3 +1,12 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: attention_types
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # name :string(255)
7
+ # default_weight :integer(4)
8
+ #
9
+
1
10
 
2
11
  class AttentionType < ActiveRecord::Base
3
12
  WRITE = 1
data/app/models/entry.rb CHANGED
@@ -22,18 +22,7 @@
22
22
  # relevant :text
23
23
  # other :text
24
24
  # grain_size :string(255) default("unknown")
25
- #
26
- # Indexes
27
- #
28
- # index_entries_on_direct_link (direct_link)
29
- # index_entries_on_feed_id (feed_id)
30
- # index_entries_on_indexed_at (indexed_at)
31
- # index_entries_on_language_id (language_id)
32
- # index_entries_on_oai_identifier (oai_identifier)
33
- # index_entries_on_permalink (permalink)
34
- # index_entries_on_published_at (published_at)
35
- # index_entries_on_relevance_calculated_at (relevance_calculated_at)
36
- # index_entries_on_grain_size (grain_size)
25
+ # comment_count :integer(4) default(0)
37
26
  #
38
27
 
39
28
  class Entry < ActiveRecord::Base
@@ -44,8 +33,10 @@ class Entry < ActiveRecord::Base
44
33
  belongs_to :language
45
34
  has_many :activities, :as => :attachable, :dependent => :destroy
46
35
  has_many :attentions, :dependent => :destroy
36
+ has_many :personal_recommendations, :as => :destination
47
37
  acts_as_commentable
48
38
  acts_as_taggable
39
+ acts_as_muck_recommendation
49
40
 
50
41
  @@default_time_on_page = 60.0
51
42
 
@@ -1,3 +1,20 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: oai_endpoints
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # uri :string(2083)
7
+ # display_uri :string(2083)
8
+ # metadata_prefix :string(255)
9
+ # title :string(1000)
10
+ # short_title :string(100)
11
+ # contributor_id :integer(4)
12
+ # status :integer(4)
13
+ # default_language_id :integer(4)
14
+ # created_at :datetime
15
+ # updated_at :datetime
16
+ #
17
+
1
18
  # == Schema Information
2
19
  #
3
20
  # Table name: oai_endpoints
@@ -1,3 +1,25 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: personal_recommendations
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # personal_recommendable_id :integer(4)
7
+ # personal_recommendable_type :string(255)
8
+ # destination_id :integer(4)
9
+ # destination_type :string(255)
10
+ # relevance :float
11
+ # created_at :datetime
12
+ # visited_at :datetime
13
+ #
14
+
1
15
  class PersonalRecommendation < ActiveRecord::Base
2
- belongs_to :entry, :foreign_key => 'destination_id', :conditions => [:destination_type => 'Entry']
16
+
17
+ belongs_to :personal_recommendable, :polymorphic => true
18
+ belongs_to :destination, :polymorphic => true
19
+
20
+ named_scope :limit, lambda { |num| { :limit => num } }
21
+ named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } }
22
+ named_scope :newest, :order => "created_at DESC"
23
+ named_scope :entries_only, :conditions => ["personal_recommendations.destination_type = 'Entry'"]
24
+ named_scope :users, :conditions => ["personal_recommendations.destination_type = 'User'"]
3
25
  end
@@ -15,6 +15,8 @@
15
15
  # active :boolean(1) default(TRUE)
16
16
  # prompt :string(255)
17
17
  # template :string(255)
18
+ # uri_data_template :string(2083) default("")
19
+ # uri_key :string(255)
18
20
  #
19
21
 
20
22
  class Service < ActiveRecord::Base
@@ -148,8 +150,6 @@ class Service < ActiveRecord::Base
148
150
  uris.collect{ |u| Feed.find_or_create(u.url, u.title, username, password, service.id, contributor) } if uris
149
151
  end
150
152
 
151
-
152
-
153
153
  def self.build_photo_feeds(terms, user, service_ids = nil, refresh_services = false)
154
154
  if service_ids.nil?
155
155
  service_ids = get_photo_tag_services(refresh_services).map(&:id)
@@ -16,7 +16,7 @@
16
16
  </td>
17
17
  <% end -%>
18
18
  <td><%= feed_row.error_message ? t('muck.services.failed_last_request', :error => feed_row.error_message) : feed_row.banned? ? t('muck.services.banned') : feed_row.pending? ? ('muck.services.pending') : t('muck.services.ok') %></td>
19
- <td><%= feed_row.default_language.english_name %></td>
19
+ <td><%= feed_row.default_language.english_name unless feed_row.default_language.nil? %></td>
20
20
  <td><%= feed_row.entries_count.nil? ? "0" : feed_row.entries_count.to_s %></td>
21
21
  <td><%= feed_row.harvested_from_short_title %></td>
22
22
  <td>
@@ -1,5 +1,5 @@
1
1
  <ul>
2
- <% recommendations.each do |r| %>
3
- <li><%= r.title %></li>
4
- <% end %>
2
+ <% recommendations.each do |r| -%>
3
+ <li><%= link_to r.destination.title, r.destination %></li>
4
+ <% end -%>
5
5
  </ul>
@@ -0,0 +1,10 @@
1
+ class AddDefaultFeedTypeToAggregationFeed < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :aggregation_feeds, :feed_type, :string, :default => 'Feed'
4
+ end
5
+
6
+ def self.down
7
+ change_column :aggregation_feeds, :feed_type, :string, :default => nil
8
+ end
9
+
10
+ end
@@ -0,0 +1,24 @@
1
+ module ActiveRecord
2
+ module Acts #:nodoc:
3
+ module MuckRecommendations # :nodoc:
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ # +has_muck_recommendations+ gives the class it is called on personalized recommendations
12
+ def has_muck_recommendations
13
+ has_many :personal_recommendations, :as => :personal_recommendable
14
+ end
15
+
16
+ def acts_as_muck_recommendation
17
+ has_many :recommended_to, :as => :destination, :class_name => 'PersonalRecommendation'
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
24
+ end
data/lib/muck_services.rb CHANGED
@@ -17,6 +17,6 @@ ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckServicesComment
17
17
  ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckServicesShare }
18
18
  ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckFeedOwner }
19
19
  ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckAggregationOwner }
20
-
20
+ ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckRecommendations }
21
21
 
22
22
  I18n.load_path += Dir[ File.join(File.dirname(__FILE__), '..', 'locales', '*.{rb,yml}') ]
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{muck-services}
8
- s.version = "0.1.14"
8
+ s.version = "0.1.16"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Joel Duffin", "Justin Ball"]
12
- s.date = %q{2009-11-17}
12
+ s.date = %q{2009-11-30}
13
13
  s.description = %q{This gem contains the rails specific code for dealing with feeds, aggregations and recommendations. It is meant to work with the muck-raker gem.}
14
14
  s.email = %q{justin@tatemae.com}
15
15
  s.extra_rdoc_files = [
@@ -347,7 +347,6 @@ Gem::Specification.new do |s|
347
347
  "db/migrate/20090623181458_add_grain_size_to_entries.rb",
348
348
  "db/migrate/20090623193525_add_grain_size_to_tag_clouds.rb",
349
349
  "db/migrate/20090703175825_denormalize_entries_subjects.rb",
350
- "db/migrate/20090704220055_create_slugs.rb",
351
350
  "db/migrate/20090716035935_change_tag_cloud_grain_sizes.rb",
352
351
  "db/migrate/20090717173900_add_contributor_to_feeds.rb",
353
352
  "db/migrate/20090717175825_normalize_entries_subjects.rb",
@@ -371,9 +370,11 @@ Gem::Specification.new do |s|
371
370
  "db/migrate/20091022150615_add_uri_key_to_services.rb",
372
371
  "db/migrate/20091115011828_add_aggregations_for_personal_recs.rb",
373
372
  "db/migrate/20091116094447_rename_action_table.rb",
373
+ "db/migrate/20091118203605_add_default_feed_type_to_aggregation_feed.rb",
374
374
  "lib/active_record/acts/muck_aggregation_owner.rb",
375
375
  "lib/active_record/acts/muck_feed_owner.rb",
376
376
  "lib/active_record/acts/muck_feed_parent.rb",
377
+ "lib/active_record/acts/muck_recommendations.rb",
377
378
  "lib/active_record/acts/muck_services_comment.rb",
378
379
  "lib/active_record/acts/muck_services_share.rb",
379
380
  "lib/muck_services.rb",
@@ -764,6 +765,9 @@ Gem::Specification.new do |s|
764
765
  "test/rails_root/db/migrate/20090924200750_add_uri_data_template_to_services.rb",
765
766
  "test/rails_root/db/migrate/20091006183742_add_feed_count_to_aggregation.rb",
766
767
  "test/rails_root/db/migrate/20091022150615_add_uri_key_to_services.rb",
768
+ "test/rails_root/db/migrate/20091115011828_add_aggregations_for_personal_recs.rb",
769
+ "test/rails_root/db/migrate/20091116094447_rename_action_table.rb",
770
+ "test/rails_root/db/migrate/20091118203605_add_default_feed_type_to_aggregation_feed.rb",
767
771
  "test/rails_root/db/schema.rb",
768
772
  "test/rails_root/features/step_definitions/common_steps.rb",
769
773
  "test/rails_root/features/step_definitions/visit_steps.rb",
@@ -792,6 +796,7 @@ Gem::Specification.new do |s|
792
796
  "test/rails_root/test/unit/feed_test.rb",
793
797
  "test/rails_root/test/unit/identity_feed_test.rb",
794
798
  "test/rails_root/test/unit/oai_endpoint_test.rb",
799
+ "test/rails_root/test/unit/personal_recommendation_test.rb",
795
800
  "test/rails_root/test/unit/service_category_test.rb",
796
801
  "test/rails_root/test/unit/service_test.rb",
797
802
  "test/rails_root/test/unit/services_mailer_test.rb",
data/rails/init.rb CHANGED
@@ -7,7 +7,7 @@ else
7
7
  require 'acts-as-taggable-on'
8
8
  rescue LoadError
9
9
  begin
10
- gem 'mbleigh-acts-as-taggable-on'
10
+ gem 'acts-as-taggable-on'
11
11
  rescue Gem::LoadError
12
12
  puts "Please install the acts-as-taggable-on gem"
13
13
  end
@@ -37,6 +37,8 @@ class User < ActiveRecord::Base
37
37
  acts_as_muck_sharer
38
38
  acts_as_muck_feed_owner
39
39
  acts_as_muck_aggregation_owner
40
+ has_muck_recommendations
41
+ acts_as_muck_recommendation
40
42
  def feed_to
41
43
  self
42
44
  end
@@ -21,8 +21,8 @@ Rails::Initializer.run do |config|
21
21
  config.gem "bcrypt-ruby", :lib => "bcrypt", :version => ">=2.0.5"
22
22
  config.gem "acts-as-taggable-on"
23
23
  config.gem "awesome_nested_set"
24
- config.gem "muck-feedbag", :lib => "feedbag", :source => "http://gems.github.com"
25
- config.gem "pauldix-feedzirra", :lib => 'feedzirra', :source => "http://gems.github.com"
24
+ config.gem "muck-feedbag", :lib => "feedbag"
25
+ config.gem "feedzirra"
26
26
  config.gem "httparty"
27
27
  config.gem "river"
28
28
  config.gem "overlord"
@@ -33,6 +33,6 @@ Rails::Initializer.run do |config|
33
33
  config.gem 'muck-activities', :lib => 'muck_activities'
34
34
  config.gem 'muck-shares', :lib => 'muck_shares'
35
35
  config.gem 'muck-solr', :lib => 'acts_as_solr'
36
- config.gem 'muck-raker', :lib => 'muck-raker'
36
+ config.gem 'muck-raker', :lib => 'muck_raker'
37
37
  config.plugin_locators << TestGemLocator
38
38
  end
@@ -1,7 +1,10 @@
1
1
  class CreateMuckRaker < ActiveRecord::Migration
2
2
 
3
3
  def self.up
4
-
4
+
5
+ # Gets the database adapter info defined in the database.yml file
6
+ adapter = User.connection.instance_variable_get("@config")[:adapter]
7
+
5
8
  create_table "action_types", :force => true do |t|
6
9
  t.string "action_type"
7
10
  t.integer "weight"
@@ -254,7 +257,13 @@ class CreateMuckRaker < ActiveRecord::Migration
254
257
  t.integer "entry_id"
255
258
  t.boolean "autogenerated", :default => false
256
259
  end
257
- execute "ALTER TABLE entries_subjects DROP COLUMN id, DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, entry_id);"
260
+
261
+ if adapter == 'mysql'
262
+ execute "ALTER TABLE entries_subjects DROP COLUMN id, DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, entry_id);"
263
+ elsif adapter == 'postgresql'
264
+ execute "CREATE UNIQUE INDEX entries_subjects_subject_id_entry_id ON entries_subjects USING btree(subject_id, entry_id); "
265
+ execute "ALTER TABLE entries_subjects CLUSTER ON entries_subjects_subject_id_entry_id; "
266
+ end
258
267
  add_index "entries_subjects", ["subject_id"]
259
268
  add_index "entries_subjects", ["entry_id"]
260
269
  add_index "entries_subjects", ["autogenerated"]
@@ -264,8 +273,14 @@ class CreateMuckRaker < ActiveRecord::Migration
264
273
  t.string "filter"
265
274
  t.string "tag_list", :limit => 2500
266
275
  end
267
- execute "ALTER TABLE cloud_caches DROP COLUMN id, DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(language_id, filter);"
268
-
276
+
277
+ if adapter == 'mysql'
278
+ execute "ALTER TABLE cloud_caches DROP COLUMN id, DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(language_id, filter);"
279
+ elsif adapter == 'postgresql'
280
+ execute "CREATE UNIQUE INDEX cloud_caches_language_id_filter ON cloud_caches USING btree(language_id, filter); "
281
+ execute "ALTER TABLE cloud_caches CLUSTER ON cloud_caches_language_id_filter; "
282
+ end
283
+
269
284
  # add a flag to the languages table to flag languages we support
270
285
  add_column :languages, :muck_raker_supported, :boolean, :default => false
271
286
  add_column :languages, :indexed_records, :integer, :default => 0
@@ -1,15 +1,41 @@
1
1
  class DenormalizeEntriesSubjects < ActiveRecord::Migration
2
2
  def self.up
3
+
4
+ # Gets the database adapter info defined in the database.yml file
5
+ adapter = User.connection.instance_variable_get("@config")[:adapter]
6
+
3
7
  add_column :entries_subjects, :language_id, :integer
4
8
  add_column :entries_subjects, :grain_size, :string
5
9
  add_index "entries_subjects", ["language_id"]
6
10
  add_index "entries_subjects", ["grain_size"]
7
- execute "ALTER TABLE entries_subjects DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, language_id, grain_size, entry_id);"
8
- execute "UPDATE entries_subjects AS es INNER JOIN entries AS e ON e.id = es.entry_id SET es.language_id = e.language_id, es.grain_size = e.grain_size"
11
+
12
+ if adapter == 'mysql'
13
+ execute "ALTER TABLE entries_subjects DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, language_id, grain_size, entry_id);"
14
+ execute "UPDATE entries_subjects AS es INNER JOIN entries AS e ON e.id = es.entry_id SET es.language_id = e.language_id, es.grain_size = e.grain_size"
15
+ elsif adapter == 'postgresql'
16
+ execute "DROP INDEX entries_subjects_subject_id_entry_id"
17
+ execute "CREATE UNIQUE INDEX entries_subjects_subject_id_entry_id ON entries_subjects USING btree(subject_id, language_id, grain_size, entry_id); "
18
+ execute "ALTER TABLE entries_subjects CLUSTER ON entries_subjects_subject_id_entry_id; "
19
+ execute "UPDATE entries_subjects es SET language_id = e.language_id, grain_size = e.grain_size FROM entries e WHERE es.entry_id = e.id"
20
+ else
21
+ raise 'Migration not implemented for this DB adapter'
22
+ end
23
+
9
24
  end
10
25
 
11
26
  def self.down
12
- execute "ALTER TABLE entries_subjects DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, entry_id);"
27
+
28
+ # Gets the database adapter info defined in the database.yml file
29
+ adapter = User.connection.instance_variable_get("@config")[:adapter]
30
+
31
+ if adapter == 'mysql'
32
+ execute "ALTER TABLE entries_subjects DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, entry_id);"
33
+ elsif adapter == 'postgresql'
34
+ execute "DROP INDEX entries_subjects_subject_id_entry_id"
35
+ execute "CREATE UNIQUE INDEX entries_subjects_subject_id_entry_id ON entries_subjects USING btree(subject_id, entry_id); "
36
+ execute "ALTER TABLE entries_subjects CLUSTER ON entries_subjects_subject_id_entry_id; "
37
+ end
38
+
13
39
  remove_column :entries_subjects, :language_id
14
40
  remove_column :entries_subjects, :grain_size
15
41
  end
@@ -1,6 +1,19 @@
1
1
  class NormalizeEntriesSubjects < ActiveRecord::Migration
2
2
  def self.up
3
- execute "ALTER TABLE entries_subjects DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, entry_id);"
3
+
4
+ # Gets the database adapter info defined in the database.yml file
5
+ adapter = User.connection.instance_variable_get("@config")[:adapter]
6
+
7
+ if adapter == 'mysql'
8
+ execute "ALTER TABLE entries_subjects DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, entry_id);"
9
+ elsif adapter == 'postgresql'
10
+ execute "DROP INDEX entries_subjects_subject_id_entry_id"
11
+ execute "CREATE UNIQUE INDEX entries_subjects_subject_id_entry_id ON entries_subjects USING btree(subject_id, entry_id); "
12
+ execute "ALTER TABLE entries_subjects CLUSTER ON entries_subjects_subject_id_entry_id; "
13
+ else
14
+ raise 'Migration not implemented for this data adapter'
15
+ end
16
+
4
17
  remove_column :entries_subjects, :language_id
5
18
  remove_column :entries_subjects, :grain_size
6
19
  execute "delete from entries_subjects where entry_id IN (select entries.id from entries inner join feeds ON feeds.id = entries.feed_id where feeds.uri = 'http://ndr.nsdl.org/oai?verb=ListRecords&metadataPrefix=nsdl_dc&set=439869');"
@@ -8,11 +21,27 @@ class NormalizeEntriesSubjects < ActiveRecord::Migration
8
21
  end
9
22
 
10
23
  def self.down
24
+
25
+ # Gets the database adapter info defined in the database.yml file
26
+ adapter = User.connection.instance_variable_get("@config")[:adapter]
27
+
11
28
  add_column :entries_subjects, :language_id, :integer
12
29
  add_column :entries_subjects, :grain_size, :string
13
30
  add_index "entries_subjects", ["language_id"]
14
31
  add_index "entries_subjects", ["grain_size"]
15
- execute "ALTER TABLE entries_subjects DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, language_id, grain_size, entry_id);"
16
- execute "UPDATE entries_subjects AS es INNER JOIN entries AS e ON e.id = es.entry_id SET es.language_id = e.language_id, es.grain_size = e.grain_size"
32
+
33
+ if adapter == 'mysql'
34
+ execute "ALTER TABLE entries_subjects DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(subject_id, language_id, grain_size, entry_id);"
35
+ execute "UPDATE entries_subjects AS es INNER JOIN entries AS e ON e.id = es.entry_id SET es.language_id = e.language_id, es.grain_size = e.grain_size"
36
+ elsif adapter == 'postgresql'
37
+ execute "DROP INDEX entries_subjects_subject_id_entry_id"
38
+ execute "CREATE UNIQUE INDEX entries_subjects_subject_id_entry_id ON entries_subjects USING btree(subject_id, language_id, grain_size, entry_id); "
39
+ execute "ALTER TABLE entries_subjects CLUSTER ON entries_subjects_subject_id_entry_id; "
40
+ execute "UPDATE entries_subjects es SET language_id = e.language_id, grain_size = e.grain_size FROM entries e WHERE es.entry_id = e.id"
41
+ else
42
+ raise 'Migration not implemented for this data adapter'
43
+ end
44
+
45
+
17
46
  end
18
47
  end
@@ -0,0 +1,9 @@
1
+ class AddAggregationsForPersonalRecs < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :aggregation_feeds, :feed_type, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :aggregation_feeds, :feed_type
8
+ end
9
+ end
@@ -0,0 +1,38 @@
1
+ class RenameActionTable < ActiveRecord::Migration
2
+ def self.up
3
+ rename_table :action_types, :attention_types
4
+ rename_column :attention_types, :action_type, :name
5
+ rename_column :attention_types, :weight, :default_weight
6
+
7
+ change_column :attentions, :attentionable_type, :string, :default => 'User'
8
+ rename_column :attentions, :action_type, :attention_type_id
9
+ change_column :attentions, :attention_type_id, :integer
10
+ change_column :attentions, :weight, :integer, :default => 5
11
+ add_column :attentions, :created_at, :datetime
12
+ add_index :attentions, :attention_type_id
13
+ add_index :attentions, :entry_id
14
+
15
+ remove_column :personal_recommendations, :rank
16
+ add_column :personal_recommendations, :created_at, :datetime
17
+ add_column :personal_recommendations, :visited_at, :datetime
18
+ add_index :personal_recommendations, :personal_recommendable_id
19
+ end
20
+
21
+ def self.down
22
+ remove_index :personal_recommendations, :personal_recommendable_id
23
+ remove_column :personal_recommendations, :visited_at
24
+ remove_column :personal_recommendations, :created_at
25
+ add_column :personal_recommendations, :rank, :integer
26
+
27
+ remove_index :attentions, :entry_id
28
+ remove_index :attentions, :attention_type_id
29
+ remove_column :attentions, :created_at
30
+ change_column :attentions, :weight, :float
31
+ change_column :attentions, :attention_type_id, :string
32
+ rename_column :attentions, :attention_type_id, :action_type
33
+
34
+ rename_column :attention_types, :default_weight, :weight
35
+ rename_column :attention_types, :name, :action_type
36
+ rename_table :attention_types, :action_types
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ class AddDefaultFeedTypeToAggregationFeed < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :aggregation_feeds, :feed_type, :string, :default => 'Feed'
4
+ end
5
+
6
+ def self.down
7
+ change_column :aggregation_feeds, :feed_type, :string, :default => nil
8
+ end
9
+
10
+ end
@@ -9,12 +9,7 @@
9
9
  #
10
10
  # It's strongly recommended to check this file into your version control system.
11
11
 
12
- ActiveRecord::Schema.define(:version => 20091022150615) do
13
-
14
- create_table "action_types", :force => true do |t|
15
- t.string "action_type"
16
- t.integer "weight"
17
- end
12
+ ActiveRecord::Schema.define(:version => 20091118203605) do
18
13
 
19
14
  create_table "activities", :force => true do |t|
20
15
  t.integer "item_id"
@@ -49,6 +44,7 @@ ActiveRecord::Schema.define(:version => 20091022150615) do
49
44
  create_table "aggregation_feeds", :force => true do |t|
50
45
  t.integer "aggregation_id"
51
46
  t.integer "feed_id"
47
+ t.string "feed_type", :default => "Feed"
52
48
  end
53
49
 
54
50
  add_index "aggregation_feeds", ["aggregation_id"], :name => "index_aggregation_feeds_on_aggregation_id"
@@ -68,14 +64,23 @@ ActiveRecord::Schema.define(:version => 20091022150615) do
68
64
 
69
65
  add_index "aggregations", ["ownable_id", "ownable_type"], :name => "index_aggregations_on_ownable_id_and_ownable_type"
70
66
 
67
+ create_table "attention_types", :force => true do |t|
68
+ t.string "name"
69
+ t.integer "default_weight"
70
+ end
71
+
71
72
  create_table "attentions", :force => true do |t|
72
- t.integer "attentionable_id"
73
- t.string "attentionable_type"
74
- t.integer "entry_id"
75
- t.string "action_type"
76
- t.float "weight"
73
+ t.integer "attentionable_id"
74
+ t.string "attentionable_type", :default => "User"
75
+ t.integer "entry_id"
76
+ t.integer "attention_type_id"
77
+ t.integer "weight", :default => 5
78
+ t.datetime "created_at"
77
79
  end
78
80
 
81
+ add_index "attentions", ["attention_type_id"], :name => "index_attentions_on_attention_type_id"
82
+ add_index "attentions", ["entry_id"], :name => "index_attentions_on_entry_id"
83
+
79
84
  create_table "clicks", :force => true do |t|
80
85
  t.integer "recommendation_id"
81
86
  t.datetime "when", :null => false
@@ -327,14 +332,17 @@ ActiveRecord::Schema.define(:version => 20091022150615) do
327
332
  end
328
333
 
329
334
  create_table "personal_recommendations", :force => true do |t|
330
- t.integer "personal_recommendable_id"
331
- t.string "personal_recommendable_type"
332
- t.integer "destination_id"
333
- t.string "destination_type"
334
- t.integer "rank"
335
- t.float "relevance"
335
+ t.integer "personal_recommendable_id"
336
+ t.string "personal_recommendable_type"
337
+ t.integer "destination_id"
338
+ t.string "destination_type"
339
+ t.float "relevance"
340
+ t.datetime "created_at"
341
+ t.datetime "visited_at"
336
342
  end
337
343
 
344
+ add_index "personal_recommendations", ["personal_recommendable_id"], :name => "index_personal_recommendations_on_personal_recommendable_id"
345
+
338
346
  create_table "queries", :force => true do |t|
339
347
  t.text "name"
340
348
  t.integer "frequency"
@@ -5,6 +5,7 @@
5
5
  # id :integer(4) not null, primary key
6
6
  # aggregation_id :integer(4)
7
7
  # feed_id :integer(4)
8
+ # feed_type :string(255) default("Feed")
8
9
  #
9
10
 
10
11
  require File.dirname(__FILE__) + '/../test_helper'
@@ -3,7 +3,7 @@
3
3
  # Table name: aggregations
4
4
  #
5
5
  # id :integer(4) not null, primary key
6
- # name :string(255)
6
+ # terms :string(255)
7
7
  # title :string(255)
8
8
  # description :text
9
9
  # top_tags :text
@@ -11,6 +11,7 @@
11
11
  # updated_at :datetime
12
12
  # ownable_id :integer(4)
13
13
  # ownable_type :string(255)
14
+ # feed_count :integer(4) default(0)
14
15
  #
15
16
 
16
17
  require File.dirname(__FILE__) + '/../test_helper'
@@ -22,18 +22,7 @@
22
22
  # relevant :text
23
23
  # other :text
24
24
  # grain_size :string(255) default("unknown")
25
- #
26
- # Indexes
27
- #
28
- # index_entries_on_direct_link (direct_link)
29
- # index_entries_on_feed_id (feed_id)
30
- # index_entries_on_indexed_at (indexed_at)
31
- # index_entries_on_language_id (language_id)
32
- # index_entries_on_oai_identifier (oai_identifier)
33
- # index_entries_on_permalink (permalink)
34
- # index_entries_on_published_at (published_at)
35
- # index_entries_on_relevance_calculated_at (relevance_calculated_at)
36
- # index_entries_on_grain_size (grain_size)
25
+ # comment_count :integer(4) default(0)
37
26
  #
38
27
 
39
28
  require File.dirname(__FILE__) + '/../test_helper'
@@ -1,3 +1,20 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: oai_endpoints
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # uri :string(2083)
7
+ # display_uri :string(2083)
8
+ # metadata_prefix :string(255)
9
+ # title :string(1000)
10
+ # short_title :string(100)
11
+ # contributor_id :integer(4)
12
+ # status :integer(4)
13
+ # default_language_id :integer(4)
14
+ # created_at :datetime
15
+ # updated_at :datetime
16
+ #
17
+
1
18
  require File.dirname(__FILE__) + '/../test_helper'
2
19
 
3
20
  # Used to test muck_content_permission
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class PersonalRecommendationTest < ActiveSupport::TestCase
4
+ context "personal recommendations" do
5
+ setup do
6
+ @user = Factory(:user)
7
+ end
8
+
9
+ context "has_muck_recommendations" do
10
+ setup do
11
+ @entry = Factory(:entry)
12
+ end
13
+ should "create a personal recommendation" do
14
+ recommendation = @user.personal_recommendations.build(:destination => @entry)
15
+ assert recommendation.save
16
+ end
17
+ end
18
+
19
+ context "acts_as_muck_recommendation" do
20
+ setup do
21
+ @recommended_user = Factory(:user)
22
+ end
23
+ should "make user recommended" do
24
+ recommendation = @user.personal_recommendations.create(:destination => @recommended_user)
25
+ assert @recommended_user.recommended_to.include?(recommendation)
26
+ end
27
+ end
28
+
29
+ context "named scopes" do
30
+ setup do
31
+ @entry = Factory(:entry)
32
+ @entry_old = Factory(:entry)
33
+ @recommended_user = Factory(:user)
34
+ @entry_recommendation = @user.personal_recommendations.create(:destination => @entry)
35
+ @user_recommendation = @user.personal_recommendations.create(:destination => @recommended_user, :created_at => 1.day.ago)
36
+ @old_recommendation = @user.personal_recommendations.create(:destination => @entry_old, :created_at => 3.weeks.ago)
37
+ end
38
+
39
+ context "entries" do
40
+ should "return an entry" do
41
+ assert @user.personal_recommendations.entries_only.include?(@entry_recommendation)
42
+ end
43
+ should "not return a user" do
44
+ assert !@user.personal_recommendations.entries_only.include?(@user_recommendation)
45
+ end
46
+ end
47
+ context "users" do
48
+ should "return an user" do
49
+ assert @user.personal_recommendations.users.include?(@user_recommendation)
50
+ end
51
+ should "not return an entry" do
52
+ assert !@user.personal_recommendations.users.include?(@entry_recommendation)
53
+ end
54
+ end
55
+ context "limited" do
56
+ should "only return a limited number of recommendations" do
57
+ assert_equal 1, @user.personal_recommendations.limit(1).length
58
+ end
59
+ end
60
+ context "recent" do
61
+ should "return recent recommendations" do
62
+ assert @user.personal_recommendations.recent.include?(@entry_recommendation)
63
+ end
64
+ should "not return old recommendations" do
65
+ assert !@user.personal_recommendations.recent.include?(@old_recommendation)
66
+ end
67
+ end
68
+ context "newest" do
69
+ should "order recommendations by newest" do
70
+ recommendations = @user.personal_recommendations.newest
71
+ assert recommendations[0].created_at > recommendations[1].created_at
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
@@ -6,7 +6,7 @@
6
6
  # uri :string(2083) default("")
7
7
  # name :string(1000) default("")
8
8
  # api_uri :string(2083) default("")
9
- # uri_data_template :string(2083) default("")
9
+ # uri_template :string(2083) default("")
10
10
  # icon :string(2083) default("rss.gif")
11
11
  # sort :integer(4)
12
12
  # requires_password :boolean(1)
@@ -15,6 +15,8 @@
15
15
  # active :boolean(1) default(TRUE)
16
16
  # prompt :string(255)
17
17
  # template :string(255)
18
+ # uri_data_template :string(2083) default("")
19
+ # uri_key :string(255)
18
20
  #
19
21
 
20
22
  require File.dirname(__FILE__) + '/../test_helper'
@@ -42,5 +42,6 @@ class UserTest < ActiveSupport::TestCase
42
42
  should_have_many :feeds
43
43
  should_have_many :own_feeds
44
44
  should_have_many :identity_feeds
45
+
45
46
  end
46
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: muck-services
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.14
4
+ version: 0.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Duffin
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-11-17 00:00:00 -07:00
13
+ date: 2009-11-30 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -473,7 +473,6 @@ files:
473
473
  - db/migrate/20090623181458_add_grain_size_to_entries.rb
474
474
  - db/migrate/20090623193525_add_grain_size_to_tag_clouds.rb
475
475
  - db/migrate/20090703175825_denormalize_entries_subjects.rb
476
- - db/migrate/20090704220055_create_slugs.rb
477
476
  - db/migrate/20090716035935_change_tag_cloud_grain_sizes.rb
478
477
  - db/migrate/20090717173900_add_contributor_to_feeds.rb
479
478
  - db/migrate/20090717175825_normalize_entries_subjects.rb
@@ -497,9 +496,11 @@ files:
497
496
  - db/migrate/20091022150615_add_uri_key_to_services.rb
498
497
  - db/migrate/20091115011828_add_aggregations_for_personal_recs.rb
499
498
  - db/migrate/20091116094447_rename_action_table.rb
499
+ - db/migrate/20091118203605_add_default_feed_type_to_aggregation_feed.rb
500
500
  - lib/active_record/acts/muck_aggregation_owner.rb
501
501
  - lib/active_record/acts/muck_feed_owner.rb
502
502
  - lib/active_record/acts/muck_feed_parent.rb
503
+ - lib/active_record/acts/muck_recommendations.rb
503
504
  - lib/active_record/acts/muck_services_comment.rb
504
505
  - lib/active_record/acts/muck_services_share.rb
505
506
  - lib/muck_services.rb
@@ -911,6 +912,9 @@ test_files:
911
912
  - test/rails_root/db/migrate/20090924200750_add_uri_data_template_to_services.rb
912
913
  - test/rails_root/db/migrate/20091006183742_add_feed_count_to_aggregation.rb
913
914
  - test/rails_root/db/migrate/20091022150615_add_uri_key_to_services.rb
915
+ - test/rails_root/db/migrate/20091115011828_add_aggregations_for_personal_recs.rb
916
+ - test/rails_root/db/migrate/20091116094447_rename_action_table.rb
917
+ - test/rails_root/db/migrate/20091118203605_add_default_feed_type_to_aggregation_feed.rb
914
918
  - test/rails_root/db/schema.rb
915
919
  - test/rails_root/features/step_definitions/common_steps.rb
916
920
  - test/rails_root/features/step_definitions/visit_steps.rb
@@ -939,6 +943,7 @@ test_files:
939
943
  - test/rails_root/test/unit/feed_test.rb
940
944
  - test/rails_root/test/unit/identity_feed_test.rb
941
945
  - test/rails_root/test/unit/oai_endpoint_test.rb
946
+ - test/rails_root/test/unit/personal_recommendation_test.rb
942
947
  - test/rails_root/test/unit/service_category_test.rb
943
948
  - test/rails_root/test/unit/service_test.rb
944
949
  - test/rails_root/test/unit/services_mailer_test.rb
@@ -1,18 +0,0 @@
1
- class CreateSlugs < ActiveRecord::Migration
2
- def self.up
3
- create_table :slugs do |t|
4
- t.string :name
5
- t.integer :sluggable_id
6
- t.integer :sequence, :null => false, :default => 1
7
- t.string :sluggable_type, :limit => 40
8
- t.string :scope, :limit => 40
9
- t.datetime :created_at
10
- end
11
- add_index :slugs, [:name, :sluggable_type, :scope, :sequence], :unique => true
12
- add_index :slugs, :sluggable_id
13
- end
14
-
15
- def self.down
16
- drop_table :slugs
17
- end
18
- end