muck-raker 0.1.31 → 0.1.32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. data/README.rdoc +2 -1
  2. data/VERSION +1 -1
  3. data/app/controllers/muck/aggregations_controller.rb +330 -0
  4. data/app/controllers/muck/identity_feeds_controller.rb +1 -0
  5. data/app/helpers/muck_raker_aggregations_helper.rb +11 -0
  6. data/app/helpers/muck_raker_services_helper.rb +3 -3
  7. data/app/models/aggregation.rb +21 -1
  8. data/app/models/aggregation_feed.rb +13 -0
  9. data/app/models/feed.rb +21 -7
  10. data/app/models/service.rb +3 -1
  11. data/app/models/service_category.rb +1 -0
  12. data/app/views/aggregations/_data_source.html.erb +4 -0
  13. data/app/views/aggregations/_data_sources.html.erb +10 -0
  14. data/app/views/aggregations/new.html.erb +12 -0
  15. data/app/views/identity_feeds/{_service_categories.html.erb → _available_service_categories.html.erb} +0 -0
  16. data/app/views/identity_feeds/index.html.erb +1 -1
  17. data/config/muck_raker_routes.rb +1 -0
  18. data/db/bootstrap/services.yml +24 -2
  19. data/db/migrate/20090915041650_aggregations_to_polymorphic.rb +15 -0
  20. data/lib/active_record/acts/muck_aggregation_owner.rb +30 -0
  21. data/lib/muck_raker.rb +2 -0
  22. data/locales/en.yml +5 -0
  23. data/muck-raker.gemspec +91 -3
  24. data/test/rails_root/app/models/user.rb +1 -0
  25. data/test/rails_root/config/environment.rb +1 -1
  26. data/test/rails_root/config/routes.rb +1 -0
  27. data/test/rails_root/config/solr/cores/de/conf/solrconfig.xml +9 -2
  28. data/test/rails_root/config/solr/cores/en/conf/solrconfig.xml +9 -2
  29. data/test/rails_root/config/solr/cores/es/conf/solrconfig.xml +9 -2
  30. data/test/rails_root/config/solr/cores/fr/conf/solrconfig.xml +9 -2
  31. data/test/rails_root/config/solr/cores/ja/conf/solrconfig.xml +9 -2
  32. data/test/rails_root/config/solr/cores/nl/conf/solrconfig.xml +11 -4
  33. data/test/rails_root/config/solr/cores/ru/conf/solrconfig.xml +9 -2
  34. data/test/rails_root/config/solr/cores/zh/conf/solrconfig.xml +9 -2
  35. data/test/rails_root/db/bootstrap/services.yml +13 -2
  36. data/test/rails_root/db/migrate/20090915041650_aggregations_to_polymorphic.rb +15 -0
  37. data/test/rails_root/public/images/service_icons/16/citeulike.png +0 -0
  38. data/test/rails_root/public/images/service_icons/16/dailymotion.png +0 -0
  39. data/test/rails_root/public/images/service_icons/16/diigo.png +0 -0
  40. data/test/rails_root/public/images/service_icons/16/fotolog.png +0 -0
  41. data/test/rails_root/public/images/service_icons/16/goodreads.png +0 -0
  42. data/test/rails_root/public/images/service_icons/16/googleblog.png +0 -0
  43. data/test/rails_root/public/images/service_icons/16/googlenews.png +0 -0
  44. data/test/rails_root/public/images/service_icons/16/identica.png +0 -0
  45. data/test/rails_root/public/images/service_icons/16/joost.png +0 -0
  46. data/test/rails_root/public/images/service_icons/16/librarything.png +0 -0
  47. data/test/rails_root/public/images/service_icons/16/mendeley.png +0 -0
  48. data/test/rails_root/public/images/service_icons/16/oai.png +0 -0
  49. data/test/rails_root/public/images/service_icons/16/odeo.png +0 -0
  50. data/test/rails_root/public/images/service_icons/16/opml.png +0 -0
  51. data/test/rails_root/public/images/service_icons/16/pandora.png +0 -0
  52. data/test/rails_root/public/images/service_icons/16/photobucket.png +0 -0
  53. data/test/rails_root/public/images/service_icons/16/polyvore.png +0 -0
  54. data/test/rails_root/public/images/service_icons/16/simpy.png +0 -0
  55. data/test/rails_root/public/images/service_icons/16/smugmug.png +0 -0
  56. data/test/rails_root/public/images/service_icons/16/tag.png +0 -0
  57. data/test/rails_root/public/images/service_icons/16/tumblr.png +0 -0
  58. data/test/rails_root/public/images/service_icons/16/xanga.png +0 -0
  59. data/test/rails_root/public/images/service_icons/16/zooomr.png +0 -0
  60. data/test/rails_root/public/images/service_icons/16/zotero.png +0 -0
  61. data/test/rails_root/public/images/service_icons/24/amazon.png +0 -0
  62. data/test/rails_root/public/images/service_icons/24/citeulike.png +0 -0
  63. data/test/rails_root/public/images/service_icons/24/dailymotion.png +0 -0
  64. data/test/rails_root/public/images/service_icons/24/diigo.png +0 -0
  65. data/test/rails_root/public/images/service_icons/24/fotolog.png +0 -0
  66. data/test/rails_root/public/images/service_icons/24/goodreads.png +0 -0
  67. data/test/rails_root/public/images/service_icons/24/googleblog.png +0 -0
  68. data/test/rails_root/public/images/service_icons/24/googlenews.png +0 -0
  69. data/test/rails_root/public/images/service_icons/24/identica.png +0 -0
  70. data/test/rails_root/public/images/service_icons/24/joost.png +0 -0
  71. data/test/rails_root/public/images/service_icons/24/librarything.png +0 -0
  72. data/test/rails_root/public/images/service_icons/24/mendeley.png +0 -0
  73. data/test/rails_root/public/images/service_icons/24/oai.png +0 -0
  74. data/test/rails_root/public/images/service_icons/24/odeo.png +0 -0
  75. data/test/rails_root/public/images/service_icons/24/opml.png +0 -0
  76. data/test/rails_root/public/images/service_icons/24/pandora.png +0 -0
  77. data/test/rails_root/public/images/service_icons/24/photobucket.png +0 -0
  78. data/test/rails_root/public/images/service_icons/24/polyvore.png +0 -0
  79. data/test/rails_root/public/images/service_icons/24/simpy.png +0 -0
  80. data/test/rails_root/public/images/service_icons/24/smugmug.png +0 -0
  81. data/test/rails_root/public/images/service_icons/24/tag.png +0 -0
  82. data/test/rails_root/public/images/service_icons/24/tumblr.png +0 -0
  83. data/test/rails_root/public/images/service_icons/24/xanga.png +0 -0
  84. data/test/rails_root/public/images/service_icons/24/zooomr.png +0 -0
  85. data/test/rails_root/public/images/service_icons/24/zotero.png +0 -0
  86. data/test/rails_root/public/images/service_icons/48/amazon.png +0 -0
  87. data/test/rails_root/public/images/service_icons/48/citeulike.png +0 -0
  88. data/test/rails_root/public/images/service_icons/48/dailymotion.png +0 -0
  89. data/test/rails_root/public/images/service_icons/48/diigo.png +0 -0
  90. data/test/rails_root/public/images/service_icons/48/fotolog.png +0 -0
  91. data/test/rails_root/public/images/service_icons/48/goodreads.png +0 -0
  92. data/test/rails_root/public/images/service_icons/48/googleblog.png +0 -0
  93. data/test/rails_root/public/images/service_icons/48/googlenews.png +0 -0
  94. data/test/rails_root/public/images/service_icons/48/identica.png +0 -0
  95. data/test/rails_root/public/images/service_icons/48/joost.png +0 -0
  96. data/test/rails_root/public/images/service_icons/48/librarything.png +0 -0
  97. data/test/rails_root/public/images/service_icons/48/mendeley.png +0 -0
  98. data/test/rails_root/public/images/service_icons/48/oai.png +0 -0
  99. data/test/rails_root/public/images/service_icons/48/odeo.png +0 -0
  100. data/test/rails_root/public/images/service_icons/48/opml.png +0 -0
  101. data/test/rails_root/public/images/service_icons/48/pandora.png +0 -0
  102. data/test/rails_root/public/images/service_icons/48/photobucket.png +0 -0
  103. data/test/rails_root/public/images/service_icons/48/polyvore.png +0 -0
  104. data/test/rails_root/public/images/service_icons/48/simpy.png +0 -0
  105. data/test/rails_root/public/images/service_icons/48/smugmug.png +0 -0
  106. data/test/rails_root/public/images/service_icons/48/tag.png +0 -0
  107. data/test/rails_root/public/images/service_icons/48/tumblr.png +0 -0
  108. data/test/rails_root/public/images/service_icons/48/xanga.png +0 -0
  109. data/test/rails_root/public/images/service_icons/48/zooomr.png +0 -0
  110. data/test/rails_root/public/images/service_icons/48/zotero.png +0 -0
  111. data/test/rails_root/public/images/service_icons/60/amazon.png +0 -0
  112. data/test/rails_root/public/images/service_icons/60/citeulike.png +0 -0
  113. data/test/rails_root/public/images/service_icons/60/dailymotion.png +0 -0
  114. data/test/rails_root/public/images/service_icons/60/diigo.png +0 -0
  115. data/test/rails_root/public/images/service_icons/60/fotolog.png +0 -0
  116. data/test/rails_root/public/images/service_icons/60/goodreads.png +0 -0
  117. data/test/rails_root/public/images/service_icons/60/googleblog.png +0 -0
  118. data/test/rails_root/public/images/service_icons/60/googlenews.png +0 -0
  119. data/test/rails_root/public/images/service_icons/60/identica.png +0 -0
  120. data/test/rails_root/public/images/service_icons/60/joost.png +0 -0
  121. data/test/rails_root/public/images/service_icons/60/librarything.png +0 -0
  122. data/test/rails_root/public/images/service_icons/60/mendeley.png +0 -0
  123. data/test/rails_root/public/images/service_icons/60/oai.png +0 -0
  124. data/test/rails_root/public/images/service_icons/60/odeo.png +0 -0
  125. data/test/rails_root/public/images/service_icons/60/opml.png +0 -0
  126. data/test/rails_root/public/images/service_icons/60/pandora.png +0 -0
  127. data/test/rails_root/public/images/service_icons/60/photobucket.png +0 -0
  128. data/test/rails_root/public/images/service_icons/60/polyvore.png +0 -0
  129. data/test/rails_root/public/images/service_icons/60/simpy.png +0 -0
  130. data/test/rails_root/public/images/service_icons/60/smugmug.png +0 -0
  131. data/test/rails_root/public/images/service_icons/60/tag.png +0 -0
  132. data/test/rails_root/public/images/service_icons/60/tumblr.png +0 -0
  133. data/test/rails_root/public/images/service_icons/60/xanga.png +0 -0
  134. data/test/rails_root/public/images/service_icons/60/zooomr.png +0 -0
  135. data/test/rails_root/public/images/service_icons/60/zotero.png +0 -0
  136. data/test/rails_root/public/images/service_icons/amazon.png +0 -0
  137. data/test/rails_root/public/stylesheets/application.css +4 -0
  138. data/test/rails_root/test/factories.rb +7 -0
  139. data/test/rails_root/test/functional/identity_feeds_controller_test.rb +11 -4
  140. data/test/rails_root/test/test_helper.rb +8 -0
  141. data/test/rails_root/test/unit/aggregation_feed_test.rb +17 -0
  142. data/test/rails_root/test/unit/aggregation_test.rb +24 -0
  143. data/test/rails_root/test/unit/amazon_request_test.rb +14 -0
  144. data/test/rails_root/test/unit/feed_test.rb +51 -0
  145. data/test/rails_root/test/unit/identity_feed_test.rb +10 -0
  146. data/test/rails_root/test/unit/service_test.rb +3 -10
  147. data/test/rails_root/test/unit/user_test.rb +4 -1
  148. metadata +91 -3
