fix rake task
[shapado:shapado.git] / lib / tasks / fixdb.rake
1
2 desc "Fix all"
3 task :fixall => [:init, "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:create_thumbnails"] 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 end
23
24 namespace :fixdb do
25   task :questions => [:init] do
26     Question.all.each do |question|
27       question.override(:_random => rand())
28       question.override(:_random_times => 0.0)
29
30       watchers = question.raw_attributes["watchers"]
31       question.unset(:watchers => true)
32       if watchers.kind_of?(Array)
33         question.override(:follower_ids => watchers)
34       end
35     end
36   end
37
38   task :contributions => [:init] do
39     Question.only(:user_id, :contributor_ids).all.each do |question|
40       question.add_contributor(question.user) if question.user
41       question.answers.only(:user_id).all.each do |answer|
42         question.add_contributor(answer.user) if answer.user
43       end
44     end
45   end
46
47   task :dates => [:init] do
48     %w[badges questions comments votes users announcements groups memberships pages reputation_events user_stats versions views_counts].each do |cname|
49       coll = Mongoid.master.collection(cname)
50       coll.find.each do |q|
51         %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|
52           if q[key].is_a?(String)
53             q[key] = Time.parse(q[key])
54           end
55         end
56         coll.save(q)
57       end
58     end
59   end
60
61   task :openid => [:init] do
62     User.all.each do |user|
63       next if user.identity_url.blank?
64
65       puts "Updating: #{user.login}"
66       user.push_uniq(:auth_keys => "open_id_#{user[:identity_url]}")
67       user.unset(:identity_url => 1)
68     end
69   end
70
71   task :update_answers_favorite => [:init] do
72     Mongoid.database.collection("favorites").remove
73     answers = Mongoid.database.collection("answers")
74     answers.update({ }, {"$set" => {"favorite_counts" => 0}})
75   end
76
77   task :sync_counts => [:init] do
78     votes = Mongoid.database.collection("votes")
79     comments = Mongoid.database.collection("comments")
80     puts "updating comment's counts"
81     comments.find.each do |c|
82       print "."
83       votes_average=0
84       votes.find(:voteable_id =>  c["_id"]).each do |v|
85         votes_average+=v["value"]
86       end
87       comments.update({:_id => c["id"]},
88                       {"$set" => {"votes_count" => votes.find(:voteable_id =>  c["_id"]).count,
89                                   "votes_average" => votes_average}})
90
91       if c["flags"]
92         comments.update({:_id => c["id"]}, {"$set" => {"flags_count" => c["flags"].size}})
93       end
94     end
95
96     puts "updating questions's counts"
97     Question.all.each do |q|
98       print "."
99       votes_average=0
100       votes.find(:voteable_id =>  q.id).each do |v|
101         votes_average+=v["value"]
102       end
103       q.override("flags_count" => q.flags.size, "votes_count" => q.votes.size, "votes_average" => votes_average)
104     end
105   end
106
107   task :counters => :init do
108     Question.all.each do |q|
109       q.override(:close_requests_count => q.close_requests.size)
110       q.override(:open_requests_count => q.open_requests.size)
111     end
112   end
113
114   task :last_target_type => [:init] do
115     puts "updating questions#last_target_type"
116     Question.where({:last_target_type.ne => nil}).all.each do |q|
117       print "."
118       if(q.last_target_type != "Comment")
119         last_target = q.last_target_type.constantize.find(q.last_target_id)
120       else
121         data = Mongoid.database.collection("comments").find_one(:_id => q.last_target_id)
122         last_target = Comment.new(data)
123       end
124
125       if(last_target)
126         if(last_target.respond_to?(:updated_at) && last_target.updated_at && last_target.updated_at.is_a?(String))
127           last_target.updated_at = Time.parse(last_target.updated_at)
128         end
129         Question.update_last_target(q.id, last_target)
130       end
131     end
132   end
133
134   task :votes => [:init] do
135     puts "updating votes"
136     comments = Mongoid.database.collection("comments")
137     comments.update({:votes => nil}, {"$set" => {"votes" =>  {}}}, :multi => true)
138     questions = Mongoid.database.collection("questions")
139     questions.update({:votes => nil}, {"$set" => {"votes" => {}}}, :multi => true)
140     Group.all.each do |group|
141       count = 0
142       Mongoid.database.collection("votes").find({:group_id => group["_id"]}).each do |vote|
143         vote.delete("group_id")
144         id = vote.delete("voteable_id")
145         klass = vote.delete("voteable_type")
146         collection = comments
147         if klass == "Question"
148           collection = questions;
149         end
150         count += 1
151         collection.update({:_id => id}, "$set" => {"votes.#{vote["user_id"]}" => vote["value"]})
152       end
153       if count > 0
154         puts "Updated #{count} #{group["name"]} votes"
155       end
156     end
157     Mongoid.database.collection("votes").drop
158   end
159
160   task :comments => [:init] do
161     puts "updating comments"
162     comments = Mongoid.database.collection("comments")
163     questions = Mongoid.database.collection("questions")
164
165     Mongoid.database.collection("comments").find(:_type => "Comment").each do |comment|
166         id = comment.delete("commentable_id")
167         klass = comment.delete("commentable_type")
168         collection = comments
169
170       %w[created_at updated_at].each do |key|
171         if comment[key].is_a?(String)
172           comment[key] = Time.parse(comment[key])
173         end
174       end
175
176       if klass == "Question"
177         collection = questions;
178       end
179
180         collection.update({:_id => id}, "$addToSet" => {:comments => comment})
181         comments.remove({:_id => comment["_id"]})
182     end
183     begin
184       Mongoid.database.collection("answers").drop
185     ensure
186       begin
187         comments.rename("answers")
188       rescue
189         puts "comments collection doesn't exists"
190       ensure
191         Answer.override({}, {:_type => "Answer"})
192       end
193     end
194
195     answers_coll = Mongoid.database.collection("answers")
196     answers_coll.find().each do |answer|
197       %w[created_at updated_at].each do |key|
198         if answer[key].is_a?(String)
199           answer[key] = Time.parse(answer[key])
200         end
201       end
202       answers_coll.save(answer)
203     end
204
205     puts "updated comments"
206   end
207
208   task :groups => [:init] do
209     Group.where({:language.in => [nil, '', 'none']}).all.each do |group|
210       lang = group.description.to_s.language
211       puts "Updating #{group.name} subdomain='#{group.subdomain}' detected as: #{lang}"
212
213       group.language = (lang == :spanish) ? 'es' : 'en'
214       group.languages = DEFAULT_USER_LANGUAGES
215
216       if group.valid?
217         group.save
218       else
219         puts "Invalid group: #{group.errors.full_messages}"
220       end
221     end
222   end
223
224   task :relocate => [:init] do
225     doc = JSON.parse(File.read('data/countries.json'))
226     i=0
227     Question.override({:address => nil}, :address => {})
228     Answer.override({:address => nil}, :address => {})
229     User.override({:address => nil}, :address => {})
230     doc.keys.each do |key|
231       User.where({:country_name => key}).all.each do |u|
232         p "#{u.login}: before: #{u.country_name}, after: #{doc[key]["address"]["country"]}"
233         lat = Float(doc[key]["lat"])
234         lon = Float(doc[key]["lon"])
235         User.override({:_id => u.id},
236                     {:position => {lat: lat, long: lon},
237                       :address => doc[key]["address"] || {}})
238 #         FIXME
239 #         Comment.override({:user_id => u.id},
240 #                     {:position => GeoPosition.new(lat, lon),
241 #                       :address => doc[key]["address"]})
242         Question.override({:user_id => u.id},
243                     {:position => {lat: lat, long: lon},
244                       :address => doc[key]["address"] || {}})
245         Answer.override({:user_id => u.id},
246                     {:position => {lat: lat, long: lon},
247                       :address => doc[key]["address"] || {}})
248       end
249     end
250   end
251
252   task :widgets => [:init] do
253     c=Group.count
254     Group.override({}, {:widgets => [], :question_widgets => [], :mainlist_widgets => [],
255                         :external_widgets => []})
256     i=0
257     Group.all.each do |g|
258       g.reset_widgets!
259       g.save
260       p "(#{i+=1}/#{c}) Updated widgets for group #{g.name}"
261     end
262   end
263
264   task :update_group_notification_config => [:init] do
265     puts "updating groups notification config"
266     Group.all.each do |g|
267       g.notification_opts = GroupNotificationConfig.new
268       g.save
269     end
270     puts "done"
271   end
272
273   task :tags => [:init] do
274     Group.all.each do |g|
275       Question.tag_cloud({:group_id => g.id} , 1000).each do |tag|
276         tag = Tag.new(:name => tag["name"], :count => tag["count"])
277         tag.group = g
278         tag.user = g.owner
279         tag.used_at = tag.created_at = tag.updated_at = g.questions.where(:tags.in => [tag["name"]]).first.created_at
280         tag.save
281       end
282     end
283   end
284
285   task :remove_retag_other_tag => [:init] do
286     Group.unset({}, "reputation_constrains.retag_others_tags" => 1 )
287   end
288
289   task :cleanup => [:init] do
290     p "removing #{Question.where(:group_id => nil).destroy_all} orphan questions"
291     p "removing #{Answer.where(:group_id => nil).destroy_all} orphan answers"
292   end
293
294   task :set_follow_ids => [:init] do
295     p "setting nil following_ids to []"
296     FriendList.collection.update({:following_ids => nil}, {:following_ids => []})
297     p "setting nil follower_ids to []"
298     FriendList.collection.update({:follower_ids => nil}, {:follower_ids => []})
299     p "done"
300   end
301
302   task :set_friends_lists => [:init] do
303     total = User.count
304     i = 1
305     p "updating #{total} users facebook friends list"
306     User.all.each do |u|
307       u.send(:initialize_fields)
308       u.send(:create_friends_lists)
309
310       p "#{i}/#{total} #{u.login}"
311       i += 1
312     end
313     p "done"
314   end
315
316   task :fix_twitter_users => [:init] do
317     users = User.where({:twitter_token => {:$ne => nil}})
318     users.each do |u|
319       twitter_id = u.twitter_token.split('-').first
320       p "fixing #{u.login} with twitter id #{twitter_id}"
321       u["auth_keys"] = [] if u["auth_keys"].nil?
322       u["auth_keys"] << "twitter_#{twitter_id}"
323       u["auth_keys"].uniq!
324       u["twitter_id"] = twitter_id
325       u["user_info"] = { } if u["user_info"].nil?
326       u["user_info"]["twitter"] = { "old" => 1}
327       u.save(:validate => false)
328     end
329   end
330
331   task :fix_facebook_users => [:init] do
332     users = User.where({:facebook_id => {:$ne => nil}})
333     users.each do |u|
334       facebook_id = u.facebook_id
335       p "fixing #{u.login} with facebook id #{facebook_id}"
336       u["auth_keys"] = [] if u["auth_keys"].nil?
337       u["auth_keys"] << "facebook_#{facebook_id}"
338       u["auth_keys"].uniq!
339       u["user_info"] = { } if u["user_info"].nil?
340       u["user_info"]["facebook"] = { "old" => 1}
341       u.save(:validate => false)
342     end
343   end
344
345   task :create_thumbnails => [:init]  do
346     Group.where.each do |g|
347       Jobs::Images.generate_group_thumbnails(g.id)
348     end
349   end
350 end