Move theme's stylesheet generation to a magent job
[shapado:shapado.git] / lib / tasks / fixdb.rake
1
2 desc "Fix all"
3 task :fixall => [:init, "fixdb:create_thumbnails", "fixdb:questions", "fixdb:contributions", "fixdb:dates", "fixdb:openid", "fixdb:relocate", "fixdb:votes", "fixdb:counters", "fixdb:sync_counts", "fixdb:last_target_type", "fixdb:comments", "fixdb:widgets", "fixdb:tags", "fixdb:update_answers_favorite", "fixdb:groups", "fixdb:remove_retag_other_tag", "setup:create_reputation_constrains_modes", "fixdb:update_group_notification_config", "fixdb:set_follow_ids", "fixdb:set_friends_lists", "fixdb:fix_twitter_users", "fixdb:fix_facebook_users", "fixdb:set_invitations_perms", "fixdb:set_signup_type", "fixdb:versions", "fixdb:ads", "fixdb:set_comment_count", "fixdb:wiki_booleans"] do
4 end
5
6
7 task :init => [:environment] do
8   class Question
9     def set_created_at; end
10     def set_updated_at; end
11   end
12
13   class Answer
14     def set_created_at; end
15     def set_updated_at; end
16   end
17
18   class Group
19     def set_created_at; end
20     def set_updated_at; end
21   end
22
23   GC.start
24 end
25
26 namespace :fixdb do
27   task :questions => [:init] do
28     Question.all.each do |question|
29       question.override(:_random => rand())
30       question.override(:_random_times => 0.0)
31
32       watchers = question.raw_attributes["watchers"]
33       question.unset(:watchers => true)
34       if watchers.kind_of?(Array)
35         question.override(:follower_ids => watchers)
36       end
37     end
38   end
39
40   task :contributions => [:init] do
41     Question.only(:user_id, :contributor_ids).all.each do |question|
42       question.add_contributor(question.user) if question.user
43       question.answers.only(:user_id).all.each do |answer|
44         question.add_contributor(answer.user) if answer.user
45       end
46     end
47   end
48
49   task :dates => [:init] do
50     %w[badges questions comments votes users announcements groups memberships pages reputation_events user_stats versions views_counts].each do |cname|
51       coll = Mongoid.master.collection(cname)
52       coll.find.each do |q|
53         %w[activity_at last_target_date created_at updated_at birthday last_logged_at starts_at ends_at last_activity_at time date].each do |key|
54           if q[key].is_a?(String)
55             q[key] = Time.parse(q[key])
56           end
57         end
58         coll.save(q)
59       end
60     end
61   end
62
63   task :openid => [:init] do
64     User.all.each do |user|
65       next if user.identity_url.blank?
66
67       puts "Updating: #{user.login}"
68       user.push_uniq(:auth_keys => "open_id_#{user[:identity_url]}")
69       user.unset(:identity_url => 1)
70     end
71   end
72
73   task :update_answers_favorite => [:init] do
74     Mongoid.database.collection("favorites").remove
75     answers = Mongoid.database.collection("answers")
76     answers.update({ }, {"$set" => {"favorite_counts" => 0}})
77   end
78
79   task :sync_counts => [:init] do
80     votes = Mongoid.database.collection("votes")
81     comments = Mongoid.database.collection("comments")
82     puts "updating comment's counts"
83     comments.find.each do |c|
84       print "."
85       votes_average=0
86       votes.find(:voteable_id =>  c["_id"]).each do |v|
87         votes_average+=v["value"]
88       end
89       comments.update({:_id => c["id"]},
90                       {"$set" => {"votes_count" => votes.find(:voteable_id =>  c["_id"]).count,
91                                   "votes_average" => votes_average}})
92
93       if c["flags"]
94         comments.update({:_id => c["id"]}, {"$set" => {"flags_count" => c["flags"].size}})
95       end
96     end
97
98     puts "updating questions's counts"
99     Question.all.each do |q|
100       print "."
101       votes_average=0
102       votes.find(:voteable_id =>  q.id).each do |v|
103         votes_average+=v["value"]
104       end
105       q.override("flags_count" => q.flags.size, "votes_count" => q.votes.size, "votes_average" => votes_average)
106     end
107   end
108
109   task :counters => :init do
110     Question.all.each do |q|
111       q.override(:close_requests_count => q.close_requests.size)
112       q.override(:open_requests_count => q.open_requests.size)
113     end
114   end
115
116   task :last_target_type => [:init] do
117     puts "updating questions#last_target_type"
118     Question.where({:last_target_type.ne => nil}).all.each do |q|
119       print "."
120       if(q.last_target_type != "Comment")
121         last_target = q.last_target_type.constantize.find(q.last_target_id)
122       else
123         data = Mongoid.database.collection("comments").find_one(:_id => q.last_target_id)
124         last_target = Comment.new(data)
125       end
126
127       if(last_target)
128         if(last_target.respond_to?(:updated_at) && last_target.updated_at && last_target.updated_at.is_a?(String))
129           last_target.updated_at = Time.parse(last_target.updated_at)
130         end
131         Question.update_last_target(q.id, last_target)
132       end
133     end
134   end
135
136   task :votes => [:init] do
137     puts "updating votes"
138     comments = Mongoid.database.collection("comments")
139     comments.update({:votes => nil}, {"$set" => {"votes" =>  {}}}, :multi => true)
140     questions = Mongoid.database.collection("questions")
141     questions.update({:votes => nil}, {"$set" => {"votes" => {}}}, :multi => true)
142     Group.all.each do |group|
143       count = 0
144       Mongoid.database.collection("votes").find({:group_id => group["_id"]}).each do |vote|
145         vote.delete("group_id")
146         id = vote.delete("voteable_id")
147         klass = vote.delete("voteable_type")
148         collection = comments
149         if klass == "Question"
150           collection = questions;
151         end
152         count += 1
153         collection.update({:_id => id}, "$set" => {"votes.#{vote["user_id"]}" => vote["value"]})
154       end
155       if count > 0
156         puts "Updated #{count} #{group["name"]} votes"
157       end
158     end
159     Mongoid.database.collection("votes").drop
160   end
161
162   task :comments => [:init] do
163     puts "updating comments"
164     comments = Mongoid.database.collection("comments")
165     questions = Mongoid.database.collection("questions")
166     questions.update({}, {"$set" => {:comments => []}})
167     comments.update({}, {"$set" => {:comments => []}})
168
169     Mongoid.database.collection("comments").find(:_type => "Comment").each do |comment|
170       id = comment.delete("commentable_id")
171       klass = comment.delete("commentable_type")
172       collection = comments
173
174       %w[created_at updated_at].each do |key|
175         if comment[key].is_a?(String)
176           comment[key] = Time.parse(comment[key])
177         end
178       end
179
180       if klass == "Question"
181         collection = questions;
182       end
183
184       comment.delete("comments")
185       collection.update({:_id => id}, "$addToSet" => {:comments => comment})
186       comments.remove({:_id => comment["_id"]})
187     end
188     begin
189       Mongoid.database.collection("answers").drop
190     ensure
191       begin
192         comments.rename("answers")
193       rescue
194         puts "comments collection doesn't exists"
195       ensure
196         Answer.override({}, {:_type => "Answer"})
197       end
198     end
199
200     answers_coll = Mongoid.database.collection("answers")
201     answers_coll.find().each do |answer|
202       %w[created_at updated_at].each do |key|
203         if answer[key].is_a?(String)
204           answer[key] = Time.parse(answer[key])
205         end
206       end
207       answers_coll.save(answer)
208     end
209
210     puts "updated comments"
211   end
212
213   task :groups => [:init] do
214     Group.where({:language.in => [nil, '', 'none']}).all.each do |group|
215       lang = group.description.to_s.language
216       puts "Updating #{group.name} subdomain='#{group.subdomain}' detected as: #{lang}"
217
218       group.language = (lang == :spanish) ? 'es' : 'en'
219       group.languages = DEFAULT_USER_LANGUAGES
220
221       if group.valid?
222         group.save
223       else
224         puts "Invalid group: #{group.errors.full_messages}"
225       end
226     end
227   end
228
229   task :relocate => [:init] do
230     doc = JSON.parse(File.read('data/countries.json'))
231     i=0
232     Question.override({:address => nil}, :address => {})
233     Answer.override({:address => nil}, :address => {})
234     User.override({:address => nil}, :address => {})
235     doc.keys.each do |key|
236       User.where({:country_name => key}).all.each do |u|
237         p "#{u.login}: before: #{u.country_name}, after: #{doc[key]["address"]["country"]}"
238         lat = Float(doc[key]["lat"])
239         lon = Float(doc[key]["lon"])
240         User.override({:_id => u.id},
241                     {:position => {lat: lat, long: lon},
242                       :address => doc[key]["address"] || {}})
243 #         FIXME
244 #         Comment.override({:user_id => u.id},
245 #                     {:position => GeoPosition.new(lat, lon),
246 #                       :address => doc[key]["address"]})
247         Question.override({:user_id => u.id},
248                     {:position => {lat: lat, long: lon},
249                       :address => doc[key]["address"] || {}})
250         Answer.override({:user_id => u.id},
251                     {:position => {lat: lat, long: lon},
252                       :address => doc[key]["address"] || {}})
253       end
254     end
255   end
256
257   task :widgets => [:init] do
258     c=Group.count
259     Group.unset({}, [:widgets, :question_widgets, :mainlist_widgets, :external_widgets])
260     i=0
261     Group.all.each do |g|
262       g.reset_widgets!
263       g.save
264       p "(#{i+=1}/#{c}) Updated widgets for group #{g.name}"
265     end
266   end
267
268   task :update_group_notification_config => [:init] do
269     puts "updating groups notification config"
270     Group.all.each do |g|
271       g.notification_opts = GroupNotificationConfig.new
272       g.save
273     end
274     puts "done"
275   end
276
277   task :tags => [:init] do
278     Group.all.each do |g|
279       Question.tag_cloud({:group_id => g.id} , 1000).each do |tag|
280         tag = Tag.new(:name => tag["name"], :count => tag["count"])
281         tag.group = g
282         tag.user = g.owner
283         tag.used_at = tag.created_at = tag.updated_at = g.questions.where(:tags.in => [tag["name"]]).first.created_at
284         tag.save
285       end
286     end
287   end
288
289   task :remove_retag_other_tag => [:init] do
290     Group.unset({}, "reputation_constrains.retag_others_tags" => 1 )
291   end
292
293   task :cleanup => [:init] do
294     p "removing #{Question.where(:group_id => nil).destroy_all} orphan questions"
295     p "removing #{Answer.where(:group_id => nil).destroy_all} orphan answers"
296   end
297
298   task :set_follow_ids => [:init] do
299     p "setting nil following_ids to []"
300     FriendList.override({:following_ids => nil}, {:following_ids => []})
301     p "setting nil follower_ids to []"
302     FriendList.override({:follower_ids => nil}, {:follower_ids => []})
303     p "done"
304   end
305
306   task :set_friends_lists => [:init] do
307     total = User.count
308     i = 1
309     p "updating #{total} users facebook friends list"
310     User.all.each do |u|
311       u.send(:initialize_fields)
312       u.send(:create_friends_lists)
313
314       p "#{i}/#{total} #{u.login}"
315       i += 1
316     end
317     p "done"
318   end
319
320   task :fix_twitter_users => [:init] do
321     users = User.where({:twitter_token => {:$ne => nil}})
322     users.each do |u|
323       twitter_id = u.twitter_token.split('-').first
324       p "fixing #{u.login} with twitter id #{twitter_id}"
325       u["auth_keys"] = [] if u["auth_keys"].nil?
326       u["auth_keys"] << "twitter_#{twitter_id}"
327       u["auth_keys"].uniq!
328       u["twitter_id"] = twitter_id
329       u["user_info"] = { } if u["user_info"].nil?
330       u["user_info"]["twitter"] = { "old" => 1}
331       u.save(:validate => false)
332     end
333   end
334
335   task :fix_facebook_users => [:init] do
336     users = User.where({:facebook_id => {:$ne => nil}})
337     users.each do |u|
338       facebook_id = u.facebook_id
339       p "fixing #{u.login} with facebook id #{facebook_id}"
340       u["auth_keys"] = [] if u["auth_keys"].nil?
341       u["auth_keys"] << "facebook_#{facebook_id}"
342       u["auth_keys"].uniq!
343       u["user_info"] = { } if u["user_info"].nil?
344       u["user_info"]["facebook"] = { "old" => 1}
345       u.save(:validate => false)
346     end
347   end
348
349   task :create_thumbnails => [:init]  do
350     Group.all.each do |g|
351       begin
352         puts "Creating thumbnails for #{g.name} #{g.id}"
353         Jobs::Images.generate_group_thumbnails(g.id)
354       rescue Mongo::GridFileNotFound => e
355         puts "error getting #{g.name}'s logo"
356       end
357     end
358   end
359
360
361   task :set_invitations_perms => [:init] do
362     p "setting invitations permissions on groups"
363     p "only owners can invite people on private group by default"
364     Group.override({:private => false}, {:invitations_perms => "owner"})
365     p "anyone can invite people on private group by default"
366     Group.override({:private => false}, {:invitations_perms => "user"})
367     p "done"
368   end
369
370   task :set_signup_type => [:init] do
371     p "setting signup type for groups"
372     Group.override({:openid_only => true}, {:signup_type => "noemail"})
373     Group.override({:openid_only => false}, {:signup_type => "all"})
374     p "done"
375   end
376
377   task :set_comment_count => [:init] do
378     questions = Mongoid.database.collection("questions")
379     answers = Mongoid.database.collection("answers")
380
381     User.only([:_id,:membership_list, :login]).all.each do |u|
382       u.membership_list.each do |group_id, vals|
383         count = 0
384         group = Group.where(:_id => group_id).only([:_id, :name]).first
385         next if group.nil?
386
387         questions.find({:group_id => group.id}, {:fields => {:user_id => 1, :"comments.user_id" => 1}}).each do |q|
388           if q["comments"]
389             q["comments"].each do |c|
390               if c["user_id"] == u.id
391                 count = count + 1
392               end
393             end
394           end
395         end
396
397         answers.find({:group_id => group.id}, {:fields => {:user_id => 1, :"comments.user_id" => 1}}).each do |a|
398           if a["comments"]
399             a["comments"].each do |c|
400               if c["user_id"] == u.id
401                 count = count + 1
402               end
403             end
404           end
405         end
406
407         u.override({"membership_list.#{group.id}.comments_count" => count})
408         if count > 0
409           p "#{u.login}: #{count} in #{group.name}"
410         end
411       end
412     end
413   end
414
415   task :versions => [:init] do
416     Question.only(:versions, :versions_count).each do |question|
417       next if question.versions.count > 0
418       question.override({:versions_count => 0})
419       (question[:versions]||[]).each do |version|
420         version["created_at"] = version.delete("date")
421         version["target"] = question
422
423         question.version_klass.create!(version)
424       end
425
426       question.unset({:versions => true})
427     end
428
429     Answer.only(:versions, :versions_count).each do |post|
430       next if post.versions_count.to_i > 0
431       post.override({:versions_count => 0})
432       (post[:versions]||[]).each do |version|
433         version["created_at"] = version.delete("date")
434         version["target"] = post
435
436         post.version_klass.create!(version)
437       end
438
439       post.unset({:versions => true})
440     end
441   end
442
443   task :ads => [:init]  do
444     collection = Mongoid.database.collection("ads")
445     collection.find.each do |ad|
446       group = Group.find(ad["group_id"])
447       positions = {'context_panel' => "sidebar",
448                    'header' => "header",
449                    'footer' => "footer",
450                    'content' => "navbar"}
451       widget = nil
452       case ad['_type']
453       when "Adsense"
454         widget = AdsenseWidget.new(:settings =>{:client => ad['google_ad_client'],
455                           :slot => ad['google_ad_slot'],
456                           :width => ad['google_ad_width'],
457                           :height => ad['google_ad_height']})
458       when "Adbard"
459         widget = AdbardWidget.new(:settings =>{:host_id => ad['adbard_host_id'],
460                                   :site_key => ad['adbard_site_key']})
461       end
462       widget_list = group.mainlist_widgets
463       widget_list.send(:"#{positions[ad['position']]}") << widget
464       widget.save
465     end
466     collection.remove
467   end
468
469   task :wiki_booleans => [:init]  do
470     Answer.override({:wiki=>"0"},{:wiki=>false})
471     Answer.override({:wiki=>"1"},{:wiki=>true})
472     Question.override({:wiki=>"0"},{:wiki=>false})
473     Question.override({:wiki=>"1"},{:wiki=>true})
474   end
475
476   task :themes => [:init] do
477     Theme.destroy_all
478     theme = Theme.create(:name => "Default", :community => true, :is_default => true)
479     Jobs::Themes.generate_stylesheet(theme.id)
480     Group.override({}, :current_theme_id => theme.id)
481   end
482
483 end