data/README.rdoc CHANGED
@@ -34,8 +34,9 @@ a user with has_muck_feeds and acts_as_muck_feed_owner the following routes woul
34
34
  # have to map into the muck/identity_feeds controller or rails can't find the identity_feeds
35
35
  users.resources :identity_feeds, :controller => 'muck/identity_feeds'
36
36
  users.resources :feeds, :controller => 'muck/feeds'
37
+ users.resources :aggregations, :controller => 'muck/aggregations'
37
38
  end
38
-
39
+
39
40
  == Usage
40
41
  Muck raker aggregates data feeds and analyzes the results to make recommendations.
41
42
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.31
1
+ 0.1.32
@@ -0,0 +1,330 @@
1
+ class Muck::AggregationsController < ApplicationController
2
+
3
+ require 'cgi'
4
+
5
+ before_filter :get_owner, :only => [:index, :new, :create]
6
+ before_filter :has_permission?, :only => [:index, :new, :create]
7
+
8
+ before_filter :get_aggregation, :only => [:destroy, :update]
9
+ before_filter :has_aggregation_permission?, :only => [:destroy, :update]
10
+
11
+ # def index
12
+ # @page_title = 'My Aggregations'
13
+ # respond_to do |format|
14
+ # format.html { @aggregations = Aggregation.find_all_by_user_id(current_user.id, :order => 'title ASC')
15
+ # render(:layout => 'reader') }
16
+ # format.opml { @aggregations = Aggregation.find_all_by_user_id(current_user.id, :include =>:feeds, :order => 'feeds.title ASC')
17
+ # render(:layout => false) }
18
+ # format.xml { @aggregations = Aggregation.find_all_by_user_id(current_user.id, :order => 'title ASC')
19
+ # render :xml => @aggregations }
20
+ # end
21
+ # end
22
+ #
23
+ # def manage
24
+ # @page_title = 'Manage'
25
+ # @user = current_user
26
+ # @aggregations = Aggregation.find_all_by_user_id(@user.id, :order => 'title ASC')
27
+ # respond_to do |format|
28
+ # format.html
29
+ # format.xml { render :xml => @aggregations }
30
+ # end
31
+ # end
32
+ #
33
+ # def show
34
+ # @aggregation = Aggregation.find(params[:id])
35
+ # user_id = -1
36
+ # user_id = current_user.id unless current_user.nil?
37
+ #
38
+ # @rss_title = @aggregation.title
39
+ # @rss_description = @aggregation.description
40
+ #
41
+ # @entries = Entry.get_entries_for_aggregation(@aggregation.id, user_id, :limit => @per_page, :offset => (@per_page * @page))
42
+ # @page_title = @aggregation.title
43
+ # respond_to do |format|
44
+ # format.html { render(:layout => false) }
45
+ # format.opml { render(:layout => false) }
46
+ # format.xml { render :xml => @entries }
47
+ # format.rss { render(:template => 'aggregations/show', :layout => false) }
48
+ # end
49
+ # end
50
+ #
51
+ # def show_marked
52
+ #
53
+ # @user = User.find(params[:user_id])
54
+ # @aggregation = Aggregation.find(params[:id])
55
+ #
56
+ # @rss_title = @aggregation.title
57
+ # @rss_description = 'View entries from all entries marked by ' + @user.login + ' in the aggregation ' + @aggregation.title
58
+ # @entries = Entry.get_marked_entries_for_aggregation_and_user(@aggregation.id, @user.id, :limit => @per_page, :offset => (@per_page * @page))
59
+ # @page_title = 'Entries marked for ' + @aggregation.title
60
+ # respond_to do |format|
61
+ # format.html { render(:template => 'aggregations/show', :layout => false) }
62
+ # format.xml { render :xml => @entries }
63
+ # format.rss { render(:template => 'aggregations/show', :layout => false) }
64
+ # end
65
+ # end
66
+ #
67
+ # def all
68
+ # @page_title = 'View entries from all aggregations'
69
+ #
70
+ # @aggregation = Aggregation.new
71
+ # @aggregation.title = @page_title
72
+ #
73
+ # @rss_title = @aggregation.title
74
+ # @rss_description = 'View entries from all aggregations'
75
+ #
76
+ # @entries = Entry.get_entries_for_user(params[:user_id], :limit => @per_page, :offset => (@per_page * @page))
77
+ # respond_to do |format|
78
+ # format.html { render(:template => 'aggregations/show', :layout => false) }
79
+ # format.xml { render :xml => @entries }
80
+ # format.rss { render(:template => 'aggregations/show', :layout => false) }
81
+ # end
82
+ # end
83
+ #
84
+ # def all_photos
85
+ # @page_title = 'View photos from all aggregations'
86
+ # @aggregation = Aggregation.new
87
+ # @aggregation.title = @page_title
88
+ # @photos = EntryImage.get_photos_for_user(params[:user_id], :limit => @per_page, :offset => (@per_page * @page))
89
+ # respond_to do |format|
90
+ # format.html { render(:template => 'aggregations/photos', :layout => false) }
91
+ # format.xml { render :xml => @photos }
92
+ # end
93
+ # end
94
+ #
95
+ # def photos
96
+ # @aggregation = Aggregation.find(params[:id])
97
+ # @page_title = "View photos from #{@aggregation.title}"
98
+ # @photos = EntryImage.get_entry_images_for_aggregation(@aggregation.id, :limit => @per_page, :offset => (@per_page * @page))
99
+ # respond_to do |format|
100
+ # format.html { render(:template => 'aggregations/photos', :layout => false) }
101
+ # format.xml { render :xml => @photos }
102
+ # end
103
+ # end
104
+ #
105
+ # def bookmarks
106
+ # @aggregation = Aggregation.find(params[:id])
107
+ # @page_title = "View bookmarks from #{@aggregation.title}"
108
+ # @entries = Entry.get_bookmarks_for_aggregation(@aggregation.id, -1, :limit => @per_page, :offset => (@per_page * @page))
109
+ # respond_to do |format|
110
+ # format.html { render(:template => 'aggregations/bookmarks', :layout => false) }
111
+ # format.xml { render :xml => @entries }
112
+ # end
113
+ # end
114
+ #
115
+ # def read_photos
116
+ # @page_title = 'View photos from read entries'
117
+ # @aggregation = Aggregation.new
118
+ # @aggregation.title = @page_title
119
+ # @photos = EntryImage.get_read_photos_for_user(params[:user_id], :limit => @per_page, :offset => (@per_page * @page)) | []
120
+ # respond_to do |format|
121
+ # format.html { render(:template => 'aggregations/photos', :layout => false) }
122
+ # format.xml { render :xml => @photos }
123
+ # end
124
+ # end
125
+ #
126
+ # def marked_photos
127
+ # @page_title = 'View photos from marked entries'
128
+ # @aggregation = Aggregation.new
129
+ # @aggregation.title = @page_title
130
+ # @photos = EntryImage.get_marked_photos_for_user(params[:user_id], :limit => @per_page, :offset => (@per_page * @page)) | []
131
+ # respond_to do |format|
132
+ # format.html { render(:template => 'aggregations/photos', :layout => false) }
133
+ # format.xml { render :xml => @photos }
134
+ # end
135
+ # end
136
+ #
137
+ # def marked
138
+ # @page_title = 'View entries that I have marked'
139
+ # @aggregation = Aggregation.new
140
+ # @aggregation.title = @page_title
141
+ # @user = User.find(params[:user_id])
142
+ #
143
+ # @rss_title = @aggregation.title
144
+ # @rss_description = 'View entries from all entries marked by ' + @user.login
145
+ #
146
+ # @entries = Entry.get_marked_entries_for_user(@user.id, :limit => @per_page, :offset => (@per_page * @page))
147
+ # respond_to do |format|
148
+ # format.html { render(:template => 'aggregations/show', :layout => false) }
149
+ # format.xml { render :xml => @entries }
150
+ # format.rss { render(:template => 'aggregations/show', :layout => false) }
151
+ # end
152
+ # end
153
+ #
154
+ # def read
155
+ # @page_title = 'View entries I have read'
156
+ # @aggregation = Aggregation.new
157
+ # @aggregation.title = @page_title
158
+ # @entries = Entry.get_entries_read_for_user(current_user.id, :limit => @per_page, :offset => (@per_page * @page))
159
+ # respond_to do |format|
160
+ # format.html { render(:template => 'aggregations/show', :layout => false) }
161
+ # format.xml { render :xml => @entries }
162
+ # end
163
+ # end
164
+ #
165
+ # def duplicate
166
+ # @page_title = 'Duplicate Aggregation'
167
+ #
168
+ # @aggregation = Aggregation.find(params[:id], :include => 'feeds')
169
+ # @new_aggregation = Aggregation.new
170
+ #
171
+ # @new_aggregation.title = @aggregation.title
172
+ # @new_aggregation.description = @aggregation.description
173
+ # @new_aggregation.user_id = current_user.id
174
+ #
175
+ # success = false
176
+ # if @new_aggregation.save
177
+ # @page_title = 'Added aggregation ' + @new_aggregation.title
178
+ # @aggregation.feeds.each do |feed|
179
+ # @new_aggregation.feeds << feed
180
+ # end
181
+ # success = true
182
+ # end
183
+ #
184
+ # respond_to do |format|
185
+ # if success
186
+ # flash[:notice] = "Successfully added the " + @new_aggregation.title + " to your aggregations"
187
+ # format.html { redirect_to(CGI::unescape(params[:return_page])) if params[:return_page] }
188
+ # format.xml { render :xml => @new_aggregation, :status => :created, :location => @new_aggregation }
189
+ # else
190
+ # flash[:notice] = "Some kind of bad thing happened when we tried to add the requested aggregation to your account. We'll look into it. If you want press the back button and try again. If that doesn't work yell at the computer for a bit, it always helps me feel better. Believe me we are just as upset about all this as you are."
191
+ # format.html
192
+ # format.xml { render :xml => @new_aggregation.errors }
193
+ # end
194
+ # end
195
+ # end
196
+
197
+ def new
198
+ @page_title = I18n.t('muck.raker.new_aggregation')
199
+ @service_categories = ServiceCategory.sorted.find(:all, :include => [:tag_services])
200
+ respond_to do |format|
201
+ format.html { render :template => 'aggregations/new' }
202
+ end
203
+ end
204
+
205
+ # def edit
206
+ # @aggregation = Aggregation.find(params[:id])
207
+ # @page_title = 'Editing ' + @aggregation.title
208
+ # end
209
+ #
210
+ # def create
211
+ # @aggregation = Aggregation.new(params[:aggregation])
212
+ # @aggregation.name = make_safe_uri(@aggregation.title)
213
+ # @aggregation.user = current_user
214
+ #
215
+ # respond_to do |format|
216
+ # if @aggregation.save
217
+ # flash[:notice] = @aggregation.title + ' created. Now add some feeds:'
218
+ # format.html { redirect_to(new_aggregation_feed_path(@aggregation)) }
219
+ # format.xml { render :xml => @aggregation, :status => :created, :location => @aggregation }
220
+ # else
221
+ # format.html { render :action => "new" }
222
+ # format.xml { render :xml => @aggregation.errors }
223
+ # end
224
+ # end
225
+ # end
226
+ #
227
+ # def update
228
+ # @aggregation = Aggregation.find(params[:id])
229
+ #
230
+ # respond_to do |format|
231
+ # if @aggregation.update_attributes(params[:aggregation])
232
+ # flash[:notice] = 'Aggregation was successfully updated.'
233
+ # format.html { redirect_to(manage_user_aggregations_path(:user_id => current_user.id)) }
234
+ # format.xml { head :ok }
235
+ # else
236
+ # format.html { render :action => "edit" }
237
+ # format.xml { render :xml => @aggregation.errors }
238
+ # end
239
+ # end
240
+ # end
241
+ #
242
+ # def destroy
243
+ # @aggregation = Aggregation.find(params[:id])
244
+ # @aggregation.destroy
245
+ #
246
+ # respond_to do |format|
247
+ # flash[:notice] = @aggregation.title + ' has been removed.'
248
+ # format.html { redirect_to(manage_user_aggregations_url(current_user)) }
249
+ # format.xml { head :ok }
250
+ # end
251
+ # end
252
+
253
+ # # associate an existing feed with an aggregation
254
+ # def associate_feed
255
+ # @aggregation = Aggregation.find(params[:id])
256
+ # @feed = Feed.find(params[:feed_id])
257
+ # current_feed = @aggregation.feeds.find(@feed) rescue nil
258
+ #
259
+ # if current_feed.nil?
260
+ # @aggregation.feeds << @feed
261
+ # notice = @feed.title + ' was successfully added to ' + @aggregation.title
262
+ # else
263
+ # notice = @feed.title + ' is already a part of ' + @aggregation.title
264
+ # end
265
+ #
266
+ # respond_to do |format|
267
+ # if params[:search_terms]
268
+ # redirect_path = url_for({:controller => 'feeds', :action => 'search', :aggregation_id => @aggregation, :id => @feed, :search_terms => params[:search_terms]})
269
+ # else
270
+ # redirect_path = aggregation_feeds_url(@aggregation)
271
+ # end
272
+ #
273
+ # if @aggregation.save
274
+ # flash[:notice] = notice
275
+ # format.html { redirect_to(redirect_path) }
276
+ # format.xml { render :xml => @aggregation, :status => :added_feed, :location => @aggregation }
277
+ # else
278
+ # flash[:notice] = 'Could not add ' + @feed.title + ' to ' + @aggregation.title
279
+ # format.html { redirect_to(redirect_path) }
280
+ # format.xml { render :xml => @aggregation.errors }
281
+ # end
282
+ # end
283
+ # end
284
+ #
285
+ # #disassciates a feed from an aggregation
286
+ # def remove_feed
287
+ # @aggregation = Aggregation.find(params[:id])
288
+ # @feed = Feed.find(params[:feed_id])
289
+ # @aggregation.feeds.delete(@feed)
290
+ # respond_to do |format|
291
+ # if @aggregation.save
292
+ # flash[:notice] = @feed.title + ' was successfully removed from ' + @aggregation.title
293
+ # format.html { redirect_to(aggregation_feeds_path(@aggregation)) }
294
+ # format.xml { render :xml => @aggregation, :status => :removed_feed, :location => @aggregation }
295
+ # else
296
+ # flash[:notice] = 'Could not remove ' + @feed.title + ' from ' + @aggregation.title
297
+ # format.html { redirect_to(aggregation_feeds_path(@aggregation)) }
298
+ # format.xml { render :xml => @aggregation.errors }
299
+ # end
300
+ # end
301
+ # end
302
+
303
+ protected
304
+
305
+ def get_owner
306
+ setup_parent
307
+ end
308
+
309
+ def get_aggregation
310
+ @aggregation = Aggregation.find(params[:id])
311
+ end
312
+
313
+ def has_aggregation_permission?
314
+ if !@aggregation.can_edit?(current_user)
315
+ message = I18n.t('muck.raker.cant_modify_aggregation')
316
+ respond_to do |format|
317
+ format.html do
318
+ flash[:notice] = message
319
+ redirect_back_or_default current_user
320
+ end
321
+ format.js { render(:update) {|page| page.alert message} }
322
+ end
323
+ end
324
+ end
325
+
326
+ def has_permission?
327
+ @parent.can_edit?(current_user)
328
+ end
329
+
330
+ end
@@ -2,6 +2,7 @@ class Muck::IdentityFeedsController < ApplicationController
2
2
 
