muck-services 0.1.23 → 0.1.24

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -78,8 +78,10 @@ muck-services uses muck-comments and muck-activities to add comments to entries
78
78
  muck-services also uses muck-shares and muck-activities to share entries with other users. Again you can omit these gems if you don't desire the share capability.
79
79
 
80
80
  To turn on this functionality add these lines to your global_config.yml file:
81
- enable_raker_comments: true
82
- enable_raker_shares: true
81
+ inform_admin_of_global_feed: true # If true then the 'admin_email' will recieve an email anytime a global feed (one that is not
82
+ # attached to any object) is added.
83
+ enable_services_comments: true # Enables or disables comments in the frame that wraps content as a user browses recommendation results
84
+ enable_services_shares: true # Enables or disables sharing in the frame that wraps content as a user browses recommendation results
83
85
 
84
86
  To install these gems:
85
87
  sudo gem install muck-comments
data/Rakefile CHANGED
@@ -3,6 +3,9 @@ require 'rake'
3
3
  require 'rake/testtask'
4
4
  require 'rake/rdoctask'
5
5
 
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
6
9
  desc 'Translate this gem'
7
10
  task :translate do
8
11
  file = File.join(File.dirname(__FILE__), 'locales', 'en.yml')
@@ -35,9 +38,6 @@ Rake::TestTask.new(:test) do |t|
35
38
  t.verbose = true
36
39
  end
37
40
 
38
- task :test => :check_dependencies
39
- task :default => :test
40
-
41
41
  begin
42
42
  require 'jeweler'
43
43
  Jeweler::Tasks.new do |gem|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.23
1
+ 0.1.24
data/app/models/entry.rb CHANGED
@@ -46,10 +46,6 @@ class Entry < ActiveRecord::Base
46
46
  self.direct_link.nil? ? self.permalink : self.direct_link
47
47
  end
48
48
 
49
- def self.top_tags(tags = nil)
50
-
51
- end
52
-
53
49
  def self.search(search_terms, grain_size = nil, language = "en", limit = 10, offset = 0, operator = :or)
54
50
  raise MuckServices::Exceptions::LanguageNotSupported, I18n.t('muck.services.language_not_supported') unless Recommender::Languages.supported_languages.include?(language)
55
51
  query = ((!grain_size.nil? && grain_size != 'all') ? (search_terms + ") AND (grain_size:#{grain_size}") : search_terms) + ") AND (aggregation:#{Aggregation.global_feeds_id}"
@@ -63,8 +59,8 @@ class Entry < ActiveRecord::Base
63
59
  Entry.find(:first, :conditions => ['permalink = ? OR direct_link = ?', uri, uri], :order => 'direct_link IS NULL DESC') || Entry.new(:permalink => uri)
64
60
  end
65
61
 
66
- def recommendations(limit = 20, order = "relevance", details = false, omit_feeds = nil)
67
- sql = "SELECT recommendations.id, dest_entry_id, entries.permalink, entries.title, entries.description, entries.direct_link, feeds.short_title AS collection "
62
+ def recommendation_entries(limit = 20, order = "relevance", details = false, omit_feeds = nil)
63
+ sql = "SELECT recommendations.dest_entry_id AS id, entries.permalink, entries.title, entries.description, entries.direct_link, feeds.short_title AS collection "
68
64
  sql << ", relevance_calculated_at, relevance, clicks, avg_time_at_dest AS avg_time_on_target, author, published_at " if details == true
69
65
  sql << "FROM recommendations "
70
66
  sql << "INNER JOIN entries ON recommendations.dest_entry_id = entries.id "
@@ -76,8 +72,8 @@ class Entry < ActiveRecord::Base
76
72
  Entry.find_by_sql([sql,self.id])
77
73
  end
78
74
 
79
- def recommendation_entries(limit = 20, order = "relevance", details = false, omit_feeds = nil)
80
- sql = "SELECT recommendations.dest_entry_id AS id, entries.permalink, entries.title, entries.description, entries.direct_link, feeds.short_title AS collection "
75
+ def recommendations(limit = 20, order = "relevance", details = false, omit_feeds = nil)
76
+ sql = "SELECT recommendations.id, dest_entry_id, entries.permalink, entries.title, entries.description, entries.direct_link, feeds.short_title AS collection "
81
77
  sql << ", relevance_calculated_at, relevance, clicks, avg_time_at_dest AS avg_time_on_target, author, published_at " if details == true
82
78
  sql << "FROM recommendations "
83
79
  sql << "INNER JOIN entries ON recommendations.dest_entry_id = entries.id "
@@ -89,90 +85,13 @@ class Entry < ActiveRecord::Base
89
85
  Entry.find_by_sql([sql,self.id])
90
86
  end
91
87
 
