1package db
2
3import (
4 "fmt"
5 "sort"
6 "time"
7)
8
9type ProfileTimelineEvent struct {
10 EventAt time.Time
11 Type string
12 *Issue
13 *Pull
14 *Repo
15
16 // optional: populate only if Repo is a fork
17 Source *Repo
18}
19
20func MakeProfileTimeline(e Execer, forDid string) ([]ProfileTimelineEvent, error) {
21 timeline := []ProfileTimelineEvent{}
22 limit := 30
23
24 pulls, err := GetPullsByOwnerDid(e, forDid)
25 if err != nil {
26 return timeline, fmt.Errorf("error getting pulls by owner did: %w", err)
27 }
28
29 for _, pull := range pulls {
30 repo, err := GetRepoByAtUri(e, string(pull.RepoAt))
31 if err != nil {
32 return timeline, fmt.Errorf("error getting repo by at uri: %w", err)
33 }
34
35 timeline = append(timeline, ProfileTimelineEvent{
36 EventAt: pull.Created,
37 Type: "pull",
38 Pull: &pull,
39 Repo: repo,
40 })
41 }
42
43 issues, err := GetIssuesByOwnerDid(e, forDid)
44 if err != nil {
45 return timeline, fmt.Errorf("error getting issues by owner did: %w", err)
46 }
47
48 for _, issue := range issues {
49 repo, err := GetRepoByAtUri(e, string(issue.RepoAt))
50 if err != nil {
51 return timeline, fmt.Errorf("error getting repo by at uri: %w", err)
52 }
53
54 timeline = append(timeline, ProfileTimelineEvent{
55 EventAt: *issue.Created,
56 Type: "issue",
57 Issue: &issue,
58 Repo: repo,
59 })
60 }
61
62 repos, err := GetAllReposByDid(e, forDid)
63 if err != nil {
64 return timeline, fmt.Errorf("error getting all repos by did: %w", err)
65 }
66
67 for _, repo := range repos {
68 var sourceRepo *Repo
69 if repo.Source != "" {
70 sourceRepo, err = GetRepoByAtUri(e, repo.Source)
71 if err != nil {
72 return nil, err
73 }
74 }
75
76 timeline = append(timeline, ProfileTimelineEvent{
77 EventAt: repo.Created,
78 Type: "repo",
79 Repo: &repo,
80 Source: sourceRepo,
81 })
82 }
83
84 sort.Slice(timeline, func(i, j int) bool {
85 return timeline[i].EventAt.After(timeline[j].EventAt)
86 })
87
88 if len(timeline) > limit {
89 timeline = timeline[:limit]
90 }
91
92 return timeline, nil
93}