prune_db.rake
7.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
namespace :prune_db do
task :all => [:invalidate_votes_with_bad_response_times]
desc "Fixes a mis-match between a vote's prompt_id and its appearance's prompt_id. Sets the appearance prompt_id to match the vote's prompt_id"
task :fix_promptid_mismatch => :environment do
bad_records = Vote.connection.select_all "
SELECT
votes.prompt_id, appearances.id appearance_id,
appearances.prompt_id appearance_prompt_id
FROM votes LEFT JOIN appearances
ON (votes.id = appearances.answerable_id
AND appearances.answerable_type = 'Vote')
WHERE votes.prompt_id <> appearances.prompt_id"
bad_records.each do |record|
Appearance.update_all("prompt_id = #{record["prompt_id"]}", "id = #{record["appearance_id"]} AND prompt_id = #{record["appearance_prompt_id"]}")
end
end
desc "Invalidates votes with bad response times"
task :invalidate_votes_with_bad_response_times => :environment do
badvotes = []
#might want to optimize later to not start from the beginning each time
STDOUT.sync = true
Vote.find_each(:batch_size => 10000, :include => :appearance) do |v|
next if v.nil? || v.appearance.nil?
server_response_time = v.created_at.to_f - v.appearance.created_at.to_f
if v.time_viewed && v.time_viewed/1000 > server_response_time
badvotes << v
print "."
end
end
puts "\n"
if badvotes.any?
badvotes.each do |v|
v.time_viewed = nil
v.missing_response_time_exp = "invalid"
v.save!
end
else
puts "Could not find any bad votes. Yay."
end
end
task :associate_skips_with_appearances => :environment do
skips_to_fix = Skip.find(:all, :conditions => {:appearance_id => nil})
skips_to_fix.each do |skip|
puts "Skip #{skip.id} : "
possible_appearances = skip.skipper.appearances.find(:all, :conditions => {:prompt_id => skip.prompt_id})
if possible_appearances.nil? || possible_appearances.empty?
puts " I couldn't find any matches!"
skip.delete
next
end
if possible_appearances.size > 1
puts " More than one possible appearance"
possible_appearances.delete_if{|a| a.answered?}
if possible_appearances.size > 1 || possible_appearances.size == 0
puts" And I couldn't narrow it down.... moving on"
skip.delete
next
end
end
possible_appearance = possible_appearances.first
if possible_appearance.answered?
puts " This appearance has been answered already! Moving on"
skip.delete
else
puts " MATCH"
skip.appearance_id = possible_appearance.id
skip.save!
end
end
end
task(:move_vote_and_skip_ids_to_appearance => :environment) do
#Vote.find_each do |v|
# @appearance = Appearance.find(v.appearance_id)
# @appearance.answerable = v
# @appearance.save
# if v.id % 1000 == 0
# puts v.id
# end
# end
Skip.find_each do |s|
if s.appearance_id
@appearance = Appearance.find(s.appearance_id)
if @appearance.answerable
puts "Appearance #{@appearance.id} has more than one skip!"
else
@appearance.answerable = s
@appearance.save
end
end
end
end
task(:remove_double_counted_votes_with_same_appearance => :environment) do
votes_with_no_appearance = []
Vote.find_each(:include => :appearance) do |v|
puts v.id if v.id % 1000 == 0
votes_with_no_appearance << v if v.appearance.nil?
end
skips_with_no_appearance = []
Skip.find_each(:include => :appearance) do |s|
puts s.id if s.id % 1000 == 0
skips_with_no_appearance << s if s.appearance.nil?
end
puts "#{votes_with_no_appearance.size} Votes"
puts "#{skips_with_no_appearance.size} Skips"
votes_with_no_appearance.each do |v|
v.valid_record = false
v.validity_information = "No associated appearance object"
v.save!
end
skips_with_no_appearance.each do |s|
s.valid_record = false
s.validity_information = "No associated appearance object"
s.save!
end
end
#call this by doing rake prune_db:populate_seed_ideas['blahblah',questionnum], where blahblah is the filename
task(:populate_seed_ideas, :args1, :args2, :needs => :environment) do | task, arguments|
filename = arguments[:args1]
question_num = arguments[:args2]
puts filename
puts question_num
q = Question.find(question_num)
creator_id = q.creator_id
File.open(filename, "r") do |infile|
while( data= infile.gets)
c = Choice.new(:creator_id => creator_id,
:question_id => q.id,
:active => true,
:data => data.chomp)
c.save
end
end
end
desc "Searches questions for orphaned votes (votes with no appearance) and marks them as invalid"
task :invalidate_orphaned_votes => :environment do
question_ids = ENV["question_ids"].split(/[\s,]+/)
question_ids.each do |question_id|
question = Question.find(question_id)
orphaned_votes = Vote.find(:all,
:select => "votes.id",
:joins => "LEFT JOIN appearances ON (votes.id = appearances.answerable_id AND answerable_type <> 'Skip')",
:conditions => ["answerable_id IS NULL AND votes.valid_record = 1 AND votes.question_id = ?", question.id])
puts "Question ##{question.id} has #{orphaned_votes.count} orphaned votes"
orphaned_votes.each do |orphaned_vote_id|
orphaned_vote = Vote.find(orphaned_vote_id.id)
# attempt to find sibling vote
# sibling vote is one that is valid has the same voter and prompt,
# is associated with an appearance, and created within 10 seconds
sibling_vote = nil
votes = Vote.find(:all, :conditions => {:voter_id => orphaned_vote.voter_id, :prompt_id => orphaned_vote.prompt_id})
votes.each do |vote|
next if vote.id == orphaned_vote.id
next if vote.created_at > orphaned_vote.created_at + 5.seconds
next if vote.created_at < orphaned_vote.created_at - 5.seconds
next if vote.appearance == nil
sibling_vote = vote
break
end
info = "Appearance XXXX already answered"
if sibling_vote
info = "Appearance #{sibling_vote.appearance.id} already answered"
end
orphaned_vote.update_attributes!(:valid_record => false, :validity_information => info)
end
end
end
desc "Updates cached values for losses and wins for choices."
task :update_cached_losses_wins => :environment do
Question.all.each do |question|
question.choices.each do |choice|
choice.reload
true_losses = question.votes.count(:conditions => {:loser_choice_id => choice.id})
true_wins = choice.votes.count
Choice.update_counters choice.id,
:losses => (true_losses - choice.losses),
:wins => (true_wins - choice.wins)
choice.reload
choice.score = choice.compute_score
choice.save(false)
end
end
end
desc "Update cached values for prompts on left and right for choices."
task :update_cached_prompts_on_left_right => :environment do
Question.all.each do |question|
question.choices.each do |choice|
choice.reload
Choice.update_counters choice.id,
:prompts_on_the_left_count => choice.prompts_on_the_left.count - choice.prompts_on_the_left_count,
:prompts_on_the_right_count => choice.prompts_on_the_right.count - choice.prompts_on_the_right_count
end
end
end
desc "Recomputes scores for all choices."
task :recompute_scores => :environment do
Choice.find_each do |choice|
choice.reload
choice.score = choice.compute_score
choice.save(false)
end
end
end