3
3
  unloadable
4
4
 
5
+ before_filter :login_required
5
6
  before_filter :get_owner, :only => [:index, :new, :create]
6
7
  before_filter :has_permission?, :only => [:index, :new, :create]
7
8
 
@@ -0,0 +1,11 @@
1
+ module MuckRakerAggregationsHelper
2
+
3
+ def data_sources(service_categories)
4
+ render :partial => 'aggregations/data_sources', :locals => { :service_categories => service_categories }
5
+ end
6
+
7
+ def data_source_checked?(data_source)
8
+ true
9
+ end
10
+
11
+ end
@@ -11,8 +11,8 @@ module MuckRakerServicesHelper
11
11
  # ServiceCategory.sorted.find(:all, :include => [:identity_services])
12
12
  # title: Optional title. Default is 'Available Services' - from I18n.t('muck.raker.available_services')
13
13
  # css: Optional css to be added to the div that surrounds the categories
14
- def service_categories(service_categories, title = nil, css = '')
15
- render :partial => 'identity_feeds/service_categories', :locals => { :service_categories => service_categories, :css => css, :title => title }
14
+ def available_service_categories(service_categories, title = nil, css = '')
15
+ render :partial => 'identity_feeds/available_service_categories', :locals => { :service_categories => service_categories, :css => css, :title => title }
16
16
  end
