muck-services 0.1.14 → 0.1.16

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.
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