muck-raker 0.1.15 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (246) hide show
  1. data/README.rdoc +21 -8
  2. data/Rakefile +6 -0
  3. data/VERSION +1 -1
  4. data/app/controllers/admin/{recommender → muck}/feeds_controller.rb +2 -2
  5. data/app/controllers/{recommender → muck}/entries_controller.rb +8 -5
  6. data/app/controllers/muck/feed_previews_controller.rb +33 -0
  7. data/app/controllers/muck/feeds_controller.rb +128 -0
  8. data/app/controllers/{recommender → muck}/recommendations_controller.rb +4 -1
  9. data/app/controllers/{recommender → muck}/search_controller.rb +3 -1
  10. data/app/helpers/muck_raker_feeds_helper.rb +24 -0
  11. data/app/models/attention.rb +13 -1
  12. data/app/models/click.rb +12 -0
  13. data/app/models/entry.rb +45 -11
  14. data/app/models/feed.rb +81 -7
  15. data/app/models/feed_parent.rb +18 -0
  16. data/app/models/language.rb +14 -0
  17. data/app/models/oai_endpoint.rb +12 -0
  18. data/app/models/raker_mailer.rb +16 -0
  19. data/app/models/recommendation.rb +13 -0
  20. data/app/models/service.rb +14 -0
  21. data/app/models/subject.rb +8 -0
  22. data/app/models/tag_cloud.rb +14 -1
  23. data/app/views/admin/feeds/index.html.erb +65 -0
  24. data/app/views/entries/_related_entry.html.erb +4 -0
  25. data/app/views/entries/_result_status.html.erb +3 -3
  26. data/app/views/entries/details.html.erb +19 -22
  27. data/app/views/entries/index.html.erb +1 -1
  28. data/app/views/entries/show.html.erb +4 -7
  29. data/app/views/feed_previews/new.html.erb +1 -0
  30. data/app/views/feed_previews/select_feeds.html.erb +6 -0
  31. data/app/views/feeds/_entry.html.erb +1 -0
  32. data/app/views/feeds/_feed.html.erb +9 -0
  33. data/app/views/feeds/index.html.erb +30 -94
  34. data/app/views/feeds/new.html.erb +1 -109
  35. data/app/views/feeds/new_extended.html.erb +1 -0
  36. data/app/views/feeds/show.html.erb +6 -0
  37. data/app/views/parts/_add_extended_feed.html.erb +31 -0
  38. data/app/views/parts/_add_feed.html.erb +20 -0
  39. data/app/views/parts/_add_single_feed.html.erb +21 -0
  40. data/app/views/parts/_select_feed.html.erb +4 -0
  41. data/app/views/raker_mailer/notification_feed_added.text.ar.html.erb +3 -0
  42. data/app/views/raker_mailer/notification_feed_added.text.ar.plain.erb +5 -0
  43. data/app/views/raker_mailer/notification_feed_added.text.bg.html.erb +3 -0
  44. data/app/views/raker_mailer/notification_feed_added.text.bg.plain.erb +5 -0
  45. data/app/views/raker_mailer/notification_feed_added.text.ca.html.erb +3 -0
  46. data/app/views/raker_mailer/notification_feed_added.text.ca.plain.erb +5 -0
  47. data/app/views/raker_mailer/notification_feed_added.text.cs.html.erb +3 -0
  48. data/app/views/raker_mailer/notification_feed_added.text.cs.plain.erb +5 -0
  49. data/app/views/raker_mailer/notification_feed_added.text.da.html.erb +3 -0
  50. data/app/views/raker_mailer/notification_feed_added.text.da.plain.erb +5 -0
  51. data/app/views/raker_mailer/notification_feed_added.text.de.html.erb +3 -0
  52. data/app/views/raker_mailer/notification_feed_added.text.de.plain.erb +5 -0
  53. data/app/views/raker_mailer/notification_feed_added.text.el.html.erb +3 -0
  54. data/app/views/raker_mailer/notification_feed_added.text.el.plain.erb +5 -0
  55. data/app/views/raker_mailer/notification_feed_added.text.es.html.erb +3 -0
  56. data/app/views/raker_mailer/notification_feed_added.text.es.plain.erb +5 -0
  57. data/app/views/raker_mailer/notification_feed_added.text.et.html.erb +3 -0
  58. data/app/views/raker_mailer/notification_feed_added.text.et.plain.erb +5 -0
  59. data/app/views/raker_mailer/notification_feed_added.text.fa.html.erb +3 -0
  60. data/app/views/raker_mailer/notification_feed_added.text.fa.plain.erb +5 -0
  61. data/app/views/raker_mailer/notification_feed_added.text.fi.html.erb +3 -0
  62. data/app/views/raker_mailer/notification_feed_added.text.fi.plain.erb +5 -0
  63. data/app/views/raker_mailer/notification_feed_added.text.fr.html.erb +3 -0
  64. data/app/views/raker_mailer/notification_feed_added.text.fr.plain.erb +5 -0
  65. data/app/views/raker_mailer/notification_feed_added.text.gl.html.erb +3 -0
  66. data/app/views/raker_mailer/notification_feed_added.text.gl.plain.erb +5 -0
  67. data/app/views/raker_mailer/notification_feed_added.text.hi.html.erb +3 -0
  68. data/app/views/raker_mailer/notification_feed_added.text.hi.plain.erb +5 -0
  69. data/app/views/raker_mailer/notification_feed_added.text.hr.html.erb +3 -0
  70. data/app/views/raker_mailer/notification_feed_added.text.hr.plain.erb +5 -0
  71. data/app/views/raker_mailer/notification_feed_added.text.html.erb +3 -0
  72. data/app/views/raker_mailer/notification_feed_added.text.hu.html.erb +3 -0
  73. data/app/views/raker_mailer/notification_feed_added.text.hu.plain.erb +5 -0
  74. data/app/views/raker_mailer/notification_feed_added.text.id.html.erb +3 -0
  75. data/app/views/raker_mailer/notification_feed_added.text.id.plain.erb +5 -0
  76. data/app/views/raker_mailer/notification_feed_added.text.it.html.erb +3 -0
  77. data/app/views/raker_mailer/notification_feed_added.text.it.plain.erb +5 -0
  78. data/app/views/raker_mailer/notification_feed_added.text.iw.html.erb +3 -0
  79. data/app/views/raker_mailer/notification_feed_added.text.iw.plain.erb +5 -0
  80. data/app/views/raker_mailer/notification_feed_added.text.ja.html.erb +3 -0
  81. data/app/views/raker_mailer/notification_feed_added.text.ja.plain.erb +5 -0
  82. data/app/views/raker_mailer/notification_feed_added.text.ko.html.erb +3 -0
  83. data/app/views/raker_mailer/notification_feed_added.text.ko.plain.erb +5 -0
  84. data/app/views/raker_mailer/notification_feed_added.text.lt.html.erb +3 -0
  85. data/app/views/raker_mailer/notification_feed_added.text.lt.plain.erb +5 -0
  86. data/app/views/raker_mailer/notification_feed_added.text.lv.html.erb +3 -0
  87. data/app/views/raker_mailer/notification_feed_added.text.lv.plain.erb +5 -0
  88. data/app/views/raker_mailer/notification_feed_added.text.mt.html.erb +3 -0
  89. data/app/views/raker_mailer/notification_feed_added.text.mt.plain.erb +5 -0
  90. data/app/views/raker_mailer/notification_feed_added.text.nl.html.erb +3 -0
  91. data/app/views/raker_mailer/notification_feed_added.text.nl.plain.erb +5 -0
  92. data/app/views/raker_mailer/notification_feed_added.text.no.html.erb +3 -0
  93. data/app/views/raker_mailer/notification_feed_added.text.no.plain.erb +5 -0
  94. data/app/views/raker_mailer/notification_feed_added.text.pl.html.erb +3 -0
  95. data/app/views/raker_mailer/notification_feed_added.text.pl.plain.erb +5 -0
  96. data/app/views/raker_mailer/notification_feed_added.text.plain.erb +5 -0
  97. data/app/views/raker_mailer/notification_feed_added.text.pt-PT.html.erb +3 -0
  98. data/app/views/raker_mailer/notification_feed_added.text.pt-PT.plain.erb +5 -0
  99. data/app/views/raker_mailer/notification_feed_added.text.ro.html.erb +3 -0
  100. data/app/views/raker_mailer/notification_feed_added.text.ro.plain.erb +5 -0
  101. data/app/views/raker_mailer/notification_feed_added.text.ru.html.erb +3 -0
  102. data/app/views/raker_mailer/notification_feed_added.text.ru.plain.erb +5 -0
  103. data/app/views/raker_mailer/notification_feed_added.text.sk.html.erb +3 -0
  104. data/app/views/raker_mailer/notification_feed_added.text.sk.plain.erb +5 -0
  105. data/app/views/raker_mailer/notification_feed_added.text.sl.html.erb +3 -0
  106. data/app/views/raker_mailer/notification_feed_added.text.sl.plain.erb +5 -0
  107. data/app/views/raker_mailer/notification_feed_added.text.sq.html.erb +3 -0
  108. data/app/views/raker_mailer/notification_feed_added.text.sq.plain.erb +5 -0
  109. data/app/views/raker_mailer/notification_feed_added.text.sr.html.erb +3 -0
  110. data/app/views/raker_mailer/notification_feed_added.text.sr.plain.erb +5 -0
  111. data/app/views/raker_mailer/notification_feed_added.text.sv.html.erb +3 -0
  112. data/app/views/raker_mailer/notification_feed_added.text.sv.plain.erb +5 -0
  113. data/app/views/raker_mailer/notification_feed_added.text.th.html.erb +3 -0
  114. data/app/views/raker_mailer/notification_feed_added.text.th.plain.erb +5 -0
  115. data/app/views/raker_mailer/notification_feed_added.text.tl.html.erb +3 -0
  116. data/app/views/raker_mailer/notification_feed_added.text.tl.plain.erb +5 -0
  117. data/app/views/raker_mailer/notification_feed_added.text.tr.html.erb +3 -0
  118. data/app/views/raker_mailer/notification_feed_added.text.tr.plain.erb +5 -0
  119. data/app/views/raker_mailer/notification_feed_added.text.uk.html.erb +3 -0
  120. data/app/views/raker_mailer/notification_feed_added.text.uk.plain.erb +5 -0
  121. data/app/views/raker_mailer/notification_feed_added.text.vi.html.erb +3 -0
  122. data/app/views/raker_mailer/notification_feed_added.text.vi.plain.erb +5 -0
  123. data/app/views/raker_mailer/notification_feed_added.text.zh-CN.html.erb +3 -0
  124. data/app/views/raker_mailer/notification_feed_added.text.zh-CN.plain.erb +5 -0
  125. data/app/views/raker_mailer/notification_feed_added.text.zh-TW.html.erb +3 -0
  126. data/app/views/raker_mailer/notification_feed_added.text.zh-TW.plain.erb +5 -0
  127. data/app/views/raker_mailer/notification_feed_added.text.zh.html.erb +3 -0
  128. data/app/views/raker_mailer/notification_feed_added.text.zh.plain.erb +5 -0
  129. data/app/views/recommendations/index.xml.builder +4 -4
  130. data/config/muck_raker_routes.rb +10 -13
  131. data/db/migrate/20090623181458_add_grain_size_to_entries.rb +6 -6
  132. data/db/migrate/20090623193525_add_grain_size_to_tag_clouds.rb +12 -0
  133. data/db/migrate/20090717175825_normalize_entries_subjects.rb +1 -0
  134. data/db/migrate/20090721043213_change_services_title_to_name.rb +9 -0
  135. data/db/migrate/20090721054927_remove_services_not_null_from_feeds.rb +9 -0
  136. data/db/migrate/20090723050510_create_feed_parents.rb +17 -0
  137. data/lib/active_record/acts/muck_feed_parent.rb +22 -0
  138. data/lib/muck_raker/muck_custom_form_builder.rb +22 -0
  139. data/lib/muck_raker/services.rb +6 -0
  140. data/lib/muck_raker/tasks.rb +8 -4
  141. data/lib/muck_raker.rb +7 -2
  142. data/locales/ar.yml +48 -15
  143. data/locales/bg.yml +48 -15
  144. data/locales/ca.yml +48 -15
  145. data/locales/cs.yml +48 -15
  146. data/locales/da.yml +48 -15
  147. data/locales/de.yml +48 -15
  148. data/locales/el.yml +48 -15
  149. data/locales/en.yml +46 -17
  150. data/locales/es.yml +48 -15
  151. data/locales/et.yml +48 -15
  152. data/locales/fa.yml +48 -15
  153. data/locales/fi.yml +49 -16
  154. data/locales/fr.yml +48 -15
  155. data/locales/gl.yml +48 -15
  156. data/locales/hi.yml +48 -15
  157. data/locales/hr.yml +48 -15
  158. data/locales/hu.yml +48 -15
  159. data/locales/id.yml +48 -15
  160. data/locales/it.yml +49 -16
  161. data/locales/iw.yml +48 -15
  162. data/locales/ja.yml +48 -15
  163. data/locales/ko.yml +48 -15
  164. data/locales/lt.yml +48 -15
  165. data/locales/lv.yml +48 -15
  166. data/locales/mt.yml +48 -15
  167. data/locales/nl.yml +48 -15
  168. data/locales/no.yml +48 -15
  169. data/locales/pl.yml +48 -15
  170. data/locales/pt-PT.yml +48 -15
  171. data/locales/ro.yml +48 -15
  172. data/locales/ru.yml +48 -15
  173. data/locales/sk.yml +48 -15
  174. data/locales/sl.yml +48 -15
  175. data/locales/sq.yml +48 -15
  176. data/locales/sr.yml +48 -15
  177. data/locales/sv.yml +48 -15
  178. data/locales/th.yml +48 -15
  179. data/locales/tl.yml +48 -15
  180. data/locales/tr.yml +48 -15
  181. data/locales/uk.yml +48 -15
  182. data/locales/vi.yml +48 -15
  183. data/locales/zh-CN.yml +48 -15
  184. data/locales/zh-TW.yml +48 -15
  185. data/locales/zh.yml +48 -15
  186. data/muck-raker.gemspec +298 -26
  187. data/rails/init.rb +0 -9
  188. data/test/rails_root/app/models/user.rb +31 -1
  189. data/test/rails_root/app/views/default/index.html.erb +15 -0
  190. data/test/rails_root/app/views/layouts/default.html.erb +38 -24
  191. data/test/rails_root/app/views/layouts/popup.html.erb +40 -0
  192. data/test/rails_root/config/database.yml +12 -11
  193. data/test/rails_root/config/environment.rb +4 -1
  194. data/test/rails_root/config/global_config.yml +3 -0
  195. data/test/rails_root/db/migrate/20090402234137_create_languages.rb +18 -0
  196. data/test/rails_root/db/migrate/20090426041056_create_countries.rb +15 -0
  197. data/test/rails_root/db/migrate/20090426041103_create_states.rb +18 -0
  198. data/test/rails_root/{migrate → db/migrate}/20090602191243_create_muck_raker.rb +0 -0
  199. data/test/rails_root/{migrate → db/migrate}/20090619211125_create_tag_clouds.rb +0 -0
  200. data/test/rails_root/db/migrate/20090623181458_add_grain_size_to_entries.rb +16 -0
  201. data/test/rails_root/db/migrate/20090623193525_add_grain_size_to_tag_clouds.rb +12 -0
  202. data/test/rails_root/{migrate → db/migrate}/20090703175825_denormalize_entries_subjects.rb +0 -0
  203. data/test/rails_root/db/migrate/20090716035935_change_tag_cloud_grain_sizes.rb +9 -0
  204. data/test/rails_root/db/migrate/20090717175825_normalize_entries_subjects.rb +18 -0
  205. data/test/rails_root/db/migrate/20090721043213_change_services_title_to_name.rb +9 -0
  206. data/test/rails_root/db/migrate/20090721054927_remove_services_not_null_from_feeds.rb +9 -0
  207. data/test/rails_root/db/migrate/20090723050510_create_feed_parents.rb +17 -0
  208. data/test/rails_root/db/schema.rb +289 -54
  209. data/test/rails_root/public/images/fancybox/fancy_closebox.png +0 -0
  210. data/test/rails_root/public/images/fancybox/fancy_left.png +0 -0
  211. data/test/rails_root/public/images/fancybox/fancy_progress.png +0 -0
  212. data/test/rails_root/public/images/fancybox/fancy_right.png +0 -0
  213. data/test/rails_root/public/images/fancybox/fancy_shadow_e.png +0 -0
  214. data/test/rails_root/public/images/fancybox/fancy_shadow_n.png +0 -0
  215. data/test/rails_root/public/images/fancybox/fancy_shadow_ne.png +0 -0
  216. data/test/rails_root/public/images/fancybox/fancy_shadow_nw.png +0 -0
  217. data/test/rails_root/public/images/fancybox/fancy_shadow_s.png +0 -0
  218. data/test/rails_root/public/images/fancybox/fancy_shadow_se.png +0 -0
  219. data/test/rails_root/public/images/fancybox/fancy_shadow_sw.png +0 -0
  220. data/test/rails_root/public/images/fancybox/fancy_shadow_w.png +0 -0
  221. data/test/rails_root/public/images/fancybox/fancy_title_left.png +0 -0
  222. data/test/rails_root/public/images/fancybox/fancy_title_main.png +0 -0
  223. data/test/rails_root/public/images/fancybox/fancy_title_right.png +0 -0
  224. data/test/rails_root/public/javascripts/jquery/jquery.easing.js +1 -0
  225. data/test/rails_root/public/javascripts/jquery/jquery.fancybox.js +9 -0
  226. data/test/rails_root/public/javascripts/muck.js +7 -3
  227. data/test/rails_root/public/stylesheets/application.css +1 -0
  228. data/test/rails_root/public/stylesheets/jquery/jquery.fancybox.css +44 -0
  229. data/test/rails_root/public/stylesheets/styles.css +6 -2
  230. data/test/rails_root/test/factories.rb +14 -1
  231. data/test/rails_root/test/functional/feed_previews_controller_test.rb +32 -0
  232. data/test/rails_root/test/functional/feeds_controller_test.rb +57 -5
  233. data/test/rails_root/test/shoulda_macros/controller.rb +5 -1
  234. data/test/rails_root/test/test_helper.rb +2 -0
  235. data/test/rails_root/test/unit/entry_test.rb +30 -5
  236. data/test/rails_root/test/unit/feed_parent_test.rb +10 -0
  237. data/test/rails_root/test/unit/feed_test.rb +55 -3
  238. data/test/rails_root/test/unit/raker_mailer_test.rb +26 -0
  239. data/test/rails_root/test/unit/tag_cloud_test.rb +16 -28
  240. data/test/rails_root/test/unit/user_test.rb +11 -0
  241. metadata +211 -18
  242. data/app/controllers/recommender/default_controller.rb +0 -15
  243. data/app/controllers/recommender/feeds_controller.rb +0 -64
  244. data/app/views/default/tour.html.erb +0 -15
  245. data/app/views/default/widgets.html.erb +0 -4
  246. data/test/rails_root/migrate/20090623181458_add_grain_size_to_entries.rb +0 -16