17
17
 
18
18
  # Render a view with the user's registered services.
@@ -108,7 +108,7 @@ module MuckRakerServicesHelper
108
108
 
109
109
  def url_by_identity_feed(owner, identity_feed, service)
110
110
  if identity_feed
111
- polymorphic_url([owner, @identity_feed], :service_id => service.to_param)
111
+ polymorphic_url([owner, identity_feed], :service_id => service.to_param)
112
112
  else
113
113
  polymorphic_url([owner, :identity_feeds], :service_id => service.to_param)
114
114
  end
@@ -1,4 +1,24 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: aggregations
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # name :string(255)
7
+ # title :string(255)
8
+ # description :text
9
+ # top_tags :text
10
+ # created_at :datetime
11
+ # updated_at :datetime
12
+ # ownable_id :integer(4)
13
+ # ownable_type :string(255)
14
+ #
15
+
1
16
  class Aggregation < ActiveRecord::Base
17
+ unloadable
18
+
19
+ belongs_to :ownable, :polymorphic => true
20
+ has_many :aggregation_feeds
21
+ has_many :feeds, :through => :aggregation_feeds
2
22
 
3
23
  # ##########################################################
4
24
  # # adds a feed to an aggregation and saves the feed
@@ -14,4 +34,4 @@ class Aggregation < ActiveRecord::Base
14
34
  # feed.save
