A vibe coded tangled fork which supports pijul.
1package models
2
3import (
4 "fmt"
5 "strings"
6 "time"
7
8 "github.com/bluesky-social/indigo/atproto/syntax"
9 securejoin "github.com/cyphar/filepath-securejoin"
10 "tangled.org/core/api/tangled"
11)
12
13type Repo struct {
14 Id int64
15 Did string
16 Name string
17 Knot string
18 Rkey string
19 Created time.Time
20 Description string
21 Website string
22 Topics []string
23 Spindle string
24 Labels []string
25 Vcs string // "git" or "pijul"
26
27 // optionally, populate this when querying for reverse mappings
28 RepoStats *RepoStats
29
30 // optional
31 Source string
32}
33
34func (r *Repo) IsGit() bool {
35 return r.Vcs == "" || r.Vcs == "git"
36}
37
38func (r *Repo) IsPijul() bool {
39 return r.Vcs == "pijul"
40}
41
42func (r *Repo) AsRecord() tangled.Repo {
43 var source, spindle, description, website *string
44
45 if r.Source != "" {
46 source = &r.Source
47 }
48
49 if r.Spindle != "" {
50 spindle = &r.Spindle
51 }
52
53 if r.Description != "" {
54 description = &r.Description
55 }
56
57 if r.Website != "" {
58 website = &r.Website
59 }
60
61 return tangled.Repo{
62 Knot: r.Knot,
63 Name: r.Name,
64 Description: description,
65 Website: website,
66 Topics: r.Topics,
67 CreatedAt: r.Created.Format(time.RFC3339),
68 Source: source,
69 Spindle: spindle,
70 Labels: r.Labels,
71 }
72}
73
74func (r Repo) RepoAt() syntax.ATURI {
75 return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", r.Did, tangled.RepoNSID, r.Rkey))
76}
77
78func (r Repo) DidSlashRepo() string {
79 p, _ := securejoin.SecureJoin(r.Did, r.Name)
80 return p
81}
82
83func (r Repo) TopicStr() string {
84 return strings.Join(r.Topics, " ")
85}
86
87type RepoStats struct {
88 Language string
89 StarCount int
90 IssueCount IssueCount
91 PullCount PullCount
92 DiscussionCount DiscussionCount
93}
94
95type IssueCount struct {
96 Open int
97 Closed int
98}
99
100type PullCount struct {
101 Open int
102 Merged int
103 Closed int
104 Deleted int
105}
106
107type RepoLabel struct {
108 Id int64
109 RepoAt syntax.ATURI
110 LabelAt syntax.ATURI
111}
112
113type RepoGroup struct {
114 Repo *Repo
115 Issues []Issue
116}
117
118type BlobContentType int
119
120const (
121 BlobContentTypeCode BlobContentType = iota
122 BlobContentTypeMarkup
123 BlobContentTypeImage
124 BlobContentTypeSvg
125 BlobContentTypeVideo
126 BlobContentTypeSubmodule
127)
128
129func (ty BlobContentType) IsCode() bool { return ty == BlobContentTypeCode }
130func (ty BlobContentType) IsMarkup() bool { return ty == BlobContentTypeMarkup }
131func (ty BlobContentType) IsImage() bool { return ty == BlobContentTypeImage }
132func (ty BlobContentType) IsSvg() bool { return ty == BlobContentTypeSvg }
133func (ty BlobContentType) IsVideo() bool { return ty == BlobContentTypeVideo }
134func (ty BlobContentType) IsSubmodule() bool { return ty == BlobContentTypeSubmodule }
135
136type BlobView struct {
137 HasTextView bool // can show as code/text
138 HasRenderedView bool // can show rendered (markup/image/video/submodule)
139 HasRawView bool // can download raw (everything except submodule)
140
141 // current display mode
142 ShowingRendered bool // currently in rendered mode
143
144 // content type flags
145 ContentType BlobContentType
146
147 // Content data
148 Contents string
149 ContentSrc string // URL for media files
150 Lines int
151 SizeHint uint64
152}
153
154// if both views are available, then show a toggle between them
155func (b BlobView) ShowToggle() bool {
156 return b.HasTextView && b.HasRenderedView
157}
158
159func (b BlobView) IsUnsupported() bool {
160 // no view available, only raw
161 return !(b.HasRenderedView || b.HasTextView)
162}
163
164func (b BlobView) ShowingText() bool {
165 return !b.ShowingRendered
166}