repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

pico / shared
Eric Bower · 20 Sep 24

config.go

  1package shared
  2
  3import (
  4	"fmt"
  5	"html/template"
  6	"log/slog"
  7	"net/http"
  8	"net/url"
  9	"os"
 10	"path"
 11	"strings"
 12
 13	"github.com/picosh/pico/db"
 14)
 15
 16var DefaultEmail = "hello@pico.sh"
 17
 18type SitePageData struct {
 19	Domain  template.URL
 20	HomeURL template.URL
 21}
 22
 23type PageData struct {
 24	Site SitePageData
 25}
 26
 27type ConfigSite struct {
 28	Debug        bool
 29	SendgridKey  string
 30	Secret       string
 31	Domain       string
 32	Port         string
 33	Protocol     string
 34	DbURL        string
 35	StorageDir   string
 36	MinioURL     string
 37	MinioUser    string
 38	MinioPass    string
 39	Space        string
 40	AllowedExt   []string
 41	HiddenPosts  []string
 42	MaxSize      uint64
 43	MaxAssetSize int64
 44	Logger       *slog.Logger
 45}
 46
 47func NewConfigSite() *ConfigSite {
 48	return &ConfigSite{}
 49}
 50
 51type CreateURL struct {
 52	Subdomain       bool
 53	UsernameInRoute bool
 54	HostDomain      string
 55	AppDomain       string
 56	Username        string
 57	Cfg             *ConfigSite
 58}
 59
 60func NewCreateURL(cfg *ConfigSite) *CreateURL {
 61	return &CreateURL{
 62		Cfg:       cfg,
 63		Subdomain: cfg.IsSubdomains(),
 64	}
 65}
 66
 67func CreateURLFromRequest(cfg *ConfigSite, r *http.Request) *CreateURL {
 68	hostDomain := strings.Split(r.Host, ":")[0]
 69	appDomain := strings.Split(cfg.Domain, ":")[0]
 70
 71	onSubdomain := cfg.IsSubdomains() && strings.Contains(hostDomain, appDomain)
 72	withUserName := !cfg.IsCustomdomains() || (!onSubdomain && hostDomain == appDomain)
 73
 74	return &CreateURL{
 75		Cfg:             cfg,
 76		AppDomain:       appDomain,
 77		HostDomain:      hostDomain,
 78		Subdomain:       onSubdomain,
 79		UsernameInRoute: withUserName,
 80	}
 81}
 82
 83func (c *ConfigSite) GetSiteData() *SitePageData {
 84	return &SitePageData{
 85		Domain:  template.URL(c.Domain),
 86		HomeURL: template.URL(c.HomeURL()),
 87	}
 88}
 89
 90func (c *ConfigSite) IsSubdomains() bool {
 91	return true
 92}
 93
 94func (c *ConfigSite) IsCustomdomains() bool {
 95	return true
 96}
 97
 98func (c *ConfigSite) HomeURL() string {
 99	if c.IsSubdomains() || c.IsCustomdomains() {
100		return fmt.Sprintf("//%s", c.Domain)
101	}
102
103	return "/"
104}
105
106func (c *ConfigSite) ReadURL() string {
107	if c.IsSubdomains() || c.IsCustomdomains() {
108		return fmt.Sprintf("%s://%s", c.Protocol, c.Domain)
109	}
110
111	return "/"
112}
113
114func (c *ConfigSite) StaticPath(fname string) string {
115	return path.Join(c.Space, fname)
116}
117
118func (c *ConfigSite) BlogURL(username string) string {
119	if c.IsSubdomains() {
120		return fmt.Sprintf("%s://%s.%s", c.Protocol, username, c.Domain)
121	}
122
123	return fmt.Sprintf("/%s", username)
124}
125
126func (c *ConfigSite) CssURL(username string) string {
127	if c.IsSubdomains() || c.IsCustomdomains() {
128		return "/_styles.css"
129	}
130
131	return fmt.Sprintf("/%s/styles.css", username)
132}
133
134func (c *ConfigSite) PostURL(username, slug string) string {
135	fname := url.PathEscape(slug)
136	if c.IsSubdomains() {
137		return fmt.Sprintf("%s://%s.%s/%s", c.Protocol, username, c.Domain, fname)
138	}
139
140	return fmt.Sprintf("/%s/%s", username, fname)
141
142}
143
144func (c *ConfigSite) RawPostURL(username, slug string) string {
145	fname := url.PathEscape(slug)
146	if c.IsSubdomains() {
147		return fmt.Sprintf("%s://%s.%s/raw/%s", c.Protocol, username, c.Domain, fname)
148	}
149
150	return fmt.Sprintf("/raw/%s/%s", username, fname)
151}
152
153func (c *ConfigSite) ImgFullURL(username, slug string) string {
154	fname := url.PathEscape(strings.TrimLeft(slug, "/"))
155	return fmt.Sprintf("%s://%s.%s/%s", c.Protocol, username, c.Domain, fname)
156}
157
158func (c *ConfigSite) FullBlogURL(curl *CreateURL, username string) string {
159	if c.IsSubdomains() && curl.Subdomain {
160		return fmt.Sprintf("%s://%s.%s", c.Protocol, username, c.Domain)
161	}
162
163	if curl.UsernameInRoute {
164		return fmt.Sprintf("/%s", username)
165	}
166
167	return fmt.Sprintf("%s://%s", c.Protocol, curl.HostDomain)
168}
169
170func (c *ConfigSite) FullPostURL(curl *CreateURL, username, slug string) string {
171	fname := url.PathEscape(strings.TrimLeft(slug, "/"))
172
173	if curl.Subdomain && c.IsSubdomains() {
174		return fmt.Sprintf("%s://%s.%s/%s", c.Protocol, username, c.Domain, fname)
175	}
176
177	if curl.UsernameInRoute {
178		return fmt.Sprintf("%s://%s/%s/%s", c.Protocol, c.Domain, username, fname)
179	}
180
181	return fmt.Sprintf("%s://%s/%s", c.Protocol, curl.HostDomain, fname)
182}
183
184func (c *ConfigSite) RssBlogURL(curl *CreateURL, username, tag string) string {
185	url := ""
186	if c.IsSubdomains() && curl.Subdomain {
187		url = fmt.Sprintf("%s://%s.%s/rss", c.Protocol, username, c.Domain)
188	} else if curl.UsernameInRoute {
189		url = fmt.Sprintf("/%s/rss", username)
190	} else {
191		url = "/rss"
192	}
193
194	if tag != "" {
195		return fmt.Sprintf("%s?tag=%s", url, tag)
196	}
197
198	return url
199}
200
201func (c *ConfigSite) ImgURL(curl *CreateURL, username string, slug string) string {
202	fname := url.PathEscape(strings.TrimLeft(slug, "/"))
203	if c.IsSubdomains() && curl.Subdomain {
204		return fmt.Sprintf("%s://%s.%s/%s", c.Protocol, username, c.Domain, fname)
205	}
206
207	if curl.UsernameInRoute {
208		return fmt.Sprintf("/%s/%s", username, fname)
209	}
210
211	return fmt.Sprintf("/%s", fname)
212}
213
214func (c *ConfigSite) ImgPostURL(curl *CreateURL, username string, slug string) string {
215	fname := url.PathEscape(strings.TrimLeft(slug, "/"))
216	if c.IsSubdomains() && curl.Subdomain {
217		return fmt.Sprintf("%s://%s.%s/p/%s", c.Protocol, username, c.Domain, fname)
218	}
219
220	if curl.UsernameInRoute {
221		return fmt.Sprintf("/%s/p/%s", username, fname)
222	}
223
224	return fmt.Sprintf("/p/%s", fname)
225}
226
227func (c *ConfigSite) ImgOrigURL(curl *CreateURL, username string, slug string) string {
228	fname := url.PathEscape(strings.TrimLeft(slug, "/"))
229	if c.IsSubdomains() && curl.Subdomain {
230		return fmt.Sprintf("%s://%s.%s/o/%s", c.Protocol, username, c.Domain, fname)
231	}
232
233	if curl.UsernameInRoute {
234		return fmt.Sprintf("/%s/o/%s", username, fname)
235	}
236
237	return fmt.Sprintf("/o/%s", fname)
238}
239
240func (c *ConfigSite) TagURL(curl *CreateURL, username, tag string) string {
241	tg := url.PathEscape(tag)
242	return fmt.Sprintf("%s?tag=%s", c.FullBlogURL(curl, username), tg)
243}
244
245func (c *ConfigSite) AssetURL(username, projectName, fpath string) string {
246	if username == projectName {
247		return fmt.Sprintf(
248			"%s://%s.%s/%s",
249			c.Protocol,
250			username,
251			c.Domain,
252			fpath,
253		)
254	}
255
256	return fmt.Sprintf(
257		"%s://%s-%s.%s/%s",
258		c.Protocol,
259		username,
260		projectName,
261		c.Domain,
262		fpath,
263	)
264}
265
266func CreateLogger(space string) *slog.Logger {
267	opts := &slog.HandlerOptions{
268		AddSource: true,
269	}
270	log := slog.New(
271		slog.NewTextHandler(os.Stdout, opts),
272	)
273	return log.With("service", space)
274}
275
276func LoggerWithUser(logger *slog.Logger, user *db.User) *slog.Logger {
277	return logger.With("user", user.Name, "userId", user.ID)
278}