15
35
  # end
16
36
 
17
- end
37
+ end
@@ -0,0 +1,13 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: aggregation_feeds
4
+ #
5
+ # id :integer(4) not null, primary key
6
+ # aggregation_id :integer(4)
7
+ # feed_id :integer(4)
8
+ #
9
+
10
+ class AggregationFeed < ActiveRecord::Base
11
+ belongs_to :aggregation
12
+ belongs_to :feed
13
+ end
data/app/models/feed.rb CHANGED
@@ -44,6 +44,8 @@ class Feed < ActiveRecord::Base
44
44
 
45
45
  has_many :feed_parents
46
46
  has_many :identity_feeds
47
+ has_many :aggregation_feeds
48
+ has_many :aggregations, :through => :aggregation_feeds
47
49
  has_many :entries, :dependent => :destroy
48
50
  belongs_to :contributor, :class_name => 'User', :foreign_key => 'contributor_id'
49
51
  belongs_to :default_language, :class_name => 'Language', :foreign_key => 'default_language_id'
@@ -65,11 +67,11 @@ class Feed < ActiveRecord::Base
65
67
  end
66
68
 
67
69
  def after_create
68
- if GlobalConfig.inform_admin_of_global_feed && self.feed_parents.empty?
70
+ if GlobalConfig.inform_admin_of_global_feed && global?
69
71
  RakerMailer.deliver_notification_feed_added(self) # Global feed. Email the admin to let them know a feed has been added