data/README.rdoc CHANGED
@@ -1,13 +1,20 @@
1
- Recommender
2
- ===========
3
- The recommender adds the ability to aggregate, search and analyze data from many different web sources.
1
+ = Muck Raker
2
+ Muck Raker adds functionality that aggregates, searches and analyzes data from many different web sources.
4
3
 
5
- Installation
6
- ===========
7
- Install gem dependencies:
4
+ == Installation
8
5
 
6
+ Be sure to add github as a gem source before proceeding as acts-as-taggable-on, mislav-will_paginate (and many other gems) live there.
7
+ gem sources -a http://gems.github.com
8
+
9
+ Install muck raker:
10
+ sudo gem install muck-raker
11
+
12
+ Installing muck raker should install all of it's dependancies. You can also install them manually:
13
+ sudo gem install httparty
9
14
  sudo gem install mbleigh-acts-as-taggable-on
10
15
  sudo gem install mislav-will_paginate
16
+ sudo gem install muck-feedbag
17
+ sudo gem install pauldix-feedzirra
11
18
 
12
19
  After install acts-as-taggable-on be sure to include the helper in application_helper.rb:
13
20
 
@@ -20,8 +27,14 @@ Add rake tasks to your Rakefile
20
27
 
21
28
  require 'muck_raker/tasks'