92
- def self.track_time_on_page(session, uri)
93
- recommendation_id = session[:last_clicked_recommendation]
94
- if !recommendation_id.nil?
95
- time_on_page = (Time.now - session[:last_clicked_recommendation_time].to_f).to_i
96
-
97
- # if they spend longer than two minutes on a page, we don't infer anything
98
- if time_on_page > 5 and time_on_page < 120
99
- if normalized_uri(uri) != session[:last_clicked_recommendation_uri]
100
- recommendation = Recommendation.find(recommendation_id)
101
- entry = Entry.find(recommendation.entry_id)
102
- new_avg = (recommendation.avg_time_at_dest*recommendation.clicks - @@default_time_on_page + time_on_page)/recommendation.clicks
103
- recommendation.avg_time_at_dest = new_avg
104
- recommendation.save!
105
- entry.rank_recommendations
106
- session[:last_clicked_recommendation] = nil
107
- end
108
- else
109
- session[:last_clicked_recommendation] = nil if time_on_page > 5
110
- end
111
- end
112
- end
113
-
114
- def self.avg_time(clicks, old_avg, time_on_page)
115
- return (old_avg*(clicks-1) + time_on_page)/clicks
116
- end
117
-
118
- def self.track_click(session, recommendation_id, referrer, redirect_type = "direct_link", requester = "unknown", user_agent = "unknown")
119
- # look up the recommendation
120
- recommendation = Recommendation.find(recommendation_id)
121
- return "" if !recommendation
122
-
123
- # get the entries being linked from and to
124
- entry = Entry.find(recommendation.entry_id)
125
- target = Entry.find(recommendation.dest_entry_id)
126
-
127
- # get the list of recommendations that have been clicked during this session
128
- clicks = session[:rids] || Array.new
129
-
130
- # redirect to our frame page
131
- redirect = "/visits/#{recommendation.dest_entry_id}"
132
-
133
- # track the time on the last page
134
- track_time_on_page(session, redirect)
135
-
136
- # if this is first time the user clicked on this recommendation during this session
137
- if !clicks.include?(recommendation_id)
138
-
139
- # add this recommendation to the end of the list
140
- clicks << recommendation_id
141
- session[:rids] = clicks
142
-
143
- # update the click time
144
- recommendation.avg_time_at_dest = ((recommendation.avg_time_at_dest*recommendation.clicks) + @@default_time_on_page)/(recommendation.clicks + 1)
145
- recommendation.clicks += 1
146
- recommendation.save!
147
-
148
- # store info about this click in the session
149
- now = Time.now
150
- session[:last_clicked_recommendation] = recommendation_id
151
- session[:last_clicked_recommendation_time] = now
152
- session[:last_clicked_recommendation_uri] = redirect
153
-
154
- # update the recommendation cache for the entry
155
- entry.rank_recommendations if entry
156
-
157
- # track the click in the db
158
- Click.create(:recommendation_id => recommendation_id, :when => now, :referrer => referrer, :requester => requester, :user_agent => user_agent)
159
- end
160
-
161
- return redirect
162
- end
163
-
164
88
  def relevant_recommendations(limit = 5, order = "relevance", details = false, omit_feeds = nil)
165
89
  return self.recommendations(limit, order, details, omit_feeds)
166
90
  end
167
91
 
168
- def self.truncate_words(text, length = 30, end_string = ' ...')
169
- words = text.split()
170
- words[0..(length-1)].join(' ') + (words.length > length ? end_string : '')
171
- end
172
-
173
92
  def ranked_recommendations(limit = 5, order = "mixed", details = false, omit_feeds = nil)
174
- return relevant_recommendations(limit, "clicks DESC, relevance", details, omit_feeds) if order == "clicks"
175
- return relevant_recommendations(limit, "relevance", details, omit_feeds) if (order == "relevance" || details == true)
93
+ return self.recommendations(limit, "clicks DESC, relevance", details, omit_feeds) if order == "clicks"
94
+ return self.recommendations(limit, "relevance", details, omit_feeds) if (order == "relevance" || details == true)
176
95
  return relevant_recommendations_filtered(limit, details, omit_feeds) if omit_feeds != nil
177
96
 
178
97
  recs = []
@@ -190,6 +109,11 @@ class Entry < ActiveRecord::Base
190
109
  return recs
191
110
  end
192
111
 
112
+ def json_recommendations(limit = 5, order = "mixed", details = false, omit_feeds = nil)
113
+ recs = ranked_recommendations(limit, order, details, omit_feeds)
114
+ (recs.nil? || recs.empty?) ? "" : ActiveSupport::JSON.encode(recs)
115
+ end
116
+
193
117
  def relevant_recommendations_filtered(limit, details, omit_feeds)
194
118
  # get recommendations for the entry from the recommendations table
195
119
  recs = self.recommendations(limit, "mixed", details, omit_feeds)
@@ -222,10 +146,6 @@ class Entry < ActiveRecord::Base
222
146
  return (popular_recs + relevant_recs + other_recs)[0..limit]