70
72
  end
71
73
  end
72
-
74
+
73
75
  # harvest_interval is stored in seconds
74
76
  # default is 86400 which is one day
75
77
  def harvest_interval_hours
@@ -107,13 +109,25 @@ class Feed < ActiveRecord::Base
107
109
  entries_changed_at
108
110
  end
109
111
 
112
+ # feeds that are not attached to anything become global to the site
113
+ def global?
114
+ self.feed_parents.empty? && self.identity_feeds.empty? && self.aggregations.empty?
115
+ end
116
+
117
+ # Checks to see if there is a reference to the feed in any of the relation tables.
118
+ def in_use?
119
+ feed = FeedParent.find_by_feed_id(self.id)
120
+ return true if feed
121
+ feed = IdentityFeed.find_by_feed_id(self.id)
122
+ return true if feed
123
+ feed = AggregationFeed.find_by_feed_id(self.id)
124
+ return true if feed
125
+ false
126
+ end
127
+
110
128
  # This will delete a feed if there are no references to it
111
129
  def delete_if_unused(user)
112
- if user.id == contributor_id
113
- feed = FeedParent.find_by_feed_id(self.id)
114
- return false if feed # feed is still being used
115
- feed = IdentityFeed.find_by_feed_id(self.id)
116
- return false if feed # feed is still being used
130
+ if user.id == contributor_id && !in_use?
117
131
  self.destroy