22
29
 
23
- Example
24
- =======
30
+ == Example
31
+
32
+
33
+ == Development
34
+
35
+ === Testing
36
+ You will need to have mysql setup to run the migrations for the test database. Muck raker has a few customizations which require mysql.
37
+
25
38
 
26
39
 
27
40
  Copyright (c) 2009 Justin Ball and Joel Duffin, released under the MIT license
data/Rakefile CHANGED
@@ -36,6 +36,8 @@ desc 'Translate this gem'
36
36
  task :translate do
37
37
  file = File.join(File.dirname(__FILE__), 'locales', 'en.yml')
38
38
  system("babelphish -o -y #{file}")
39
+ path = File.join(File.dirname(__FILE__), 'app', 'views', 'raker_mailer')
40
+ system("babelphish -o -h #{path} -l en")
39
41
  end
40
42
 
41
43
  desc 'Generate documentation for the recommender plugin.'
@@ -57,6 +59,10 @@ begin
57
59
  gemspec.description = "The aggregation and recommendation engine for the muck system."
58
60
  gemspec.authors = ["Joel Duffin Justin Ball"]
59
61
  gemspec.rubyforge_project = 'muck-raker'
62
+ gemspec.add_dependency "mbleigh-acts-as-taggable-on"
63
+ gemspec.add_dependency "mislav-will_paginate"
64
+ gemspec.add_dependency "httparty"
65
+ gemspec.add_dependency "jbasdf-feedbag"
60
66
  gemspec.add_dependency "muck-engine"
