@@ -363,6 +363,114 @@ func (s *LogService) Delete(ctx context.Context, id string) (*models.Log, error)
|
||||
return log, nil
|
||||
}
|
||||
|
||||
func (s *LogService) FixImportDateBug(ctx context.Context) error {
|
||||
start := time.Now()
|
||||
|
||||
logs, err := s.logs.List(ctx, models.LogFilter{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
eg := errgroup.Group{}
|
||||
for i := range logs {
|
||||
l := logs[i]
|
||||
|
||||
eg.Go(func() error {
|
||||
return s.fixImportDateBug(ctx, *l)
|
||||
})
|
||||
}
|
||||
err = eg.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Date import bug check finished: logs: %d, duration: %s", len(logs), time.Since(start))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *LogService) fixImportDateBug(ctx context.Context, l models.Log) error {
|
||||
// Find the log's posts.
|
||||
posts, err := s.ListPosts(ctx, &models.PostFilter{LogID: &l.ShortID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(posts) < 8 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find first action post
|
||||
first := posts[0]
|
||||
fi := 0
|
||||
for first.Kind != "action" && first.Kind != "text" {
|
||||
fi++
|
||||
if fi >= len(posts) {
|
||||
return nil
|
||||
}
|
||||
|
||||
first = posts[fi]
|
||||
}
|
||||
last := posts[len(posts)-1]
|
||||
if first == last {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop here if this log probably isn't affected
|
||||
if last.Time.Sub(first.Time) < time.Hour*72 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find the first post past midnight.
|
||||
midnight := first
|
||||
mi := fi
|
||||
for i, post := range posts[fi+1:] {
|
||||
if post.Time.Hour() < first.Time.Hour() {
|
||||
midnight = post
|
||||
mi = fi + 1 + i
|
||||
break
|
||||
}
|
||||
}
|
||||
if midnight == last {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(posts[mi+1:]) == 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
hits := 0
|
||||
prev := midnight
|
||||
for _, offender := range posts[mi+1:] {
|
||||
if offender.Time.Day() != prev.Time.Day() {
|
||||
hits += 1
|
||||
}
|
||||
|
||||
prev = offender
|
||||
}
|
||||
if hits < ((len(posts[mi+1:]) * 3) / 4) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, offender := range posts[mi+1:] {
|
||||
ot := offender.Time.UTC()
|
||||
mt := midnight.Time.UTC()
|
||||
|
||||
y, m, d := mt.Date()
|
||||
hr, mi, se, ns := ot.Hour(), ot.Minute(), ot.Second(), ot.Nanosecond()
|
||||
|
||||
newTime := time.Date(y, m, d, hr, mi, se, ns, time.UTC)
|
||||
|
||||
_, err := s.posts.Update(ctx, *offender, models.PostUpdate{Time: &newTime})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Fixed import date bug in %d posts in log %s", len(posts[mi+1:]), l.ID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *LogService) RefreshAllLogCharacters(ctx context.Context) error {
|
||||
start := time.Now()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user