muck-raker 0.1.21 → 0.1.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/README.rdoc +14 -0
  2. data/Rakefile +2 -0
  3. data/VERSION +1 -1
  4. data/app/controllers/admin/muck/feeds_controller.rb +23 -157
  5. data/app/controllers/muck/entries_controller.rb +7 -7
  6. data/app/controllers/muck/feeds_controller.rb +1 -1
  7. data/app/controllers/muck/recommendations_controller.rb +20 -16
  8. data/app/controllers/muck/visits_controller.rb +20 -0
  9. data/app/helpers/muck_raker_helper.rb +5 -1
  10. data/app/models/click.rb +8 -0
  11. data/app/models/entry.rb +39 -9
  12. data/app/models/feed.rb +89 -25
  13. data/app/models/feed_parent.rb +5 -0
  14. data/app/models/recommendation.rb +5 -0
  15. data/app/models/tag_cloud.rb +4 -0
  16. data/app/views/admin/feeds/index.html.erb +29 -59
  17. data/app/views/entries/_related_entry.html.erb +1 -1
  18. data/app/views/entries/_result.html.erb +1 -1
  19. data/app/views/feeds/_feed.html.erb +14 -1
  20. data/app/views/feeds/edit.html.erb +1 -1
  21. data/app/views/parts/_add_feed.html.erb +4 -4
  22. data/app/views/recommendations/index.pjs.erb +8 -8
  23. data/app/views/recommendations/index.rss.builder +3 -3
  24. data/app/views/recommendations/index.xml.builder +8 -8
  25. data/app/views/recommendations/index_js.pjs.erb +4 -0
  26. data/app/views/recommendations/index_real_time.pjs.erb +44 -0
  27. data/app/views/recommendations/index_real_time.xml.builder +26 -0
  28. data/app/views/visits/show.html.erb +156 -0
  29. data/config/muck_raker_routes.rb +19 -15
  30. data/db/bootstrap/services.yml +23 -23
  31. data/db/migrate/20090602191243_create_muck_raker.rb +2 -2
  32. data/db/migrate/20090728165716_add_etag_to_feeds.rb +9 -0
  33. data/db/migrate/20090730045848_add_comment_cache_to_entries.rb +9 -0
  34. data/db/migrate/20090804211240_add_entry_id_to_shares.rb +9 -0
  35. data/lib/muck_raker/tasks.rb +21 -24
  36. data/locales/en.yml +18 -1
  37. data/muck-raker.gemspec +82 -6
  38. data/raker/lib/recommenderd.jar +0 -0
  39. data/test/feed_archive/http---www-oercommons-org-oai-verb-ListRecords-metadataPrefix-oer_recommender-set-collection-american-physical-society/1248886128173.xml +56 -0
  40. data/test/feed_archive/http---www-oercommons-org-oai-verb-ListRecords-metadataPrefix-oer_recommender-set-collection-arizona-state-university/1248886130492.xml +49 -0
  41. data/test/feed_archive/http---www-oercommons-org-oai-verb-ListRecords-metadataPrefix-oer_recommender-set-collection-aspire/1248886130883.xml +192 -0
  42. data/test/rails_root/Rakefile +3 -0
  43. data/test/rails_root/app/controllers/application_controller.rb +10 -1
  44. data/test/rails_root/app/models/activity.rb +3 -0
  45. data/test/rails_root/app/models/comment.rb +3 -0
  46. data/test/rails_root/app/models/share.rb +4 -0
  47. data/test/rails_root/app/models/user.rb +5 -0
  48. data/test/rails_root/app/views/default/index.html.erb +2 -0
  49. data/test/rails_root/app/views/layouts/frame.html.erb +35 -0
  50. data/test/rails_root/config/database.yml +4 -2
  51. data/test/rails_root/config/environment.rb +3 -0
  52. data/test/rails_root/config/environments/cucumber.rb +21 -0
  53. data/test/rails_root/config/global_config.yml +2 -0
  54. data/test/rails_root/config/routes.rb +1 -1
  55. data/test/rails_root/db/bootstrap/attention.yml +6 -0
  56. data/test/rails_root/db/bootstrap/feeds.yml +4268 -0
  57. data/test/rails_root/db/bootstrap/oai_endpoints.yml +6 -0
  58. data/test/rails_root/db/bootstrap/services.yml +172 -0
  59. data/test/rails_root/db/migrate/20090402033319_add_muck_activities.rb +36 -0
  60. data/test/rails_root/db/migrate/20090602191243_create_muck_raker.rb +2 -2
  61. data/test/rails_root/db/migrate/20090613173314_create_comments.rb +24 -0
  62. data/test/rails_root/db/migrate/20090728165716_add_etag_to_feeds.rb +9 -0
  63. data/test/rails_root/db/migrate/20090730044139_add_comment_cache.rb +9 -0
  64. data/test/rails_root/db/migrate/20090730045848_add_comment_cache_to_entries.rb +9 -0
  65. data/test/rails_root/db/migrate/20090730154102_allow_null_user.rb +9 -0
  66. data/test/rails_root/db/migrate/20090803185323_create_shares.rb +18 -0
  67. data/test/rails_root/db/migrate/20090804211240_add_entry_id_to_shares.rb.rb +9 -0
  68. data/test/rails_root/features/feeds.feature +13 -0
  69. data/test/rails_root/features/step_definitions/common_steps.rb +93 -0
  70. data/test/rails_root/features/step_definitions/visit_steps.rb +6 -0
  71. data/test/rails_root/features/step_definitions/webrat_steps.rb +52 -23
  72. data/test/rails_root/features/support/paths.rb +36 -0
  73. data/test/rails_root/features/visit.feature +10 -0
  74. data/test/rails_root/lib/tasks/cucumber.rake +20 -0
  75. data/test/rails_root/public/images/icons/blue_guy.png +0 -0
  76. data/test/rails_root/public/images/icons/cancel.png +0 -0
  77. data/test/rails_root/public/images/icons/close.png +0 -0
  78. data/test/rails_root/public/images/icons/delete.png +0 -0
  79. data/test/rails_root/public/images/icons/exclaim.png +0 -0
  80. data/test/rails_root/public/images/icons/grey_guy.png +0 -0
  81. data/test/rails_root/public/images/icons/hide.png +0 -0
  82. data/test/rails_root/public/images/icons/information.png +0 -0
  83. data/test/rails_root/public/images/icons/minus.png +0 -0
  84. data/test/rails_root/public/images/icons/question.png +0 -0
  85. data/test/rails_root/public/images/icons/search_box.png +0 -0
  86. data/test/rails_root/public/images/icons/star.png +0 -0
  87. data/test/rails_root/public/images/icons/stop.png +0 -0
  88. data/test/rails_root/public/images/icons/thumb_down.png +0 -0
  89. data/test/rails_root/public/images/icons/thumb_up.png +0 -0
  90. data/test/rails_root/public/images/icons/vote.png +0 -0
  91. data/test/rails_root/public/javascripts/jquery/jrails.js +1 -0
  92. data/test/rails_root/public/javascripts/muck.js +15 -1
  93. data/test/rails_root/public/javascripts/muck_activities.js +1 -1
  94. data/test/rails_root/public/stylesheets/application.css +49 -1
  95. data/test/rails_root/public/stylesheets/styles.css +2 -1
  96. data/test/rails_root/script/cucumber +2 -1
  97. data/test/rails_root/test/functional/admin/feeds_controller_test.rb +37 -0
  98. data/test/rails_root/test/functional/feed_previews_controller_test.rb +1 -1
  99. data/test/rails_root/test/functional/visits_controller_test.rb +21 -0
  100. data/test/rails_root/test/test_helper.rb +2 -1
  101. data/test/rails_root/test/unit/entry_test.rb +12 -0
  102. data/test/rails_root/test/unit/feed_parent_test.rb +17 -0
  103. data/test/rails_root/test/unit/feed_test.rb +42 -3
  104. data/test/rails_root/test/unit/tag_cloud_test.rb +4 -0
  105. metadata +89 -4
  106. data/app/models/language.rb +0 -16
  107. data/app/views/recommendations/document_not_found.html.erb +0 -13