61
67
  gemspec.add_dependency "muck-users"
62
68
  gemspec.add_dependency "muck-solr"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.15
1
+ 0.1.16
@@ -1,6 +1,6 @@
1
- class Admin::Recommender::FeedsController < ApplicationController
1
+ class Admin::Muck::FeedsController < ApplicationController
2
2
 
3
- layout "default"
3
+ unloadable
4
4
 
5
5
  before_filter :login_required, :only => [:index, :edit, :ban, :unban, :destroy, :update, :new]
6
6
 
@@ -1,5 +1,7 @@
1
- class Recommender::EntriesController < ApplicationController
2
-
1
+ class Muck::EntriesController < ApplicationController
2
+
3
+ unloadable
4
+
3
5
  def initialize
4
6
  @no_index = true
5
7
  end
@@ -35,19 +37,20 @@ class Recommender::EntriesController < ApplicationController
35
37
  end
36
38
 
37
39
  def show
38
- @page_title = "Related Resources"
39
40
  @entry = Entry.find(params[:id], :include => :feed)
40
41
  if @entry.nil?
41
42
  render_text "Unable to find the specified document"
42
43
  return
43
44
  end
44
- @entry_title = @entry.title + " (" + @entry.feed.short_title + ")"
45
+ @entry_title = @entry.title + ' (' + @entry.feed.short_title + ')'
46
+ @page_title = @entry_title + ' - ' + I18n.t('muck.raker.related_resources_title')
45
47
  # I18n.locale = @entry.language[0..1]