223
147
  end
224
148
 
225
- def json_recommendations(limit = 5, order = "mixed", details = false, omit_feeds = nil)
226
- ActiveSupport::JSON.encode(ranked_recommendations(limit, order, details, omit_feeds))
227
- end
228
-
229
149
  def rank_recommendations
230
150
  return
231
151
  # get recommendations for the entry from the recommendations table
@@ -304,6 +224,83 @@ class Entry < ActiveRecord::Base
304
224
  return threshold > 5 ? threshold : 5
305
225
  end
306
226
 
227
+ def self.avg_time(clicks, old_avg, time_on_page)
228
+ return (old_avg*(clicks-1) + time_on_page)/clicks
229
+ end
230
+
231
+ def self.track_time_on_page(session, uri)
232
+ recommendation_id = session[:last_clicked_recommendation]
233
+ if !recommendation_id.nil?
234
+ time_on_page = (Time.now - session[:last_clicked_recommendation_time].to_f).to_i
235
+
236
+ # if they spend longer than two minutes on a page, we don't infer anything
237
+ if time_on_page > 5 and time_on_page < 120
238
+ if normalized_uri(uri) != session[:last_clicked_recommendation_uri]
239
+ recommendation = Recommendation.find(recommendation_id)
240
+ entry = Entry.find(recommendation.entry_id)
241
+ new_avg = (recommendation.avg_time_at_dest*recommendation.clicks - @@default_time_on_page + time_on_page)/recommendation.clicks
242
+ recommendation.avg_time_at_dest = new_avg
243
+ recommendation.save!
244
+ entry.rank_recommendations
245
+ session[:last_clicked_recommendation] = nil
246
+ end
247
+ else
248
+ session[:last_clicked_recommendation] = nil if time_on_page > 5
249
+ end
250
+ end
251
+ end
252
+
253
+ def self.track_click(session, recommendation_id, referrer, redirect_type = "direct_link", requester = "unknown", user_agent = "unknown")
254
+ # look up the recommendation
255
+ recommendation = Recommendation.find(recommendation_id)
256
+ return "" if !recommendation
257
+
258
+ # get the entries being linked from and to
259
+ entry = Entry.find(recommendation.entry_id)
260
+ target = Entry.find(recommendation.dest_entry_id)
261
+
262
+ # get the list of recommendations that have been clicked during this session
263
+ clicks = session[:rids] || Array.new
264
+
265
+ # redirect to our frame page
266
+ redirect = "/visits/#{recommendation.dest_entry_id}"
267
+
268
+ # track the time on the last page
269
+ track_time_on_page(session, redirect)
270
+
271
+ # if this is first time the user clicked on this recommendation during this session
272
+ if !clicks.include?(recommendation_id)
273
+
274
+ # add this recommendation to the end of the list
275
+ clicks << recommendation_id
276
+ session[:rids] = clicks
277
+
278
+ # update the click time
279
+ recommendation.avg_time_at_dest = ((recommendation.avg_time_at_dest*recommendation.clicks) + @@default_time_on_page)/(recommendation.clicks + 1)
280
+ recommendation.clicks += 1
281
+ recommendation.save!
282
+
283
+ # store info about this click in the session
284
+ now = Time.now
285
+ session[:last_clicked_recommendation] = recommendation_id
286
+ session[:last_clicked_recommendation_time] = now
287
+ session[:last_clicked_recommendation_uri] = redirect
288
+
289
+ # update the recommendation cache for the entry
290
+ entry.rank_recommendations if entry
291
+
292
+ # track the click in the db
293
+ Click.create(:recommendation_id => recommendation_id, :when => now, :referrer => referrer, :requester => requester, :user_agent => user_agent)
294
+ end
295
+
296
+ return redirect
297
+ end
298
+
299
+ def self.truncate_words(text, length = 30, end_string = ' ...')
300
+ words = text.split()
301
+ words[0..(length-1)].join(' ') + (words.length > length ? end_string : '')
302
+ end
303
+
307
304
  protected
308
305
 
309
306
  # def self.redirect_uri(target, referrer, redirect_type)
@@ -14,18 +14,6 @@
14
14
  # created_at :datetime
15
15
  # updated_at :datetime
16
16
  #
17
-
18
- # == Schema Information
19
- #
20
- # Table name: oai_endpoints
21
- #
22
- # id :integer(4) not null, primary key
23
- # uri :string(2083)
24
- # display_uri :string(2083)
25
- # metadata_prefix :string(255)
26
- # title :string(1000)
27
- # short_title :string(100)
28
- #
29
17
  class OaiEndpoint < ActiveRecord::Base
30
18
 
31
19
  belongs_to :contributor, :class_name => 'User', :foreign_key => 'contributor_id'
@@ -33,7 +21,7 @@ class OaiEndpoint < ActiveRecord::Base
33
21
 
34
22
  validates_presence_of :uri
