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.
- data/VERSION +1 -1
- data/app/controllers/muck/feeds_controller.rb +1 -1
- data/app/helpers/muck_services_service_helper.rb +1 -2
- data/app/models/aggregation.rb +9 -5
- data/app/models/aggregation_feed.rb +1 -0
- data/app/models/attention.rb +4 -3
- data/app/models/attention_type.rb +9 -0
- data/app/models/entry.rb +3 -12
- data/app/models/oai_endpoint.rb +17 -0
- data/app/models/personal_recommendation.rb +23 -1
- data/app/models/service.rb +2 -2
- data/app/views/feeds/_feed_row.html.erb +1 -1
- data/app/views/services/_personal_recommendations.html.erb +3 -3
- data/db/migrate/20091118203605_add_default_feed_type_to_aggregation_feed.rb +10 -0
- data/lib/active_record/acts/muck_recommendations.rb +24 -0
- data/lib/muck_services.rb +1 -1
- data/muck-services.gemspec +8 -3
- data/rails/init.rb +1 -1
- data/test/rails_root/app/models/user.rb +2 -0
- data/test/rails_root/config/environment.rb +3 -3
- data/test/rails_root/db/migrate/20090602191243_create_muck_raker.rb +19 -4
- data/test/rails_root/db/migrate/20090703175825_denormalize_entries_subjects.rb +29 -3
- data/test/rails_root/db/migrate/20090717175825_normalize_entries_subjects.rb +32 -3
- data/test/rails_root/db/migrate/20091115011828_add_aggregations_for_personal_recs.rb +9 -0
- data/test/rails_root/db/migrate/20091116094447_rename_action_table.rb +38 -0
- data/test/rails_root/db/migrate/20091118203605_add_default_feed_type_to_aggregation_feed.rb +10 -0
- data/test/rails_root/db/schema.rb +25 -17
- data/test/rails_root/test/unit/aggregation_feed_test.rb +1 -0
- data/test/rails_root/test/unit/aggregation_test.rb +2 -1
- data/test/rails_root/test/unit/entry_test.rb +1 -12
- data/test/rails_root/test/unit/oai_endpoint_test.rb +17 -0
- data/test/rails_root/test/unit/personal_recommendation_test.rb +78 -0
- data/test/rails_root/test/unit/service_test.rb +3 -1
- data/test/rails_root/test/unit/user_test.rb +1 -0
- metadata +8 -3
- data/db/migrate/20090704220055_create_slugs.rb +0 -18
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.16
|
@@ -8,8 +8,7 @@ module MuckServicesServiceHelper
|
|
8
8
|
|
9
9
|
# Render personal recommendations
|
10
10
|
def personal_recommendations(user, limit = 5)
|
11
|
-
recommendations
|
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.
|
data/app/models/aggregation.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Table name: aggregations
|
4
4
|
#
|
5
5
|
# id :integer(4) not null, primary key
|
6
|
-
# terms
|
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
|
-
|
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.
|
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
|
data/app/models/attention.rb
CHANGED
@@ -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
|
-
#
|
10
|
-
# weight :
|
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
|
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
|
|
data/app/models/oai_endpoint.rb
CHANGED
@@ -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
|
-
|
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
|
data/app/models/service.rb
CHANGED
@@ -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>
|
@@ -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}') ]
|
data/muck-services.gemspec
CHANGED
@@ -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.
|
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-
|
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
@@ -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"
|
25
|
-
config.gem "
|
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 => '
|
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
|
-
|
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
|
-
|
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
|
-
|
8
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
16
|
-
|
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,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 =>
|
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
|
73
|
-
t.string
|
74
|
-
t.integer
|
75
|
-
t.
|
76
|
-
t.
|
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
|
331
|
-
t.string
|
332
|
-
t.integer
|
333
|
-
t.string
|
334
|
-
t.
|
335
|
-
t.
|
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"
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Table name: aggregations
|
4
4
|
#
|
5
5
|
# id :integer(4) not null, primary key
|
6
|
-
#
|
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
|
-
#
|
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'
|
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.
|
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-
|
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
|