46
48
  @limit = params[:limit] ? params[:limit].to_i : 20
47
49
  @limit = 40 if @limit > 40
48
50
 
49
51
  respond_to do |format|
50
- format.html {
52
+ format.html {
53
+ @recommendations = @entry.recommendations(@limit, 'relevance', params[:details] == 'true')
51
54
  if params[:details] == 'true'
52
55
  render :template => "entries/details"
53
56
  else
@@ -0,0 +1,33 @@
1
+ class Muck::FeedPreviewsController < ApplicationController
2
+
3
+ unloadable
4
+
5
+ def new
6
+ respond_to do |format|
7
+ format.pjs do
8
+ render_as_html do
9
+ render :template => 'feed_previews/new', :layout => false
10
+ end
11
+ end
12
+ format.html { render :template => 'feed_previews/new' }
13
+ end
14
+ end
15
+
16
+ def select_feeds
17
+ @feed = Feed.new(params[:feed])
18
+ @feeds = Feed.gather_information(@feed.uri)
19
+ respond_to do |format|
20
+ format.pjs do
21
+ render_as_html do
22
+ render :template => 'feed_previews/select_feeds', :layout => false
23
+ end
24
+ end
25
+ format.html { render :template => 'feed_previews/select_feeds' }
26
+ end
27
+ end
28
+
29
+ def create
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,128 @@
1
+ class Muck::FeedsController < ApplicationController
2
+
3
+ unloadable
4
+
5
+ before_filter :get_parent
6
+
7
+ def index
8
+ @feeds = Feed.valid.by_title.paginate(:page => @page, :per_page => @per_page)
9
+ respond_to do |format|
10
+ format.html { render :template => 'feeds/index' }
11
+ format.xml { render :xml => @feeds.to_xml }
12
+ end
13
+ end
14
+
15
+ # pass layout=popup to remove most of the chrome
16
+ def show
17
+ @feed = Feed.find(params[:id])
18
+ @entries = @feed.entries
19
+ respond_to do |format|
20
+ format.html { render :template => 'feeds/show', :layout => params[:layout] || true }
21
+ format.pjs { debugger; render :template => 'feeds/show', :layout => false }
22
+ format.json { render :json => @feed.as_json }
23
+ end
24
+ end
25
+
26
+ def new
27
+ respond_to do |format|
28
+ format.html { render :template => 'feeds/new', :layout => 'popup' }
29
+ end
30
+ end
31
+
32
+ def new_extended
33
+ respond_to do |format|
34
+ format.html { render :template => 'feeds/new_extended', :layout => 'popup' }
35
+ end
36
+ end
37
+
38
+ def create
39
+ @feed = Feed.new(params[:feed])
40
+ @feed.contributor = current_user # record the user that submitted the feed for auditing purposes
41
+ @feed.harvested_from_display_uri = @feed.display_uri
42
+
43
+ # setup the feed to be harvested
44
+ @feed.entries_count = 0
45
+ @feed.last_requested_at = 4.weeks.ago
46
+ @feed.last_harvested_at = 4.weeks.ago
47
+
48
+ # associate the parent if present
49
+ @parent.feeds << @feed if @parent
50
+
51
+ after_create_response(@feed.save)
52
+ end
53
+
54
+
55
+ def update
56
+ @feed = Feed.find(params[:id])
57
+ after_update_response(@feed.update_attributes(params[:feed]))
58
+ end
59
+
60
+ def destroy
61
+ @feed = Feed.find(params[:id])
62
+ @feed.destroy
63
+ after_destroy_response
64
+ end
65
+
66
+ protected
67
+
68
+ def get_parent
69
+ if !params[:parent_type] || !params[:parent_id]
70
+ return
71
+ end
72
+ @klass = params[:parent_type].to_s.constantize
73
+ @parent = @klass.find(params[:parent_id])
74
+ unless has_permission_to_add_feed(current_user, @parent)
75
+ permission_denied
76
+ end
77
+ end
78
+
79
+ def has_permission_to_add_feed(user, parent)
80
+ user == parent || parent.can_add_feed?(user)
81
+ end
82
+
83
+ # Handles render and redirect after success or failure of the
84
+ # create action. Override to perform a different action
85
+ def after_create_response(success)
86
+ if success
87
+ flash[:notice] = t('muck.raker.feed_successfully_created')
88
+ respond_to do |format|
89
+ format.html { redirect_to feed_path(@feed) }
90
+ format.pjs { render :template => 'feeds/show', :layout => false }
91
+ format.json { render :json => @feed.as_json }
92
+ format.xml { head :created, :location => feed_url(@feed) }
93
+ end
94
+ else
95
+ respond_to do |format|
96
+ format.html { render :template => "feeds/new" }
97
+ format.pjs { render :template => "feeds/new", :layout => false }
98
+ format.json { render :json => @feed.as_json }
99
+ format.xml { render :xml => @feed.errors.to_xml }
100
+ end
101
+ end
102
+ end
103
+
104
+ # Handles render and redirect after success or failure of the
105
+ # update action. Override to perform a different action
106
+ def after_update_response(success)
107
+ respond_to do |format|
108
+ if success
109
+ flash[:notice] = t('muck.raker.feed_successfully_updated')
110
+ format.html { redirect_to feed_path(@feed) }
111
+ format.xml { head :ok }
112
+ else
113
+ format.html { render :template => "feeds/edit" }
114
+ format.xml { render :xml => @feed.errors.to_xml }
115
+ end
116
+ end
117
+ end
118
+
119
+ # Handles render and redirect after the delete action.
120
+ # Override to perform a different action
121
+ def after_destroy_response
122
+ respond_to do |format|
123
+ format.html { redirect_to feeds_path }
124
+ format.xml { head :ok }
125
+ end
126
+ end
127
+
128
+ end
@@ -1,5 +1,7 @@
1
- class Recommender::RecommendationsController < ApplicationController
1
+ class Muck::RecommendationsController < ApplicationController
2
2
 
3
+ unloadable
4
+
3
5
  # GET /recommendations
4
6
  # GET /recommendations.xml
5
7
  def index
@@ -27,6 +29,7 @@ class Recommender::RecommendationsController < ApplicationController
27
29
  order = params[:order] || "mixed"
28
30
  redirect_to "/documents/" + @document.id.to_s + "?limit=" + @limit.to_s + "&order=" + order + "&details=" + @details.to_s if !@document.nil?
29
31
  render(:template => '/recommendations/document_not_found.html.erb', :layout => false) if @document.nil?
32
+ @recommendations = @entry.recommendations(@limit, params[:order] || "relevance")
30
33
  }
31
34
  format.xml {
32
35
  render(:template => '/recommendations/index.xml.builder', :layout => false)
@@ -1,5 +1,7 @@
1
- class Recommender::SearchController < ApplicationController
1
+ class Muck::SearchController < ApplicationController
2
2
 
3
+ unloadable
4
+
3
5
  def initialize
4
6
  @limit = 50
5
7
  @no_index = true
@@ -1,3 +1,27 @@
1
1
  module MuckRakerFeedsHelper
2
2
 
3
+ def add_feed(parent = nil)
4
+ render :partial => 'parts/add_feed', :locals => {:parent => parent}
5
+ end
6
+
7
+ def add_single_feed(parent = nil)
8
+ render :partial => 'parts/add_single_feed', :locals => {:parent => parent}
9
+ end
10
+
11
+ def add_extended_feed(parent = nil)
12
+ render :partial => 'parts/add_extended_feed', :locals => {:parent => parent}
13
+ end
14
+
15
+ def new_feed_path_with_parent(parent)
16
+ if parent
17
+ feeds_path(make_parent_params(parent))
18
+ else
19
+ feeds_path
20
+ end
21
+ end
22
+
23
+ def make_parent_params(parent)
24
+ { :parent_id => parent.id, :parent_type => parent.class.to_s }
25
+ end
26
+
3
27
  end
@@ -1,2 +1,14 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: attentions
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # attentionable_id :integer(4)
7
+ # attentionable_type :string(255)
8
+ # entry_id :integer(4)
9
+ # action_type :string(255)
10
+ # weight :float
11
+ #
12
+
1
13
  class Attention < ActiveRecord::Base
2
- end
14
+ end
data/app/models/click.rb CHANGED
@@ -1,2 +1,14 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: clicks
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # recommendation_id :integer(4)
7
+ # when :datetime not null
8
+ # referrer :string(2083)
9
+ # requester :string(255)
10
+ # user_agent :string(2083)
11
+ #
12
+
1
13
  class Click < ActiveRecord::Base
2
14
  end
data/app/models/entry.rb CHANGED
@@ -1,11 +1,39 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: entries
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # feed_id :integer(4) not null
7
+ # permalink :string(2083) default(""), not null
8
+ # author :string(2083)
9
+ # title :text default(""), not null
10
+ # description :text
11
+ # content :text
12
+ # unique_content :boolean(1)
13
+ # published_at :datetime not null
14
+ # entry_updated_at :datetime
15
+ # harvested_at :datetime
16
+ # oai_identifier :string(2083)
17
+ # language_id :integer(4)
18
+ # direct_link :string(2083)
19
+ # indexed_at :datetime default(Fri Jan 01 01:01:01 UTC 1971), not null
20
+ # relevance_calculated_at :datetime default(Fri Jan 01 01:01:01 UTC 1971), not null
21
+ # popular :text
22
+ # relevant :text
23
+ # other :text
24
+ # grain_size :string(255) default("unknown")
25
+ #
26
+
1
27
  class Entry < ActiveRecord::Base
28
+
2
29
  belongs_to :feed
30
+ belongs_to :language
3
31
 
4
32
  acts_as_taggable
5
33
 
6
34
  @@default_time_on_page = 60.0
7
35
 
8
- acts_as_solr({:if => false, :fields => [{:feed_id => :integer}, {:grain_size => :string}]}, {:type_field => :type_s})
36
+ # acts_as_solr({:if => false, :fields => [{:feed_id => :integer}, {:grain_size => :string}]}, {:type_field => :type_s})
9
37
 
10
38
  def self.top_tags(tags = nil)
11
39
 
@@ -27,8 +55,21 @@ class Entry < ActiveRecord::Base
27
55
  end
28
56
 
29
57
  def recommendations(limit = 20, order = "relevance", details = false, omit_feeds = nil)
30
- sql = "SELECT recommendations.id, dest_entry_id, permalink, entries.title, relevance_calculated_at, relevance, clicks, avg_time_at_dest AS avg_time_on_target, direct_link, feeds.short_title AS collection "
31
- sql << ", entries.description, author, published_at " if details == true
58
+ sql = "SELECT recommendations.id, dest_entry_id, entries.permalink, entries.title, entries.description, entries.direct_link, feeds.short_title AS collection "
59
+ sql << ", relevance_calculated_at, relevance, clicks, avg_time_at_dest AS avg_time_on_target, author, published_at " if details == true
60
+ sql << "FROM recommendations "
61
+ sql << "INNER JOIN entries ON recommendations.dest_entry_id = entries.id "
62
+ sql << "INNER JOIN feeds ON entries.feed_id = feeds.id "
63
+ sql << "WHERE recommendations.entry_id = ? "
64
+ sql << ("AND entries.feed_id NOT IN (" + omit_feeds.gsub(/[^0-9,]/,'') + ") ") if omit_feeds != nil
65
+ sql << "ORDER BY " + order + " DESC "
66
+ sql << "LIMIT " + limit.to_s
67
+ Entry.find_by_sql([sql,self.id])
68
+ end
69
+
70
+ def recommendation_entries(limit = 20, order = "relevance", details = false, omit_feeds = nil)
71
+ sql = "SELECT recommendations.dest_entry_id AS id, entries.permalink, entries.title, entries.description, entries.direct_link, feeds.short_title AS collection "
72
+ sql << ", relevance_calculated_at, relevance, clicks, avg_time_at_dest AS avg_time_on_target, author, published_at " if details == true
32
73
  sql << "FROM recommendations "
33
74
  sql << "INNER JOIN entries ON recommendations.dest_entry_id = entries.id "
34
75
  sql << "INNER JOIN feeds ON entries.feed_id = feeds.id "
@@ -46,22 +87,14 @@ class Entry < ActiveRecord::Base
46
87
 
47
88
  # if they spend longer than two minutes on a page, we don't infer anything
48
89
  if time_on_page > 5 and time_on_page < 120
49
- # puts "==============================old: " + session[:last_clicked_recommendation_uri]
50
- # puts "==============================new: " + normalized_uri(uri)
51
90
  if normalized_uri(uri) != session[:last_clicked_recommendation_uri]
52
91
  recommendation = Recommendation.find(recommendation_id)
53
92
  entry = Entry.find(recommendation.entry_id)
54
- # puts "clicks ================= " + recommendation.clicks.to_s
55
- # puts "old avg ================= " + recommendation.avg_time_at_dest.to_s
56
93
  new_avg = (recommendation.avg_time_at_dest*recommendation.clicks - @@default_time_on_page + time_on_page)/recommendation.clicks
57
94
  recommendation.avg_time_at_dest = new_avg
58
- # puts "time on page ================= " + time_on_page.to_s
59
- # puts "new average ==================== " + new_avg.to_s
60
95
  recommendation.save!
61
96
  entry.rank_recommendations
62
97
  session[:last_clicked_recommendation] = nil
63
- # else
64
- # puts "same!!!!!!!!!!!!!!!!!!!!!!!"
65
98
  end
66
99
  else
67
100
  session[:last_clicked_recommendation] = nil if time_on_page > 5
@@ -196,6 +229,7 @@ class Entry < ActiveRecord::Base
196
229
  end
197
230
 
198
231
  def rank_recommendations
232
+ return
199
233
  # get recommendations for the entry from the recommendations table
200
234
  recs = self.recommendations
201
235
 
data/app/models/feed.rb CHANGED
@@ -1,20 +1,70 @@
1
- # require 'httparty'
2
-
1
+ # == Schema Information
2
+ #
3
+ # Table name: feeds
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # uri :string(2083)
7
+ # display_uri :string(2083)
8
+ # title :string(1000)
9
+ # short_title :string(100)
10
+ # description :text
11
+ # tag_filter :string(1000)
12
+ # top_tags :text
13
+ # priority :integer(4) default(10)
14
+ # status :integer(4) default(1)
15
+ # last_requested_at :datetime
16
+ # last_harvested_at :datetime
17
+ # harvest_interval :integer(4) default(86400)
18
+ # failed_requests :integer(4) default(0)
19
+ # error_message :text
20
+ # service_id :integer(4) default(0)
21
+ # login :string(255)
22
+ # password :string(255)
23
+ # created_at :datetime
24
+ # updated_at :datetime
25
+ # entries_changed_at :datetime
26
+ # harvested_from_display_uri :string(2083)
27
+ # harvested_from_title :string(1000)
28
+ # harvested_from_short_title :string(100)
29
+ # entries_count :integer(4)
30
+ # default_language_id :integer(4) default(0)
31
+ # default_grain_size :string(255) default("unknown")
32
+ # contributor_id :integer(4)
33
+ #
3
34
  class Feed < ActiveRecord::Base
4
35
 
5
- # include HTTParty
6
- # format :xml
36
+ require 'httparty'
37
+
38
+ include HTTParty
39
+ format :xml
7
40
 
41
+ validates_presence_of :uri
42
+
43
+ has_many :feed_parents
8
44
  has_many :entries
9
45
  belongs_to :contributor, :class_name => 'User', :foreign_key => 'contributor_id'
46
+ belongs_to :default_language, :class_name => 'Language', :foreign_key => 'default_language_id'
47
+
48
+ named_scope :banned, :conditions => "status < 0"
49
+ named_scope :valid, :conditions => "status >= 0"
50
+ named_scope :by_title, :order => "title ASC"
51
+ named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } }
52
+ named_scope :by_newest, :order => "created_at DESC"
10
53
 