118
132
  else
119
133
  false
@@ -10,9 +10,11 @@
10
10
  # icon :string(2083) default("rss.gif")
11
11
  # sort :integer(4)
12
12
  # requires_password :boolean(1)
13
- # is_identity :boolean(1)
13
+ # use_for :string(255)
14
14
  # service_category_id :integer(4)
15
15
  # active :boolean(1) default(TRUE)
16
+ # prompt :string(255)
17
+ # template :string(255)
16
18
  #
17
19
 
18
20
  class Service < ActiveRecord::Base
@@ -11,4 +11,5 @@ class ServiceCategory < ActiveRecord::Base
11
11
  named_scope :sorted, :order => "sort ASC"
12
12
  has_many :services, :order => 'sort ASC'
13
13
  has_many :identity_services, :class_name => 'Service', :order => 'sort ASC', :conditions => ['use_for = ?', 'identity']
14
+ has_many :tag_services, :class_name => 'Service', :order => 'sort ASC', :conditions => ['use_for = ?', 'tags']
14
15
  end
@@ -0,0 +1,4 @@
1
+ <li id="<%= data_source.name.parameterize %>-link" <%= service_icon_background(data_source) %> class="service-link">
2
+ <%= check_box_tag "#{@parent.to_s.underscore}[service_ids][]", data_source.id, data_source_checked?(data_source) -%>
3
+ <%= data_source.name %>
4
+ </li>
@@ -0,0 +1,10 @@
1
+ <div id="sources-list">
2
+ <% service_categories.each do |service_category| -%>
3
+ <% if service_category.tag_services.length > 0 -%>
4
+ <ul id="<%= service_category.dom_id %>-sources-list" class="services-list">
5
+ <li class="source-title"><%= service_category.name %></li>
6
+ <%= render :partial => 'aggregations/data_source', :collection => service_category.tag_services %>
7
+ </ul>
8
+ <% end -%>
9
+ <% end -%>
10
+ </div>
@@ -0,0 +1,12 @@
1
+ <%= output_errors('', {:class => 'help-box'}) %>
2
+ <% form_for(:aggregation, :url => polymorphic_url([@parent, :aggregations])) do |f| -%>
3
+ <div id="add-data-source" class="services-main span-6 column">
4
+ <h2><%= I18n.t('muck.raker.search_for') %></h2>
5
+ <%= f.text_field :name %>
6
+ <%= f.submit t('muck.raker.add_aggregation') %>
7
+ </div>
8
+ <div id="data-sources" class="services-main span-16 column">
9
+ <h2><%= I18n.t('muck.raker.available_sources') %></h2>
10
+ <%= data_sources(@service_categories) %>
11
+ </div>
12
+ <% end -%>
@@ -1,5 +1,5 @@
1
1
  <%= output_errors('', {:class => 'help-box'}) %>