data/README.rdoc CHANGED
@@ -27,6 +27,20 @@ Add rake tasks to your Rakefile
27
27
 
28
28
  require 'muck_raker/tasks'
29
29
 
30
+ == Notes
31
+ muck-raker uses muck-comments and muck-activities to add comments to entries in the 'visits' frame view. You can omit these gems if you don't desire comments.
32
+ muck-raker 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.
33
+
34
+ To turn on this functionality add these lines to your global_config.yml file:
35
+ enable_raker_comments: true
36
+ enable_raker_shares: true
37
+
38
+ To install these gems:
39
+ sudo gem install muck-comments
40
+ sudo gem install muck-activities
41
+ sudo gem install muck-shares
42
+
43
+
30
44
  == Example
31
45
 
32
46
 
data/Rakefile CHANGED
@@ -63,8 +63,10 @@ begin
63
63
  gemspec.add_dependency "mislav-will_paginate"
64
64
  gemspec.add_dependency "httparty"
65
65
  gemspec.add_dependency "muck-feedbag"
66
+ gemspec.add_dependency "pauldix-feedzirra"
66
67
  gemspec.add_dependency "muck-engine"
67
68
  gemspec.add_dependency "muck-users"
69
+ gemspec.add_dependency "muck-comments"
68
70
  gemspec.add_dependency "muck-solr"