11
54
  # named_scope :ready_to_harvest, lambda { |*args| { :conditions => [ "feeds.last_harvested_at < ?", args.first || 1.day.ago.end_of_day ] } }
12
-
55
+
56
+ def after_create
57
+ if GlobalConfig.inform_admin_of_global_feed && self.feed_parents.empty?
58
+ RakerMailer.deliver_notification_feed_added(self) # Global feed. Email the admin to let them know a feed has been added
59
+ end
60
+ end
61
+
62
+ # harvest_interval is stored in seconds
13
63
  def refresh_interval_hours
14
64
  if self.harvest_interval
15
- self.harvest_interval.split(':')[0]
65
+ self.harvest_interval/3600
16
66
  else
17
- "168"
67
+ 168 # TODO what's this?
18
68
  end
19
69
  end
20
70
 
@@ -26,5 +76,29 @@ class Feed < ActiveRecord::Base
26
76
  # feed = Feed.first # .ready_to_harvest.first
27
77
  # get(feed.uri)
28
78
  # end
79
+
80
+ # Gathers all available feed uris from the given uri and parses them into
81
+ # feed objects
82
+ def self.gather_information(uri)
83
+ feeds = []
84
+ @available_feeds = discover_feeds(uri)
85
+ @available_feeds.each do |feed|
86
+ feeds << make_feed(Feedzirra::Feed.fetch_and_parse(feed.url))
87
+ end
88
+ feeds
89
+ end
90
+
91
+ # Turns a feed from feedzirra into a muck feed
92
+ def self.make_feed(feed)
93
+ Feed.new(:short_title => feed.title,
94
+ :title => feed.title,
95
+ :display_uri => feed.url,
96
+ :uri => feed.feed_url)
97
+ end
98
+
99
+ # Looks for feeds from a given url
100
+ def self.discover_feeds(uri)
101
+ Feedbag.find(uri)
102
+ end
29
103
 
