forked from tangled.org/core
this repo has no description
at tracing 2.4 kB view raw
1package db 2 3import ( 4 "context" 5 "sort" 6 "time" 7 8 "go.opentelemetry.io/otel/attribute" 9 "go.opentelemetry.io/otel/trace" 10) 11 12type TimelineEvent struct { 13 *Repo 14 *Follow 15 *Star 16 17 EventAt time.Time 18 19 // optional: populate only if Repo is a fork 20 Source *Repo 21} 22 23// TODO: this gathers heterogenous events from different sources and aggregates 24// them in code; if we did this entirely in sql, we could order and limit and paginate easily 25func MakeTimeline(ctx context.Context, e Execer) ([]TimelineEvent, error) { 26 span := trace.SpanFromContext(ctx) 27 defer span.End() 28 29 var events []TimelineEvent 30 limit := 50 31 32 span.SetAttributes(attribute.Int("timeline.limit", limit)) 33 34 repos, err := GetAllRepos(ctx, e, limit) 35 if err != nil { 36 span.RecordError(err) 37 span.SetAttributes(attribute.String("error.from", "GetAllRepos")) 38 return nil, err 39 } 40 span.SetAttributes(attribute.Int("timeline.repos.count", len(repos))) 41 42 follows, err := GetAllFollows(e, limit) 43 if err != nil { 44 span.RecordError(err) 45 span.SetAttributes(attribute.String("error.from", "GetAllFollows")) 46 return nil, err 47 } 48 span.SetAttributes(attribute.Int("timeline.follows.count", len(follows))) 49 50 stars, err := GetAllStars(e, limit) 51 if err != nil { 52 span.RecordError(err) 53 span.SetAttributes(attribute.String("error.from", "GetAllStars")) 54 return nil, err 55 } 56 span.SetAttributes(attribute.Int("timeline.stars.count", len(stars))) 57 58 for _, repo := range repos { 59 var sourceRepo *Repo 60 if repo.Source != "" { 61 sourceRepo, err = GetRepoByAtUri(ctx, e, repo.Source) 62 if err != nil { 63 span.RecordError(err) 64 span.SetAttributes( 65 attribute.String("error.from", "GetRepoByAtUri"), 66 attribute.String("repo.source", repo.Source), 67 ) 68 return nil, err 69 } 70 } 71 72 events = append(events, TimelineEvent{ 73 Repo: &repo, 74 EventAt: repo.Created, 75 Source: sourceRepo, 76 }) 77 } 78 79 for _, follow := range follows { 80 events = append(events, TimelineEvent{ 81 Follow: &follow, 82 EventAt: follow.FollowedAt, 83 }) 84 } 85 86 for _, star := range stars { 87 events = append(events, TimelineEvent{ 88 Star: &star, 89 EventAt: star.Created, 90 }) 91 } 92 93 sort.Slice(events, func(i, j int) bool { 94 return events[i].EventAt.After(events[j].EventAt) 95 }) 96 97 // Limit the slice to 100 events 98 if len(events) > limit { 99 events = events[:limit] 100 } 101 102 span.SetAttributes(attribute.Int("timeline.events.total", len(events))) 103 104 return events, nil 105}