2
- <%= service_categories(@service_categories, nil, 'span-15') %>
2
+ <%= available_service_categories(@service_categories, nil, 'span-15') %>
3
3
  <%= services_for_user(@user_services, nil, 'span-5') %>
4
4
 
5
5
  <% content_for :javascript do -%>
@@ -26,6 +26,7 @@ ActionController::Routing::Routes.draw do |map|
26
26
  map.resources :recommendations, :controller => 'muck/recommendations'
27
27
 
28
28
  map.resources :identity_feeds, :controller => 'muck/identity_feeds'
29
+ map.resources :aggregations, :controller => 'muck/aggregations'
29
30
 
30
31
  # redirect (and hit tracking)
31
32
 
@@ -21,7 +21,7 @@ oai:
21
21
  use_for: 'system'
22
22
  active: true
23
23
  twitter:
24
- id: 3
24
+ id: 3
25
25
  name: Twitter
26
26
  uri: "http://www.twitter.com"
27
27
  api_uri:
@@ -621,4 +621,26 @@ amazon:
621
621
  use_for: "identity"
622
622
  service_category_id: 10
623
623
  active: true
624
- prompt: amazon_prompt
624
+ prompt: amazon_prompt
625
+ twitter_tags:
626
+ id: 59
627
+ name: Twitter
628
+ uri: "http://www.twitter.com"
629
+ api_uri:
630
+ uri_template: "http://search.twitter.com/search.atom?q=+{tag}"
631
+ icon: twitter.png
632
+ sort: 59
633
+ use_for: "tags"
634
+ service_category_id: 5
635
+ active: true
636
+ youtube_tags:
637
+ id: 60
638
+ name: You Tube
639
+ uri: "http://www.youtube.com"
640
+ api_uri:
641
+ uri_template: "http://gdata.youtube.com/feeds/base/videos?q={tag}&amp;client=ytapi-youtube-search&amp;alt=rss&amp;v=2"
642
+ icon: youtube.png
643
+ sort: 60
644
+ use_for: "tags"
645
+ service_category_id: 6
646
+ active: true
@@ -0,0 +1,15 @@
1
+ class AggregationsToPolymorphic < ActiveRecord::Migration
2
+ def self.up
3
+ remove_column :aggregations, :user_id
4
+ add_column :aggregations, :ownable_id, :integer
5
+ add_column :aggregations, :ownable_type, :string
6
+ add_index :aggregations, [:ownable_id, :ownable_type]
7
+ end
8
+
9
+ def self.down
10
+ add_column :aggregations, :user_id, :integer
11
+ remove_column :aggregations, :ownable_id, :integer
12
+ remove_column :aggregations, :ownable_type, :string
13
+ remove_index :aggregations, [:ownable_id, :ownable_type]
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ module ActiveRecord
2
+ module Acts #:nodoc:
3
+ module MuckAggregationOwner # :nodoc:
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ # +acts_as_muck_aggregation_owner+ adds identity aggregations to a given object. The aggregations
12
+ # attached to the object in this way are then assumed to be produced by the object.
13
+ # For example, if a user writes a blog the blog could be associated with the user in this way.
14
+ def acts_as_muck_aggregation_owner
15
+ has_many :aggregations, :as => :ownable
16
+ include ActiveRecord::Acts::MuckAggregationOwner::InstanceMethods
17
+ extend ActiveRecord::Acts::MuckAggregationOwner::SingletonMethods
18
+ end
19
+ end
20
+
21
+ # class methods
22
+ module SingletonMethods
23
+ end
24
+
25
+ module InstanceMethods
26
+ end
27
+
28
+ end
29
+ end
30
+ end
data/lib/muck_raker.rb CHANGED
@@ -4,11 +4,13 @@ require 'muck_raker/services'
4
4
  ActionController::Base.send :helper, MuckRakerHelper
5
5
  ActionController::Base.send :helper, MuckRakerFeedsHelper
6
6
  ActionController::Base.send :helper, MuckRakerServicesHelper
7
+ ActionController::Base.send :helper, MuckRakerAggregationsHelper
7
8
 
8
9
  ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckFeedParent }
9
10
  ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckRakerComment }
10
11
  ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckRakerShare }
11
12
  ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckFeedOwner }
13
+ ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckAggregationOwner }
12
14
 
13
15
 
14
16
  I18n.load_path += Dir[ File.join(File.dirname(__FILE__), '..', 'locales', '*.{rb,yml}') ]
data/locales/en.yml CHANGED
@@ -140,6 +140,11 @@ en:
140
140
  facebook_shares: "Facebook Shared Links"
141
141
  facebook_notes: "Facebook Notes"
142
142
  add_edit_feeds: "Add/Edit Feeds"
143
+ available_sources: "Available Sources"
144
+ new_aggregation: "New Aggregation"
145
+ cant_modify_aggregation: "You don't have permission to access the specified aggregation."
146
+ search_for: "Search for:"
147
+ add_aggregation: "Add Aggregation"
143
148
  comment_entries_count:
144
149
  one: "1 Comment"
145
150
  other: "{{count}} Comments"