30
104
  end
@@ -0,0 +1,18 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: feed_parents
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # feed_id :integer(4)
7
+ # ownable_id :integer(4)
8
+ # ownable_type :string(255)
9
+ # created_at :datetime
10
+ # updated_at :datetime
11
+ #
12
+
13
+ class FeedParent < ActiveRecord::Base
14
+ unloadable
15
+
16
+ belongs_to :feed
17
+ belongs_to :ownable, :polymorphic => true
18
+ end
@@ -1,2 +1,16 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: languages
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # name :string(255)
7
+ # english_name :string(255)
8
+ # locale :string(255)
9
+ # supported :boolean(1) default(TRUE)
10
+ # is_default :integer(4) default(0)
11
+ # muck_raker_supported :boolean(1)
12
+ # indexed_records :integer(4) default(0)
13
+ #
14
+
1
15
  class Language < ActiveRecord::Base
2
16
  end
@@ -1,2 +1,14 @@
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
+ #
12
+
1
13
  class OaiEndpoint < ActiveRecord::Base
2
14
  end
@@ -0,0 +1,16 @@
1
+ class RakerMailer < ActionMailer::Base
2
+ unloadable
3
+
4
+ layout 'email_default'
5
+ default_url_options[:host] = GlobalConfig.application_url
6
+
7
+ def notification_feed_added(feed)
8
+ recipients GlobalConfig.admin_email
9
+ from "#{GlobalConfig.from_email_name} <#{GlobalConfig.from_email}>"
10
+ sent_on Time.now
11
+ subject I18n.t('muck.raker.new_global_feed', :application_name => GlobalConfig.application_name)
12
+ body :feed => feed,
13
+ :application_name => GlobalConfig.application_name
14
+ end
15
+
16
+ end
@@ -1,2 +1,15 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: recommendations
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # entry_id :integer(4)
7
+ # dest_entry_id :integer(4)
8
+ # rank :integer(4)
9
+ # relevance :decimal(8, 6) default(0.0)
10
+ # clicks :integer(4) default(0)
11
+ # avg_time_at_dest :integer(4) default(60)
12
+ #
13
+
1
14
  class Recommendation < ActiveRecord::Base
2
15
  end
@@ -1,2 +1,16 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: services
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # uri :string(2083) default("")
7
+ # name :string(1000) default("")
8
+ # api_uri :string(2083) default("")
9
+ # uri_template :string(2083) default("")
10
+ # icon :string(2083) default("rss.gif")
11
+ # sequence :integer(4)
12
+ # requires_password :boolean(1)
13
+ #
14
+
1
15
  class Service < ActiveRecord::Base
2
16
  end
@@ -1,2 +1,10 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: subjects
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # name :string(255)
7
+ #
8
+
1
9
  class Subject < ActiveRecord::Base
2
10
  end