35
23
 
36
- named_scope :banned, :conditions => "status < 0"
24
+ named_scope :banned, :conditions => ["status = ?", MuckServices::Status::BANNED]
37
25
  named_scope :valid, :conditions => "status >= 0"
38
26
  named_scope :by_title, :order => "title ASC"
39
27
  named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } }
@@ -13,10 +13,14 @@
13
13
  #
14
14
 
15
15
  class PersonalRecommendation < ActiveRecord::Base
16
-
16
+ unloadable
17
+
17
18
  belongs_to :personal_recommendable, :polymorphic => true
18
19
  belongs_to :destination, :polymorphic => true
19
-
20
+
21
+ belongs_to :entry, :class_name => 'Entry', :foreign_key => 'destination_id', :include => :feed
22
+ belongs_to :user, :class_name => 'User', :foreign_key => 'destination_id'
23
+
20
24
  named_scope :limit, lambda { |num| { :limit => num } }
21
25
  named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } }
22
26
  named_scope :newest, :order => "created_at DESC"
@@ -230,7 +230,7 @@ class Service < ActiveRecord::Base
230
230
  # will result in the values being repopulated from the database
231
231
  def self.get_photo_services(refresh_services = false)
232
232
  @photo_services = nil if refresh_services
233
- @photo_services ||= get_services(refresh_services).find_all{|service| service.service_category.name == 'Photos' }
233
+ @photo_services ||= get_services(refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Photos' }
234
234
  end
235
235
 
236
236
  # Get all video services
@@ -239,7 +239,7 @@ class Service < ActiveRecord::Base
239
239
  # will result in the values being repopulated from the database
240
240
  def self.get_video_services(refresh_services = false)
241
241
  @video_services = nil if refresh_services
242
- @video_services ||= get_services(refresh_services).find_all{|service| service.service_category.name == 'Videos' }
242
+ @video_services ||= get_services(refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Videos' }
243
243
  end
244
244
 
245
245
  # Get all bookmark services
@@ -248,7 +248,7 @@ class Service < ActiveRecord::Base
248
248
  # will result in the values being repopulated from the database
249
249
  def self.get_bookmark_services(refresh_services = false)
250
250
  @bookmark_services = nil if refresh_services
251
- @bookmark_services ||= get_services(refresh_services).find_all{|service| service.service_category.name == 'Bookmarks' }
251
+ @bookmark_services ||= get_services(refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Bookmarks' }
252
252
  end
253
253
 
254
254
  # Get all music services
@@ -257,7 +257,7 @@ class Service < ActiveRecord::Base
257
257
  # will result in the values being repopulated from the database
258
258
  def self.get_music_services(refresh_services = false)
259
259
  @music_services = nil if refresh_services
260
- @music_services ||= get_services(refresh_services).find_all{|service| service.service_category.name == 'Music' }
260
+ @music_services ||= get_services(refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Music' }
261
261
  end
262
262
 
263
263
  # Get all news services
@@ -266,7 +266,7 @@ class Service < ActiveRecord::Base
266
266
  # will result in the values being repopulated from the database
267
267
  def self.get_news_services(refresh_services = false)
268
268
  @news_services = nil if refresh_services
269
- @news_services ||= get_services(refresh_services).find_all{|service| service.service_category.name == 'News' }
269
+ @news_services ||= get_services(refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'News' }
270
270
  end
271
271
 
272
272
  # Get all blog services
@@ -275,7 +275,7 @@ class Service < ActiveRecord::Base
275
275
  # will result in the values being repopulated from the database
276
276
  def self.get_blog_services(refresh_services = false)
277
277
  @blog_services = nil if refresh_services
278
- @blog_services ||= get_services(refresh_services).find_all{|service| service.service_category.name == 'Blogging' }
278
+ @blog_services ||= get_services(refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Blogging' }
279
279
  end
280
280
 
281
281
  # Get all search services
@@ -284,7 +284,7 @@ class Service < ActiveRecord::Base
284
284
  # will result in the values being repopulated from the database
285
285
  def self.get_search_services(refresh_services = false)
286
286
  @search_services = nil if refresh_services
287
- @search_services ||= get_services(refresh_services).find_all{|service| service.service_category.name == 'Search' }
287
+ @search_services ||= get_services(refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Search' }
288
288
  end
289
289
 
290
290
  # Get all general services. These are all services except photo, video, bookmark and music.
@@ -304,7 +304,7 @@ class Service < ActiveRecord::Base
304
304
  # will result in the values being repopulated from the database
305
305
  def self.get_photo_tag_services(refresh_services = false)
306
306
  @photo_services = nil if refresh_services
307
- @photo_services ||= get_tag_services(nil, refresh_services).find_all{|service| service.service_category.name == 'Photos' }
307
+ @photo_services ||= get_tag_services(nil, refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Photos' }
308
308
  end
309
309
 
310
310
  # Get all video services that are used to generate tag feeds
@@ -313,7 +313,7 @@ class Service < ActiveRecord::Base
313
313
  # will result in the values being repopulated from the database
314
314
  def self.get_video_tag_services(refresh_services = false)
315
315
  @video_services = nil if refresh_services
316
- @video_services ||= get_tag_services(nil, refresh_services).find_all{|service| service.service_category.name == 'Videos' }
316
+ @video_services ||= get_tag_services(nil, refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Videos' }
317
317
  end
318
318
 
319
319
  # Get all bookmark services that are used to generate tag feeds
@@ -322,7 +322,7 @@ class Service < ActiveRecord::Base
322
322
  # will result in the values being repopulated from the database
323
323
  def self.get_bookmark_tag_services(refresh_services = false)
324
324
  @bookmark_services = nil if refresh_services
325
- @bookmark_services ||= get_tag_services(nil, refresh_services).find_all{|service| service.service_category.name == 'Bookmarks' }
325
+ @bookmark_services ||= get_tag_services(nil, refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Bookmarks' }
326
326
  end
327
327
 
328
328
  # Get all music services that are used to generate tag feeds
@@ -331,7 +331,7 @@ class Service < ActiveRecord::Base
331
331
  # will result in the values being repopulated from the database
332
332
  def self.get_music_tag_services(refresh_services = false)
333
333
  @music_services = nil if refresh_services
334
- @music_services ||= get_tag_services(nil, refresh_services).find_all{|service| service.service_category.name == 'Music' }
334
+ @music_services ||= get_tag_services(nil, refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Music' }
335
335
  end
336
336
 
337
337
  # Get all news services that are used to generate tag feeds
@@ -340,7 +340,7 @@ class Service < ActiveRecord::Base
340
340
  # will result in the values being repopulated from the database
341
341
  def self.get_news_tag_services(refresh_services = false)
342
342
  @news_services = nil if refresh_services
343
- @news_services ||= get_tag_services(nil, refresh_services).find_all{|service| service.service_category.name == 'News' }
343
+ @news_services ||= get_tag_services(nil, refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'News' }
344
344
  end
345
345
 
346
346
  # Get all blog services that are used to generate tag feeds
@@ -349,7 +349,7 @@ class Service < ActiveRecord::Base
349
349
  # will result in the values being repopulated from the database
350
350
  def self.get_blog_tag_services(refresh_services = false)
351
351
  @blog_services = nil if refresh_services
352
- @blog_services ||= get_tag_services(nil, refresh_services).find_all{|service| service.service_category.name == 'Blogging' }
352
+ @blog_services ||= get_tag_services(nil, refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Blogging' }
353
353
  end
354
354
 
355
355
  # Get all search services that are used to generate tag feeds
@@ -358,7 +358,7 @@ class Service < ActiveRecord::Base
358
358
  # will result in the values being repopulated from the database
359
359
  def self.get_search_tag_services(refresh_services = false)
360
360
  @search_services = nil if refresh_services
361
- @search_services ||= get_tag_services(nil, refresh_services).find_all{|service| service.service_category.name == 'Search' }
361
+ @search_services ||= get_tag_services(nil, refresh_services).find_all{|service| !service.service_category.blank? && service.service_category.name == 'Search' }
362
362
  end
363
363
 
364
364
  # Get all general services that are used to generate tag feeds
@@ -1,6 +1,6 @@
1
1
  <%
2
2
  @json_recommendations = @entry.json_recommendations(@limit, params[:order] || "mixed", true, params[:omit_feeds] || nil)
3
- if !@json_recommendations.nil?
3
+ if !@json_recommendations.empty?
4
4
  @direct_link_text = params[:direct_link_text] || t('muck.services.direct_link')
5
5
  %>
6
6
  var catalog_page = <%= !@entry.direct_link.nil? and @uri == @entry.permalink %>;
@@ -26,6 +26,7 @@ document.write('<div class="oer_recommender_list">');
26
26
  for(nRec = 0; nRec < recs.length; nRec++) {
27
27
  r = recs[nRec].entry;
28
28
  if (r == null) r = recs[nRec].attributes;
29
+ if (r == null) r = recs[nRec];
29
30
  metadata_link = catalog_page && document_host == r.uri.substring(0, document_host.length);
30
31
  direct_link = metadata_link && r.direct_link;
31
32
  document.write('<p class="oer_recommender_item">');
@@ -35,11 +36,11 @@ for(nRec = 0; nRec < recs.length; nRec++) {
35
36
  document.write(' <span class="oer_recommender_published_at">(' + format_date(r.published_at) + ')</span>');
36
37
  document.write(' <span class="oer_recommender_relevance_score"><%= t('muck.services.relevance')%>: ' + Math.round(r.relevance*100)/100 + '</span>');
37
38
  document.write('<br/><span class="oer_recommender_description">' + truncate(r.description) + '</span>');
38
- document.write('<br/><span class="oer_recommender_uri">' + r.uri + '</span>');
39
+ document.write('<br/><span class="oer_recommender_uri">' + r.permalink + '</span>');
39
40
  <% end -%>
40
41
  document.write('</a></p>');
41
42
  }
42
43
  document.write('</div>');
43
- <% if params[:more_link] %>document.write('<div class="oer_recommender_more_link"><a href="' + app + 'documents/<%= @entry.id %>"><%= t('muck.services.gm_more_prompt') %></a></div>');<% end %>
44
+ <% if params[:more_link] %>document.write('<div class="oer_recommender_more_link"><a href="' + app + 'resources/<%= @entry.id %>"><%= t('muck.services.gm_more_prompt') %></a></div>');<% end %>
44
45
  document.write('</div>');
45
46
  <% end %>
@@ -25,6 +25,7 @@ ActionController::Routing::Routes.draw do |map|
25
25
  map.resources :oai_endpoints, :controller => 'muck/oai_endpoints', :has_many => :feeds
26
26
 
27
27
  map.resources :feeds, :controller => 'muck/feeds', :collection => { :new_extended => :get, :new_oai_rss => :get }, :has_many => :entries
28
+ map.connection 'users/:login/recommendations', :controller => 'muck/personal_recommendations', :action => 'index'
28
29
 
29
30
  map.connect 'recommendations/real_time', :controller => 'muck/recommendations', :action => 'real_time'
30
31
  map.connect 'recommendations/get_button', :controller => 'muck/recommendations', :action => 'get_button'
@@ -11,6 +11,8 @@ module ActiveRecord
11
11
  # +has_muck_recommendations+ gives the class it is called on personalized recommendations
12
12
  def has_muck_recommendations
13
13
  has_many :personal_recommendations, :as => :personal_recommendable
14
+ has_many :recommended_entries, :through => :personal_recommendations, :source => :entry,
15
+ :conditions => "personal_recommendations.destination_type = 'Entry'"
14
16
  end
15
17
 
16
18
  def acts_as_muck_recommendation
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{muck-services}
8
- s.version = "0.1.23"
8
+ s.version = "0.1.24"
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-12-11}
12
+ s.date = %q{2009-12-19}
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 = [
@@ -140,7 +140,6 @@ Gem::Specification.new do |s|
140
140
  "app/views/service_templates/_zotero_group.html.erb",
141
141
  "app/views/services/_edit_service.html.erb",
142
142
  "app/views/services/_new_service.html.erb",
143
- "app/views/services/_personal_recommendations.html.erb",
144
143
  "app/views/services/_summary.html.erb",
145
144
  "app/views/services/_view_service.html.erb",
146
145
  "app/views/services_mailer/notification_feed_added.text.ar.html.erb",
@@ -857,4 +856,3 @@ Gem::Specification.new do |s|
857
856
  s.add_dependency(%q<shoulda>, [">= 0"])
858
857
  end
859
858
  end
860
-
@@ -98,7 +98,7 @@ ul#add_oai_rss_feed_menu li{display:inline;margin:0 5px;}
98
98
  #recs_header{color:#777;background-color:white;font-weight:bold;font-size:16px;font-family:Arial,Helvetica,sans-serif;margin: 2px 3px 0 3px; padding: 2px;}
99
99
  #recs_list{margin: 1px; padding: 1px; list-style-type: none;}
100
100
  #recs_list li{margin-left: 0px; padding: 3px; list-style-type: none; font-size: 12px;}
101
- .even{background-color:#E6E6E6;}
101
+ .even{background-color:#DDD;}
102
102
  #more_recs{margin:4px 0 6px;padding:0;text-align:center;}
103
103
  #recs_panel a{color:#3987DC;text-decoration:none;}
104
104
  #recs_panel a:hover{text-decoration:underline;}
@@ -31,6 +31,7 @@ Rails::Initializer.run do |config|
31
31
  config.gem "geokit"
32
32
  config.gem 'muck-engine', :lib => 'muck_engine'
33
33
  config.gem 'muck-users', :lib => 'muck_users'
34
+ config.gem 'muck-profiles', :lib => 'muck_profiles'
34
35
  config.gem 'muck-comments', :lib => 'muck_comments'
35
36
  config.gem 'muck-activities', :lib => 'muck_activities'
36
37
  config.gem 'muck-shares', :lib => 'muck_shares'
@@ -29,44 +29,10 @@ class AggregationTest < ActiveSupport::TestCase
29
29
  should_have_many :aggregation_feeds
30
30
  should_have_many :feeds
31
31
 
32
- context "named scope" do
33
- context "by_title" do
34
- setup do
35
- Aggregation.delete_all
36
- @first = Factory(:aggregation, :title => 'a')
37
- @second = Factory(:aggregation, :title => 'b')
38
- end
39
- should "sort by title" do
40
- assert_equal @first, Aggregation.by_title[0]
41
- assert_equal @second, Aggregation.by_title[1]
42
- end
43
- end
44
- context "recent" do
45
- setup do
46
- Aggregation.delete_all
47
- @recent = Factory(:aggregation)
48
- @not_recent = Factory(:aggregation, :created_at => 10.weeks.ago)
49
- end
50
- should "get recent aggregations" do
51
- assert Aggregation.recent.include?(@recent)
52
- end
53
- should "not get recent aggregations" do
54
- assert !Aggregation.recent.include?(@not_recent)
55
- end
56
- end
57
- context "newest" do
58
- setup do
59
- Aggregation.delete_all
60
- @first = Factory(:aggregation, :created_at => 1.day.ago)
61
- @second = Factory(:aggregation, :created_at => 1.week.ago)
62
- end
63
- should "sort by created_at" do
64
- assert_equal @first, Aggregation.newest[0]
65
- assert_equal @second, Aggregation.newest[1]
66
- end
67
- end
68
- end
69
-
32
+ should_scope_by_title
33
+ should_scope_recent
34
+ should_scope_newest
35
+
70
36
  context "filter feed types" do
71
37
  setup do
72
38
  build_music_service
@@ -53,11 +53,9 @@ class FeedTest < ActiveSupport::TestCase
53
53
 
54
54
  should_validate_presence_of :uri
55
55
 
56
- should_have_named_scope :by_newest
57
- should_have_named_scope :banned
58
- should_have_named_scope :valid
59
- should_have_named_scope :by_title
60
- should_have_named_scope :recent
56
+ should_scope_by_title
57
+ should_scope_recent
58
+ should_scope_by_newest
61
59
 
62
60
  should "set 24 hours as default interval" do
63
61
  assert_equal @feed.harvest_interval_hours, 24
@@ -68,6 +66,35 @@ class FeedTest < ActiveSupport::TestCase
68
66
  assert_equal @feed.harvest_interval, 10 * 3600
69
67
  end
70
68
 
69
+ context "named scope" do
70
+ context "banned" do
71
+ # named_scope :banned, :conditions => ["status = ?", MuckServices::Status::BANNED]
72
+ setup do
73
+ @feed = Factory(:feed, :status => MuckServices::Status::BANNED)
74
+ @feed_not = Factory(:feed)
75
+ end
76
+ should "find feeds that are banned" do
77
+ assert Feed.banned.include?(@feed)
78
+ end
79
+ should "not find feeds that are not banned" do
80
+ assert !Feed.banned.include?(@feed_not)
81
+ end
82
+ end
83
+ context "valid" do
84
+ # named_scope :valid, :conditions => "status >= 0", :include => [:default_language]
85
+ setup do
86
+ @feed = Factory(:feed, :status => 0)
87
+ @feed_not = Factory(:feed, :status => MuckServices::Status::BANNED)
88
+ end
89
+ should "find valid feeds" do
90
+ assert Feed.valid.include?(@feed)
91
+ end
92
+ should "not find invalid feeds" do
93
+ assert !Feed.valid.include?(@feed_not)
94
+ end
95
+ end
96
+ end
97
+
71
98
  end
72
99
 
73
100
  context "Feed status" do
@@ -32,25 +32,52 @@ class OaiEndpointTest < ActiveSupport::TestCase
32
32
 
33
33
  should_validate_presence_of :uri
34
34
 
35
- should_have_named_scope :by_newest
36
- should_have_named_scope :banned
37
- should_have_named_scope :valid
38
- should_have_named_scope :by_title
39
- should_have_named_scope :recent
35
+ should_scope_by_title
36
+ should_scope_recent
37
+ should_scope_by_newest
38
+
39
+ context "named scope" do
40
+ context "banned" do
41
+ # named_scope :banned, :conditions => ["status = ?", MuckServices::Status::BANNED]
42
+ setup do
43
+ @oai_endpoint = Factory(:oai_endpoint, :status => MuckServices::Status::BANNED)
44
+ @oai_endpoint_not = Factory(:oai_endpoint)
45
+ end
46
+ should "find oai_endpoints that are banned" do
47
+ assert OaiEndpoint.banned.include?(@oai_endpoint)
48
+ end
49
+ should "not find oai_endpoints that are not banned" do
50
+ assert !OaiEndpoint.banned.include?(@oai_endpoint_not)
51
+ end
52
+ end
53
+ context "valid" do
54
+ # named_scope :valid, :conditions => "status >= 0", :include => [:default_language]
55
+ setup do
56
+ @oai_endpoint = Factory(:oai_endpoint, :status => 0)
57
+ @oai_endpoint_not = Factory(:oai_endpoint, :status => MuckServices::Status::BANNED)
58
+ end
59
+ should "find valid oai_endpoints" do
60
+ assert OaiEndpoint.valid.include?(@oai_endpoint)
61
+ end
62
+ should "not find invalid oai_endpoints" do
63
+ assert !OaiEndpoint.valid.include?(@oai_endpoint_not)
64
+ end
65
+ end
66
+ end
40
67
 
41
68
  end
42
69
 
43
70
  context "banned/unbanned" do
44
71
  setup do
45
- @feed = Factory(:feed)
72
+ @oai_endpoint = Factory(:oai_endpoint)
46
73
  end
47
74
  should "be banned" do
48
- @feed.status = -1
49
- assert @feed.banned?
75
+ @oai_endpoint.status = -1
76
+ assert @oai_endpoint.banned?
50
77
  end
51
78
  should "not be banned" do
52
- @feed.status = 0
53
- assert !@feed.banned?
79
+ @oai_endpoint.status = 0
80
+ assert !@oai_endpoint.banned?
54
81
  end
55
82
  end
56
83
 
@@ -13,7 +13,7 @@ class ServiceCategoryTest < ActiveSupport::TestCase
13
13
 
14
14
  context "service category instance" do
15
15
  should_have_many :services
16
- should_have_named_scope :sorted
16
+ should_scope_sorted
17
17
  end
18
18
 
19
19
  end
@@ -24,11 +24,64 @@ require File.dirname(__FILE__) + '/../test_helper'
24
24
  class ServiceTest < ActiveSupport::TestCase
25
25
 
26
26
  context "service instance" do
27
-
27
+
28
28
  should_belong_to :service_category
29
- should_have_named_scope :sorted
30
- should_have_named_scope :identity_services
31
- should_have_named_scope :tag_services
29
+ should_scope_sorted
30
+
31
+ context "named scope" do
32
+ context "identity_services" do
33
+ # named_scope :identity_services, :conditions => ['use_for = ?', 'identity']
34
+ setup do
35
+ @service = Factory(:service, :use_for => 'identity')
36
+ @service_not = Factory(:service, :use_for => 'not')
37
+ end
38
+ should "find services that have use_for=='identity_services'" do
39
+ assert Service.identity_services.include?(@service)
40
+ end
41
+ should "not find services that where use_for!='identity_services'" do
42
+ assert !Service.identity_services.include?(@service_not)
43
+ end
44
+ end
45
+ context "tag_services" do
46
+ # named_scope :tag_services, :conditions => ['use_for = ?', 'tags']
47
+ setup do
48
+ @service = Factory(:service, :use_for => 'tags')
49
+ @service_not = Factory(:service, :use_for => 'not')
50
+ end
51
+ should "find services that have use_for=='tags'" do
52
+ assert Service.tag_services.include?(@service)
53
+ end
54
+ should "not find services that where use_for!='tags'" do
55
+ assert !Service.tag_services.include?(@service_not)
56
+ end
57
+ end
58
+ context "sorted_id" do
59
+ # named_scope :sorted_id, :order => "id ASC"
60
+ setup do
61
+ Service.delete_all
62
+ @first = Factory(:service)
63
+ @second = Factory(:service)
64
+ end
65
+ should "sort by 'sort' field" do
66
+ assert_equal @first, Service.sorted_id[0]
67
+ assert_equal @second, Service.sorted_id[1]
68
+ end
69
+ end
70
+ context "photo_services" do
71
+ # named_scope :photo_services, :conditions => ["service_categories.id = services.service_category_id AND service_categories.name = 'Photos'"], :include => ['service_category']
72
+ setup do
73
+ @service_category = Factory(:service_category, :name => 'Photos')
74
+ @service = Factory(:service, :service_category => @service_category)
75
+ @service_not = Factory(:service)
76
+ end
77
+ should "find services that have 'Photos' for a service category" do
78
+ assert Service.photo_services.include?(@service)
79
+ end
80
+ should "not find services that don't have 'Photos' for a service category" do
81
+ assert !Service.photo_services.include?(@service_not)
82
+ end
83
+ end
84
+ end
32
85
 
33
86
  context "photos" do
34
87
  setup do
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.23
4
+ version: 0.1.24
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-12-11 00:00:00 -07:00
13
+ date: 2009-12-19 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -266,7 +266,6 @@ files:
266
266
  - app/views/service_templates/_zotero_group.html.erb
267
267
  - app/views/services/_edit_service.html.erb
268
268
  - app/views/services/_new_service.html.erb
269
- - app/views/services/_personal_recommendations.html.erb
270
269
  - app/views/services/_summary.html.erb
271
270
  - app/views/services/_view_service.html.erb
272
271
  - app/views/services_mailer/notification_feed_added.text.ar.html.erb
@@ -1,5 +0,0 @@
1
- <ul>
2
- <% recommendations.each do |r| -%>
3
- <li><%= link_to r.destination.title, r.destination %></li>
4
- <% end -%>
5
- </ul>