adds labels to accounts that have created records outside of Bluesky
22
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: simplify application management

+354 -126
+71
cmd/generate/main.go
··· 1 + package main 2 + 3 + import ( 4 + "encoding/json" 5 + "fmt" 6 + "log" 7 + "slices" 8 + 9 + "golang.org/x/text/collate" 10 + "golang.org/x/text/language" 11 + 12 + "github.com/edavis/recordcollector/pkg" 13 + ) 14 + 15 + type Locale struct { 16 + Lang string `json:"lang"` 17 + Name string `json:"name"` 18 + Description string `json:"description"` 19 + } 20 + 21 + type Definition struct { 22 + Blurs string `json:"blurs"` 23 + Severity string `json:"severity"` 24 + AdultOnly bool `json:"adultOnly"` 25 + Identifier string `json:"identifier"` 26 + DefaultSetting string `json:"defaultSetting"` 27 + Locales []Locale `json:"locales"` 28 + } 29 + 30 + type Document struct { 31 + Values []string `json:"labelValues"` 32 + Definitions []Definition `json:"labelValueDefinitions"` 33 + } 34 + 35 + func main() { 36 + var values []string 37 + var defs []Definition 38 + 39 + col := collate.New(language.English) 40 + slices.SortFunc(pkg.Applications, func(a, b pkg.Application) int { 41 + return col.CompareString(a.Name, b.Name) 42 + }) 43 + 44 + for _, app := range pkg.Applications { 45 + values = append(values, app.Label) 46 + defs = append(defs, Definition{ 47 + Blurs: "none", 48 + Severity: "inform", 49 + AdultOnly: false, 50 + Identifier: app.Label, 51 + DefaultSetting: "warn", 52 + Locales: []Locale{ 53 + { 54 + Lang: "en", 55 + Name: app.Name, 56 + Description: fmt.Sprintf("%s (%s.*)", app.Description, app.NSID), 57 + }, 58 + }, 59 + }) 60 + } 61 + 62 + doc := Document{ 63 + Values: values, 64 + Definitions: defs, 65 + } 66 + out, err := json.Marshal(doc) 67 + if err != nil { 68 + log.Fatalln("error creating JSON") 69 + } 70 + fmt.Println(string(out)) 71 + }
+8 -45
cmd/recordcollector/main.go
··· 20 20 "github.com/bluesky-social/jetstream/pkg/client" 21 21 "github.com/bluesky-social/jetstream/pkg/client/schedulers/sequential" 22 22 "github.com/bluesky-social/jetstream/pkg/models" 23 + "github.com/edavis/recordcollector/pkg" 23 24 _ "github.com/joho/godotenv/autoload" 24 25 _ "github.com/mattn/go-sqlite3" 25 26 ) ··· 33 34 "jp.5leaf", 34 35 } 35 36 36 - var labelPrefixes = map[string]string{ 37 - // nsid.prefix // Label from defs 38 - "social.popfeed": "social-popfeed", 39 - "blue.badge": "blue-badge", 40 - "blue.zio.atfile": "blue-zio-atfile", 41 - "space.roomy": "space-roomy", 42 - "com.shinolabs.pinksea": "com-shinolabs-pinksea", 43 - "com.whtwnd": "com-whtwnd", 44 - "events.smokesignal": "events-smokesignal", 45 - "fm.teal": "fm-teal", 46 - "fyi.unravel.frontpage": "fyi-unravel-frontpage", 47 - "im.flushing": "im-flushing", 48 - "place.stream": "place-stream", 49 - "sh.tangled": "sh-tangled", 50 - "so.sprk": "so-sprk", 51 - "xyz.statusphere": "xyz-statusphere", 52 - "blue.2048": "blue-twentyfortyeight", 53 - "exchange.recipe": "exchange-recipe", 54 - "blue.linkat": "blue-linkat", 55 - "app.rocksky": "app-rocksky", 56 - "pub.leaflet": "pub-leaflet", 57 - "com.wamellow": "com-wamellow", 58 - "social.grain": "social-grain", 59 - "net.anisota": "net-anisota", 60 - "buzz.bookhive": "buzz-bookhive", 61 - "link.woosh": "link-woosh", 62 - "st.snowpo": "st-snowpo", 63 - "my.skylights": "my-skylights", 64 - "io.zzstoatzz.status": "io-zzstoatzz-status", 65 - "app.yoten": "app-yoten", 66 - "blue.flashes": "blue-flashes", 67 - "place.atwork": "place-atwork", 68 - "at.monomarks": "at-monomarks", 69 - "net.wafrn": "net-wafrn", 70 - "community.nooki": "community-nooki", 71 - "org.xcvr": "org-xcvr", 72 - "app.lanyards": "app-lanyards", 73 - "stream.thought": "stream-thought", 74 - "fm.plyr": "fm-plyr", 75 - "app.sidetrail": "app-sidetrail", 76 - "app.dropanchor": "app-dropanchor", 77 - "com.atprotofans": "com-atprotofans", 78 - "network.cosmik": "network-cosmik", 79 - "site.standard": "site-standard", 80 - "app.blento": "app-blento", 37 + var labelPrefixes map[string]string 38 + 39 + func init() { 40 + labelPrefixes = make(map[string]string) 41 + for _, app := range pkg.Applications { 42 + labelPrefixes[app.NSID] = app.Label 43 + } 81 44 } 82 45 83 46 //go:embed schema.sql
-80
genlabeldefs.py
··· 1 - #!/usr/bin/env python3 2 - 3 - import json 4 - 5 - collections = { 6 - 'Popfeed': ('social-popfeed', 'pop culture hub'), 7 - 'PinkSea': ('com-shinolabs-pinksea', 'oekaki on atproto'), 8 - 'WhiteWind': ('com-whtwnd', 'markdown blog service'), 9 - 'Smoke Signal': ('events-smokesignal', 'manage events and RSVPs'), 10 - 'teal.fm': ('fm-teal', 'your music, beautifully tracked'), 11 - 'Frontpage': ('fyi-unravel-frontpage', 'a decentralised and federated link aggregator'), 12 - 'Flushes': ('im-flushing', 'The Decentralized Toilet Network of Planet Earth & Simulation 12B'), 13 - 'Streamplace': ('place-stream', 'live video on the AT Protocol'), 14 - 'Tangled': ('sh-tangled', 'tightly-knit social coding'), 15 - 'Spark': ('so-sprk', 'short-form video/photo app'), 16 - 'Statusphere': ('xyz-statusphere', 'atproto quick start'), 17 - 'Roomy': ('space-roomy', 'group chat on atproto'), 18 - 'ATFile': ('blue-zio-atfile', 'store and retrieve files'), 19 - 'Blue Badge': ('blue-badge', 'badges for atproto handles'), 20 - '2048': ('blue-twentyfortyeight', '2048 on atproto'), 21 - 'recipe.exchange': ('exchange-recipe', 'discover and share your favorite recipes'), 22 - 'Linkat': ('blue-linkat', 'link collections'), 23 - 'Rocksky': ('app-rocksky', 'decentralized music tracking and discovery platform'), 24 - 'Leaflet': ('pub-leaflet', 'social publishing / blogging'), 25 - 'Wamellow': ('com-wamellow', 'bluesky to discord notifications'), 26 - 'Grain': ('social-grain', 'a photo sharing platform'), 27 - 'Anisota': ('net-anisota', 'a new, experimental way to use social media'), 28 - 'BookHive': ('buzz-bookhive', 'manage, organize, and review your books anywhere'), 29 - 'Woosh': ('link-woosh', 'effortlessly share everything you create, curate, and sell'), 30 - 'Snowpost': ('st-snowpo', 'a simple, minimalist writing platform'), 31 - 'Skylights': ('my-skylights', 'a simple, minimalist writing platform'), 32 - 'Status': ('io-zzstoatzz-status', 'a personal status tracker built on at protocol'), 33 - 'Yōten': ('app-yoten', 'a social tracker for your language learning journey'), 34 - 'Flashes': ('blue-flashes', 'a photo viewing client for u'), 35 - 'at://work': ('place-atwork', 'Your Career. Your Data. Your Place.'), 36 - 'Monomarks': ('at-monomarks', 'a place for sharing and discovering interesting links'), 37 - 'Wafrn': ('net-wafrn', 'a federated social media inspired by Tumblr'), 38 - 'Nooki': ('community-nooki', 'a federated social media inspired by Tumblr'), 39 - 'xcvr': ('org-xcvr', 'hyper-real-time communication on atproto'), 40 - 'Lanyards': ('app-lanyards', 'one link to make your research life easier to share'), 41 - 'Thought Stream': ('stream-thought', 'an experimental real-time, global, multi-agent communication system with optional human participation'), 42 - 'plyr.fm': ('fm-plyr', 'music on atproto'), 43 - 'Sidetrail': ('app-sidetrail', 'a little app for sharing "trails"'), 44 - 'Anchor': ('app-dropanchor', 'an experiment in geolocation on the AT protocol'), 45 - 'ATProtoFans': ('com-atprotofans', 'Connecting Fans and Creators'), 46 - 'Semble': ('network-cosmik', 'A social knowledge tool for researchers built on ATProto'), 47 - 'standard.site': ('site-standard', 'Open standards for long-form & site lexicons'), 48 - 'blento': ('app-blento', 'your home on the internet, create your own personal page'), 49 - # 'name': ('nsid-with-dashes', 'description'), 50 - } 51 - 52 - values = [] 53 - defs = [] 54 - 55 - key_func = lambda obj: str.casefold(obj[0]) 56 - for name, (identifier, description) in sorted(collections.items(), key=key_func): 57 - nsid = identifier.replace('-', '.') 58 - if identifier == 'blue-twentyfortyeight': 59 - # https://atproto.com/specs/label#recommended-string-syntax 60 - nsid = 'blue.2048' 61 - values.append(identifier) 62 - defs.append(dict( 63 - blurs = 'none', 64 - severity = 'inform', 65 - adultOnly = False, 66 - identifier = identifier, 67 - defaultSetting = 'warn', 68 - locales = [dict( 69 - lang = 'en', 70 - name = name, 71 - description = f'{description} ({nsid}.*)', 72 - )], 73 - )) 74 - 75 - doc = { 76 - 'labelValues': values, 77 - 'labelValueDefinitions': defs, 78 - } 79 - 80 - print(json.dumps(doc))
+4 -1
go.mod
··· 1 1 module github.com/edavis/recordcollector 2 2 3 - go 1.23.6 3 + go 1.24.0 4 + 5 + toolchain go1.24.12 4 6 5 7 require ( 6 8 github.com/bluesky-social/indigo v0.0.0-20250320052052-4873aceeabf4 7 9 github.com/bluesky-social/jetstream v0.0.0-20241210005130-ea96859b93d1 8 10 github.com/joho/godotenv v1.5.1 9 11 github.com/mattn/go-sqlite3 v1.14.22 12 + golang.org/x/text v0.33.0 10 13 ) 11 14 12 15 require (
+2
go.sum
··· 211 211 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 212 212 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 213 213 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 214 + golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= 215 + golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= 214 216 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 215 217 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 216 218 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+269
pkg/apps.go
··· 1 + package pkg 2 + 3 + type Application struct { 4 + Name string 5 + Description string 6 + NSID string 7 + Label string 8 + } 9 + 10 + var Applications = []Application{ 11 + { 12 + Name: "Popfeed", 13 + Description: "pop culture hub", 14 + NSID: "social.popfeed", 15 + Label: "social-popfeed", 16 + }, 17 + { 18 + Name: "PinkSea", 19 + Description: "oekaki on atproto", 20 + NSID: "com.shinolabs.pinksea", 21 + Label: "com-shinolabs-pinksea", 22 + }, 23 + { 24 + Name: "WhiteWind", 25 + Description: "markdown blog service", 26 + NSID: "com.whtwnd", 27 + Label: "com-whtwnd", 28 + }, 29 + { 30 + Name: "Smoke Signal", 31 + Description: "manage events and RSVPs", 32 + NSID: "events.smokesignal", 33 + Label: "events-smokesignal", 34 + }, 35 + { 36 + Name: "teal.fm", 37 + Description: "your music, beautifully tracked", 38 + NSID: "fm.teal", 39 + Label: "fm-teal", 40 + }, 41 + { 42 + Name: "Frontpage", 43 + Description: "a decentralised and federated link aggregator", 44 + NSID: "fyi.unravel.frontpage", 45 + Label: "fyi-unravel-frontpage", 46 + }, 47 + { 48 + Name: "Flushes", 49 + Description: "The Decentralized Toilet Network of Planet Earth & Simulation 12B", 50 + NSID: "im.flushing", 51 + Label: "im-flushing", 52 + }, 53 + { 54 + Name: "Streamplace", 55 + Description: "live video on the AT Protocol", 56 + NSID: "place.stream", 57 + Label: "place-stream", 58 + }, 59 + { 60 + Name: "Tangled", 61 + Description: "tightly-knit social coding", 62 + NSID: "sh.tangled", 63 + Label: "sh-tangled", 64 + }, 65 + { 66 + Name: "Spark", 67 + Description: "short-form video/photo app", 68 + NSID: "so.sprk", 69 + Label: "so-sprk", 70 + }, 71 + { 72 + Name: "Statusphere", 73 + Description: "atproto quick start", 74 + NSID: "xyz.statusphere", 75 + Label: "xyz-statusphere", 76 + }, 77 + { 78 + Name: "Roomy", 79 + Description: "group chat on atproto", 80 + NSID: "space.roomy", 81 + Label: "space-roomy", 82 + }, 83 + { 84 + Name: "ATFile", 85 + Description: "store and retrieve files", 86 + NSID: "blue.zio.atfile", 87 + Label: "blue-zio-atfile", 88 + }, 89 + { 90 + Name: "Blue Badge", 91 + Description: "badges for atproto handles", 92 + NSID: "blue.badge", 93 + Label: "blue-badge", 94 + }, 95 + { 96 + Name: "2048", 97 + Description: "2048 on atproto", 98 + NSID: "blue.2048", 99 + Label: "blue-twentyfortyeight", 100 + }, 101 + { 102 + Name: "recipe.exchange", 103 + Description: "discover and share your favorite recipes", 104 + NSID: "exchange.recipe", 105 + Label: "exchange-recipe", 106 + }, 107 + { 108 + Name: "Linkat", 109 + Description: "link collections", 110 + NSID: "blue.linkat", 111 + Label: "blue-linkat", 112 + }, 113 + { 114 + Name: "Rocksky", 115 + Description: "decentralized music tracking and discovery platform", 116 + NSID: "app.rocksky", 117 + Label: "app-rocksky", 118 + }, 119 + { 120 + Name: "Leaflet", 121 + Description: "social publishing / blogging", 122 + NSID: "pub.leaflet", 123 + Label: "pub-leaflet", 124 + }, 125 + { 126 + Name: "Wamellow", 127 + Description: "bluesky to discord notifications", 128 + NSID: "com.wamellow", 129 + Label: "com-wamellow", 130 + }, 131 + { 132 + Name: "Grain", 133 + Description: "a photo sharing platform", 134 + NSID: "social.grain", 135 + Label: "social-grain", 136 + }, 137 + { 138 + Name: "Anisota", 139 + Description: "a new, experimental way to use social media", 140 + NSID: "net.anisota", 141 + Label: "net-anisota", 142 + }, 143 + { 144 + Name: "BookHive", 145 + Description: "manage, organize, and review your books anywhere", 146 + NSID: "buzz.bookhive", 147 + Label: "buzz-bookhive", 148 + }, 149 + { 150 + Name: "Woosh", 151 + Description: "effortlessly share everything you create, curate, and sell", 152 + NSID: "link.woosh", 153 + Label: "link-woosh", 154 + }, 155 + { 156 + Name: "Snowpost", 157 + Description: "a simple, minimalist writing platform", 158 + NSID: "st.snowpo", 159 + Label: "st-snowpo", 160 + }, 161 + { 162 + Name: "Skylights", 163 + Description: "a simple, minimalist writing platform", 164 + NSID: "my.skylights", 165 + Label: "my-skylights", 166 + }, 167 + { 168 + Name: "Status", 169 + Description: "a personal status tracker built on at protocol", 170 + NSID: "io.zzstoatzz.status", 171 + Label: "io-zzstoatzz-status", 172 + }, 173 + { 174 + Name: "Yōten", 175 + Description: "a social tracker for your language learning journey", 176 + NSID: "app.yoten", 177 + Label: "app-yoten", 178 + }, 179 + { 180 + Name: "Flashes", 181 + Description: "a photo viewing client for u", 182 + NSID: "blue.flashes", 183 + Label: "blue-flashes", 184 + }, 185 + { 186 + Name: "at://work", 187 + Description: "Your Career. Your Data. Your Place.", 188 + NSID: "place.atwork", 189 + Label: "place-atwork", 190 + }, 191 + { 192 + Name: "Monomarks", 193 + Description: "a place for sharing and discovering interesting links", 194 + NSID: "at.monomarks", 195 + Label: "at-monomarks", 196 + }, 197 + { 198 + Name: "Wafrn", 199 + Description: "a federated social media inspired by Tumblr", 200 + NSID: "net.wafrn", 201 + Label: "net-wafrn", 202 + }, 203 + { 204 + Name: "Nooki", 205 + Description: "a federated social media inspired by Tumblr", 206 + NSID: "community.nooki", 207 + Label: "community-nooki", 208 + }, 209 + { 210 + Name: "xcvr", 211 + Description: "hyper-real-time communication on atproto", 212 + NSID: "org.xcvr", 213 + Label: "org-xcvr", 214 + }, 215 + { 216 + Name: "Lanyards", 217 + Description: "one link to make your research life easier to share", 218 + NSID: "app.lanyards", 219 + Label: "app-lanyards", 220 + }, 221 + { 222 + Name: "Thought Stream", 223 + Description: "an experimental real-time, global, multi-agent communication system with optional human participation", 224 + NSID: "stream.thought", 225 + Label: "stream-thought", 226 + }, 227 + { 228 + Name: "plyr.fm", 229 + Description: "music on atproto", 230 + NSID: "fm.plyr", 231 + Label: "fm-plyr", 232 + }, 233 + { 234 + Name: "Sidetrail", 235 + Description: "a little app for sharing \"trails\"", 236 + NSID: "app.sidetrail", 237 + Label: "app-sidetrail", 238 + }, 239 + { 240 + Name: "Anchor", 241 + Description: "an experiment in geolocation on the AT protocol", 242 + NSID: "app.dropanchor", 243 + Label: "app-dropanchor", 244 + }, 245 + { 246 + Name: "ATProtoFans", 247 + Description: "Connecting Fans and Creators", 248 + NSID: "com.atprotofans", 249 + Label: "com-atprotofans", 250 + }, 251 + { 252 + Name: "Semble", 253 + Description: "A social knowledge tool for researchers built on ATProto", 254 + NSID: "network.cosmik", 255 + Label: "network-cosmik", 256 + }, 257 + { 258 + Name: "standard.site", 259 + Description: "Open standards for long-form & site lexicons", 260 + NSID: "site.standard", 261 + Label: "site-standard", 262 + }, 263 + { 264 + Name: "blento", 265 + Description: "your home on the internet, create your own personal page", 266 + NSID: "app.blento", 267 + Label: "app-blento", 268 + }, 269 + }