69
71
  gemspec.files.include %w( tasks/*
70
72
  db/bootstrap/*.yml
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.21
1
+ 0.1.22
@@ -1,174 +1,40 @@
1
- class Admin::Muck::FeedsController < ApplicationController
1
+ class Admin::Muck::FeedsController < Admin::Muck::BaseController
2
2
 
3
3
  unloadable
4
4
 
5
- before_filter :login_required, :only => [:index, :edit, :ban, :unban, :destroy, :update, :new]
6
-
7
- # GET /feeds
8
- # GET /feeds.xml
9
5
  def index
10
- @feeds = Feed.find(:all, :conditions => "status >= 0", :order => "title")
11
- @banned_feeds = Feed.find(:all, :conditions => "status < 0", :order => "title")
12
-
6
+ @feeds = Feed.by_newest.paginate(:page => @page, :per_page => @per_page)
13
7
  respond_to do |format|
14
- format.html # index.rhtml
8
+ format.html { render :template => 'admin/feeds/index' }
15
9
  format.xml { render :xml => @feeds.to_xml }
16
10
  end
17
11
  end
18
12
 
19
- def entries
20
- @new_feed = params[:new_feed]
21
- @feed = Feed.find(params[:id])
22
- @courses = @feed.entries.find(:all, :order => "title")
23
-
24
- respond_to do |format|
25
- format.html { render :partial => "courses", :layout => "default" }
26
- format.xml { render :xml => @courses.to_xml }
13
+ def update
14
+ feed = Feed.find(params[:id])
15
+ if params[:status] == 'unban'
16
+ unban(feed)
17
+ flash[:notice] = t('muck.raker.feed_validated_message')
18
+ elsif params[:status] == 'ban'
19
+ ban(feed)
20
+ flash[:notice] = t('muck.raker.feed_banned_message')
27
21
  end
28
- end
29
-
30
- # GET /feeds/selection_list
31
- def selection_list
32
- @feeds = Feed.find(:all, :order => "short_title")
33
- render :partial => "feed_selection", :collection => @feeds, :layout => false
34
- end
35
-
36
- # GET /feeds/1
37
- # GET /feeds/1.xml
38
- def show
39
- redirect_to "/feeds/" + params[:id] + "/entries"
40
- end
41
-
42
- # GET /feeds/new
43
- def new
44
- @no_follow = true
45
- @feeds = Feed.find(:all, :conditions => "status >= 0", :order => "title")
46
- @feed = Feed.new
47
- render :layout => "default"
48
- end
49
-
50
- # GET /feeds/1;edit
51
- def edit
52
- @feed = Feed.find(params[:id])
53
- render :layout => "default"
54
- end
55
-
56
- # # GET /feeds/1;reharvest
57
- # def harvest_now
58
- # @no_index = true
59
- # @feed = Feed.find(params[:id])
60
- # @feed.entries.destroy_all
61
- # @feed.failed_requests = "0"
62
- # @feed.refreshed_at = "2001"
63
- # @feed.save!
64
- # end
65
-
66
- # GET /feeds/1;ban
67
- def ban
68
- @feed = Feed.find(params[:id])
69
- @feed.entries.destroy_all
70
- @feed.status = -1
71
- @feed.save!
72
- #redirect_to feeds_path
73
- redirect_to "/feeds"
74
- end
75
-
76
- # GET /feeds/1;unban
77
- def unban
78
- @feed = Feed.find(params[:id])
79
- @feed.unban = true
80
- @feed.status = 0
81
- @feed.refreshed_at = "2001"
82
- @feed.save!
83
- #redirect_to feeds_path
84
- redirect_to "/feeds"
85
- end
86
-
87
- # def notification_feed_added(feed)
88
- # begin
89
- # FeedNotify.deliver_feed_added(feed)
90
- # return
91
- # rescue Exception => e
92
- # # unble to send activation email. Activate the user anyway which means
93
- # # letting flow continue below
94
- # logger.error 'Unable to send feed added notification E-Mail:'
95
- # logger.error e
96
- # end
97
- # end
98
- #
99
- # def notification_feed_updated(feed)
100
- # begin
101
- # FeedNotify.deliver_feed_updated(feed)
102
- # return
103
- # rescue Exception => e
104
- # # unble to send activation email. Activate the user anyway which means
105
- # # letting flow continue below
106
- # logger.error 'Unable to send feed added notification E-Mail:'
107
- # logger.error e
108
- # end
109
- # end
110
-
111
- # POST /feeds
112
- # POST /feeds.xml
113
- def create
114
- @feed = Feed.new(params[:feed])
115
- @feed.harvested_from_display_uri = @feed.display_uri
116
- @feed.entries_count = 0
117
- @feed.last_requested_at = Time.now - 2592000
118
- @feed.last_harvested_at = Time.now - 2592000
119
-
120
22
  respond_to do |format|
121
- if @feed.save
122
- flash[:notice] = 'Feed was successfully created.'
123
-
124
- # email the admin to let them know a feed has been added
125
- # notification_feed_added(@feed)
126
-
127
- # redirect to a page letting them know the feed has been created
128
- #format.html { redirect_to entries_path(@feed) + "?new_feed=true" }
129
- format.html { redirect_to "/feeds/" }
130
- format.xml { head :created, :location => feed_url(@feed) }
131
- else
132
- format.html { render :action => "new" }
133
- format.xml { render :xml => @feed.errors.to_xml }
134
- end
23
+ format.html { redirect_to admin_feeds_path }
135
24
  end
136
25
  end
137
26
 
138
- # PUT /feeds/1
139
- # PUT /feeds/1.xml
140
- def update
141
- @feed = Feed.find(params[:id])
142
-
143
- # force a harvest now
144
- # harvest_now
145
-
146
- respond_to do |format|
147
- if @feed.update_attributes(params[:feed])
148
- # notification_feed_updated(@feed)
149
- flash[:notice] = 'Feed was successfully updated.'
150
- format.html {
151
- redirect_to "/feeds/"
152
- return
153
- }
154
- format.xml { head :ok }
155
- else
156
- format.html { render :action => "edit" }
157
- format.xml { render :xml => @feed.errors.to_xml }
158
- end
27
+ protected
28
+
29
+ def ban(feed)
30
+ feed.entries.destroy_all
31
+ feed.status = -1
32
+ feed.save!
159
33
  end
160
- end
161
-
162
- # # DELETE /feeds/1
163
- # # DELETE /feeds/1.xml
164
- # def destroy
165
- # @feed = Feed.find(params[:id])
166
- # @feed.destroy
167
- #
168
- # respond_to do |format|
169
- # format.html { redirect_to feeds_url }
170
- # format.xml { head :ok }
171
- # end
172
- # end
173
34
 
35
+ def unban(feed)
36
+ feed.status = 0
37
+ feed.save!
38
+ end
39
+
174
40
  end
@@ -49,14 +49,14 @@ class Muck::EntriesController < ApplicationController
49
49
  @limit = 40 if @limit > 40
50
50
 
51
51
  respond_to do |format|
52
- format.html {
53
- @recommendations = @entry.recommendations(@limit, 'relevance', params[:details] == 'true')
54
- if params[:details] == 'true'
55
- render :template => "entries/details"
56
- else
57
- render :template => "entries/show"
52
+ format.html do
53
+ @recommendations = @entry.recommendations(@limit, 'relevance', params[:details] == 'true')
54
+ if params[:details] == 'true'
55
+ render :template => "entries/details"
56
+ else
57
+ render :template => "entries/show"
58
+ end
58
59
  end
59
- }# show.html.erb
60
60
  format.xml { render :xml => @entry }
61
61
  end
62
62
  end
@@ -18,7 +18,7 @@ class Muck::FeedsController < ApplicationController
18
18
  @entries = @feed.entries
19
19
  respond_to do |format|
20
20
  format.html { render :template => 'feeds/show', :layout => params[:layout] || true }
21
- format.pjs { debugger; render :template => 'feeds/show', :layout => false }
21
+ format.pjs { render :template => 'feeds/show', :layout => false }
22
22
  format.json { render :json => @feed.as_json }
23
23
  end
24
24
  end
@@ -7,8 +7,11 @@ class Muck::RecommendationsController < ApplicationController
7
7
  def index
8
8
  @details = params[:details] == "true"
9
9
 
10
- @referrer = request.env['HTTP_REFERER']
11
- @uri = params[:u] || @referrer
10
+ @uri = params[:u] || request.env['HTTP_REFERER']
11
+ if !allowed_uri(@uri)
12
+ render :text => '<!-- permission denied -->'
13
+ return
14
+ end
12
15
 
13
16
  if params[:educommons]
14
17
  @uri = @uri[%r=http://.*?/.*?/[^/]+=] || @uri
@@ -17,33 +20,34 @@ class Muck::RecommendationsController < ApplicationController
17
20
  end
18
21
 
19
22
  Entry.track_time_on_page(session, @uri)
20
- @document = Entry.recommender_entry(@uri)
21
- # I18n.locale = @document.language[0..1] if !@document.nil?
23
+ @entry = Entry.recommender_entry(@uri)
24
+ # I18n.locale = @entry.language[0..1] if !@entry.nil?
22
25
 
23
26
  @limit = params[:limit] ? params[:limit].to_i : 5
24
27
  @limit = 25 if @limit > 25
25
28
 
26
29
  respond_to do |format|
27
30
  format.html {
28
- @languages = Language.find(:all, :order => "name")
29
31
  order = params[:order] || "mixed"
30
- redirect_to "/documents/" + @document.id.to_s + "?limit=" + @limit.to_s + "&order=" + order + "&details=" + @details.to_s if !@document.nil?
31
- render(:template => '/recommendations/document_not_found.html.erb', :layout => false) if @document.nil?
32
- @recommendations = @entry.recommendations(@limit, params[:order] || "relevance")
32
+ redirect_to resource_path(@entry) + "?limit=" + @limit.to_s + "&order=" + order + "&details=" + @details.to_s if !@entry.id.nil?
33
33
  }
34
34
  format.xml {
35
- render(:template => '/recommendations/index.xml.builder', :layout => false)
35
+ render(:template => @entry.id.nil? ? '/recommendations/index_real_time.xml.builder' : '/recommendations/index.xml.builder', :layout => false)
36
36
  }
37
37
  format.pjs {
38
- if @document.nil?
39
- render_text ""
40
- else
41
- @host = "http://" + URI.parse(@uri).host
42
- render(:template => 'recommendations/index.pjs.erb', :layout => false)
43
- end
38
+ @host = "http://" + URI.parse(@uri).host
39
+ render(:template => @entry.id.nil? ? 'recommendations/index_real_time.pjs.erb' : 'recommendations/index.pjs.erb', :layout => false)
40
+ }
41
+ format.rss {
42
+ render(:template => 'recommendations/index.rss.builder', :layout => false)
44
43
  }
45
- format.rss { render(:template => 'recommendations/index.rss.builder', :layout => false) }
46
44
  end
47
45
  end
48
46
 
47
+ protected
48
+
49
+ def allowed_uri(uri)
50
+ uri.match(/^(10\.|192\.168|172\.|127\.)/) == nil && uri.include?('localhost') == false
51
+ end
52
+
49
53
  end
@@ -0,0 +1,20 @@
1
+ class Muck::VisitsController < ApplicationController
2
+
3
+ unloadable
4
+
5
+ before_filter :store_location
6
+
7
+ def show
8
+ @entry = Entry.find(params[:id])
9
+ @page_title = @entry.title
10
+ @resource_uri = @entry.resource_uri
11
+ @comments = @entry.comments.by_newest if GlobalConfig.enable_raker_comments
12
+ @share = Share.new(:title => @entry.title, :uri => @resource_uri, :entry_id => @entry.id) if GlobalConfig.enable_raker_shares
13
+ respond_to do |format|
14
+ format.html { render :template => 'visits/show', :layout => 'frame' }
15
+ format.pjs { render :template => 'visits/show', :layout => false }
16
+ format.json { render :json => @entry.as_json }
17
+ end
18
+ end
19
+
20
+ end
@@ -14,7 +14,7 @@ module MuckRakerHelper
14
14
  end
15
15
 
16
16
  def filtered_tag_link(tag, filter, css_class, grain_size)
17
- link_to h(tag), "/resources/tags/#{filter}/#{tag}?grain_size=#{grain_size}", :class => css_class
17
+ link_to h(tag), "/resources/tags/#{filter.join('/')}/#{tag}?grain_size=#{grain_size}", :class => css_class
18
18
  end
19
19
 
20
20
  def results_status
@@ -76,4 +76,8 @@ module MuckRakerHelper
76
76
  "/search/results?terms=feed_id:" + feed.id.to_s + "&locale=en"
77
77
  end
78
78
 
79
+ def already_shared_entry?(user, entry)
80
+ user.shares.find(:all, :conditions => ['entry_id = ?', entry.id])
81
+ end
82
+
79
83
  end
data/app/models/click.rb CHANGED
@@ -9,6 +9,14 @@
9
9
  # requester :string(255)
10
10
  # user_agent :string(2083)
11
11
  #
12
+ # Indexes
13
+ #
14
+ # index_clicks_on_recommendation_id (recommendation_id)
15
+ # index_clicks_on_referrer (referrer)
16
+ # index_clicks_on_requester (requester)
17
+ # index_clicks_on_user_agent (user_agent)
18
+ # index_clicks_on_when (when)
19
+ #
12
20
 
13
21
  class Click < ActiveRecord::Base
14
22
  end
data/app/models/entry.rb CHANGED
@@ -23,18 +23,37 @@
23
23
  # other :text
24
24
  # grain_size :string(255) default("unknown")
25
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)
37
+ #
26
38
 
27
39
  class Entry < ActiveRecord::Base
28
40
 
41
+ unloadable
42
+
29
43
  belongs_to :feed
30
44
  belongs_to :language
31
45
 
46
+ acts_as_commentable
32
47
  acts_as_taggable
33
48
 
34
49
  @@default_time_on_page = 60.0
35
50
 
36
51
  acts_as_solr({:if => false, :fields => [{:feed_id => :integer}, {:grain_size => :string}]}, {:type_field => :type_s})
37
52
 
53
+ def resource_uri
54
+ self.direct_link.nil? ? self.permalink : self.direct_link
55
+ end
56
+
38
57
  def self.top_tags(tags = nil)
39
58
 
40
59
  end
@@ -44,14 +63,9 @@ class Entry < ActiveRecord::Base
44
63
  return find_by_solr(query, :limit => limit, :offset => offset, :scores => true, :select => "entries.id, entries.title, entries.permalink, entries.direct_link, entries.published_at, entries.description, entries.feed_id, feeds.short_title AS collection", :joins => "INNER JOIN feeds ON feeds.id = entries.feed_id", :core => language, :operator => operator)
45
64
  end
46
65
 
47
- def self.normalized_uri(uri)
48
- uri.sub(/index.?\.(html|aspx|shtm|htm|asp|php|cfm|jsp|shtml|jhtml)$/, '')
49
- end
50
-
51
66
  def self.recommender_entry(uri)
52
67
  uri = normalized_uri(uri)
53
- sql = "SELECT * FROM entries WHERE permalink = ? OR direct_link = ?"
54
- Entry.find_by_sql([sql,uri,uri]).first
68
+ Entry.find(:first, :conditions => ['permalink = ? OR direct_link = ?', uri, uri], :order => 'direct_link IS NULL DESC') || Entry.new(:permalink => uri)
55
69
  end
56
70
 
57
71
  def recommendations(limit = 20, order = "relevance", details = false, omit_feeds = nil)
@@ -173,9 +187,13 @@ class Entry < ActiveRecord::Base
173
187
  end
174
188
 
175
189
  def ranked_recommendations(limit = 5, order = "mixed", details = false, omit_feeds = nil)
176
- return relevant_recommendations(limit, "clicks DESC, relevance", details, omit_feeds) if order == "clicks"
177
- return relevant_recommendations(limit, "relevance", details, omit_feeds) if (order == "relevance" || details == true)
178
- return relevant_recommendations_filtered(limit, details, omit_feeds) if omit_feeds != nil
190
+ if self.id.nil?
191
+ return Entry.real_time_recommendations(self.permalink, details, :core => 'en', :limit => limit)
192
+ else
193
+ return relevant_recommendations(limit, "clicks DESC, relevance", details, omit_feeds) if order == "clicks"
194
+ return relevant_recommendations(limit, "relevance", details, omit_feeds) if (order == "relevance" || details == true)
195
+ return relevant_recommendations_filtered(limit, details, omit_feeds) if omit_feeds != nil
196
+ end
179
197
 
180
198
  recs = []
181
199
  if self.popular != nil && !self.popular.empty?
@@ -306,4 +324,16 @@ class Entry < ActiveRecord::Base
306
324
  return threshold > 5 ? threshold : 5
307
325
  end
308
326
 
327
+ protected
328
+
329
+ def self.normalized_uri(uri)
330
+ uri.sub(/index.?\.(html|aspx|shtm|htm|asp|php|cfm|jsp|shtml|jhtml)$/, '')
331
+ end
332
+
333
+ def self.real_time_recommendations(uri, details = false, options = {})
334
+ fields = "entries.id, entries.title, entries.permalink, entries.direct_link, feeds.short_title AS collection"
335
+ fields << ", entries.published_at, entries.description, entries.author" if details == true
336
+ more_like_this(uri, options.merge(:select => fields, :joins => "INNER JOIN feeds ON feeds.id = entries.feed_id"))
337
+ end
338
+
309
339
  end