Commit eb3b3bb

Eric Bower  ·  2026-01-25 09:55:59 -0500 EST
parent bccde8d
refactor: fix issues with imports and create shared/router pkg
55 files changed,  +479, -482
+3, -5
......@@ -13,14 +13,12 @@ import (
1313 "github.com/darkweak/souin/pkg/middleware"
1414 "github.com/hashicorp/golang-lru/v2/expirable"
1515 "github.com/picosh/pico/pkg/apps/pgs"
16- "github.com/picosh/pico/pkg/cache"
1716 "github.com/picosh/pico/pkg/shared"
18- "github.com/picosh/utils"
1917 "github.com/prometheus/client_golang/prometheus/promhttp"
2018 )
2119
2220 func main() {
23- withPipe := strings.ToLower(utils.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
21+ withPipe := strings.ToLower(shared.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
2422 logger := shared.CreateLogger("pgs-cdn", withPipe)
2523 ctx := context.Background()
2624 drain := pgs.CreateSubCacheDrain(ctx, logger)
......@@ -32,8 +30,8 @@ func main() {
3230 httpCache := pgs.SetupCache(cfg)
3331 router := &pgs.WebRouter{
3432 Cfg: cfg,
35- RedirectsCache: expirable.NewLRU[string, []*pgs.RedirectRule](2048, nil, cache.CacheTimeout),
36- HeadersCache: expirable.NewLRU[string, []*pgs.HeaderRule](2048, nil, cache.CacheTimeout),
33+ RedirectsCache: expirable.NewLRU[string, []*pgs.RedirectRule](2048, nil, shared.CacheTimeout),
34+ HeadersCache: expirable.NewLRU[string, []*pgs.HeaderRule](2048, nil, shared.CacheTimeout),
3735 }
3836 cacher := &cachedHttp{
3937 handler: httpCache,
+2, -3
......@@ -8,12 +8,11 @@ import (
88 pgsdb "github.com/picosh/pico/pkg/apps/pgs/db"
99 "github.com/picosh/pico/pkg/shared"
1010 "github.com/picosh/pico/pkg/shared/storage"
11- "github.com/picosh/utils"
1211 "golang.org/x/crypto/ssh"
1312 )
1413
1514 func main() {
16- dbURL := utils.GetEnv("DATABASE_URL", "./data/pgs.sqlite3")
15+ dbURL := shared.GetEnv("DATABASE_URL", "./data/pgs.sqlite3")
1716 logger := shared.CreateLogger("pgs-standalone", false)
1817 dbpool, err := pgsdb.NewSqliteDB(dbURL, logger)
1918 if err != nil {
......@@ -45,7 +44,7 @@ func main() {
4544 logger.Error("parse pubkey", "err", err)
4645 return
4746 }
48- pubkey := utils.KeyForKeyText(key)
47+ pubkey := shared.KeyForKeyText(key)
4948 logger.Info("init cli", "userName", userName, "pubkey", pubkey)
5049
5150 err = dbpool.RegisterAdmin(userName, pubkey, comment)
+2, -2
......@@ -6,7 +6,7 @@ import (
66
77 "github.com/picosh/pico/pkg/db"
88 "github.com/picosh/pico/pkg/db/postgres"
9- "github.com/picosh/utils"
9+ "github.com/picosh/pico/pkg/shared"
1010 )
1111
1212 func main() {
......@@ -19,7 +19,7 @@ func main() {
1919
2020 stats, err := dbpool.VisitSummary(
2121 &db.SummaryOpts{
22- Origin: utils.StartOfMonth(),
22+ Origin: shared.StartOfMonth(),
2323 Host: host,
2424 },
2525 )
+3, -3
......@@ -6,7 +6,7 @@ import (
66 "os"
77
88 "github.com/picosh/pico/pkg/db/postgres"
9- "github.com/picosh/pico/pkg/shared"
9+ "github.com/picosh/pico/pkg/shared/router"
1010 )
1111
1212 func main() {
......@@ -47,7 +47,7 @@ func main() {
4747
4848 update := false
4949
50- host, err := shared.CleanHost(origHost)
50+ host, err := router.CleanHost(origHost)
5151 if err != nil {
5252 fmt.Println(err)
5353 }
......@@ -60,7 +60,7 @@ func main() {
6060 )
6161 }
6262
63- ref, err := shared.CleanReferer(origRef)
63+ ref, err := router.CleanReferer(origRef)
6464 if err != nil {
6565 fmt.Println(err)
6666 }
+1, -2
......@@ -6,7 +6,6 @@ import (
66
77 "github.com/picosh/pico/pkg/db/postgres"
88 "github.com/picosh/pico/pkg/shared"
9- "github.com/picosh/utils"
109 )
1110
1211 func main() {
......@@ -25,7 +24,7 @@ func main() {
2524 empty := 0
2625 diff := 0
2726 for _, post := range posts {
28- nextShasum := utils.Shasum([]byte(post.Text))
27+ nextShasum := shared.Shasum([]byte(post.Text))
2928 if post.Shasum == "" {
3029 empty += 1
3130 } else if post.Shasum != nextShasum {
+28, -28
......@@ -19,7 +19,7 @@ import (
1919 "github.com/picosh/pico/pkg/db"
2020 "github.com/picosh/pico/pkg/db/postgres"
2121 "github.com/picosh/pico/pkg/shared"
22- "github.com/picosh/utils"
22+ "github.com/picosh/pico/pkg/shared/router"
2323 "github.com/picosh/utils/pipe"
2424 "github.com/picosh/utils/pipe/metrics"
2525 "github.com/prometheus/client_golang/prometheus/promhttp"
......@@ -48,7 +48,7 @@ func generateURL(cfg *shared.ConfigSite, path string, space string) string {
4848 return fmt.Sprintf("%s/%s%s", cfg.Domain, path, query)
4949 }
5050
51-func wellKnownHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
51+func wellKnownHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
5252 return func(w http.ResponseWriter, r *http.Request) {
5353 space := r.PathValue("space")
5454 if space == "" {
......@@ -80,7 +80,7 @@ type oauth2Introspection struct {
8080 Username string `json:"username"`
8181 }
8282
83-func introspectHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
83+func introspectHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
8484 return func(w http.ResponseWriter, r *http.Request) {
8585 token := r.FormValue("token")
8686 apiConfig.Cfg.Logger.Info("introspect token", "token", token)
......@@ -114,7 +114,7 @@ func introspectHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
114114 }
115115 }
116116
117-func authorizeHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
117+func authorizeHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
118118 return func(w http.ResponseWriter, r *http.Request) {
119119 responseType := r.URL.Query().Get("response_type")
120120 clientID := r.URL.Query().Get("client_id")
......@@ -158,7 +158,7 @@ func authorizeHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
158158 }
159159 }
160160
161-func redirectHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
161+func redirectHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
162162 return func(w http.ResponseWriter, r *http.Request) {
163163 token := r.FormValue("token")
164164 redirectURI := r.FormValue("redirect_uri")
......@@ -194,7 +194,7 @@ type oauth2Token struct {
194194 AccessToken string `json:"access_token"`
195195 }
196196
197-func tokenHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
197+func tokenHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
198198 return func(w http.ResponseWriter, r *http.Request) {
199199 token := r.FormValue("code")
200200 redirectURI := r.FormValue("redirect_uri")
......@@ -233,7 +233,7 @@ type sishData struct {
233233 RemoteAddress string `json:"remote_addr"`
234234 }
235235
236-func keyHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
236+func keyHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
237237 return func(w http.ResponseWriter, r *http.Request) {
238238 var data sishData
239239
......@@ -292,7 +292,7 @@ func keyHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
292292 log.Error("cannot insert access log", "err", err)
293293 }
294294
295- if !apiConfig.HasPrivilegedAccess(shared.GetApiToken(r)) {
295+ if !apiConfig.HasPrivilegedAccess(router.GetApiToken(r)) {
296296 w.WriteHeader(http.StatusOK)
297297 return
298298 }
......@@ -307,9 +307,9 @@ func keyHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
307307 }
308308 }
309309
310-func userHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
310+func userHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
311311 return func(w http.ResponseWriter, r *http.Request) {
312- if !apiConfig.HasPrivilegedAccess(shared.GetApiToken(r)) {
312+ if !apiConfig.HasPrivilegedAccess(router.GetApiToken(r)) {
313313 w.WriteHeader(http.StatusForbidden)
314314 return
315315 }
......@@ -354,7 +354,7 @@ func userHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
354354 }
355355 }
356356
357-func rssHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
357+func rssHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
358358 return func(w http.ResponseWriter, r *http.Request) {
359359 apiToken := r.PathValue("token")
360360 user, err := apiConfig.Dbpool.FindUserByToken(apiToken)
......@@ -387,7 +387,7 @@ func rssHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
387387 }
388388 }
389389
390-func pubkeysHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
390+func pubkeysHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
391391 return func(w http.ResponseWriter, r *http.Request) {
392392 userName := r.PathValue("user")
393393 user, err := apiConfig.Dbpool.FindUserByName(userName)
......@@ -456,7 +456,7 @@ type OrderEvent struct {
456456
457457 // Status code must be 200 or else lemonsqueezy will keep retrying
458458 // https://docs.lemonsqueezy.com/help/webhooks
459-func paymentWebhookHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
459+func paymentWebhookHandler(apiConfig *router.ApiConfig) http.HandlerFunc {
460460 return func(w http.ResponseWriter, r *http.Request) {
461461 dbpool := apiConfig.Dbpool
462462 logger := apiConfig.Cfg.Logger
......@@ -482,7 +482,7 @@ func paymentWebhookHandler(apiConfig *shared.ApiConfig) http.HandlerFunc {
482482 return
483483 }
484484
485- hash := shared.HmacString(apiConfig.Cfg.SecretWebhook, string(payload))
485+ hash := router.HmacString(apiConfig.Cfg.SecretWebhook, string(payload))
486486 sig := r.Header.Get("X-Signature")
487487 if !hmac.Equal([]byte(hash), []byte(sig)) {
488488 logger.Error("invalid signature X-Signature")
......@@ -678,14 +678,14 @@ func deserializeCaddyAccessLog(dbpool db.DB, access *AccessLog) (*db.AnalyticsVi
678678 } else if strings.HasSuffix(host, "prose.sh") {
679679 subdomain = strings.TrimSuffix(host, ".prose.sh")
680680 } else {
681- subdomain = shared.GetCustomDomain(host, space)
681+ subdomain = router.GetCustomDomain(host, space)
682682 }
683683
684684 subdomain = strings.TrimSuffix(subdomain, ".nue")
685685 subdomain = strings.TrimSuffix(subdomain, ".ash")
686686
687687 // get user and namespace details from subdomain
688- props, err := shared.GetProjectFromSubdomain(subdomain)
688+ props, err := router.GetProjectFromSubdomain(subdomain)
689689 if err != nil {
690690 return nil, fmt.Errorf("could not get project from subdomain %s: %w", subdomain, err)
691691 }
......@@ -772,7 +772,7 @@ func metricDrainSub(ctx context.Context, dbpool db.DB, logger *slog.Logger, secr
772772 }
773773
774774 logger.Info("received visit", "visit", visit)
775- err = shared.AnalyticsVisitFromVisit(visit, dbpool, secret)
775+ err = router.AnalyticsVisitFromVisit(visit, dbpool, secret)
776776 if err != nil {
777777 logger.Info("could not record analytics visit", "err", err)
778778 continue
......@@ -834,7 +834,7 @@ func tunsEventLogDrainSub(ctx context.Context, dbpool db.DB, logger *slog.Logger
834834 }
835835 }
836836
837-func authMux(apiConfig *shared.ApiConfig) *http.ServeMux {
837+func authMux(apiConfig *router.ApiConfig) *http.ServeMux {
838838 serverRoot, err := fs.Sub(embedFS, "public")
839839 if err != nil {
840840 panic(err)
......@@ -866,24 +866,24 @@ func authMux(apiConfig *shared.ApiConfig) *http.ServeMux {
866866 mux.HandleFunc("GET /_metrics", promhttp.Handler().ServeHTTP)
867867
868868 if apiConfig.Cfg.Debug {
869- shared.CreatePProfRoutesMux(mux)
869+ router.CreatePProfRoutesMux(mux)
870870 }
871871
872872 return mux
873873 }
874874
875875 func StartApiServer() {
876- debug := utils.GetEnv("AUTH_DEBUG", "0")
877- withPipe := strings.ToLower(utils.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
876+ debug := shared.GetEnv("AUTH_DEBUG", "0")
877+ withPipe := strings.ToLower(shared.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
878878
879879 cfg := &shared.ConfigSite{
880- DbURL: utils.GetEnv("DATABASE_URL", ""),
880+ DbURL: shared.GetEnv("DATABASE_URL", ""),
881881 Debug: debug == "1",
882- Issuer: utils.GetEnv("AUTH_ISSUER", "pico.sh"),
883- Domain: utils.GetEnv("AUTH_DOMAIN", "http://0.0.0.0:3000"),
884- Port: utils.GetEnv("AUTH_WEB_PORT", "3000"),
885- Secret: utils.GetEnv("PICO_SECRET", ""),
886- SecretWebhook: utils.GetEnv("PICO_SECRET_WEBHOOK", ""),
882+ Issuer: shared.GetEnv("AUTH_ISSUER", "pico.sh"),
883+ Domain: shared.GetEnv("AUTH_DOMAIN", "http://0.0.0.0:3000"),
884+ Port: shared.GetEnv("AUTH_WEB_PORT", "3000"),
885+ Secret: shared.GetEnv("PICO_SECRET", ""),
886+ SecretWebhook: shared.GetEnv("PICO_SECRET_WEBHOOK", ""),
887887 }
888888
889889 if cfg.SecretWebhook == "" {
......@@ -911,7 +911,7 @@ func StartApiServer() {
911911 // gather connect/disconnect logs from tuns
912912 go tunsEventLogDrainSub(ctx, db, logger, cfg.Secret)
913913
914- apiConfig := &shared.ApiConfig{
914+ apiConfig := &router.ApiConfig{
915915 Cfg: cfg,
916916 Dbpool: db,
917917 }
+4, -3
......@@ -15,6 +15,7 @@ import (
1515 "github.com/picosh/pico/pkg/db"
1616 "github.com/picosh/pico/pkg/db/stub"
1717 "github.com/picosh/pico/pkg/shared"
18+ "github.com/picosh/pico/pkg/shared/router"
1819 )
1920
2021 var testUserID = "user-1"
......@@ -41,7 +42,7 @@ func TestPaymentWebhook(t *testing.T) {
4142 }
4243 jso, err := json.Marshal(event)
4344 bail(err)
44- hash := shared.HmacString(apiConfig.Cfg.SecretWebhook, string(jso))
45+ hash := router.HmacString(apiConfig.Cfg.SecretWebhook, string(jso))
4546 body := bytes.NewReader(jso)
4647
4748 request := httptest.NewRequest("POST", mkpath("/webhook"), body)
......@@ -275,7 +276,7 @@ func mkpath(path string) string {
275276 return fmt.Sprintf("https://auth.pico.test%s", path)
276277 }
277278
278-func setupTest() *shared.ApiConfig {
279+func setupTest() *router.ApiConfig {
279280 logger := shared.CreateLogger("auth-test", false)
280281 cfg := &shared.ConfigSite{
281282 Issuer: "auth.pico.test",
......@@ -286,7 +287,7 @@ func setupTest() *shared.ApiConfig {
286287 }
287288 cfg.Logger = logger
288289 db := NewAuthDb(cfg.Logger)
289- apiConfig := &shared.ApiConfig{
290+ apiConfig := &router.ApiConfig{
290291 Cfg: cfg,
291292 Dbpool: db,
292293 }
+25, -24
......@@ -8,13 +8,14 @@ import (
88
99 "github.com/picosh/pico/pkg/db/postgres"
1010 "github.com/picosh/pico/pkg/shared"
11+ "github.com/picosh/pico/pkg/shared/router"
1112 "github.com/prometheus/client_golang/prometheus/promhttp"
1213 )
1314
1415 func keepAliveHandler(w http.ResponseWriter, r *http.Request) {
15- dbpool := shared.GetDB(r)
16- logger := shared.GetLogger(r)
17- postID, _ := url.PathUnescape(shared.GetField(r, 0))
16+ dbpool := router.GetDB(r)
17+ logger := router.GetLogger(r)
18+ postID, _ := url.PathUnescape(router.GetField(r, 0))
1819
1920 post, err := dbpool.FindPost(postID)
2021 if err != nil {
......@@ -60,9 +61,9 @@ func keepAliveHandler(w http.ResponseWriter, r *http.Request) {
6061 }
6162
6263 func unsubHandler(w http.ResponseWriter, r *http.Request) {
63- dbpool := shared.GetDB(r)
64- logger := shared.GetLogger(r)
65- postID, _ := url.PathUnescape(shared.GetField(r, 0))
64+ dbpool := router.GetDB(r)
65+ logger := router.GetLogger(r)
66+ postID, _ := url.PathUnescape(router.GetField(r, 0))
6667
6768 post, err := dbpool.FindPost(postID)
6869 if err != nil {
......@@ -96,12 +97,12 @@ func unsubHandler(w http.ResponseWriter, r *http.Request) {
9697 }
9798 }
9899
99-func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
100- routes := []shared.Route{
101- shared.NewRoute("GET", "/", shared.CreatePageHandler("html/marketing.page.tmpl")),
102- shared.NewRoute("GET", "/keep-alive/(.+)", keepAliveHandler),
103- shared.NewRoute("GET", "/unsub/(.+)", unsubHandler),
104- shared.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
100+func createMainRoutes(staticRoutes []router.Route) []router.Route {
101+ routes := []router.Route{
102+ router.NewRoute("GET", "/", router.CreatePageHandler("html/marketing.page.tmpl")),
103+ router.NewRoute("GET", "/keep-alive/(.+)", keepAliveHandler),
104+ router.NewRoute("GET", "/unsub/(.+)", unsubHandler),
105+ router.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
105106 }
106107
107108 routes = append(
......@@ -112,15 +113,15 @@ func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
112113 return routes
113114 }
114115
115-func createStaticRoutes() []shared.Route {
116- return []shared.Route{
117- shared.NewRoute("GET", "/main.css", shared.ServeFile("main.css", "text/css")),
118- shared.NewRoute("GET", "/card.png", shared.ServeFile("card.png", "image/png")),
119- shared.NewRoute("GET", "/favicon-16x16.png", shared.ServeFile("favicon-16x16.png", "image/png")),
120- shared.NewRoute("GET", "/favicon-32x32.png", shared.ServeFile("favicon-32x32.png", "image/png")),
121- shared.NewRoute("GET", "/apple-touch-icon.png", shared.ServeFile("apple-touch-icon.png", "image/png")),
122- shared.NewRoute("GET", "/favicon.ico", shared.ServeFile("favicon.ico", "image/x-icon")),
123- shared.NewRoute("GET", "/robots.txt", shared.ServeFile("robots.txt", "text/plain")),
116+func createStaticRoutes() []router.Route {
117+ return []router.Route{
118+ router.NewRoute("GET", "/main.css", router.ServeFile("main.css", "text/css")),
119+ router.NewRoute("GET", "/card.png", router.ServeFile("card.png", "image/png")),
120+ router.NewRoute("GET", "/favicon-16x16.png", router.ServeFile("favicon-16x16.png", "image/png")),
121+ router.NewRoute("GET", "/favicon-32x32.png", router.ServeFile("favicon-32x32.png", "image/png")),
122+ router.NewRoute("GET", "/apple-touch-icon.png", router.ServeFile("apple-touch-icon.png", "image/png")),
123+ router.NewRoute("GET", "/favicon.ico", router.ServeFile("favicon.ico", "image/x-icon")),
124+ router.NewRoute("GET", "/robots.txt", router.ServeFile("robots.txt", "text/plain")),
124125 }
125126 }
126127
......@@ -139,16 +140,16 @@ func StartApiServer() {
139140 staticRoutes := createStaticRoutes()
140141
141142 if cfg.Debug {
142- staticRoutes = shared.CreatePProfRoutes(staticRoutes)
143+ staticRoutes = router.CreatePProfRoutes(staticRoutes)
143144 }
144145
145146 mainRoutes := createMainRoutes(staticRoutes)
146147
147- apiConfig := &shared.ApiConfig{
148+ apiConfig := &router.ApiConfig{
148149 Cfg: cfg,
149150 Dbpool: db,
150151 }
151- handler := shared.CreateServe(mainRoutes, []shared.Route{}, apiConfig)
152+ handler := router.CreateServe(mainRoutes, []router.Route{}, apiConfig)
152153 router := http.HandlerFunc(handler)
153154
154155 portStr := fmt.Sprintf(":%s", cfg.Port)
+7, -8
......@@ -4,17 +4,16 @@ import (
44 "strings"
55
66 "github.com/picosh/pico/pkg/shared"
7- "github.com/picosh/utils"
87 )
98
109 func NewConfigSite(service string) *shared.ConfigSite {
11- debug := utils.GetEnv("FEEDS_DEBUG", "0")
12- domain := utils.GetEnv("FEEDS_DOMAIN", "feeds.pico.sh")
13- port := utils.GetEnv("FEEDS_WEB_PORT", "3000")
14- protocol := utils.GetEnv("FEEDS_PROTOCOL", "https")
15- dbURL := utils.GetEnv("DATABASE_URL", "")
16- sendgridKey := utils.GetEnv("SENDGRID_API_KEY", "")
17- withPipe := strings.ToLower(utils.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
10+ debug := shared.GetEnv("FEEDS_DEBUG", "0")
11+ domain := shared.GetEnv("FEEDS_DOMAIN", "feeds.pico.sh")
12+ port := shared.GetEnv("FEEDS_WEB_PORT", "3000")
13+ protocol := shared.GetEnv("FEEDS_PROTOCOL", "https")
14+ dbURL := shared.GetEnv("DATABASE_URL", "")
15+ sendgridKey := shared.GetEnv("SENDGRID_API_KEY", "")
16+ withPipe := strings.ToLower(shared.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
1817
1918 return &shared.ConfigSite{
2019 Debug: debug == "1",
+1, -2
......@@ -21,7 +21,6 @@ import (
2121 "github.com/mmcdole/gofeed"
2222 "github.com/picosh/pico/pkg/db"
2323 "github.com/picosh/pico/pkg/shared"
24- "github.com/picosh/utils"
2524 )
2625
2726 var ErrNoRecentArticles = errors.New("no recent articles")
......@@ -564,7 +563,7 @@ func (f *Fetcher) FetchAll(logger *slog.Logger, urls []string, inlineContent boo
564563 }
565564
566565 // cap body size to prevent abuse
567- if len(html)+len(text) > 5*utils.MB {
566+ if len(html)+len(text) > 5*shared.MB {
568567 feeds.Options.InlineContent = false
569568 feeds.SizeWarning = true
570569 html, err = f.PrintHtml(feeds)
+2, -3
......@@ -11,7 +11,6 @@ import (
1111 "github.com/picosh/pico/pkg/filehandlers"
1212 "github.com/picosh/pico/pkg/pssh"
1313 "github.com/picosh/pico/pkg/shared"
14- "github.com/picosh/utils"
1514 )
1615
1716 type FeedHooks struct {
......@@ -20,7 +19,7 @@ type FeedHooks struct {
2019 }
2120
2221 func (p *FeedHooks) FileValidate(s *pssh.SSHServerConnSession, data *filehandlers.PostMetaData) (bool, error) {
23- if !utils.IsTextFile(string(data.Text)) {
22+ if !shared.IsTextFile(string(data.Text)) {
2423 err := fmt.Errorf(
2524 "WARNING: (%s) invalid file must be plain text (utf-8), skipping",
2625 data.Filename,
......@@ -28,7 +27,7 @@ func (p *FeedHooks) FileValidate(s *pssh.SSHServerConnSession, data *filehandler
2827 return false, err
2928 }
3029
31- if !utils.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) {
30+ if !shared.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) {
3231 extStr := strings.Join(p.Cfg.AllowedExt, ",")
3332 err := fmt.Errorf(
3433 "WARNING: (%s) invalid file, format must be (%s), skipping",
+3, -4
......@@ -16,15 +16,14 @@ import (
1616 "github.com/picosh/pico/pkg/send/protocols/scp"
1717 "github.com/picosh/pico/pkg/send/protocols/sftp"
1818 "github.com/picosh/pico/pkg/shared"
19- "github.com/picosh/utils"
2019 )
2120
2221 func StartSshServer() {
2322 appName := "feeds-ssh"
2423
25- host := utils.GetEnv("FEEDS_HOST", "0.0.0.0")
26- port := utils.GetEnv("FEEDS_SSH_PORT", "2222")
27- promPort := utils.GetEnv("FEEDS_PROM_PORT", "9222")
24+ host := shared.GetEnv("FEEDS_HOST", "0.0.0.0")
25+ port := shared.GetEnv("FEEDS_SSH_PORT", "2222")
26+ promPort := shared.GetEnv("FEEDS_PROM_PORT", "9222")
2827 cfg := NewConfigSite(appName)
2928 logger := cfg.Logger
3029
+54, -54
......@@ -11,7 +11,7 @@ import (
1111 "github.com/picosh/pico/pkg/db"
1212 "github.com/picosh/pico/pkg/db/postgres"
1313 "github.com/picosh/pico/pkg/shared"
14- "github.com/picosh/utils"
14+ "github.com/picosh/pico/pkg/shared/router"
1515 "github.com/prometheus/client_golang/prometheus/promhttp"
1616 )
1717
......@@ -73,11 +73,11 @@ type HeaderTxt struct {
7373 }
7474
7575 func blogHandler(w http.ResponseWriter, r *http.Request) {
76- username := shared.GetUsernameFromRequest(r)
77- dbpool := shared.GetDB(r)
78- blogger := shared.GetLogger(r)
76+ username := router.GetUsernameFromRequest(r)
77+ dbpool := router.GetDB(r)
78+ blogger := router.GetLogger(r)
7979 logger := blogger.With("user", username)
80- cfg := shared.GetCfg(r)
80+ cfg := router.GetCfg(r)
8181
8282 user, err := dbpool.FindUserByName(username)
8383 if err != nil {
......@@ -96,7 +96,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
9696
9797 posts := pager.Data
9898
99- ts, err := shared.RenderTemplate(cfg, []string{
99+ ts, err := router.RenderTemplate(cfg, []string{
100100 cfg.StaticPath("html/blog.page.tmpl"),
101101 })
102102
......@@ -120,7 +120,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
120120 Title: post.Filename,
121121 PublishAt: post.PublishAt.Format(time.DateOnly),
122122 PublishAtISO: post.PublishAt.Format(time.RFC3339),
123- UpdatedTimeAgo: utils.TimeAgo(post.UpdatedAt),
123+ UpdatedTimeAgo: shared.TimeAgo(post.UpdatedAt),
124124 UpdatedAtISO: post.UpdatedAt.Format(time.RFC3339),
125125 }
126126 postCollection = append(postCollection, p)
......@@ -156,19 +156,19 @@ func GetBlogName(username string) string {
156156 }
157157
158158 func postHandler(w http.ResponseWriter, r *http.Request) {
159- username := shared.GetUsernameFromRequest(r)
160- subdomain := shared.GetSubdomain(r)
161- cfg := shared.GetCfg(r)
159+ username := router.GetUsernameFromRequest(r)
160+ subdomain := router.GetSubdomain(r)
161+ cfg := router.GetCfg(r)
162162
163163 var slug string
164164 if !cfg.IsSubdomains() || subdomain == "" {
165- slug, _ = url.PathUnescape(shared.GetField(r, 1))
165+ slug, _ = url.PathUnescape(router.GetField(r, 1))
166166 } else {
167- slug, _ = url.PathUnescape(shared.GetField(r, 0))
167+ slug, _ = url.PathUnescape(router.GetField(r, 0))
168168 }
169169
170- dbpool := shared.GetDB(r)
171- blogger := shared.GetLogger(r)
170+ dbpool := router.GetDB(r)
171+ blogger := router.GetLogger(r)
172172 logger := blogger.With("slug", slug, "user", username)
173173
174174 user, err := dbpool.FindUserByName(username)
......@@ -190,7 +190,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
190190 unlisted := false
191191 parsedText := ""
192192 // we dont want to syntax highlight huge files
193- if post.FileSize > 1*utils.MB {
193+ if post.FileSize > 1*shared.MB {
194194 logger.Warn("paste too large to parse and apply syntax highlighting")
195195 parsedText = post.Text
196196 } else {
......@@ -242,7 +242,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
242242 }
243243 }
244244
245- ts, err := shared.RenderTemplate(cfg, []string{
245+ ts, err := router.RenderTemplate(cfg, []string{
246246 cfg.StaticPath("html/post.page.tmpl"),
247247 })
248248
......@@ -259,19 +259,19 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
259259 }
260260
261261 func postHandlerRaw(w http.ResponseWriter, r *http.Request) {
262- username := shared.GetUsernameFromRequest(r)
263- subdomain := shared.GetSubdomain(r)
264- cfg := shared.GetCfg(r)
262+ username := router.GetUsernameFromRequest(r)
263+ subdomain := router.GetSubdomain(r)
264+ cfg := router.GetCfg(r)
265265
266266 var slug string
267267 if !cfg.IsSubdomains() || subdomain == "" {
268- slug, _ = url.PathUnescape(shared.GetField(r, 1))
268+ slug, _ = url.PathUnescape(router.GetField(r, 1))
269269 } else {
270- slug, _ = url.PathUnescape(shared.GetField(r, 0))
270+ slug, _ = url.PathUnescape(router.GetField(r, 0))
271271 }
272272
273- dbpool := shared.GetDB(r)
274- blogger := shared.GetLogger(r)
273+ dbpool := router.GetDB(r)
274+ blogger := router.GetLogger(r)
275275 logger := blogger.With("user", username, "slug", slug)
276276
277277 user, err := dbpool.FindUserByName(username)
......@@ -300,8 +300,8 @@ func postHandlerRaw(w http.ResponseWriter, r *http.Request) {
300300
301301 func serveFile(file string, contentType string) http.HandlerFunc {
302302 return func(w http.ResponseWriter, r *http.Request) {
303- logger := shared.GetLogger(r)
304- cfg := shared.GetCfg(r)
303+ logger := router.GetLogger(r)
304+ cfg := router.GetCfg(r)
305305
306306 contents, err := os.ReadFile(cfg.StaticPath(fmt.Sprintf("public/%s", file)))
307307 if err != nil {
......@@ -318,25 +318,25 @@ func serveFile(file string, contentType string) http.HandlerFunc {
318318 }
319319 }
320320
321-func createStaticRoutes() []shared.Route {
322- return []shared.Route{
323- shared.NewRoute("GET", "/main.css", serveFile("main.css", "text/css")),
324- shared.NewRoute("GET", "/smol.css", serveFile("smol.css", "text/css")),
325- shared.NewRoute("GET", "/syntax.css", serveFile("syntax.css", "text/css")),
326- shared.NewRoute("GET", "/card.png", serveFile("card.png", "image/png")),
327- shared.NewRoute("GET", "/favicon-16x16.png", serveFile("favicon-16x16.png", "image/png")),
328- shared.NewRoute("GET", "/favicon-32x32.png", serveFile("favicon-32x32.png", "image/png")),
329- shared.NewRoute("GET", "/apple-touch-icon.png", serveFile("apple-touch-icon.png", "image/png")),
330- shared.NewRoute("GET", "/favicon.ico", serveFile("favicon.ico", "image/x-icon")),
331- shared.NewRoute("GET", "/robots.txt", serveFile("robots.txt", "text/plain")),
321+func createStaticRoutes() []router.Route {
322+ return []router.Route{
323+ router.NewRoute("GET", "/main.css", serveFile("main.css", "text/css")),
324+ router.NewRoute("GET", "/smol.css", serveFile("smol.css", "text/css")),
325+ router.NewRoute("GET", "/syntax.css", serveFile("syntax.css", "text/css")),
326+ router.NewRoute("GET", "/card.png", serveFile("card.png", "image/png")),
327+ router.NewRoute("GET", "/favicon-16x16.png", serveFile("favicon-16x16.png", "image/png")),
328+ router.NewRoute("GET", "/favicon-32x32.png", serveFile("favicon-32x32.png", "image/png")),
329+ router.NewRoute("GET", "/apple-touch-icon.png", serveFile("apple-touch-icon.png", "image/png")),
330+ router.NewRoute("GET", "/favicon.ico", serveFile("favicon.ico", "image/x-icon")),
331+ router.NewRoute("GET", "/robots.txt", serveFile("robots.txt", "text/plain")),
332332 }
333333 }
334334
335-func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
336- routes := []shared.Route{
337- shared.NewRoute("GET", "/", shared.CreatePageHandler("html/marketing.page.tmpl")),
338- shared.NewRoute("GET", "/check", shared.CheckHandler),
339- shared.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
335+func createMainRoutes(staticRoutes []router.Route) []router.Route {
336+ routes := []router.Route{
337+ router.NewRoute("GET", "/", router.CreatePageHandler("html/marketing.page.tmpl")),
338+ router.NewRoute("GET", "/check", router.CheckHandler),
339+ router.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
340340 }
341341
342342 routes = append(
......@@ -346,18 +346,18 @@ func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
346346
347347 routes = append(
348348 routes,
349- shared.NewRoute("GET", "/([^/]+)", blogHandler),
350- shared.NewRoute("GET", "/([^/]+)/([^/]+)", postHandler),
351- shared.NewRoute("GET", "/([^/]+)/([^/]+)/raw", postHandlerRaw),
352- shared.NewRoute("GET", "/raw/([^/]+)/([^/]+)", postHandlerRaw),
349+ router.NewRoute("GET", "/([^/]+)", blogHandler),
350+ router.NewRoute("GET", "/([^/]+)/([^/]+)", postHandler),
351+ router.NewRoute("GET", "/([^/]+)/([^/]+)/raw", postHandlerRaw),
352+ router.NewRoute("GET", "/raw/([^/]+)/([^/]+)", postHandlerRaw),
353353 )
354354
355355 return routes
356356 }
357357
358-func createSubdomainRoutes(staticRoutes []shared.Route) []shared.Route {
359- routes := []shared.Route{
360- shared.NewRoute("GET", "/", blogHandler),
358+func createSubdomainRoutes(staticRoutes []router.Route) []router.Route {
359+ routes := []router.Route{
360+ router.NewRoute("GET", "/", blogHandler),
361361 }
362362
363363 routes = append(
......@@ -367,9 +367,9 @@ func createSubdomainRoutes(staticRoutes []shared.Route) []shared.Route {
367367
368368 routes = append(
369369 routes,
370- shared.NewRoute("GET", "/([^/]+)", postHandler),
371- shared.NewRoute("GET", "/([^/]+)/raw", postHandlerRaw),
372- shared.NewRoute("GET", "/raw/([^/]+)", postHandlerRaw),
370+ router.NewRoute("GET", "/([^/]+)", postHandler),
371+ router.NewRoute("GET", "/([^/]+)/raw", postHandlerRaw),
372+ router.NewRoute("GET", "/raw/([^/]+)", postHandlerRaw),
373373 )
374374
375375 return routes
......@@ -388,17 +388,17 @@ func StartApiServer() {
388388 staticRoutes := createStaticRoutes()
389389
390390 if cfg.Debug {
391- staticRoutes = shared.CreatePProfRoutes(staticRoutes)
391+ staticRoutes = router.CreatePProfRoutes(staticRoutes)
392392 }
393393
394394 mainRoutes := createMainRoutes(staticRoutes)
395395 subdomainRoutes := createSubdomainRoutes(staticRoutes)
396396
397- apiConfig := &shared.ApiConfig{
397+ apiConfig := &router.ApiConfig{
398398 Cfg: cfg,
399399 Dbpool: db,
400400 }
401- handler := shared.CreateServe(mainRoutes, subdomainRoutes, apiConfig)
401+ handler := router.CreateServe(mainRoutes, subdomainRoutes, apiConfig)
402402 router := http.HandlerFunc(handler)
403403
404404 portStr := fmt.Sprintf(":%s", cfg.Port)
+7, -8
......@@ -4,16 +4,15 @@ import (
44 "strings"
55
66 "github.com/picosh/pico/pkg/shared"
7- "github.com/picosh/utils"
87 )
98
109 func NewConfigSite(service string) *shared.ConfigSite {
11- debug := utils.GetEnv("PASTES_DEBUG", "0")
12- domain := utils.GetEnv("PASTES_DOMAIN", "pastes.sh")
13- port := utils.GetEnv("PASTES_WEB_PORT", "3000")
14- dbURL := utils.GetEnv("DATABASE_URL", "")
15- protocol := utils.GetEnv("PASTES_PROTOCOL", "https")
16- withPipe := strings.ToLower(utils.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
10+ debug := shared.GetEnv("PASTES_DEBUG", "0")
11+ domain := shared.GetEnv("PASTES_DOMAIN", "pastes.sh")
12+ port := shared.GetEnv("PASTES_WEB_PORT", "3000")
13+ dbURL := shared.GetEnv("DATABASE_URL", "")
14+ protocol := shared.GetEnv("PASTES_PROTOCOL", "https")
15+ withPipe := strings.ToLower(shared.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
1716
1817 return &shared.ConfigSite{
1918 Debug: debug == "1",
......@@ -23,6 +22,6 @@ func NewConfigSite(service string) *shared.ConfigSite {
2322 DbURL: dbURL,
2423 Space: "pastes",
2524 Logger: shared.CreateLogger(service, withPipe),
26- MaxAssetSize: int64(3 * utils.MB),
25+ MaxAssetSize: int64(3 * shared.MB),
2726 }
2827 }
+2, -3
......@@ -11,7 +11,6 @@ import (
1111 "github.com/picosh/pico/pkg/filehandlers"
1212 "github.com/picosh/pico/pkg/pssh"
1313 "github.com/picosh/pico/pkg/shared"
14- "github.com/picosh/utils"
1514 )
1615
1716 var DEFAULT_EXPIRES_AT = 90
......@@ -22,7 +21,7 @@ type FileHooks struct {
2221 }
2322
2423 func (p *FileHooks) FileValidate(s *pssh.SSHServerConnSession, data *filehandlers.PostMetaData) (bool, error) {
25- if !utils.IsTextFile(string(data.Text)) {
24+ if !shared.IsTextFile(string(data.Text)) {
2625 err := fmt.Errorf(
2726 "ERROR: (%s) invalid file must be plain text (utf-8), skipping",
2827 data.Filename,
......@@ -43,7 +42,7 @@ func (p *FileHooks) FileValidate(s *pssh.SSHServerConnSession, data *filehandler
4342 }
4443
4544 func (p *FileHooks) FileMeta(s *pssh.SSHServerConnSession, data *filehandlers.PostMetaData) error {
46- data.Title = utils.ToUpper(data.Slug)
45+ data.Title = shared.ToUpper(data.Slug)
4746 // we want the slug to be the filename for pastes
4847 data.Slug = data.Filename
4948
+3, -4
......@@ -17,15 +17,14 @@ import (
1717 "github.com/picosh/pico/pkg/send/protocols/scp"
1818 "github.com/picosh/pico/pkg/send/protocols/sftp"
1919 "github.com/picosh/pico/pkg/shared"
20- "github.com/picosh/utils"
2120 )
2221
2322 func StartSshServer() {
2423 appName := "pastes-ssh"
2524
26- host := utils.GetEnv("PASTES_HOST", "0.0.0.0")
27- port := utils.GetEnv("PASTES_SSH_PORT", "2222")
28- promPort := utils.GetEnv("PASTES_PROM_PORT", "9222")
25+ host := shared.GetEnv("PASTES_HOST", "0.0.0.0")
26+ port := shared.GetEnv("PASTES_SSH_PORT", "2222")
27+ promPort := shared.GetEnv("PASTES_PROM_PORT", "9222")
2928 cfg := NewConfigSite(appName)
3029 logger := cfg.Logger
3130
+3, -4
......@@ -14,7 +14,6 @@ import (
1414 "github.com/picosh/pico/pkg/db"
1515 sst "github.com/picosh/pico/pkg/pobj/storage"
1616 "github.com/picosh/pico/pkg/shared"
17- "github.com/picosh/utils"
1817 )
1918
2019 func NewTabWriter(out io.Writer) *tabwriter.Writer {
......@@ -46,7 +45,7 @@ func projectTable(sesh io.Writer, projects []*db.Project) {
4645
4746 type Cmd struct {
4847 User *db.User
49- Session utils.CmdSession
48+ Session shared.CmdSession
5049 Log *slog.Logger
5150 Store sst.ObjectStorage
5251 Dbpool pgsdb.PgsDB
......@@ -222,8 +221,8 @@ func (c *Cmd) stats(cfgMaxSize uint64) error {
222221 _, _ = fmt.Fprintf(
223222 writer,
224223 "%.4f\t%.4f\t%.4f\t%d\r\n",
225- utils.BytesToGB(int(totalFileSize)),
226- utils.BytesToGB(int(storageMax)),
224+ shared.BytesToGB(int(totalFileSize)),
225+ shared.BytesToGB(int(storageMax)),
227226 (float32(totalFileSize)/float32(storageMax))*100,
228227 len(projects),
229228 )
+11, -11
......@@ -7,8 +7,8 @@ import (
77 "time"
88
99 pgsdb "github.com/picosh/pico/pkg/apps/pgs/db"
10+ "github.com/picosh/pico/pkg/shared"
1011 "github.com/picosh/pico/pkg/shared/storage"
11- "github.com/picosh/utils"
1212 )
1313
1414 type PgsConfig struct {
......@@ -61,26 +61,26 @@ func (c *PgsConfig) StaticPath(fname string) string {
6161 return filepath.Join("pkg", "apps", "pgs", fname)
6262 }
6363
64-var maxSize = uint64(25 * utils.MB)
65-var maxAssetSize = int64(10 * utils.MB)
64+var maxSize = uint64(25 * shared.MB)
65+var maxAssetSize = int64(10 * shared.MB)
6666
6767 // Needs to be small for caching files like _headers and _redirects.
68-var maxSpecialFileSize = int64(5 * utils.KB)
68+var maxSpecialFileSize = int64(5 * shared.KB)
6969
7070 func NewPgsConfig(logger *slog.Logger, dbpool pgsdb.PgsDB, st storage.StorageServe, pubsub PicoPubsub) *PgsConfig {
71- domain := utils.GetEnv("PGS_DOMAIN", "pgs.sh")
72- port := utils.GetEnv("PGS_WEB_PORT", "3000")
73- protocol := utils.GetEnv("PGS_PROTOCOL", "https")
74- cacheTTL, err := time.ParseDuration(utils.GetEnv("PGS_CACHE_TTL", ""))
71+ domain := shared.GetEnv("PGS_DOMAIN", "pgs.sh")
72+ port := shared.GetEnv("PGS_WEB_PORT", "3000")
73+ protocol := shared.GetEnv("PGS_PROTOCOL", "https")
74+ cacheTTL, err := time.ParseDuration(shared.GetEnv("PGS_CACHE_TTL", ""))
7575 if err != nil {
7676 cacheTTL = 600 * time.Second
7777 }
78- cacheControl := utils.GetEnv(
78+ cacheControl := shared.GetEnv(
7979 "PGS_CACHE_CONTROL",
8080 fmt.Sprintf("max-age=%d", int(cacheTTL.Seconds())))
8181
82- sshHost := utils.GetEnv("PGS_SSH_HOST", "0.0.0.0")
83- sshPort := utils.GetEnv("PGS_SSH_PORT", "2222")
82+ sshHost := shared.GetEnv("PGS_SSH_HOST", "0.0.0.0")
83+ sshPort := shared.GetEnv("PGS_SSH_PORT", "2222")
8484
8585 cfg := PgsConfig{
8686 CacheControl: cacheControl,
+4, -4
......@@ -7,7 +7,7 @@ import (
77
88 "github.com/google/uuid"
99 "github.com/picosh/pico/pkg/db"
10- "github.com/picosh/utils"
10+ "github.com/picosh/pico/pkg/shared"
1111 )
1212
1313 type MemoryDB struct {
......@@ -37,9 +37,9 @@ func (me *MemoryDB) SetupTestData() {
3737 feature := db.NewFeatureFlag(
3838 user.ID,
3939 "plus",
40- uint64(25*utils.MB),
41- int64(10*utils.MB),
42- int64(5*utils.KB),
40+ uint64(25*shared.MB),
41+ int64(10*shared.MB),
42+ int64(5*shared.KB),
4343 )
4444 expiresAt := time.Now().Add(time.Hour * 24)
4545 feature.ExpiresAt = &expiresAt
+2, -2
......@@ -8,7 +8,7 @@ import (
88 "github.com/jmoiron/sqlx"
99 _ "github.com/lib/pq"
1010 "github.com/picosh/pico/pkg/db"
11- "github.com/picosh/utils"
11+ "github.com/picosh/pico/pkg/shared"
1212 )
1313
1414 type PgsPsqlDB struct {
......@@ -107,7 +107,7 @@ func (me *PgsPsqlDB) InsertAccessLog(log *db.AccessLog) error {
107107 }
108108
109109 func (me *PgsPsqlDB) InsertProject(userID, name, projectDir string) (string, error) {
110- if !utils.IsValidSubdomain(name) {
110+ if !shared.IsValidSubdomain(name) {
111111 return "", fmt.Errorf("'%s' is not a valid project name, must match /^[a-z0-9-]+$/", name)
112112 }
113113
+3, -4
......@@ -15,13 +15,12 @@ import (
1515 "github.com/picosh/pico/pkg/send/protocols/sftp"
1616 "github.com/picosh/pico/pkg/shared"
1717 "github.com/picosh/pico/pkg/tunkit"
18- "github.com/picosh/utils"
1918 )
2019
2120 func StartSshServer(cfg *PgsConfig, killCh chan error) {
22- host := utils.GetEnv("PGS_HOST", "0.0.0.0")
23- port := utils.GetEnv("PGS_SSH_PORT", "2222")
24- promPort := utils.GetEnv("PGS_PROM_PORT", "9222")
21+ host := shared.GetEnv("PGS_HOST", "0.0.0.0")
22+ port := shared.GetEnv("PGS_SSH_PORT", "2222")
23+ promPort := shared.GetEnv("PGS_PROM_PORT", "9222")
2524 logger := cfg.Logger
2625
2726 ctx, cancel := context.WithCancel(context.Background())
+3, -3
......@@ -16,8 +16,8 @@ import (
1616
1717 pgsdb "github.com/picosh/pico/pkg/apps/pgs/db"
1818 "github.com/picosh/pico/pkg/db"
19+ "github.com/picosh/pico/pkg/shared"
1920 "github.com/picosh/pico/pkg/shared/storage"
20- "github.com/picosh/utils"
2121 "github.com/pkg/sftp"
2222 "github.com/prometheus/client_golang/prometheus"
2323 "golang.org/x/crypto/ssh"
......@@ -55,7 +55,7 @@ func TestSshServerSftp(t *testing.T) {
5555 dbpool.Pubkeys = append(dbpool.Pubkeys, &db.PublicKey{
5656 ID: "nice-pubkey",
5757 UserID: dbpool.Users[0].ID,
58- Key: utils.KeyForKeyText(user.signer.PublicKey()),
58+ Key: shared.KeyForKeyText(user.signer.PublicKey()),
5959 })
6060
6161 client, err := user.NewClient()
......@@ -139,7 +139,7 @@ func TestSshServerRsync(t *testing.T) {
139139 time.Sleep(time.Millisecond * 100)
140140
141141 user := GenerateUser()
142- key := utils.KeyForKeyText(user.signer.PublicKey())
142+ key := shared.KeyForKeyText(user.signer.PublicKey())
143143 // add user's pubkey to the default test account
144144 dbpool.Pubkeys = append(dbpool.Pubkeys, &db.PublicKey{
145145 ID: "nice-pubkey",
+10, -10
......@@ -8,7 +8,7 @@ import (
88
99 "github.com/picosh/pico/pkg/db"
1010 "github.com/picosh/pico/pkg/pssh"
11- "github.com/picosh/pico/pkg/shared"
11+ "github.com/picosh/pico/pkg/shared/router"
1212 "golang.org/x/crypto/ssh"
1313 )
1414
......@@ -30,7 +30,7 @@ func tunnelPerm(proj *db.Project) bool {
3030
3131 func (web *TunnelWebRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
3232 ctx := r.Context()
33- ctx = context.WithValue(ctx, shared.CtxSubdomainKey{}, web.subdomain)
33+ ctx = context.WithValue(ctx, router.CtxSubdomainKey{}, web.subdomain)
3434 web.UserRouter.ServeHTTP(w, r.WithContext(ctx))
3535 }
3636
......@@ -57,17 +57,17 @@ func CreateHttpHandler(cfg *PgsConfig) CtxHttpBridge {
5757 pubkey := ctx.Permissions().Extensions["pubkey"]
5858 if pubkey == "" {
5959 log.Error("pubkey not found in extensions", "subdomain", subdomain)
60- return http.HandlerFunc(shared.UnauthorizedHandler)
60+ return http.HandlerFunc(router.UnauthorizedHandler)
6161 }
6262
6363 log = log.With(
6464 "pubkey", pubkey,
6565 )
6666
67- props, err := shared.GetProjectFromSubdomain(subdomain)
67+ props, err := router.GetProjectFromSubdomain(subdomain)
6868 if err != nil {
6969 log.Error("could not get project from subdomain", "err", err.Error())
70- return http.HandlerFunc(shared.UnauthorizedHandler)
70+ return http.HandlerFunc(router.UnauthorizedHandler)
7171 }
7272
7373 owner, err := cfg.DB.FindUserByName(props.Username)
......@@ -77,7 +77,7 @@ func CreateHttpHandler(cfg *PgsConfig) CtxHttpBridge {
7777 "name", props.Username,
7878 "err", err.Error(),
7979 )
80- return http.HandlerFunc(shared.UnauthorizedHandler)
80+ return http.HandlerFunc(router.UnauthorizedHandler)
8181 }
8282 log = log.With(
8383 "owner", owner.Name,
......@@ -86,7 +86,7 @@ func CreateHttpHandler(cfg *PgsConfig) CtxHttpBridge {
8686 project, err := cfg.DB.FindProjectByName(owner.ID, props.ProjectName)
8787 if err != nil {
8888 log.Error("could not get project by name", "project", props.ProjectName, "err", err.Error())
89- return http.HandlerFunc(shared.UnauthorizedHandler)
89+ return http.HandlerFunc(router.UnauthorizedHandler)
9090 }
9191
9292 requester, _ := cfg.DB.FindUserByPubkey(pubkey)
......@@ -108,7 +108,7 @@ func CreateHttpHandler(cfg *PgsConfig) CtxHttpBridge {
108108
109109 if !isAdmin {
110110 log.Error("impersonation attempt failed")
111- return http.HandlerFunc(shared.UnauthorizedHandler)
111+ return http.HandlerFunc(router.UnauthorizedHandler)
112112 }
113113 requester, _ = cfg.DB.FindUserByName(asUser)
114114 }
......@@ -117,11 +117,11 @@ func CreateHttpHandler(cfg *PgsConfig) CtxHttpBridge {
117117 publicKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubkey))
118118 if err != nil {
119119 log.Error("could not parse public key", "pubkey", pubkey, "err", err)
120- return http.HandlerFunc(shared.UnauthorizedHandler)
120+ return http.HandlerFunc(router.UnauthorizedHandler)
121121 }
122122 if !HasProjectAccess(project, owner, requester, publicKey) {
123123 log.Error("no access")
124- return http.HandlerFunc(shared.UnauthorizedHandler)
124+ return http.HandlerFunc(router.UnauthorizedHandler)
125125 }
126126
127127 log.Info("user has access to site")
+7, -8
......@@ -22,7 +22,6 @@ import (
2222 "github.com/picosh/pico/pkg/pssh"
2323 sendutils "github.com/picosh/pico/pkg/send/utils"
2424 "github.com/picosh/pico/pkg/shared"
25- "github.com/picosh/utils"
2625 ignore "github.com/sabhiram/go-gitignore"
2726 )
2827
......@@ -405,7 +404,7 @@ func (h *UploadAssetHandler) Write(s *pssh.SSHServerConnSession, entry *sendutil
405404
406405 fsize, err := h.writeAsset(
407406 s,
408- utils.NewMaxBytesReader(data.Reader, int64(sizeRemaining)),
407+ shared.NewMaxBytesReader(data.Reader, int64(sizeRemaining)),
409408 data,
410409 )
411410 if err != nil {
......@@ -413,10 +412,10 @@ func (h *UploadAssetHandler) Write(s *pssh.SSHServerConnSession, entry *sendutil
413412 cerr := fmt.Errorf(
414413 "%s: storage size %.2fmb, storage max %.2fmb, file max %.2fmb, special file max %.4fmb",
415414 err,
416- utils.BytesToMB(int(curStorageSize)),
417- utils.BytesToMB(int(storageMax)),
418- utils.BytesToMB(int(fileMax)),
419- utils.BytesToMB(int(specialFileMax)),
415+ shared.BytesToMB(int(curStorageSize)),
416+ shared.BytesToMB(int(storageMax)),
417+ shared.BytesToMB(int(fileMax)),
418+ shared.BytesToMB(int(specialFileMax)),
420419 )
421420 return "", cerr
422421 }
......@@ -434,8 +433,8 @@ func (h *UploadAssetHandler) Write(s *pssh.SSHServerConnSession, entry *sendutil
434433 str := fmt.Sprintf(
435434 "%s (space: %.2f/%.2fGB, %.2f%%)",
436435 url,
437- utils.BytesToGB(int(nextStorageSize)),
438- utils.BytesToGB(maxSize),
436+ shared.BytesToGB(int(nextStorageSize)),
437+ shared.BytesToGB(maxSize),
439438 (float32(nextStorageSize)/float32(maxSize))*100,
440439 )
441440
+13, -13
......@@ -22,10 +22,10 @@ import (
2222 "github.com/darkweak/storages/core"
2323 "github.com/gorilla/feeds"
2424 "github.com/hashicorp/golang-lru/v2/expirable"
25- "github.com/picosh/pico/pkg/cache"
2625 "github.com/picosh/pico/pkg/db"
2726 sst "github.com/picosh/pico/pkg/pobj/storage"
2827 "github.com/picosh/pico/pkg/shared"
28+ "github.com/picosh/pico/pkg/shared/router"
2929 "github.com/picosh/pico/pkg/shared/storage"
3030 "github.com/prometheus/client_golang/prometheus/promhttp"
3131 "google.golang.org/protobuf/proto"
......@@ -115,8 +115,8 @@ func NewWebRouter(cfg *PgsConfig) *WebRouter {
115115 func newWebRouter(cfg *PgsConfig) *WebRouter {
116116 router := &WebRouter{
117117 Cfg: cfg,
118- RedirectsCache: expirable.NewLRU[string, []*RedirectRule](2048, nil, cache.CacheTimeout),
119- HeadersCache: expirable.NewLRU[string, []*HeaderRule](2048, nil, cache.CacheTimeout),
118+ RedirectsCache: expirable.NewLRU[string, []*RedirectRule](2048, nil, shared.CacheTimeout),
119+ HeadersCache: expirable.NewLRU[string, []*HeaderRule](2048, nil, shared.CacheTimeout),
120120 }
121121 router.initRouters()
122122 return router
......@@ -242,8 +242,8 @@ func (web *WebRouter) checkHandler(w http.ResponseWriter, r *http.Request) {
242242 appDomain := strings.Split(cfg.Domain, ":")[0]
243243
244244 if !strings.Contains(hostDomain, appDomain) {
245- subdomain := shared.GetCustomDomain(hostDomain, cfg.TxtPrefix)
246- props, err := shared.GetProjectFromSubdomain(subdomain)
245+ subdomain := router.GetCustomDomain(hostDomain, cfg.TxtPrefix)
246+ props, err := router.GetProjectFromSubdomain(subdomain)
247247 if err != nil {
248248 logger.Error(
249249 "could not get project from subdomain",
......@@ -448,7 +448,7 @@ func (web *WebRouter) ImageRequest(perm func(proj *db.Project) bool) http.Handle
448448 }
449449
450450 func (web *WebRouter) ServeAsset(fname string, opts *storage.ImgProcessOpts, hasPerm HasPerm, w http.ResponseWriter, r *http.Request) {
451- subdomain := shared.GetSubdomain(r)
451+ subdomain := router.GetSubdomain(r)
452452
453453 logger := web.Cfg.Logger.With(
454454 "subdomain", subdomain,
......@@ -457,7 +457,7 @@ func (web *WebRouter) ServeAsset(fname string, opts *storage.ImgProcessOpts, has
457457 "host", r.Host,
458458 )
459459
460- props, err := shared.GetProjectFromSubdomain(subdomain)
460+ props, err := router.GetProjectFromSubdomain(subdomain)
461461 if err != nil {
462462 logger.Info(
463463 "could not determine project from subdomain",
......@@ -542,23 +542,23 @@ func (web *WebRouter) ServeAsset(fname string, opts *storage.ImgProcessOpts, has
542542 }
543543
544544 func (web *WebRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
545- subdomain := shared.GetSubdomainFromRequest(r, web.Cfg.Domain, web.Cfg.TxtPrefix)
545+ subdomain := router.GetSubdomainFromRequest(r, web.Cfg.Domain, web.Cfg.TxtPrefix)
546546 if web.RootRouter == nil || web.UserRouter == nil {
547547 web.Cfg.Logger.Error("routers not initialized")
548548 http.Error(w, "routers not initialized", http.StatusInternalServerError)
549549 return
550550 }
551551
552- var router *http.ServeMux
552+ var mux *http.ServeMux
553553 if subdomain == "" {
554- router = web.RootRouter
554+ mux = web.RootRouter
555555 } else {
556- router = web.UserRouter
556+ mux = web.UserRouter
557557 }
558558
559559 ctx := r.Context()
560- ctx = context.WithValue(ctx, shared.CtxSubdomainKey{}, subdomain)
561- router.ServeHTTP(w, r.WithContext(ctx))
560+ ctx = context.WithValue(ctx, router.CtxSubdomainKey{}, subdomain)
561+ mux.ServeHTTP(w, r.WithContext(ctx))
562562 }
563563
564564 type CompatLogger struct {
+7, -8
......@@ -12,7 +12,6 @@ import (
1212 "github.com/picosh/pico/pkg/db"
1313 "github.com/picosh/pico/pkg/pssh"
1414 "github.com/picosh/pico/pkg/shared"
15- "github.com/picosh/utils"
1615
1716 pipeLogger "github.com/picosh/utils/pipe/log"
1817 )
......@@ -22,7 +21,7 @@ func getUser(s *pssh.SSHServerConnSession, dbpool db.DB) (*db.User, error) {
2221 return nil, fmt.Errorf("key not found")
2322 }
2423
25- key := utils.KeyForKeyText(s.PublicKey())
24+ key := shared.KeyForKeyText(s.PublicKey())
2625
2726 user, err := dbpool.FindUserByKey(s.User(), key)
2827 if err != nil {
......@@ -39,7 +38,7 @@ func getUser(s *pssh.SSHServerConnSession, dbpool db.DB) (*db.User, error) {
3938 type Cmd struct {
4039 User *db.User
4140 SshSession *pssh.SSHServerConnSession
42- Session utils.CmdSession
41+ Session shared.CmdSession
4342 Log *slog.Logger
4443 Dbpool db.DB
4544 Write bool
......@@ -77,9 +76,9 @@ func (c *Cmd) user() {
7776 }
7877
7978 func (c *Cmd) notFound(host, interval string) error {
80- origin := utils.StartOfYear()
79+ origin := shared.StartOfYear()
8180 if interval == "month" {
82- origin = utils.StartOfMonth()
81+ origin = shared.StartOfMonth()
8382 }
8483 c.output(fmt.Sprintf("starting from: %s\n", origin.Format(time.RFC3339)))
8584 urls, err := c.Dbpool.VisitUrlNotFound(&db.SummaryOpts{
......@@ -155,10 +154,10 @@ func (c *Cmd) logs(ctx context.Context) error {
155154 continue
156155 }
157156
158- user := utils.AnyToStr(parsedData, "user")
159- userId := utils.AnyToStr(parsedData, "userId")
157+ user := shared.AnyToStr(parsedData, "user")
158+ userId := shared.AnyToStr(parsedData, "userId")
160159
161- hidden := utils.AnyToBool(parsedData, "hidden")
160+ hidden := shared.AnyToBool(parsedData, "hidden")
162161
163162 if !hidden && (user == c.User.Name || userId == c.User.ID) {
164163 select {
+3, -4
......@@ -4,13 +4,12 @@ import (
44 "strings"
55
66 "github.com/picosh/pico/pkg/shared"
7- "github.com/picosh/utils"
87 )
98
109 func NewConfigSite(service string) *shared.ConfigSite {
11- dbURL := utils.GetEnv("DATABASE_URL", "")
12- tuns := utils.GetEnv("TUNS_CONSOLE_SECRET", "")
13- withPipe := strings.ToLower(utils.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
10+ dbURL := shared.GetEnv("DATABASE_URL", "")
11+ tuns := shared.GetEnv("TUNS_CONSOLE_SECRET", "")
12+ withPipe := strings.ToLower(shared.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
1413
1514 return &shared.ConfigSite{
1615 DbURL: dbURL,
+2, -3
......@@ -15,7 +15,6 @@ import (
1515 "github.com/picosh/pico/pkg/pssh"
1616 sendutils "github.com/picosh/pico/pkg/send/utils"
1717 "github.com/picosh/pico/pkg/shared"
18- "github.com/picosh/utils"
1918 "golang.org/x/crypto/ssh"
2019 )
2120
......@@ -242,7 +241,7 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger,
242241 diff := authorizedKeysDiff(s.PublicKey(), curKeys, nextKeys)
243242
244243 for _, pk := range diff.Add {
245- key := utils.KeyForKeyText(pk.Pk)
244+ key := shared.KeyForKeyText(pk.Pk)
246245
247246 _, _ = fmt.Fprintf(s.Stderr(), "adding pubkey (%s)\n", key)
248247 logger.Info("adding pubkey", "pubkey", key)
......@@ -255,7 +254,7 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger,
255254 }
256255
257256 for _, pk := range diff.Update {
258- key := utils.KeyForKeyText(pk.Pk)
257+ key := shared.KeyForKeyText(pk.Pk)
259258
260259 _, _ = fmt.Fprintf(s.Stderr(), "updating pubkey with comment: %s (%s)\n", pk.Comment, key)
261260 logger.Info(
+4, -5
......@@ -19,7 +19,6 @@ import (
1919 "github.com/picosh/pico/pkg/send/protocols/sftp"
2020 "github.com/picosh/pico/pkg/shared"
2121 "github.com/picosh/pico/pkg/tui"
22- "github.com/picosh/utils"
2322 "golang.org/x/crypto/ssh"
2423 )
2524
......@@ -41,9 +40,9 @@ func createTui(shrd *tui.SharedModel) pssh.SSHServerMiddleware {
4140 func StartSshServer() {
4241 appName := "pico-ssh"
4342
44- host := utils.GetEnv("PICO_HOST", "0.0.0.0")
45- port := utils.GetEnv("PICO_SSH_PORT", "2222")
46- promPort := utils.GetEnv("PICO_PROM_PORT", "9222")
43+ host := shared.GetEnv("PICO_HOST", "0.0.0.0")
44+ port := shared.GetEnv("PICO_SSH_PORT", "2222")
45+ promPort := shared.GetEnv("PICO_PROM_PORT", "9222")
4746 cfg := NewConfigSite(appName)
4847 logger := cfg.Logger
4948
......@@ -84,7 +83,7 @@ func StartSshServer() {
8483 if perms == nil {
8584 perms = &ssh.Permissions{
8685 Extensions: map[string]string{
87- "pubkey": utils.KeyForKeyText(key),
86+ "pubkey": shared.KeyForKeyText(key),
8887 },
8988 }
9089 }
+37, -36
......@@ -20,6 +20,7 @@ import (
2020 "github.com/picosh/pico/pkg/db"
2121 "github.com/picosh/pico/pkg/db/postgres"
2222 "github.com/picosh/pico/pkg/shared"
23+ "github.com/picosh/pico/pkg/shared/router"
2324 "github.com/picosh/utils/pipe"
2425 "github.com/prometheus/client_golang/prometheus/promhttp"
2526 )
......@@ -36,8 +37,8 @@ var (
3637
3738 func serveFile(file string, contentType string) http.HandlerFunc {
3839 return func(w http.ResponseWriter, r *http.Request) {
39- logger := shared.GetLogger(r)
40- cfg := shared.GetCfg(r)
40+ logger := router.GetLogger(r)
41+ cfg := router.GetCfg(r)
4142
4243 contents, err := os.ReadFile(cfg.StaticPath(fmt.Sprintf("public/%s", file)))
4344 if err != nil {
......@@ -54,18 +55,18 @@ func serveFile(file string, contentType string) http.HandlerFunc {
5455 }
5556 }
5657
57-func createStaticRoutes() []shared.Route {
58- return []shared.Route{
59- shared.NewRoute("GET", "/main.css", serveFile("main.css", "text/css")),
60- shared.NewRoute("GET", "/smol.css", serveFile("smol.css", "text/css")),
61- shared.NewRoute("GET", "/syntax.css", serveFile("syntax.css", "text/css")),
62- shared.NewRoute("GET", "/card.png", serveFile("card.png", "image/png")),
63- shared.NewRoute("GET", "/favicon-16x16.png", serveFile("favicon-16x16.png", "image/png")),
64- shared.NewRoute("GET", "/favicon-32x32.png", serveFile("favicon-32x32.png", "image/png")),
65- shared.NewRoute("GET", "/apple-touch-icon.png", serveFile("apple-touch-icon.png", "image/png")),
66- shared.NewRoute("GET", "/favicon.ico", serveFile("favicon.ico", "image/x-icon")),
67- shared.NewRoute("GET", "/robots.txt", serveFile("robots.txt", "text/plain")),
68- shared.NewRoute("GET", "/anim.js", serveFile("anim.js", "text/javascript")),
58+func createStaticRoutes() []router.Route {
59+ return []router.Route{
60+ router.NewRoute("GET", "/main.css", serveFile("main.css", "text/css")),
61+ router.NewRoute("GET", "/smol.css", serveFile("smol.css", "text/css")),
62+ router.NewRoute("GET", "/syntax.css", serveFile("syntax.css", "text/css")),
63+ router.NewRoute("GET", "/card.png", serveFile("card.png", "image/png")),
64+ router.NewRoute("GET", "/favicon-16x16.png", serveFile("favicon-16x16.png", "image/png")),
65+ router.NewRoute("GET", "/favicon-32x32.png", serveFile("favicon-32x32.png", "image/png")),
66+ router.NewRoute("GET", "/apple-touch-icon.png", serveFile("apple-touch-icon.png", "image/png")),
67+ router.NewRoute("GET", "/favicon.ico", serveFile("favicon.ico", "image/x-icon")),
68+ router.NewRoute("GET", "/robots.txt", serveFile("robots.txt", "text/plain")),
69+ router.NewRoute("GET", "/anim.js", serveFile("anim.js", "text/javascript")),
6970 }
7071 }
7172
......@@ -86,10 +87,10 @@ var _ io.Writer = writeFlusher{}
8687
8788 func handleSub(pubsub bool) http.HandlerFunc {
8889 return func(w http.ResponseWriter, r *http.Request) {
89- logger := shared.GetLogger(r)
90+ logger := router.GetLogger(r)
9091
9192 clientInfo := shared.NewPicoPipeClient()
92- topic, _ := url.PathUnescape(shared.GetField(r, 0))
93+ topic, _ := url.PathUnescape(router.GetField(r, 0))
9394
9495 topic = cleanRegex.ReplaceAllString(topic, "")
9596
......@@ -139,10 +140,10 @@ func handleSub(pubsub bool) http.HandlerFunc {
139140
140141 func handlePub(pubsub bool) http.HandlerFunc {
141142 return func(w http.ResponseWriter, r *http.Request) {
142- logger := shared.GetLogger(r)
143+ logger := router.GetLogger(r)
143144
144145 clientInfo := shared.NewPicoPipeClient()
145- topic, _ := url.PathUnescape(shared.GetField(r, 0))
146+ topic, _ := url.PathUnescape(router.GetField(r, 0))
146147
147148 topic = cleanRegex.ReplaceAllString(topic, "")
148149
......@@ -283,7 +284,7 @@ func handlePub(pubsub bool) http.HandlerFunc {
283284
284285 func handlePipe() http.HandlerFunc {
285286 return func(w http.ResponseWriter, r *http.Request) {
286- logger := shared.GetLogger(r)
287+ logger := router.GetLogger(r)
287288
288289 c, err := upgrader.Upgrade(w, r, nil)
289290 if err != nil {
......@@ -296,7 +297,7 @@ func handlePipe() http.HandlerFunc {
296297 }()
297298
298299 clientInfo := shared.NewPicoPipeClient()
299- topic, _ := url.PathUnescape(shared.GetField(r, 0))
300+ topic, _ := url.PathUnescape(router.GetField(r, 0))
300301
301302 topic = cleanRegex.ReplaceAllString(topic, "")
302303
......@@ -435,7 +436,7 @@ func handlePipe() http.HandlerFunc {
435436
436437 func rssHandler(cfg *shared.ConfigSite, dbpool db.DB) http.HandlerFunc {
437438 return func(w http.ResponseWriter, r *http.Request) {
438- apiToken, _ := url.PathUnescape(shared.GetField(r, 0))
439+ apiToken, _ := url.PathUnescape(router.GetField(r, 0))
439440 user, err := dbpool.FindUserByToken(apiToken)
440441 if err != nil {
441442 cfg.Logger.Error(
......@@ -470,20 +471,20 @@ func rssHandler(cfg *shared.ConfigSite, dbpool db.DB) http.HandlerFunc {
470471 }
471472 }
472473
473-func createMainRoutes(staticRoutes []shared.Route, cfg *shared.ConfigSite, dbpool db.DB) []shared.Route {
474- routes := []shared.Route{
475- shared.NewRoute("GET", "/", shared.CreatePageHandler("html/marketing.page.tmpl")),
476- shared.NewRoute("GET", "/check", shared.CheckHandler),
477- shared.NewRoute("GET", "/rss/(.+)", rssHandler(cfg, dbpool)),
478- shared.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
474+func createMainRoutes(staticRoutes []router.Route, cfg *shared.ConfigSite, dbpool db.DB) []router.Route {
475+ routes := []router.Route{
476+ router.NewRoute("GET", "/", router.CreatePageHandler("html/marketing.page.tmpl")),
477+ router.NewRoute("GET", "/check", router.CheckHandler),
478+ router.NewRoute("GET", "/rss/(.+)", rssHandler(cfg, dbpool)),
479+ router.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
479480 }
480481
481- pipeRoutes := []shared.Route{
482- shared.NewRoute("GET", "/topic/(.+)", handleSub(false)),
483- shared.NewRoute("POST", "/topic/(.+)", handlePub(false)),
484- shared.NewRoute("GET", "/pubsub/(.+)", handleSub(true)),
485- shared.NewRoute("POST", "/pubsub/(.+)", handlePub(true)),
486- shared.NewRoute("GET", "/pipe/(.+)", handlePipe()),
482+ pipeRoutes := []router.Route{
483+ router.NewRoute("GET", "/topic/(.+)", handleSub(false)),
484+ router.NewRoute("POST", "/topic/(.+)", handlePub(false)),
485+ router.NewRoute("GET", "/pubsub/(.+)", handleSub(true)),
486+ router.NewRoute("POST", "/pubsub/(.+)", handlePub(true)),
487+ router.NewRoute("GET", "/pipe/(.+)", handlePipe()),
487488 }
488489
489490 for _, route := range pipeRoutes {
......@@ -510,7 +511,7 @@ func StartApiServer() {
510511 staticRoutes := createStaticRoutes()
511512
512513 if cfg.Debug {
513- staticRoutes = shared.CreatePProfRoutes(staticRoutes)
514+ staticRoutes = router.CreatePProfRoutes(staticRoutes)
514515 }
515516
516517 mainRoutes := createMainRoutes(staticRoutes, cfg, db)
......@@ -541,11 +542,11 @@ func StartApiServer() {
541542 }
542543 }()
543544
544- apiConfig := &shared.ApiConfig{
545+ apiConfig := &router.ApiConfig{
545546 Cfg: cfg,
546547 Dbpool: db,
547548 }
548- handler := shared.CreateServe(mainRoutes, subdomainRoutes, apiConfig)
549+ handler := router.CreateServe(mainRoutes, subdomainRoutes, apiConfig)
549550 router := http.HandlerFunc(handler)
550551
551552 portStr := fmt.Sprintf(":%s", cfg.Port)
+5, -6
......@@ -4,15 +4,14 @@ import (
44 "strings"
55
66 "github.com/picosh/pico/pkg/shared"
7- "github.com/picosh/utils"
87 )
98
109 func NewConfigSite(service string) *shared.ConfigSite {
11- domain := utils.GetEnv("PIPE_DOMAIN", "pipe.pico.sh")
12- port := utils.GetEnv("PIPE_WEB_PORT", "3000")
13- dbURL := utils.GetEnv("DATABASE_URL", "")
14- protocol := utils.GetEnv("PIPE_PROTOCOL", "https")
15- withPipe := strings.ToLower(utils.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
10+ domain := shared.GetEnv("PIPE_DOMAIN", "pipe.pico.sh")
11+ port := shared.GetEnv("PIPE_WEB_PORT", "3000")
12+ dbURL := shared.GetEnv("DATABASE_URL", "")
13+ protocol := shared.GetEnv("PIPE_PROTOCOL", "https")
14+ withPipe := strings.ToLower(shared.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
1615
1716 return &shared.ConfigSite{
1817 Domain: domain,
+5, -6
......@@ -11,17 +11,16 @@ import (
1111 "github.com/picosh/pico/pkg/pssh"
1212 "github.com/picosh/pico/pkg/shared"
1313 psub "github.com/picosh/pubsub"
14- "github.com/picosh/utils"
1514 "golang.org/x/crypto/ssh"
1615 )
1716
1817 func StartSshServer() {
1918 appName := "pipe-ssh"
2019
21- host := utils.GetEnv("PIPE_HOST", "0.0.0.0")
22- port := utils.GetEnv("PIPE_SSH_PORT", "2222")
23- portOverride := utils.GetEnv("PIPE_SSH_PORT_OVERRIDE", port)
24- promPort := utils.GetEnv("PIPE_PROM_PORT", "9222")
20+ host := shared.GetEnv("PIPE_HOST", "0.0.0.0")
21+ port := shared.GetEnv("PIPE_SSH_PORT", "2222")
22+ portOverride := shared.GetEnv("PIPE_SSH_PORT_OVERRIDE", port)
23+ promPort := shared.GetEnv("PIPE_PROM_PORT", "9222")
2524 cfg := NewConfigSite(appName)
2625 logger := cfg.Logger
2726
......@@ -62,7 +61,7 @@ func StartSshServer() {
6261 if perms == nil {
6362 perms = &ssh.Permissions{
6463 Extensions: map[string]string{
65- "pubkey": utils.KeyForKeyText(key),
64+ "pubkey": shared.KeyForKeyText(key),
6665 },
6766 }
6867 }
+2, -3
......@@ -18,7 +18,6 @@ import (
1818 "github.com/picosh/pico/pkg/pssh"
1919 "github.com/picosh/pico/pkg/shared"
2020 psub "github.com/picosh/pubsub"
21- "github.com/picosh/utils"
2221 "github.com/prometheus/client_golang/prometheus"
2322 "golang.org/x/crypto/ssh"
2423 )
......@@ -225,7 +224,7 @@ func NewTestSSHServer(t *testing.T) *TestSSHServer {
225224 if perms == nil {
226225 perms = &ssh.Permissions{
227226 Extensions: map[string]string{
228- "pubkey": utils.KeyForKeyText(key),
227+ "pubkey": shared.KeyForKeyText(key),
229228 },
230229 }
231230 }
......@@ -294,7 +293,7 @@ func GenerateUser(username string) UserSSH {
294293 }
295294
296295 func (u UserSSH) PublicKey() string {
297- return utils.KeyForKeyText(u.signer.PublicKey())
296+ return shared.KeyForKeyText(u.signer.PublicKey())
298297 }
299298
300299 func (u UserSSH) NewClient() (*ssh.Client, error) {
+97, -97
......@@ -19,8 +19,8 @@ import (
1919 "github.com/picosh/pico/pkg/db"
2020 "github.com/picosh/pico/pkg/db/postgres"
2121 "github.com/picosh/pico/pkg/shared"
22+ "github.com/picosh/pico/pkg/shared/router"
2223 "github.com/picosh/pico/pkg/shared/storage"
23- "github.com/picosh/utils"
2424 "github.com/prometheus/client_golang/prometheus/promhttp"
2525 )
2626
......@@ -124,10 +124,10 @@ func GetBlogName(username string) string {
124124 }
125125
126126 func blogStyleHandler(w http.ResponseWriter, r *http.Request) {
127- username := shared.GetUsernameFromRequest(r)
128- dbpool := shared.GetDB(r)
129- logger := shared.GetLogger(r)
130- cfg := shared.GetCfg(r)
127+ username := router.GetUsernameFromRequest(r)
128+ dbpool := router.GetDB(r)
129+ logger := router.GetLogger(r)
130+ cfg := router.GetCfg(r)
131131
132132 user, err := dbpool.FindUserByName(username)
133133 if err != nil {
......@@ -154,10 +154,10 @@ func blogStyleHandler(w http.ResponseWriter, r *http.Request) {
154154 }
155155
156156 func blogHandler(w http.ResponseWriter, r *http.Request) {
157- username := shared.GetUsernameFromRequest(r)
158- dbpool := shared.GetDB(r)
159- logger := shared.GetLogger(r)
160- cfg := shared.GetCfg(r)
157+ username := router.GetUsernameFromRequest(r)
158+ dbpool := router.GetDB(r)
159+ logger := router.GetLogger(r)
160+ cfg := router.GetCfg(r)
161161
162162 user, err := dbpool.FindUserByName(username)
163163 if err != nil {
......@@ -184,7 +184,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
184184 return
185185 }
186186
187- ts, err := shared.RenderTemplate(cfg, []string{
187+ ts, err := router.RenderTemplate(cfg, []string{
188188 cfg.StaticPath("html/blog-default.partial.tmpl"),
189189 cfg.StaticPath("html/blog-aside.partial.tmpl"),
190190 cfg.StaticPath("html/blog.page.tmpl"),
......@@ -257,10 +257,10 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
257257 p := PostItemData{
258258 URL: template.URL(cfg.FullPostURL(curl, post.Username, post.Slug)),
259259 BlogURL: template.URL(cfg.FullBlogURL(curl, post.Username)),
260- Title: utils.FilenameToTitle(post.Filename, post.Title),
260+ Title: shared.FilenameToTitle(post.Filename, post.Title),
261261 PublishAt: post.PublishAt.Format(time.DateOnly),
262262 PublishAtISO: post.PublishAt.Format(time.RFC3339),
263- UpdatedTimeAgo: utils.TimeAgo(post.UpdatedAt),
263+ UpdatedTimeAgo: shared.TimeAgo(post.UpdatedAt),
264264 UpdatedAtISO: post.UpdatedAt.Format(time.RFC3339),
265265 }
266266 postCollection = append(postCollection, p)
......@@ -289,20 +289,20 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
289289 }
290290
291291 func postRawHandler(w http.ResponseWriter, r *http.Request) {
292- username := shared.GetUsernameFromRequest(r)
293- subdomain := shared.GetSubdomain(r)
294- cfg := shared.GetCfg(r)
292+ username := router.GetUsernameFromRequest(r)
293+ subdomain := router.GetSubdomain(r)
294+ cfg := router.GetCfg(r)
295295
296296 var slug string
297297 if !cfg.IsSubdomains() || subdomain == "" {
298- slug, _ = url.PathUnescape(shared.GetField(r, 1))
298+ slug, _ = url.PathUnescape(router.GetField(r, 1))
299299 } else {
300- slug, _ = url.PathUnescape(shared.GetField(r, 0))
300+ slug, _ = url.PathUnescape(router.GetField(r, 0))
301301 }
302302 slug = strings.TrimSuffix(slug, "/")
303303
304- dbpool := shared.GetDB(r)
305- logger := shared.GetLogger(r)
304+ dbpool := router.GetDB(r)
305+ logger := router.GetLogger(r)
306306 logger = logger.With("slug", slug)
307307
308308 user, err := dbpool.FindUserByName(username)
......@@ -330,10 +330,10 @@ func postRawHandler(w http.ResponseWriter, r *http.Request) {
330330 }
331331
332332 func robotsHandler(w http.ResponseWriter, r *http.Request) {
333- username := shared.GetUsernameFromRequest(r)
334- cfg := shared.GetCfg(r)
335- dbpool := shared.GetDB(r)
336- logger := shared.GetLogger(r)
333+ username := router.GetUsernameFromRequest(r)
334+ cfg := router.GetCfg(r)
335+ dbpool := router.GetDB(r)
336+ logger := router.GetLogger(r)
337337 user, err := dbpool.FindUserByName(username)
338338 if err != nil {
339339 logger.Info("blog not found", "user", username)
......@@ -356,20 +356,20 @@ func robotsHandler(w http.ResponseWriter, r *http.Request) {
356356 }
357357
358358 func postHandler(w http.ResponseWriter, r *http.Request) {
359- username := shared.GetUsernameFromRequest(r)
360- subdomain := shared.GetSubdomain(r)
361- cfg := shared.GetCfg(r)
359+ username := router.GetUsernameFromRequest(r)
360+ subdomain := router.GetSubdomain(r)
361+ cfg := router.GetCfg(r)
362362
363363 var slug string
364364 if !cfg.IsSubdomains() || subdomain == "" {
365- slug, _ = url.PathUnescape(shared.GetField(r, 1))
365+ slug, _ = url.PathUnescape(router.GetField(r, 1))
366366 } else {
367- slug, _ = url.PathUnescape(shared.GetField(r, 0))
367+ slug, _ = url.PathUnescape(router.GetField(r, 0))
368368 }
369369 slug = strings.TrimSuffix(slug, "/")
370370
371- dbpool := shared.GetDB(r)
372- logger := shared.GetLogger(r)
371+ dbpool := router.GetDB(r)
372+ logger := router.GetLogger(r)
373373
374374 user, err := dbpool.FindUserByName(username)
375375 if err != nil {
......@@ -473,7 +473,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
473473 URL: template.URL(cfg.FullPostURL(curl, post.Username, post.Slug)),
474474 BlogURL: template.URL(cfg.FullBlogURL(curl, username)),
475475 Description: post.Description,
476- Title: utils.FilenameToTitle(post.Filename, post.Title),
476+ Title: shared.FilenameToTitle(post.Filename, post.Title),
477477 Slug: post.Slug,
478478 PublishAt: post.PublishAt.Format(time.DateOnly),
479479 PublishAtISO: post.PublishAt.Format(time.RFC3339),
......@@ -544,7 +544,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
544544 w.WriteHeader(http.StatusNotFound)
545545 }
546546
547- ts, err := shared.RenderTemplate(cfg, []string{
547+ ts, err := router.RenderTemplate(cfg, []string{
548548 cfg.StaticPath("html/list.partial.tmpl"),
549549 cfg.StaticPath("html/post.page.tmpl"),
550550 })
......@@ -563,9 +563,9 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
563563 }
564564
565565 func readHandler(w http.ResponseWriter, r *http.Request) {
566- dbpool := shared.GetDB(r)
567- logger := shared.GetLogger(r)
568- cfg := shared.GetCfg(r)
566+ dbpool := router.GetDB(r)
567+ logger := router.GetLogger(r)
568+ cfg := router.GetCfg(r)
569569
570570 page, _ := strconv.Atoi(r.URL.Query().Get("page"))
571571 tag := r.URL.Query().Get("tag")
......@@ -583,7 +583,7 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
583583 return
584584 }
585585
586- ts, err := shared.RenderTemplate(cfg, []string{
586+ ts, err := router.RenderTemplate(cfg, []string{
587587 cfg.StaticPath("html/read.page.tmpl"),
588588 })
589589
......@@ -625,12 +625,12 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
625625 item := PostItemData{
626626 URL: template.URL(cfg.FullPostURL(curl, post.Username, post.Slug)),
627627 BlogURL: template.URL(cfg.FullBlogURL(curl, post.Username)),
628- Title: utils.FilenameToTitle(post.Filename, post.Title),
628+ Title: shared.FilenameToTitle(post.Filename, post.Title),
629629 Description: post.Description,
630630 Username: post.Username,
631631 PublishAt: post.PublishAt.Format(time.DateOnly),
632632 PublishAtISO: post.PublishAt.Format(time.RFC3339),
633- UpdatedTimeAgo: utils.TimeAgo(post.UpdatedAt),
633+ UpdatedTimeAgo: shared.TimeAgo(post.UpdatedAt),
634634 UpdatedAtISO: post.UpdatedAt.Format(time.RFC3339),
635635 }
636636 data.Posts = append(data.Posts, item)
......@@ -644,10 +644,10 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
644644 }
645645
646646 func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
647- username := shared.GetUsernameFromRequest(r)
648- dbpool := shared.GetDB(r)
649- logger := shared.GetLogger(r)
650- cfg := shared.GetCfg(r)
647+ username := router.GetUsernameFromRequest(r)
648+ dbpool := router.GetDB(r)
649+ logger := router.GetLogger(r)
650+ cfg := router.GetCfg(r)
651651
652652 user, err := dbpool.FindUserByName(username)
653653 if err != nil {
......@@ -675,7 +675,7 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
675675 return
676676 }
677677
678- ts, err := template.New("rss.page.tmpl").Funcs(shared.FuncMap).ParseFiles(
678+ ts, err := template.New("rss.page.tmpl").Funcs(router.FuncMap).ParseFiles(
679679 cfg.StaticPath("html/list.partial.tmpl"),
680680 cfg.StaticPath("html/rss.page.tmpl"),
681681 )
......@@ -775,7 +775,7 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
775775
776776 item := &feeds.Item{
777777 Id: feedId,
778- Title: utils.FilenameToTitle(post.Filename, post.Title),
778+ Title: shared.FilenameToTitle(post.Filename, post.Title),
779779 Link: &feeds.Link{Href: realUrl},
780780 Content: content,
781781 Updated: *post.PublishAt,
......@@ -805,9 +805,9 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
805805 }
806806
807807 func rssHandler(w http.ResponseWriter, r *http.Request) {
808- dbpool := shared.GetDB(r)
809- logger := shared.GetLogger(r)
810- cfg := shared.GetCfg(r)
808+ dbpool := router.GetDB(r)
809+ logger := router.GetLogger(r)
810+ cfg := router.GetCfg(r)
811811
812812 pager, err := dbpool.FindPostsByFeed(&db.Pager{Num: 25, Page: 0}, cfg.Space)
813813 if err != nil {
......@@ -816,7 +816,7 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
816816 return
817817 }
818818
819- ts, err := template.New("rss.page.tmpl").Funcs(shared.FuncMap).ParseFiles(
819+ ts, err := template.New("rss.page.tmpl").Funcs(router.FuncMap).ParseFiles(
820820 cfg.StaticPath("html/list.partial.tmpl"),
821821 cfg.StaticPath("html/rss.page.tmpl"),
822822 )
......@@ -907,8 +907,8 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
907907
908908 func serveFile(file string, contentType string) http.HandlerFunc {
909909 return func(w http.ResponseWriter, r *http.Request) {
910- logger := shared.GetLogger(r)
911- cfg := shared.GetCfg(r)
910+ logger := router.GetLogger(r)
911+ cfg := router.GetCfg(r)
912912
913913 contents, err := os.ReadFile(cfg.StaticPath(fmt.Sprintf("public/%s", file)))
914914 if err != nil {
......@@ -925,29 +925,29 @@ func serveFile(file string, contentType string) http.HandlerFunc {
925925 }
926926 }
927927
928-func createStaticRoutes() []shared.Route {
929- return []shared.Route{
930- shared.NewRoute("GET", "/main.css", serveFile("main.css", "text/css")),
931- shared.NewRoute("GET", "/smol.css", serveFile("smol.css", "text/css")),
932- shared.NewRoute("GET", "/smol-v2.css", serveFile("smol-v2.css", "text/css")),
933- shared.NewRoute("GET", "/syntax.css", serveFile("syntax.css", "text/css")),
934- shared.NewRoute("GET", "/card.png", serveFile("card.png", "image/png")),
935- shared.NewRoute("GET", "/favicon-16x16.png", serveFile("favicon-16x16.png", "image/png")),
936- shared.NewRoute("GET", "/favicon-32x32.png", serveFile("favicon-32x32.png", "image/png")),
937- shared.NewRoute("GET", "/apple-touch-icon.png", serveFile("apple-touch-icon.png", "image/png")),
938- shared.NewRoute("GET", "/favicon.ico", serveFile("favicon.ico", "image/x-icon")),
939- shared.NewRoute("GET", "/robots.txt", serveFile("robots.txt", "text/plain")),
928+func createStaticRoutes() []router.Route {
929+ return []router.Route{
930+ router.NewRoute("GET", "/main.css", serveFile("main.css", "text/css")),
931+ router.NewRoute("GET", "/smol.css", serveFile("smol.css", "text/css")),
932+ router.NewRoute("GET", "/smol-v2.css", serveFile("smol-v2.css", "text/css")),
933+ router.NewRoute("GET", "/syntax.css", serveFile("syntax.css", "text/css")),
934+ router.NewRoute("GET", "/card.png", serveFile("card.png", "image/png")),
935+ router.NewRoute("GET", "/favicon-16x16.png", serveFile("favicon-16x16.png", "image/png")),
936+ router.NewRoute("GET", "/favicon-32x32.png", serveFile("favicon-32x32.png", "image/png")),
937+ router.NewRoute("GET", "/apple-touch-icon.png", serveFile("apple-touch-icon.png", "image/png")),
938+ router.NewRoute("GET", "/favicon.ico", serveFile("favicon.ico", "image/x-icon")),
939+ router.NewRoute("GET", "/robots.txt", serveFile("robots.txt", "text/plain")),
940940 }
941941 }
942942
943-func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
944- routes := []shared.Route{
945- shared.NewRoute("GET", "/", readHandler),
946- shared.NewRoute("GET", "/read", readHandler),
947- shared.NewRoute("GET", "/check", shared.CheckHandler),
948- shared.NewRoute("GET", "/rss", rssHandler),
949- shared.NewRoute("GET", "/rss.atom", rssHandler),
950- shared.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
943+func createMainRoutes(staticRoutes []router.Route) []router.Route {
944+ routes := []router.Route{
945+ router.NewRoute("GET", "/", readHandler),
946+ router.NewRoute("GET", "/read", readHandler),
947+ router.NewRoute("GET", "/check", router.CheckHandler),
948+ router.NewRoute("GET", "/rss", rssHandler),
949+ router.NewRoute("GET", "/rss.atom", rssHandler),
950+ router.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
951951 }
952952
953953 routes = append(
......@@ -959,10 +959,10 @@ func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
959959 }
960960
961961 func imgRequest(w http.ResponseWriter, r *http.Request) {
962- logger := shared.GetLogger(r)
963- st := shared.GetStorage(r)
964- dbpool := shared.GetDB(r)
965- username := shared.GetUsernameFromRequest(r)
962+ logger := router.GetLogger(r)
963+ st := router.GetStorage(r)
964+ dbpool := router.GetDB(r)
965+ username := router.GetUsernameFromRequest(r)
966966 user, err := dbpool.FindUserByName(username)
967967 if err != nil {
968968 logger.Error("could not find user", "username", username)
......@@ -971,8 +971,8 @@ func imgRequest(w http.ResponseWriter, r *http.Request) {
971971 }
972972 logger = shared.LoggerWithUser(logger, user)
973973
974- rawname := shared.GetField(r, 0)
975- imgOpts := shared.GetField(r, 1)
974+ rawname := router.GetField(r, 0)
975+ imgOpts := router.GetField(r, 1)
976976 // we place all prose images inside a "prose" folder
977977 fname := filepath.Join("/prose", rawname)
978978
......@@ -1037,17 +1037,17 @@ func imgRequest(w http.ResponseWriter, r *http.Request) {
10371037 }
10381038 }
10391039
1040-func createSubdomainRoutes(staticRoutes []shared.Route) []shared.Route {
1041- routes := []shared.Route{
1042- shared.NewRoute("GET", "/", blogHandler),
1043- shared.NewRoute("GET", "/_styles.css", blogStyleHandler),
1044- shared.NewRoute("GET", "/robots.txt", robotsHandler),
1045- shared.NewRoute("GET", "/rss", rssBlogHandler),
1046- shared.NewRoute("GET", "/rss.xml", rssBlogHandler),
1047- shared.NewRoute("GET", "/atom.xml", rssBlogHandler),
1048- shared.NewRoute("GET", "/feed.xml", rssBlogHandler),
1049- shared.NewRoute("GET", "/atom", rssBlogHandler),
1050- shared.NewRoute("GET", "/blog/index.xml", rssBlogHandler),
1040+func createSubdomainRoutes(staticRoutes []router.Route) []router.Route {
1041+ routes := []router.Route{
1042+ router.NewRoute("GET", "/", blogHandler),
1043+ router.NewRoute("GET", "/_styles.css", blogStyleHandler),
1044+ router.NewRoute("GET", "/robots.txt", robotsHandler),
1045+ router.NewRoute("GET", "/rss", rssBlogHandler),
1046+ router.NewRoute("GET", "/rss.xml", rssBlogHandler),
1047+ router.NewRoute("GET", "/atom.xml", rssBlogHandler),
1048+ router.NewRoute("GET", "/feed.xml", rssBlogHandler),
1049+ router.NewRoute("GET", "/atom", rssBlogHandler),
1050+ router.NewRoute("GET", "/blog/index.xml", rssBlogHandler),
10511051 }
10521052
10531053 routes = append(
......@@ -1057,13 +1057,13 @@ func createSubdomainRoutes(staticRoutes []shared.Route) []shared.Route {
10571057
10581058 routes = append(
10591059 routes,
1060- shared.NewRoute("GET", "/raw/(.+)", postRawHandler),
1061- shared.NewRoute("GET", "/(.+).md", postRawHandler),
1062- shared.NewRoute("GET", "/(.+).lxt", postRawHandler),
1063- shared.NewRoute("GET", `/(.+\.(?:jpg|jpeg|png|gif|webp|svg|ico))/(.+)`, imgRequest),
1064- shared.NewRoute("GET", `/(.+\.(?:jpg|jpeg|png|gif|webp|svg|ico))$`, imgRequest),
1065- shared.NewRoute("GET", "/(.+).html", postHandler),
1066- shared.NewRoute("GET", "/(.+)", postHandler),
1060+ router.NewRoute("GET", "/raw/(.+)", postRawHandler),
1061+ router.NewRoute("GET", "/(.+).md", postRawHandler),
1062+ router.NewRoute("GET", "/(.+).lxt", postRawHandler),
1063+ router.NewRoute("GET", `/(.+\.(?:jpg|jpeg|png|gif|webp|svg|ico))/(.+)`, imgRequest),
1064+ router.NewRoute("GET", `/(.+\.(?:jpg|jpeg|png|gif|webp|svg|ico))$`, imgRequest),
1065+ router.NewRoute("GET", "/(.+).html", postHandler),
1066+ router.NewRoute("GET", "/(.+)", postHandler),
10671067 )
10681068
10691069 return routes
......@@ -1087,18 +1087,18 @@ func StartApiServer() {
10871087 staticRoutes := createStaticRoutes()
10881088
10891089 if cfg.Debug {
1090- staticRoutes = shared.CreatePProfRoutes(staticRoutes)
1090+ staticRoutes = router.CreatePProfRoutes(staticRoutes)
10911091 }
10921092
10931093 mainRoutes := createMainRoutes(staticRoutes)
10941094 subdomainRoutes := createSubdomainRoutes(staticRoutes)
10951095
1096- apiConfig := &shared.ApiConfig{
1096+ apiConfig := &router.ApiConfig{
10971097 Cfg: cfg,
10981098 Dbpool: dbpool,
10991099 Storage: st,
11001100 }
1101- handler := shared.CreateServe(mainRoutes, subdomainRoutes, apiConfig)
1101+ handler := router.CreateServe(mainRoutes, subdomainRoutes, apiConfig)
11021102 router := http.HandlerFunc(handler)
11031103
11041104 portStr := fmt.Sprintf(":%s", cfg.Port)
+9, -10
......@@ -4,20 +4,19 @@ import (
44 "strings"
55
66 "github.com/picosh/pico/pkg/shared"
7- "github.com/picosh/utils"
87 )
98
10-var MAX_FILE_SIZE = 3 * utils.MB
9+var MAX_FILE_SIZE = 3 * shared.MB
1110
1211 func NewConfigSite(service string) *shared.ConfigSite {
13- debug := utils.GetEnv("PROSE_DEBUG", "0")
14- domain := utils.GetEnv("PROSE_DOMAIN", "prose.sh")
15- port := utils.GetEnv("PROSE_WEB_PORT", "3000")
16- protocol := utils.GetEnv("PROSE_PROTOCOL", "https")
17- dbURL := utils.GetEnv("DATABASE_URL", "")
18- maxSize := uint64(25 * utils.MB)
19- maxImgSize := int64(10 * utils.MB)
20- withPipe := strings.ToLower(utils.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
12+ debug := shared.GetEnv("PROSE_DEBUG", "0")
13+ domain := shared.GetEnv("PROSE_DOMAIN", "prose.sh")
14+ port := shared.GetEnv("PROSE_WEB_PORT", "3000")
15+ protocol := shared.GetEnv("PROSE_PROTOCOL", "https")
16+ dbURL := shared.GetEnv("DATABASE_URL", "")
17+ maxSize := uint64(25 * shared.MB)
18+ maxImgSize := int64(10 * shared.MB)
19+ withPipe := strings.ToLower(shared.GetEnv("PICO_PIPE_ENABLED", "true")) == "true"
2120
2221 return &shared.ConfigSite{
2322 Debug: debug == "1",
+4, -5
......@@ -11,7 +11,6 @@ import (
1111 "github.com/picosh/pico/pkg/filehandlers"
1212 "github.com/picosh/pico/pkg/pssh"
1313 "github.com/picosh/pico/pkg/shared"
14- "github.com/picosh/utils"
1514 pipeUtil "github.com/picosh/utils/pipe"
1615 )
1716
......@@ -22,7 +21,7 @@ type MarkdownHooks struct {
2221 }
2322
2423 func (p *MarkdownHooks) FileValidate(s *pssh.SSHServerConnSession, data *filehandlers.PostMetaData) (bool, error) {
25- if !utils.IsTextFile(data.Text) {
24+ if !shared.IsTextFile(data.Text) {
2625 err := fmt.Errorf(
2726 "ERROR: (%s) invalid file must be plain text (utf-8), skipping",
2827 data.Filename,
......@@ -42,7 +41,7 @@ func (p *MarkdownHooks) FileValidate(s *pssh.SSHServerConnSession, data *filehan
4241 return true, nil
4342 }
4443
45- if !utils.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) {
44+ if !shared.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) {
4645 extStr := strings.Join(p.Cfg.AllowedExt, ",")
4746 err := fmt.Errorf(
4847 "ERROR: (%s) invalid file, format must be (%s), skipping",
......@@ -67,7 +66,7 @@ func (p *MarkdownHooks) metaLxt(data *filehandlers.PostMetaData) error {
6766 parsedText := shared.ListParseText(data.Text)
6867
6968 if parsedText.Title == "" {
70- data.Title = utils.ToUpper(data.Slug)
69+ data.Title = shared.ToUpper(data.Slug)
7170 } else {
7271 data.Title = parsedText.Title
7372 }
......@@ -91,7 +90,7 @@ func (p *MarkdownHooks) metaMd(data *filehandlers.PostMetaData) error {
9190 }
9291
9392 if parsedText.Title == "" {
94- data.Title = utils.ToUpper(data.Slug)
93+ data.Title = shared.ToUpper(data.Slug)
9594 } else {
9695 data.Title = parsedText.Title
9796 }
+3, -4
......@@ -19,15 +19,14 @@ import (
1919 "github.com/picosh/pico/pkg/send/protocols/sftp"
2020 "github.com/picosh/pico/pkg/shared"
2121 "github.com/picosh/pico/pkg/shared/storage"
22- "github.com/picosh/utils"
2322 )
2423
2524 func StartSshServer() {
2625 appName := "prose-ssh"
2726
28- host := utils.GetEnv("PROSE_HOST", "0.0.0.0")
29- port := utils.GetEnv("PROSE_SSH_PORT", "2222")
30- promPort := utils.GetEnv("PROSE_PROM_PORT", "9222")
27+ host := shared.GetEnv("PROSE_HOST", "0.0.0.0")
28+ port := shared.GetEnv("PROSE_SSH_PORT", "2222")
29+ promPort := shared.GetEnv("PROSE_PROM_PORT", "9222")
3130 cfg := NewConfigSite(appName)
3231 logger := cfg.Logger
3332
+0, -21
......@@ -1,21 +0,0 @@
1-package cache
2-
3-import (
4- "log/slog"
5- "time"
6-
7- "github.com/picosh/utils"
8-)
9-
10-var CacheTimeout time.Duration
11-
12-func init() {
13- cacheDuration := utils.GetEnv("STORAGE_MINIO_CACHE_DURATION", "1m")
14- duration, err := time.ParseDuration(cacheDuration)
15- if err != nil {
16- slog.Error("Invalid STORAGE_MINIO_CACHE_DURATION value, using default 1m", "error", err)
17- duration = 1 * time.Minute
18- }
19-
20- CacheTimeout = duration
21-}
+2, -2
......@@ -14,7 +14,7 @@ import (
1414 "github.com/jmoiron/sqlx"
1515 _ "github.com/lib/pq"
1616 "github.com/picosh/pico/pkg/db"
17- "github.com/picosh/utils"
17+ "github.com/picosh/pico/pkg/shared"
1818 )
1919
2020 var PAGER_SIZE = 15
......@@ -1232,7 +1232,7 @@ func (me *PsqlDB) FindFeedItemsByPostID(postID string) ([]*db.FeedItem, error) {
12321232 }
12331233
12341234 func (me *PsqlDB) InsertProject(userID, name, projectDir string) (string, error) {
1235- if !utils.IsValidSubdomain(name) {
1235+ if !shared.IsValidSubdomain(name) {
12361236 return "", fmt.Errorf("'%s' is not a valid project name, must match /^[a-z0-9-]+$/", name)
12371237 }
12381238
+3, -4
......@@ -19,7 +19,6 @@ import (
1919 sendutils "github.com/picosh/pico/pkg/send/utils"
2020 "github.com/picosh/pico/pkg/shared"
2121 "github.com/picosh/pico/pkg/shared/storage"
22- "github.com/picosh/utils"
2322 )
2423
2524 var Space = "imgs"
......@@ -214,8 +213,8 @@ func (h *UploadImgHandler) Write(s *pssh.SSHServerConnSession, entry *sendutils.
214213 str := fmt.Sprintf(
215214 "%s (space: %.2f/%.2fGB, %.2f%%)",
216215 url,
217- utils.BytesToGB(metadata.TotalFileSize+fileSize),
218- utils.BytesToGB(maxSize),
216+ shared.BytesToGB(metadata.TotalFileSize+fileSize),
217+ shared.BytesToGB(maxSize),
219218 (float32(totalFileSize)/float32(maxSize))*100,
220219 )
221220 return str, nil
......@@ -262,7 +261,7 @@ func (h *UploadImgHandler) validateImg(data *PostMetaData) (bool, error) {
262261 return false, fmt.Errorf("ERROR: user (%s) has exceeded (%d bytes) max (%d bytes)", data.User.Name, data.TotalFileSize, storageMax)
263262 }
264263
265- if !utils.IsExtAllowed(data.Filename, h.Cfg.AllowedExt) {
264+ if !shared.IsExtAllowed(data.Filename, h.Cfg.AllowedExt) {
266265 extStr := strings.Join(h.Cfg.AllowedExt, ",")
267266 err := fmt.Errorf(
268267 "ERROR: (%s) invalid file, format must be (%s), skipping",
+2, -3
......@@ -14,7 +14,6 @@ import (
1414 "github.com/picosh/pico/pkg/pssh"
1515 sendutils "github.com/picosh/pico/pkg/send/utils"
1616 "github.com/picosh/pico/pkg/shared"
17- "github.com/picosh/utils"
1817 )
1918
2019 type PostMetaData struct {
......@@ -116,9 +115,9 @@ func (h *ScpUploadHandler) Write(s *pssh.SSHServerConnSession, entry *sendutils.
116115 }
117116
118117 now := time.Now()
119- slug := utils.SanitizeFileExt(filename)
118+ slug := shared.SanitizeFileExt(filename)
120119 fileSize := binary.Size(origText)
121- shasum := utils.Shasum(origText)
120+ shasum := shared.Shasum(origText)
122121
123122 nextPost := db.Post{
124123 Filename: filename,
+4, -2
......@@ -17,9 +17,11 @@ import (
1717 "github.com/google/renameio/v2"
1818 "github.com/picosh/pico/pkg/send/utils"
1919 "github.com/picosh/pico/pkg/shared/mime"
20- putils "github.com/picosh/utils"
2120 )
2221
22+var KB = 1000
23+var MB = KB * 1000
24+
2325 // https://stackoverflow.com/a/32482941
2426 func dirSize(path string) (int64, error) {
2527 var size int64
......@@ -121,7 +123,7 @@ func (s *StorageFS) GetObject(bucket Bucket, fpath string) (utils.ReadAndReaderA
121123
122124 etag := ""
123125 // only generate etag if file is less than 10MB
124- if info.Size() <= int64(10*putils.MB) {
126+ if info.Size() <= int64(10*MB) {
125127 // calculate etag
126128 h := md5.New()
127129 if _, err := io.Copy(h, dat); err != nil {
+5, -0
......@@ -0,0 +1,5 @@
1+package shared
2+
3+import "time"
4+
5+var CacheTimeout = 2 * time.Minute
+37, -0
......@@ -0,0 +1,37 @@
1+package shared
2+
3+import (
4+ "fmt"
5+ "io"
6+ "log/slog"
7+ "os"
8+)
9+
10+type CmdSessionLogger struct {
11+ Log *slog.Logger
12+}
13+
14+func (c *CmdSessionLogger) Write(out []byte) (int, error) {
15+ c.Log.Info(string(out))
16+ return 0, nil
17+}
18+
19+func (c *CmdSessionLogger) Exit(code int) error {
20+ os.Exit(code)
21+ return fmt.Errorf("panic %d", code)
22+}
23+
24+func (c *CmdSessionLogger) Close() error {
25+ return fmt.Errorf("closing")
26+}
27+
28+func (c *CmdSessionLogger) Stderr() io.ReadWriter {
29+ return nil
30+}
31+
32+type CmdSession interface {
33+ Write([]byte) (int, error)
34+ Exit(code int) error
35+ Close() error
36+ Stderr() io.ReadWriter
37+}
+6, -7
......@@ -1,17 +1,16 @@
11 package shared
22
33 import (
4- "github.com/picosh/utils"
54 "github.com/picosh/utils/pipe"
65 )
76
87 func NewPicoPipeClient() *pipe.SSHClientInfo {
98 return &pipe.SSHClientInfo{
10- RemoteHost: utils.GetEnv("PICO_PIPE_ENDPOINT", "pipe.pico.sh:22"),
11- KeyLocation: utils.GetEnv("PICO_PIPE_KEY", "ssh_data/term_info_ed25519"),
12- CertificateLocation: utils.GetEnv("PICO_PIPE_KEY_CERT", ""),
13- KeyPassphrase: utils.GetEnv("PICO_PIPE_PASSPHRASE", ""),
14- RemoteHostname: utils.GetEnv("PICO_PIPE_REMOTE_HOST", "pipe.pico.sh"),
15- RemoteUser: utils.GetEnv("PICO_PIPE_USER", "pico"),
9+ RemoteHost: GetEnv("PICO_PIPE_ENDPOINT", "pipe.pico.sh:22"),
10+ KeyLocation: GetEnv("PICO_PIPE_KEY", "ssh_data/term_info_ed25519"),
11+ CertificateLocation: GetEnv("PICO_PIPE_KEY_CERT", ""),
12+ KeyPassphrase: GetEnv("PICO_PIPE_PASSPHRASE", ""),
13+ RemoteHostname: GetEnv("PICO_PIPE_REMOTE_HOST", "pipe.pico.sh"),
14+ RemoteUser: GetEnv("PICO_PIPE_USER", "pico"),
1615 }
1716 }
R pkg/shared/analytics.go => pkg/shared/router/analytics.go
+3, -2
......@@ -1,4 +1,4 @@
1-package shared
1+package router
22
33 import (
44 "context"
......@@ -16,6 +16,7 @@ import (
1616 "time"
1717
1818 "github.com/picosh/pico/pkg/db"
19+ "github.com/picosh/pico/pkg/shared"
1920 "github.com/picosh/utils/pipe/metrics"
2021 "github.com/simplesurance/go-ip-anonymizer/ipanonymizer"
2122 "github.com/x-way/crawlerdetect"
......@@ -233,7 +234,7 @@ func AnalyticsCollect(ch chan *db.AnalyticsVisits, dbpool db.DB, logger *slog.Lo
233234 drain := metrics.RegisterReconnectMetricRecorder(
234235 context.Background(),
235236 logger,
236- NewPicoPipeClient(),
237+ shared.NewPicoPipeClient(),
237238 100,
238239 10*time.Millisecond,
239240 )
R pkg/shared/api.go => pkg/shared/router/api.go
+5, -5
......@@ -1,4 +1,4 @@
1-package shared
1+package router
22
33 import (
44 "encoding/json"
......@@ -9,7 +9,7 @@ import (
99 "strings"
1010
1111 "github.com/picosh/pico/pkg/db"
12- "github.com/picosh/utils"
12+ "github.com/picosh/pico/pkg/shared"
1313 "golang.org/x/crypto/ssh"
1414 )
1515
......@@ -61,7 +61,7 @@ type UserApi struct {
6161 func NewUserApi(user *db.User, pubkey ssh.PublicKey) *UserApi {
6262 return &UserApi{
6363 User: user,
64- Fingerprint: utils.KeyForSha256(pubkey),
64+ Fingerprint: shared.KeyForSha256(pubkey),
6565 }
6666 }
6767
......@@ -136,7 +136,7 @@ var FuncMap = template.FuncMap{
136136 "intRange": intRange,
137137 }
138138
139-func RenderTemplate(cfg *ConfigSite, templates []string) (*template.Template, error) {
139+func RenderTemplate(cfg *shared.ConfigSite, templates []string) (*template.Template, error) {
140140 files := make([]string, len(templates))
141141 copy(files, templates)
142142 files = append(
......@@ -165,7 +165,7 @@ func CreatePageHandler(fname string) http.HandlerFunc {
165165 return
166166 }
167167
168- data := PageData{
168+ data := shared.PageData{
169169 Site: *cfg.GetSiteData(),
170170 }
171171 err = ts.Execute(w, data)
R pkg/shared/router.go => pkg/shared/router/router.go
+7, -7
......@@ -1,4 +1,4 @@
1-package shared
1+package router
22
33 import (
44 "context"
......@@ -11,9 +11,9 @@ import (
1111 "strings"
1212
1313 "github.com/hashicorp/golang-lru/v2/expirable"
14- "github.com/picosh/pico/pkg/cache"
1514 "github.com/picosh/pico/pkg/db"
1615 "github.com/picosh/pico/pkg/pssh"
16+ "github.com/picosh/pico/pkg/shared"
1717 "github.com/picosh/pico/pkg/shared/storage"
1818 )
1919
......@@ -71,7 +71,7 @@ func CreatePProfRoutesMux(mux *http.ServeMux) {
7171 }
7272
7373 type ApiConfig struct {
74- Cfg *ConfigSite
74+ Cfg *shared.ConfigSite
7575 Dbpool db.DB
7676 Storage storage.StorageServe
7777 }
......@@ -147,7 +147,7 @@ func GetSubdomainFromRequest(r *http.Request, domain, space string) string {
147147 return ""
148148 }
149149
150-func findRouteConfig(r *http.Request, routes []Route, subdomainRoutes []Route, cfg *ConfigSite) ([]Route, string) {
150+func findRouteConfig(r *http.Request, routes []Route, subdomainRoutes []Route, cfg *shared.ConfigSite) ([]Route, string) {
151151 if len(subdomainRoutes) == 0 {
152152 return routes, ""
153153 }
......@@ -185,8 +185,8 @@ func GetSshCtx(r *http.Request) (*pssh.SSHServerConnSession, error) {
185185 return payload, nil
186186 }
187187
188-func GetCfg(r *http.Request) *ConfigSite {
189- return r.Context().Value(ctxCfg{}).(*ConfigSite)
188+func GetCfg(r *http.Request) *shared.ConfigSite {
189+ return r.Context().Value(ctxCfg{}).(*shared.ConfigSite)
190190 }
191191
192192 func GetLogger(r *http.Request) *slog.Logger {
......@@ -213,7 +213,7 @@ func GetSubdomain(r *http.Request) string {
213213 return r.Context().Value(CtxSubdomainKey{}).(string)
214214 }
215215
216-var txtCache = expirable.NewLRU[string, string](2048, nil, cache.CacheTimeout)
216+var txtCache = expirable.NewLRU[string, string](2048, nil, shared.CacheTimeout)
217217
218218 func GetCustomDomain(host string, space string) string {
219219 txt := fmt.Sprintf("_%s.%s", space, host)
+2, -3
......@@ -7,7 +7,6 @@ import (
77 "time"
88
99 "github.com/picosh/pico/pkg/db"
10- "github.com/picosh/utils"
1110 "golang.org/x/crypto/ssh"
1211 )
1312
......@@ -41,7 +40,7 @@ type AuthedPubkey struct {
4140 }
4241
4342 func PubkeyCertVerify(key ssh.PublicKey, srcPrincipal string) (*AuthedPubkey, error) {
44- origPubkey := utils.KeyForKeyText(key)
43+ origPubkey := KeyForKeyText(key)
4544 authed := &AuthedPubkey{
4645 OrigPubkey: origPubkey,
4746 Pubkey: origPubkey,
......@@ -74,7 +73,7 @@ func PubkeyCertVerify(key ssh.PublicKey, srcPrincipal string) (*AuthedPubkey, er
7473 return nil, fmt.Errorf("ssh-cert has expired")
7574 }
7675
77- authed.Pubkey = utils.KeyForKeyText(cert.SignatureKey)
76+ authed.Pubkey = KeyForKeyText(cert.SignatureKey)
7877 authed.Identity = cert.KeyId
7978 return authed, nil
8079 }
+3, -3
......@@ -4,18 +4,18 @@ import (
44 "fmt"
55 "log/slog"
66
7- "github.com/picosh/utils"
7+ "github.com/picosh/pico/pkg/shared"
88 )
99
1010 func GetStorageTypeFromEnv() string {
11- return utils.GetEnv("STORAGE_ADAPTER", "fs")
11+ return shared.GetEnv("STORAGE_ADAPTER", "fs")
1212 }
1313
1414 func NewStorage(logger *slog.Logger, adapter string) (StorageServe, error) {
1515 logger.Info("storage adapter", "adapter", adapter)
1616 switch adapter {
1717 case "fs":
18- fsPath := utils.GetEnv("FS_STORAGE_DIR", "/tmp/pico_storage")
18+ fsPath := shared.GetEnv("FS_STORAGE_DIR", "/tmp/pico_storage")
1919 logger.Info("using filesystem storage", "path", fsPath)
2020 return NewStorageFS(logger, fsPath)
2121 case "memory":
+4, -4
......@@ -11,7 +11,7 @@ import (
1111 "git.sr.ht/~rockorager/vaxis/vxfw/richtext"
1212 "git.sr.ht/~rockorager/vaxis/vxfw/text"
1313 "github.com/picosh/pico/pkg/db"
14- "github.com/picosh/utils"
14+ "github.com/picosh/pico/pkg/shared"
1515 )
1616
1717 type SitesLoaded struct{}
......@@ -355,7 +355,7 @@ func (m *AnalyticsPage) visits(ctx vxfw.DrawContext, intervals []*db.VisitInterv
355355 func (m *AnalyticsPage) fetchSites() {
356356 siteList, err := m.shared.Dbpool.FindVisitSiteList(&db.SummaryOpts{
357357 UserID: m.shared.User.ID,
358- Origin: utils.StartOfMonth(),
358+ Origin: shared.StartOfMonth(),
359359 })
360360 if err != nil {
361361 m.loadingSites = false
......@@ -376,9 +376,9 @@ func (m *AnalyticsPage) fetchSiteStats(site string, interval string) {
376376 }
377377
378378 if interval == "day" {
379- opts.Origin = utils.StartOfMonth()
379+ opts.Origin = shared.StartOfMonth()
380380 } else {
381- opts.Origin = utils.StartOfYear()
381+ opts.Origin = shared.StartOfYear()
382382 }
383383
384384 summary, err := m.shared.Dbpool.VisitSummary(opts)
+10, -11
......@@ -14,7 +14,6 @@ import (
1414 "git.sr.ht/~rockorager/vaxis/vxfw/richtext"
1515 "git.sr.ht/~rockorager/vaxis/vxfw/text"
1616 "github.com/picosh/pico/pkg/shared"
17- "github.com/picosh/utils"
1817 pipeLogger "github.com/picosh/utils/pipe/log"
1918 )
2019
......@@ -215,10 +214,10 @@ func (m *LogsPage) connectToLogs() error {
215214 continue
216215 }
217216
218- user := utils.AnyToStr(parsedData, "user")
219- userId := utils.AnyToStr(parsedData, "userId")
217+ user := shared.AnyToStr(parsedData, "user")
218+ userId := shared.AnyToStr(parsedData, "userId")
220219
221- hidden := utils.AnyToBool(parsedData, "hidden")
220+ hidden := shared.AnyToBool(parsedData, "hidden")
222221
223222 if !hidden && (user == m.shared.User.Name || userId == m.shared.User.ID) {
224223 m.shared.App.PostEvent(LogLineLoaded{parsedData})
......@@ -250,13 +249,13 @@ type LogLine struct {
250249 }
251250
252251 func NewLogLine(data map[string]any) *LogLine {
253- rawtime := utils.AnyToStr(data, "time")
254- service := utils.AnyToStr(data, "service")
255- level := utils.AnyToStr(data, "level")
256- msg := utils.AnyToStr(data, "msg")
257- errMsg := utils.AnyToStr(data, "err")
258- status := utils.AnyToFloat(data, "status")
259- url := utils.AnyToStr(data, "url")
252+ rawtime := shared.AnyToStr(data, "time")
253+ service := shared.AnyToStr(data, "service")
254+ level := shared.AnyToStr(data, "level")
255+ msg := shared.AnyToStr(data, "msg")
256+ errMsg := shared.AnyToStr(data, "err")
257+ status := shared.AnyToFloat(data, "status")
258+ url := shared.AnyToStr(data, "url")
260259 date, err := time.Parse(time.RFC3339Nano, rawtime)
261260 dateStr := rawtime
262261 if err == nil {
+2, -2
......@@ -11,7 +11,7 @@ import (
1111 "git.sr.ht/~rockorager/vaxis/vxfw/richtext"
1212 "git.sr.ht/~rockorager/vaxis/vxfw/text"
1313 "github.com/picosh/pico/pkg/db"
14- "github.com/picosh/utils"
14+ "github.com/picosh/pico/pkg/shared"
1515 "golang.org/x/crypto/ssh"
1616 )
1717
......@@ -253,7 +253,7 @@ func (m *AddKeyPage) addPubkey(pubkey string) error {
253253 return err
254254 }
255255
256- key := utils.KeyForKeyText(pk)
256+ key := shared.KeyForKeyText(pk)
257257
258258 return m.shared.Dbpool.InsertPublicKey(
259259 m.shared.User.ID, key, comment,
+2, -2
......@@ -10,7 +10,7 @@ import (
1010 "git.sr.ht/~rockorager/vaxis/vxfw/text"
1111 "github.com/picosh/pico/pkg/db"
1212 "github.com/picosh/pico/pkg/pssh"
13- "github.com/picosh/utils"
13+ "github.com/picosh/pico/pkg/shared"
1414 "golang.org/x/crypto/ssh"
1515 )
1616
......@@ -44,7 +44,7 @@ func (m *SignupPage) createAccount(name string) (*db.User, error) {
4444 if name == "" {
4545 return nil, fmt.Errorf("name cannot be empty")
4646 }
47- key := utils.KeyForKeyText(m.shared.Session.PublicKey())
47+ key := shared.KeyForKeyText(m.shared.Session.PublicKey())
4848 return m.shared.Dbpool.RegisterUser(name, key, "")
4949 }
5050
+1, -2
......@@ -14,7 +14,6 @@ import (
1414 "github.com/picosh/pico/pkg/db"
1515 "github.com/picosh/pico/pkg/pssh"
1616 "github.com/picosh/pico/pkg/shared"
17- "github.com/picosh/utils"
1817 )
1918
2019 const (
......@@ -289,7 +288,7 @@ func FindUser(shrd *SharedModel) (*db.User, error) {
289288 return nil, fmt.Errorf("unable to find public key")
290289 }
291290
292- key := utils.KeyForKeyText(shrd.Session.PublicKey())
291+ key := shared.KeyForKeyText(shrd.Session.PublicKey())
293292
294293 user, err := shrd.Dbpool.FindUserByKey(usr, key)
295294 if err != nil {