diff --git a/.air.toml b/.air.toml index ed9155d..98619b8 100644 --- a/.air.toml +++ b/.air.toml @@ -2,9 +2,8 @@ root = "." tmp_dir = "bin" [build] - bin = "./bin/main server" - args_bin = ["server"] - cmd = "go build -o ./bin/main main.go" + bin = "./bin/main" + cmd = "go build -o ./bin/main ./cmd/server/main.go" delay = 1000 exclude_dir = ["bin", "cmd", "public"] @@ -17,7 +16,7 @@ tmp_dir = "bin" include_ext = ["go", "tpl", "tmpl", "templ", "html"] kill_delay = "0s" log = "build-errors.log" - send_interrupt = true + send_interrupt = false stop_on_error = true [color] diff --git a/pkg/scraper/main.go b/cmd/scraper/main.go similarity index 58% rename from pkg/scraper/main.go rename to cmd/scraper/main.go index 08f1914..7527931 100644 --- a/pkg/scraper/main.go +++ b/cmd/scraper/main.go @@ -1,14 +1,13 @@ -package scraper +package main import ( "context" - scraper "github.com/salt-today/salttoday2/pkg/scraper/internal" + "github.com/salt-today/salttoday2/internal/scraper" ) -func Main() { +func main() { scraper.ScrapeAndStoreArticles(context.Background()) scraper.ScrapeAndStoreComments(context.Background()) - } diff --git a/pkg/server/main.go b/cmd/server/main.go similarity index 80% rename from pkg/server/main.go rename to cmd/server/main.go index 3a1f60d..22e8c83 100644 --- a/pkg/server/main.go +++ b/cmd/server/main.go @@ -1,4 +1,4 @@ -package server +package main import ( "context" @@ -9,15 +9,15 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" - "github.com/salt-today/salttoday2/pkg/server/internal/handlers" - "github.com/salt-today/salttoday2/pkg/store" + "github.com/salt-today/salttoday2/internal/server/handlers" + "github.com/salt-today/salttoday2/internal/store/rdb" ) -func Main() { +func main() { r := chi.NewRouter() r.Use(middleware.Logger) - storage, err := store.NewSQLStorage(context.Background()) + storage, err := rdb.New(context.Background()) if err != nil { panic(err) } @@ -36,7 +36,7 @@ func Main() { r.Get("/user/{userID}", handler.HandleUser) r.Get("/user/{userID}/comments", handler.HandleGetUserComments) - r.Handle("/public/*", http.StripPrefix("/public/", http.FileServer(http.Dir("public")))) + r.Handle("/public/*", http.StripPrefix("/public/", http.FileServer(http.Dir("web/public")))) port := os.Getenv("PORT") if port == `` { diff --git a/pkg/scraper/internal/scraper.go b/internal/scraper/scraper.go similarity index 97% rename from pkg/scraper/internal/scraper.go rename to internal/scraper/scraper.go index 4dad24a..1543213 100644 --- a/pkg/scraper/internal/scraper.go +++ b/internal/scraper/scraper.go @@ -14,8 +14,10 @@ import ( "github.com/PuerkitoBio/goquery" "github.com/sirupsen/logrus" - "github.com/salt-today/salttoday2/pkg/sdk" - "github.com/salt-today/salttoday2/pkg/store" + "github.com/salt-today/salttoday2/internal" + "github.com/salt-today/salttoday2/internal/sdk" + "github.com/salt-today/salttoday2/internal/store" + "github.com/salt-today/salttoday2/internal/store/rdb" ) // verify these are still correct and if there's any missing @@ -34,13 +36,13 @@ var potentialPrefixes = []string{ func ScrapeAndStoreArticles(ctx context.Context) { logEntry := sdk.Logger(ctx).WithField("job", "scraper/articles") - storage, err := store.NewSQLStorage(ctx) + storage, err := rdb.New(ctx) if err != nil { logEntry.WithError(err).Fatal("failed to create storage") } articles := make([]*store.Article, 0) - for _, site := range sdk.GetSites() { + for _, site := range internal.GetSites() { foundArticles := ScrapeArticles(ctx, site) articles = append(articles, foundArticles...) } @@ -52,7 +54,7 @@ func ScrapeAndStoreArticles(ctx context.Context) { func ScrapeAndStoreComments(ctx context.Context) { logEntry := sdk.Logger(ctx).WithField("job", "scraper/comments") - storage, err := store.NewSQLStorage(ctx) + storage, err := rdb.New(ctx) if err != nil { logEntry.WithError(err).Fatal("failed to create storage") } diff --git a/pkg/sdk/log.go b/internal/sdk/log.go similarity index 100% rename from pkg/sdk/log.go rename to internal/sdk/log.go diff --git a/pkg/server/internal/handlers/about.go b/internal/server/handlers/about.go similarity index 70% rename from pkg/server/internal/handlers/about.go rename to internal/server/handlers/about.go index 7500020..e3a2895 100644 --- a/pkg/server/internal/handlers/about.go +++ b/internal/server/handlers/about.go @@ -3,7 +3,7 @@ package handlers import ( "net/http" - "github.com/salt-today/salttoday2/pkg/server/internal/ui/views" + "github.com/salt-today/salttoday2/internal/server/ui/views" ) func (h *Handler) HandleAbout(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/server/internal/handlers/comments.go b/internal/server/handlers/comments.go similarity index 93% rename from pkg/server/internal/handlers/comments.go rename to internal/server/handlers/comments.go index 6af797c..0c91376 100644 --- a/pkg/server/internal/handlers/comments.go +++ b/internal/server/handlers/comments.go @@ -8,10 +8,10 @@ import ( "strings" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/salt-today/salttoday2/pkg/sdk" - "github.com/salt-today/salttoday2/pkg/server/internal/ui/components" - "github.com/salt-today/salttoday2/pkg/server/internal/ui/views" - "github.com/salt-today/salttoday2/pkg/store" + "github.com/salt-today/salttoday2/internal/sdk" + "github.com/salt-today/salttoday2/internal/server/ui/components" + "github.com/salt-today/salttoday2/internal/server/ui/views" + "github.com/salt-today/salttoday2/internal/store" "github.com/samber/lo" ) diff --git a/pkg/server/internal/handlers/common_query_params.go b/internal/server/handlers/common_query_params.go similarity index 97% rename from pkg/server/internal/handlers/common_query_params.go rename to internal/server/handlers/common_query_params.go index cbb6fdc..df04159 100644 --- a/pkg/server/internal/handlers/common_query_params.go +++ b/internal/server/handlers/common_query_params.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/salt-today/salttoday2/pkg/store" + "github.com/salt-today/salttoday2/internal/store" ) func processPageQueryParams(parameters map[string]string) (*store.PageQueryOptions, error) { diff --git a/pkg/server/internal/handlers/handler.go b/internal/server/handlers/handler.go similarity index 77% rename from pkg/server/internal/handlers/handler.go rename to internal/server/handlers/handler.go index 8a82d49..3df1f53 100644 --- a/pkg/server/internal/handlers/handler.go +++ b/internal/server/handlers/handler.go @@ -1,7 +1,7 @@ package handlers import ( - "github.com/salt-today/salttoday2/pkg/store" + "github.com/salt-today/salttoday2/internal/store" ) type Handler struct { diff --git a/pkg/server/internal/handlers/user.go b/internal/server/handlers/user.go similarity index 90% rename from pkg/server/internal/handlers/user.go rename to internal/server/handlers/user.go index 456855a..9082de5 100644 --- a/pkg/server/internal/handlers/user.go +++ b/internal/server/handlers/user.go @@ -8,10 +8,10 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/go-chi/chi/v5" - "github.com/salt-today/salttoday2/pkg/sdk" - "github.com/salt-today/salttoday2/pkg/server/internal/ui/components" - "github.com/salt-today/salttoday2/pkg/server/internal/ui/views" - "github.com/salt-today/salttoday2/pkg/store" + "github.com/salt-today/salttoday2/internal/sdk" + "github.com/salt-today/salttoday2/internal/server/ui/components" + "github.com/salt-today/salttoday2/internal/server/ui/views" + "github.com/salt-today/salttoday2/internal/store" ) func (h *Handler) HandleUser(w http.ResponseWriter, r *http.Request) { diff --git a/internal/server/ui/components/comments.templ b/internal/server/ui/components/comments.templ new file mode 100644 index 0000000..dfd9af9 --- /dev/null +++ b/internal/server/ui/components/comments.templ @@ -0,0 +1,57 @@ +package components + +import "fmt" +import "github.com/salt-today/salttoday2/internal/store" + +func getGradient(comment *store.Comment) string { +if comment.Likes+comment.Dislikes == 0 { +return "bg-gray-500" +} +if comment.Likes == 0 { +return "bg-red-600" +} +if comment.Dislikes == 0 { +return "bg-blue-600" +} +return fmt.Sprintf("bg-gradient-to-br from-blue-600 to-red-600 from-%d%% to-%d%%", +max(0, +int((float64(comment.Likes)/float64(comment.Likes+comment.Dislikes))*100)/5*5), +min(100, +int((float64(comment.Likes)/float64(comment.Likes+comment.Dislikes))*100-5)/5*5), +) + +} + +func max(x, y int) int { +if x > y { +return x +} +return y +} + +func min(x, y int) int { +if x > y { +return y +} +return x +} + +templ CommentComponent(comment *store.Comment) { +
+
+ { comment.Article.Title } +
+
+
+ { comment.Text } + πŸ‘ { fmt.Sprintf("%d", comment.Likes) } πŸ‘Ž { fmt.Sprintf("%d", comment.Dislikes) } +
+
+
+
- { comment.User.UserName }
+ if comment.Deleted { +
DELETED
+ } +
+
+} diff --git a/pkg/server/internal/ui/components/comments_form.templ b/internal/server/ui/components/comments_form.templ similarity index 97% rename from pkg/server/internal/ui/components/comments_form.templ rename to internal/server/ui/components/comments_form.templ index 0952d7a..20262c3 100644 --- a/pkg/server/internal/ui/components/comments_form.templ +++ b/internal/server/ui/components/comments_form.templ @@ -1,6 +1,6 @@ package components -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/store" func selectedUintPtr(ptr *uint, lookingFor uint) bool { if ptr == nil { diff --git a/pkg/server/internal/ui/components/comments_form_templ.go b/internal/server/ui/components/comments_form_templ.go similarity index 51% rename from pkg/server/internal/ui/components/comments_form_templ.go rename to internal/server/ui/components/comments_form_templ.go index d1cd07b..24c4941 100644 --- a/pkg/server/internal/ui/components/comments_form_templ.go +++ b/internal/server/ui/components/comments_form_templ.go @@ -10,7 +10,7 @@ import "context" import "io" import "bytes" -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/store" func selectedUintPtr(ptr *uint, lookingFor uint) bool { if ptr == nil { @@ -32,120 +32,120 @@ func CommentsFormComponent(targetUrl string, queryOpts *store.CommentQueryOption templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 22) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/server/internal/ui/components/comments_list.templ b/internal/server/ui/components/comments_list.templ similarity index 84% rename from pkg/server/internal/ui/components/comments_list.templ rename to internal/server/ui/components/comments_list.templ index bee7679..bb9eb12 100644 --- a/pkg/server/internal/ui/components/comments_list.templ +++ b/internal/server/ui/components/comments_list.templ @@ -1,6 +1,6 @@ package components -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/store" templ CommentsListComponent(comments []*store.Comment, nextUrl string) {
diff --git a/pkg/server/internal/ui/components/comments_list_templ.go b/internal/server/ui/components/comments_list_templ.go similarity index 77% rename from pkg/server/internal/ui/components/comments_list_templ.go rename to internal/server/ui/components/comments_list_templ.go index 99a89db..7ca05d1 100644 --- a/pkg/server/internal/ui/components/comments_list_templ.go +++ b/internal/server/ui/components/comments_list_templ.go @@ -10,7 +10,7 @@ import "context" import "io" import "bytes" -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/store" func CommentsListComponent(comments []*store.Comment, nextUrl string) templ.Component { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { @@ -25,7 +25,7 @@ func CommentsListComponent(comments []*store.Comment, nextUrl string) templ.Comp templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -35,25 +35,25 @@ func CommentsListComponent(comments []*store.Comment, nextUrl string) templ.Comp return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if len(comments) > 0 { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/server/internal/ui/components/comments_templ.go b/internal/server/ui/components/comments_templ.go similarity index 73% rename from pkg/server/internal/ui/components/comments_templ.go rename to internal/server/ui/components/comments_templ.go index 450d832..d7da3bb 100644 --- a/pkg/server/internal/ui/components/comments_templ.go +++ b/internal/server/ui/components/comments_templ.go @@ -11,7 +11,7 @@ import "io" import "bytes" import "fmt" -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/store" func getGradient(comment *store.Comment) string { if comment.Likes+comment.Dislikes == 0 { @@ -59,7 +59,7 @@ func CommentComponent(comment *store.Comment) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(comment.Article.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/server/internal/ui/components/comments.templ`, Line: 42, Col: 69} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/server/ui/components/comments.templ`, Line: 42, Col: 70} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -90,59 +90,59 @@ func CommentComponent(comment *store.Comment) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 5) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(comment.Text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/server/internal/ui/components/comments.templ`, Line: 46, Col: 24} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/server/ui/components/comments.templ`, Line: 46, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" πŸ‘ ") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 6) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", comment.Likes)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/server/internal/ui/components/comments.templ`, Line: 47, Col: 49} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/server/ui/components/comments.templ`, Line: 47, Col: 51} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" πŸ‘Ž ") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 7) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", comment.Dislikes)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/server/internal/ui/components/comments.templ`, Line: 47, Col: 94} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/server/ui/components/comments.templ`, Line: 47, Col: 96} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 12) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/server/internal/ui/components/no_results.templ b/internal/server/ui/components/no_results.templ similarity index 100% rename from pkg/server/internal/ui/components/no_results.templ rename to internal/server/ui/components/no_results.templ diff --git a/pkg/server/internal/ui/components/no_results_templ.go b/internal/server/ui/components/no_results_templ.go similarity index 83% rename from pkg/server/internal/ui/components/no_results_templ.go rename to internal/server/ui/components/no_results_templ.go index 729fd96..8e57f96 100644 --- a/pkg/server/internal/ui/components/no_results_templ.go +++ b/internal/server/ui/components/no_results_templ.go @@ -23,20 +23,20 @@ func NoResultsFound(resourceName string) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(resourceName) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/server/internal/ui/components/no_results.templ`, Line: 4, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/server/ui/components/no_results.templ`, Line: 4, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" not found :(") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/server/internal/ui/components/user.templ b/internal/server/ui/components/user.templ similarity index 83% rename from pkg/server/internal/ui/components/user.templ rename to internal/server/ui/components/user.templ index 6d33f88..bb44afb 100644 --- a/pkg/server/internal/ui/components/user.templ +++ b/internal/server/ui/components/user.templ @@ -1,6 +1,6 @@ package components -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/store" import "fmt" templ UserComponent(user *store.User) { diff --git a/pkg/server/internal/ui/components/user_templ.go b/internal/server/ui/components/user_templ.go similarity index 75% rename from pkg/server/internal/ui/components/user_templ.go rename to internal/server/ui/components/user_templ.go index 12e190e..1f934b8 100644 --- a/pkg/server/internal/ui/components/user_templ.go +++ b/internal/server/ui/components/user_templ.go @@ -10,7 +10,7 @@ import "context" import "io" import "bytes" -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/store" import "fmt" func UserComponent(user *store.User) templ.Component { @@ -26,7 +26,7 @@ func UserComponent(user *store.User) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(user.UserName) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/server/internal/ui/components/user.templ`, Line: 9, Col: 80} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/server/ui/components/user.templ`, Line: 9, Col: 80} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
πŸ‘ ") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", 123)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/server/internal/ui/components/user.templ`, Line: 12, Col: 38} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/server/ui/components/user.templ`, Line: 12, Col: 38} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" πŸ‘Ž ") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", 456)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/server/internal/ui/components/user.templ`, Line: 12, Col: 70} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/server/ui/components/user.templ`, Line: 12, Col: 70} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 5) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/server/ui/components/users_list.templ b/internal/server/ui/components/users_list.templ new file mode 100644 index 0000000..b217e0a --- /dev/null +++ b/internal/server/ui/components/users_list.templ @@ -0,0 +1,9 @@ +package components + +import "github.com/salt-today/salttoday2/internal/store" + +templ UsersListComponent(users []*store.User) { +for _, user := range users { +@UserComponent(user) +} +} diff --git a/pkg/server/internal/ui/components/users_list_templ.go b/internal/server/ui/components/users_list_templ.go similarity index 95% rename from pkg/server/internal/ui/components/users_list_templ.go rename to internal/server/ui/components/users_list_templ.go index fdd07f5..87cae63 100644 --- a/pkg/server/internal/ui/components/users_list_templ.go +++ b/internal/server/ui/components/users_list_templ.go @@ -10,7 +10,7 @@ import "context" import "io" import "bytes" -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/store" func UsersListComponent(users []*store.User) templ.Component { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { diff --git a/pkg/server/internal/ui/views/about.templ b/internal/server/ui/views/about.templ similarity index 98% rename from pkg/server/internal/ui/views/about.templ rename to internal/server/ui/views/about.templ index 660cf1f..ff985f9 100644 --- a/pkg/server/internal/ui/views/about.templ +++ b/internal/server/ui/views/about.templ @@ -3,6 +3,7 @@ package views templ About() { @Page(true) {
+

hi

Definition diff --git a/pkg/server/internal/ui/views/about_templ.go b/internal/server/ui/views/about_templ.go similarity index 58% rename from pkg/server/internal/ui/views/about_templ.go rename to internal/server/ui/views/about_templ.go index 25cae81..be64f30 100644 --- a/pkg/server/internal/ui/views/about_templ.go +++ b/internal/server/ui/views/about_templ.go @@ -29,7 +29,7 @@ func About() templ.Component { templ_7745c5c3_Buffer = templ.GetBuffer() defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Definition
saltΒ·y
/ˈsΓ΄ltΔ“,ˈsΓ€ltΔ“/
Soojavu was so salty after reading a SooToday article.
What is this?
A website that ranks both the comments and users on various news sites. We started with SooToday but have expanded to other sites in the same news network. The ranking of both comments and users is based on the number of likes and dislikes they've accumulated. Likes count for one point, dislikes count for two.
Your site is broken!
Probably. Let me know about it here , or instead of being salty, try contributing?
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/server/ui/views/home.templ b/internal/server/ui/views/home.templ new file mode 100644 index 0000000..ae6a57e --- /dev/null +++ b/internal/server/ui/views/home.templ @@ -0,0 +1,17 @@ +package views + +import "github.com/salt-today/salttoday2/internal/server/ui/components" +import "github.com/salt-today/salttoday2/internal/store" + +templ Home(queryOpts *store.CommentQueryOptions, comments []*store.Comment, nextUrl string) { +@Page(true) { +@components.CommentsFormComponent("/comments", queryOpts) +
+ if len(comments) > 0 { + @components.CommentsListComponent(comments, nextUrl) + } else { + @components.NoResultsFound("Comments") + } +
+} +} diff --git a/pkg/server/internal/ui/views/home_templ.go b/internal/server/ui/views/home_templ.go similarity index 88% rename from pkg/server/internal/ui/views/home_templ.go rename to internal/server/ui/views/home_templ.go index fc771cf..34ce429 100644 --- a/pkg/server/internal/ui/views/home_templ.go +++ b/internal/server/ui/views/home_templ.go @@ -10,8 +10,8 @@ import "context" import "io" import "bytes" -import "github.com/salt-today/salttoday2/pkg/server/internal/ui/components" -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/server/ui/components" +import "github.com/salt-today/salttoday2/internal/store" func Home(queryOpts *store.CommentQueryOptions, comments []*store.Comment, nextUrl string) templ.Component { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { @@ -36,7 +36,7 @@ func Home(queryOpts *store.CommentQueryOptions, comments []*store.Comment, nextU if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -51,7 +51,7 @@ func Home(queryOpts *store.CommentQueryOptions, comments []*store.Comment, nextU return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/server/internal/ui/views/page.templ b/internal/server/ui/views/page.templ similarity index 100% rename from pkg/server/internal/ui/views/page.templ rename to internal/server/ui/views/page.templ diff --git a/internal/server/ui/views/page_templ.go b/internal/server/ui/views/page_templ.go new file mode 100644 index 0000000..45559ae --- /dev/null +++ b/internal/server/ui/views/page_templ.go @@ -0,0 +1,53 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.636 +package views + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import "context" +import "io" +import "bytes" + +func Page(nav bool) templ.Component { + return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if nav { + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 4) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/internal/server/ui/views/user.templ b/internal/server/ui/views/user.templ new file mode 100644 index 0000000..c52ebf5 --- /dev/null +++ b/internal/server/ui/views/user.templ @@ -0,0 +1,20 @@ +package views + +import ( +"fmt" +"github.com/salt-today/salttoday2/internal/server/ui/components" +"github.com/salt-today/salttoday2/internal/store" +) + +templ User(user *store.User, queryOpts *store.CommentQueryOptions, comments []*store.Comment, nextUrl string) { +@Page(true) { +@components.CommentsFormComponent(fmt.Sprintf("/user/%d/comments", user.ID), queryOpts) +
+ if len(comments) > 0 { + @components.CommentsListComponent(comments, nextUrl) + } else { + @components.NoResultsFound("User") + } +
+} +} diff --git a/pkg/server/internal/ui/views/user_templ.go b/internal/server/ui/views/user_templ.go similarity index 86% rename from pkg/server/internal/ui/views/user_templ.go rename to internal/server/ui/views/user_templ.go index 0fd7b8c..8b55a14 100644 --- a/pkg/server/internal/ui/views/user_templ.go +++ b/internal/server/ui/views/user_templ.go @@ -12,8 +12,8 @@ import "bytes" import ( "fmt" - "github.com/salt-today/salttoday2/pkg/server/internal/ui/components" - "github.com/salt-today/salttoday2/pkg/store" + "github.com/salt-today/salttoday2/internal/server/ui/components" + "github.com/salt-today/salttoday2/internal/store" ) func User(user *store.User, queryOpts *store.CommentQueryOptions, comments []*store.Comment, nextUrl string) templ.Component { @@ -39,20 +39,20 @@ func User(user *store.User, queryOpts *store.CommentQueryOptions, comments []*st if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -67,7 +67,7 @@ func User(user *store.User, queryOpts *store.CommentQueryOptions, comments []*st return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 3) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/server/internal/ui/views/users.templ b/internal/server/ui/views/users.templ similarity index 66% rename from pkg/server/internal/ui/views/users.templ rename to internal/server/ui/views/users.templ index 4c6e058..2b2ad73 100644 --- a/pkg/server/internal/ui/views/users.templ +++ b/internal/server/ui/views/users.templ @@ -1,7 +1,7 @@ package views -import "github.com/salt-today/salttoday2/pkg/server/internal/ui/components" -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/server/ui/components" +import "github.com/salt-today/salttoday2/internal/store" templ Users(users []*store.User) { @Page(true) { diff --git a/pkg/server/internal/ui/views/users_templ.go b/internal/server/ui/views/users_templ.go similarity index 83% rename from pkg/server/internal/ui/views/users_templ.go rename to internal/server/ui/views/users_templ.go index 68f8c3f..734b496 100644 --- a/pkg/server/internal/ui/views/users_templ.go +++ b/internal/server/ui/views/users_templ.go @@ -10,8 +10,8 @@ import "context" import "io" import "bytes" -import "github.com/salt-today/salttoday2/pkg/server/internal/ui/components" -import "github.com/salt-today/salttoday2/pkg/store" +import "github.com/salt-today/salttoday2/internal/server/ui/components" +import "github.com/salt-today/salttoday2/internal/store" func Users(users []*store.User) templ.Component { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { @@ -32,7 +32,7 @@ func Users(users []*store.User) templ.Component { templ_7745c5c3_Buffer = templ.GetBuffer() defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Users page

Probably some sort of form here to filter users
This div is supposed to contain users") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 1) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -40,7 +40,7 @@ func Users(users []*store.User) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/sdk/sites.go b/internal/sites.go similarity index 99% rename from pkg/sdk/sites.go rename to internal/sites.go index 216852e..2cf18da 100644 --- a/pkg/sdk/sites.go +++ b/internal/sites.go @@ -1,4 +1,4 @@ -package sdk +package internal // TODO uncomment sites when we're ready, no need to hammer all of them yet // List taken from here: villagemedia.ca/sites/ diff --git a/pkg/store/dynamodb_storage.go b/internal/store/ddb/dynamodb_storage.go similarity index 90% rename from pkg/store/dynamodb_storage.go rename to internal/store/ddb/dynamodb_storage.go index d68dfbe..91f715a 100644 --- a/pkg/store/dynamodb_storage.go +++ b/internal/store/ddb/dynamodb_storage.go @@ -1,4 +1,4 @@ -package store +package internal import ( "context" @@ -10,6 +10,8 @@ import ( "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue" "github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression" "github.com/aws/aws-sdk-go-v2/service/dynamodb" + + "github.com/salt-today/salttoday2/internal/store" ) // var _ Storage = (*dynamodbStorage)(nil) @@ -27,7 +29,7 @@ func NewDynamodbStorage(cfg aws.Config, tableName string) *dynamodbStorage { } } -func (s *dynamodbStorage) AddComments(ctx context.Context, comments ...*Comment) error { +func (s *dynamodbStorage) AddComments(ctx context.Context, comments ...*store.Comment) error { var items []types.WriteRequest for _, c := range comments { item, err := attributevalue.MarshalMap(c) @@ -49,8 +51,8 @@ func (s *dynamodbStorage) AddComments(ctx context.Context, comments ...*Comment) return err } -func (s *dynamodbStorage) GetUserComments(ctx context.Context, userID int, opts *CommentQueryOptions) ([]*Comment, error) { - var responseComments []*Comment +func (s *dynamodbStorage) GetUserComments(ctx context.Context, userID int, opts *store.CommentQueryOptions) ([]*store.Comment, error) { + var responseComments []*store.Comment keyEx := expression.KeyAnd( expression.Key("user_id").Equal(expression.Value(userID)), // PK @@ -76,7 +78,7 @@ func (s *dynamodbStorage) GetUserComments(ctx context.Context, userID int, opts return responseComments, err } -func (s *dynamodbStorage) AddArticles(ctx context.Context, articles ...*Article) error { +func (s *dynamodbStorage) AddArticles(ctx context.Context, articles ...*store.Article) error { var items []types.WriteRequest for _, a := range articles { item, err := attributevalue.MarshalMap(a) @@ -98,7 +100,7 @@ func (s *dynamodbStorage) AddArticles(ctx context.Context, articles ...*Article) return err } -func (s *dynamodbStorage) AddUsers(ctx context.Context, users ...*User) error { +func (s *dynamodbStorage) AddUsers(ctx context.Context, users ...*store.User) error { var items []types.WriteRequest for _, u := range users { item, err := attributevalue.MarshalMap(u) @@ -120,7 +122,7 @@ func (s *dynamodbStorage) AddUsers(ctx context.Context, users ...*User) error { return err } -func (s *dynamodbStorage) GetUnscrapedArticlesSince(ctx context.Context, scrapeThreshold time.Time) ([]*Article, error) { +func (s *dynamodbStorage) GetUnscrapedArticlesSince(ctx context.Context, scrapeThreshold time.Time) ([]*store.Article, error) { return nil, fmt.Errorf("not yet implemented") } diff --git a/pkg/store/migrations/0000-init.sql b/internal/store/rdb/migrations/0000-init.sql similarity index 100% rename from pkg/store/migrations/0000-init.sql rename to internal/store/rdb/migrations/0000-init.sql diff --git a/pkg/store/migrations/migrate.go b/internal/store/rdb/migrations/migrate.go similarity index 100% rename from pkg/store/migrations/migrate.go rename to internal/store/rdb/migrations/migrate.go diff --git a/pkg/store/sql_constants.go b/internal/store/rdb/sql_constants.go similarity index 98% rename from pkg/store/sql_constants.go rename to internal/store/rdb/sql_constants.go index b967c1c..49f8fe5 100644 --- a/pkg/store/sql_constants.go +++ b/internal/store/rdb/sql_constants.go @@ -1,4 +1,4 @@ -package store +package rdb // Tables const ( diff --git a/pkg/store/sql_storage.go b/internal/store/rdb/sql_storage.go similarity index 85% rename from pkg/store/sql_storage.go rename to internal/store/rdb/sql_storage.go index 7760ce3..69b2786 100644 --- a/pkg/store/sql_storage.go +++ b/internal/store/rdb/sql_storage.go @@ -1,4 +1,4 @@ -package store +package rdb import ( "context" @@ -8,17 +8,17 @@ import ( "os" "time" - "github.com/salt-today/salttoday2/pkg/sdk" - "github.com/salt-today/salttoday2/pkg/store/migrations" - "github.com/sirupsen/logrus" - "github.com/doug-martin/goqu/v9" _ "github.com/doug-martin/goqu/v9/dialect/mysql" - _ "github.com/go-sql-driver/mysql" + "github.com/sirupsen/logrus" + + "github.com/salt-today/salttoday2/internal/sdk" + "github.com/salt-today/salttoday2/internal/store" + "github.com/salt-today/salttoday2/internal/store/rdb/migrations" ) -var _ Storage = (*sqlStorage)(nil) +var _ store.Storage = (*sqlStorage)(nil) type sqlStorage struct { db *sql.DB @@ -37,7 +37,7 @@ func getSqlConnString(ctx context.Context) string { return url } -func NewSQLStorage(ctx context.Context) (*sqlStorage, error) { +func New(ctx context.Context) (*sqlStorage, error) { entry := logrus.WithField(`component`, `sql-storage`) db, err := sql.Open("mysql", getSqlConnString(ctx)+"?parseTime=true") @@ -67,7 +67,7 @@ func NewSQLStorage(ctx context.Context) (*sqlStorage, error) { return s, nil } -func (s *sqlStorage) AddComments(ctx context.Context, comments ...*Comment) error { +func (s *sqlStorage) AddComments(ctx context.Context, comments ...*store.Comment) error { ds := s.dialect.Insert(CommentsTable). Cols(CommentsID, CommentsArticleID, CommentsUserID, CommentsTime, CommentsText, CommentsLikes, CommentsDislikes). As(NewAlias). @@ -86,7 +86,7 @@ func (s *sqlStorage) AddComments(ctx context.Context, comments ...*Comment) erro return err } -func (s *sqlStorage) QueryUsers(ctx context.Context, opts UserQueryOptions) ([]*User, error) { +func (s *sqlStorage) QueryUsers(ctx context.Context, opts store.UserQueryOptions) ([]*store.User, error) { // TODO Join and Aggregate comments table with users sd := s.dialect. Select(UsersID, UsersName). @@ -108,10 +108,10 @@ func (s *sqlStorage) QueryUsers(ctx context.Context, opts UserQueryOptions) ([]* } defer rows.Close() - users := make([]*User, 0) + users := make([]*store.User, 0) for rows.Next() { - u := &User{} + u := &store.User{} err := rows.Scan(&u.ID, &u.UserName) if err != nil { return nil, fmt.Errorf("failed to scan user record: %w", err) @@ -122,7 +122,7 @@ func (s *sqlStorage) QueryUsers(ctx context.Context, opts UserQueryOptions) ([]* return users, nil } -func (s *sqlStorage) GetComments(ctx context.Context, opts CommentQueryOptions) ([]*Comment, error) { +func (s *sqlStorage) GetComments(ctx context.Context, opts store.CommentQueryOptions) ([]*store.Comment, error) { sd := s.dialect. Select(CommentsID, CommentsTime, CommentsText, CommentsLikes, CommentsDislikes, goqu.L(CommentsLikes+" + 2 * "+CommentsDislikes). As(CommentsScore), CommentsDeleted, CommentsArticleID, CommentsUserID, ArticlesID, ArticlesTitle, ArticlesUrl, UsersID, UsersName). @@ -155,11 +155,11 @@ func (s *sqlStorage) GetComments(ctx context.Context, opts CommentQueryOptions) sd = addPaging(sd, &opts.PageOpts) if opts.PageOpts.Order != nil { - if *opts.PageOpts.Order == OrderByLikes { + if *opts.PageOpts.Order == store.OrderByLikes { sd = sd.Order(goqu.I(CommentsLikes).Desc()) - } else if *opts.PageOpts.Order == OrderByDislikes { + } else if *opts.PageOpts.Order == store.OrderByDislikes { sd = sd.Order(goqu.I(CommentsDislikes).Desc()) - } else if *opts.PageOpts.Order == OrderByBoth { + } else if *opts.PageOpts.Order == store.OrderByBoth { sd = sd.Order(goqu.I(CommentsScore).Desc()) } else { return nil, fmt.Errorf("unexpected ordering directive %d", *opts.PageOpts.Order) @@ -177,7 +177,7 @@ func (s *sqlStorage) GetComments(ctx context.Context, opts CommentQueryOptions) } defer rows.Close() - comments := make([]*Comment, 0) + comments := make([]*store.Comment, 0) var id, articleID, commentsArticleID, userID, commentsUserID int var tm time.Time var text string @@ -192,10 +192,10 @@ func (s *sqlStorage) GetComments(ctx context.Context, opts CommentQueryOptions) if err != nil { return nil, err } - comments = append(comments, &Comment{ + comments = append(comments, &store.Comment{ ID: id, - Article: Article{ID: articleID, Title: articleTitle, Url: articleUrl}, - User: User{ID: userID, UserName: userName}, + Article: store.Article{ID: articleID, Title: articleTitle, Url: articleUrl}, + User: store.User{ID: userID, UserName: userName}, Time: tm.Local(), Text: text, Likes: likes, @@ -209,13 +209,13 @@ func (s *sqlStorage) GetComments(ctx context.Context, opts CommentQueryOptions) } if len(comments) == 0 { - return nil, &NoQueryResultsError{} + return nil, &store.NoQueryResultsError{} } return comments, nil } -func (s *sqlStorage) AddArticles(ctx context.Context, articles ...*Article) error { +func (s *sqlStorage) AddArticles(ctx context.Context, articles ...*store.Article) error { ds := s.dialect.Insert(ArticlesTable).Cols(ArticlesID, ArticlesUrl, ArticlesTitle, ArticlesDiscoveryTime, ArticlesLastScrapeTime). OnConflict(goqu.DoNothing()) @@ -233,7 +233,7 @@ func (s *sqlStorage) AddArticles(ctx context.Context, articles ...*Article) erro return err } -func (s *sqlStorage) GetArticles(ctx context.Context, ids ...int) ([]*Article, error) { +func (s *sqlStorage) GetArticles(ctx context.Context, ids ...int) ([]*store.Article, error) { sd := s.dialect. Select(ArticlesID, ArticlesUrl, ArticlesTitle, ArticlesDiscoveryTime, ArticlesLastScrapeTime). From(ArticlesTable). @@ -253,7 +253,7 @@ func (s *sqlStorage) GetArticles(ctx context.Context, ids ...int) ([]*Article, e return hydrateArticles(rows) } -func (s *sqlStorage) AddUsers(ctx context.Context, users ...*User) error { +func (s *sqlStorage) AddUsers(ctx context.Context, users ...*store.User) error { ds := s.dialect.Insert(UsersTable).Cols(UsersID, UsersName).OnConflict(goqu.DoNothing()) // TODO Something other than nothing for _, user := range users { ds = ds.Vals(goqu.Vals{user.ID, user.UserName}) @@ -268,7 +268,7 @@ func (s *sqlStorage) AddUsers(ctx context.Context, users ...*User) error { return err } -func (s *sqlStorage) GetUserByID(ctx context.Context, id int) (*User, error) { +func (s *sqlStorage) GetUserByID(ctx context.Context, id int) (*store.User, error) { sd := s.dialect.Select(UsersID, UsersName). From(UsersTable). Where(goqu.Ex{UsersID: id}) @@ -283,13 +283,13 @@ func (s *sqlStorage) GetUserByID(ctx context.Context, id int) (*User, error) { row := s.db.QueryRow(query) if err := row.Err(); err != nil { if errors.Is(err, sql.ErrNoRows) { - return nil, &NoQueryResultsError{} + return nil, &store.NoQueryResultsError{} } return nil, err } row.Scan(&userID, &userName) - user := &User{ + user := &store.User{ ID: userID, UserName: userName, } @@ -297,7 +297,7 @@ func (s *sqlStorage) GetUserByID(ctx context.Context, id int) (*User, error) { return user, nil } -func (s *sqlStorage) GetUserByName(ctx context.Context, name string) (*User, error) { +func (s *sqlStorage) GetUserByName(ctx context.Context, name string) (*store.User, error) { sd := s.dialect.Select(UsersID, UsersName). From(UsersTable). Where(goqu.Ex{UsersName: name}) @@ -320,16 +320,16 @@ func (s *sqlStorage) GetUserByName(ctx context.Context, name string) (*User, err if err != nil { return nil, err } - return &User{ + return &store.User{ ID: id, UserName: foundName, }, nil } - return nil, &NoQueryResultsError{} + return nil, &store.NoQueryResultsError{} } -func addPaging(sd *goqu.SelectDataset, pageOpts *PageQueryOptions) *goqu.SelectDataset { +func addPaging(sd *goqu.SelectDataset, pageOpts *store.PageQueryOptions) *goqu.SelectDataset { limit := maxPageSize if pageOpts.Limit != nil && *pageOpts.Limit < limit { limit = *pageOpts.Limit @@ -344,8 +344,8 @@ func addPaging(sd *goqu.SelectDataset, pageOpts *PageQueryOptions) *goqu.SelectD return sd } -func hydrateArticles(rows *sql.Rows) ([]*Article, error) { - articles := make([]*Article, 0) +func hydrateArticles(rows *sql.Rows) ([]*store.Article, error) { + articles := make([]*store.Article, 0) var id int var url, title string var first, last sql.NullTime @@ -355,7 +355,7 @@ func hydrateArticles(rows *sql.Rows) ([]*Article, error) { return nil, err } - article := &Article{ + article := &store.Article{ ID: id, Url: url, Title: title, @@ -374,13 +374,13 @@ func hydrateArticles(rows *sql.Rows) ([]*Article, error) { } if len(articles) == 0 { - return nil, &NoQueryResultsError{} + return nil, &store.NoQueryResultsError{} } return articles, nil } -func (s *sqlStorage) GetUnscrapedArticlesSince(ctx context.Context, scrapeThreshold time.Time) ([]*Article, error) { +func (s *sqlStorage) GetUnscrapedArticlesSince(ctx context.Context, scrapeThreshold time.Time) ([]*store.Article, error) { sd := s.dialect. Select(ArticlesID, ArticlesUrl, ArticlesTitle, ArticlesDiscoveryTime, ArticlesLastScrapeTime). From(ArticlesTable). @@ -414,7 +414,7 @@ func (s *sqlStorage) GetUnscrapedArticlesSince(ctx context.Context, scrapeThresh return articles, nil } -func (s *sqlStorage) GetRecentlyDiscoveredArticles(ctx context.Context, threshold time.Time) ([]*Article, error) { +func (s *sqlStorage) GetRecentlyDiscoveredArticles(ctx context.Context, threshold time.Time) ([]*store.Article, error) { sd := s.dialect. Select(ArticlesID, ArticlesUrl, ArticlesTitle, ArticlesDiscoveryTime, ArticlesLastScrapeTime). From(ArticlesTable). diff --git a/pkg/store/store_test.go b/internal/store/rdb/store_test.go similarity index 89% rename from pkg/store/store_test.go rename to internal/store/rdb/store_test.go index 45ab05d..e207978 100644 --- a/pkg/store/store_test.go +++ b/internal/store/rdb/store_test.go @@ -1,4 +1,4 @@ -package store +package rdb import ( "context" @@ -8,6 +8,8 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/stretchr/testify/require" + + stor "github.com/salt-today/salttoday2/internal/store" ) // These tests will fuck up your local Comments table if it fails and junk. Just here to smoke test. @@ -15,7 +17,7 @@ import ( // Should probably also mock the DB, but meh. // Will remove, probably. func TestStorage_Comments(t *testing.T) { - store, err := NewSQLStorage(context.Background()) + store, err := New(context.Background()) require.NoError(t, err) _, err = store.db.Exec("TRUNCATE TABLE Comments;") @@ -31,13 +33,13 @@ func TestStorage_Comments(t *testing.T) { "they should all be fired", } - allComments := make([]*Comment, 0, 100) - commentsByUser := make(map[int][]*Comment) + allComments := make([]*stor.Comment, 0, 100) + commentsByUser := make(map[int][]*stor.Comment) for i := 0; i < 1; i++ { user := users[i%len(users)] - comment := &Comment{ + comment := &stor.Comment{ ID: i, - User: User{ID: user}, + User: stor.User{ID: user}, Time: time.Now().Truncate(time.Second), Text: texts[i%len(texts)], Likes: rand.Int31(), @@ -51,7 +53,7 @@ func TestStorage_Comments(t *testing.T) { require.NoError(t, store.AddComments(context.Background(), allComments...)) for _, user := range users { - opts := CommentQueryOptions{UserID: aws.Int(user)} + opts := stor.CommentQueryOptions{UserID: aws.Int(user)} comments, err := store.GetComments(context.Background(), opts) require.NoError(t, err) require.ElementsMatch(t, commentsByUser[user], comments) @@ -62,7 +64,7 @@ func TestStorage_Comments(t *testing.T) { } func TestStorage_Articles(t *testing.T) { - store, err := NewSQLStorage(context.Background()) + store, err := New(context.Background()) require.NoError(t, err) _, err = store.db.Exec("TRUNCATE TABLE Articles;") @@ -85,13 +87,13 @@ func TestStorage_Articles(t *testing.T) { } numArts := 10 - allArticles := make([]*Article, 0, numArts) + allArticles := make([]*stor.Article, 0, numArts) toScrapeTimes := make([]time.Time, 0, numArts) artIDs := make([]int, 0, numArts) start := time.Now() toScrapeTime := time.Now() for i := 0; i < numArts; i++ { - article := &Article{ + article := &stor.Article{ ID: i, Title: titles[i%len(titles)], Url: urls[i%len(urls)], diff --git a/pkg/store/store.go b/internal/store/store.go similarity index 100% rename from pkg/store/store.go rename to internal/store/store.go diff --git a/pkg/store/types.go b/internal/store/types.go similarity index 100% rename from pkg/store/types.go rename to internal/store/types.go diff --git a/localdev/db/populate.go b/localdev/db/populate.go index 3337de2..c774f6d 100644 --- a/localdev/db/populate.go +++ b/localdev/db/populate.go @@ -9,11 +9,12 @@ import ( "strings" "time" - stor "github.com/salt-today/salttoday2/pkg/store" + stor "github.com/salt-today/salttoday2/internal/store" + "github.com/salt-today/salttoday2/internal/store/rdb" ) func main() { - store, err := stor.NewSQLStorage(context.Background()) + store, err := rdb.New(context.Background()) if err != nil { panic(err) } diff --git a/main.go b/main.go deleted file mode 100644 index 7708d90..0000000 --- a/main.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "flag" - "fmt" - - "github.com/sirupsen/logrus" - - "github.com/salt-today/salttoday2/pkg/scraper" - "github.com/salt-today/salttoday2/pkg/server" -) - -func main() { - flag.Usage = func() { - fmt.Println("\nSalttoday scrapes comments from various news sites and displays them.") - fmt.Println("\nUsage:") - fmt.Println("\n\tsalttoday [arguments]") - fmt.Println("\nCommands:") - fmt.Println(` server Runs the HTTP server`) - fmt.Println(` scraper Runs the scraper to collect and store comments`) - fmt.Println() - } - flag.Parse() - - switch flag.Arg(0) { - case `server`: - server.Main() - case `scraper`: - scraper.Main() - default: - if len(flag.Arg(0)) == 0 { - logrus.Error(`command not provided`) - } else { - logrus.Errorf(`%q is not a valid command.`, flag.Arg(0)) - } - flag.Usage() - } -} diff --git a/pkg/server/internal/ui/components/comments.templ b/pkg/server/internal/ui/components/comments.templ deleted file mode 100644 index f8b2e8e..0000000 --- a/pkg/server/internal/ui/components/comments.templ +++ /dev/null @@ -1,57 +0,0 @@ -package components - -import "fmt" -import "github.com/salt-today/salttoday2/pkg/store" - -func getGradient(comment *store.Comment) string { - if comment.Likes+comment.Dislikes == 0 { - return "bg-gray-500" - } - if comment.Likes == 0 { - return "bg-red-600" - } - if comment.Dislikes == 0 { - return "bg-blue-600" - } - return fmt.Sprintf("bg-gradient-to-br from-blue-600 to-red-600 from-%d%% to-%d%%", - max(0, - int((float64(comment.Likes)/float64(comment.Likes+comment.Dislikes))*100)/5*5), - min(100, - int((float64(comment.Likes)/float64(comment.Likes+comment.Dislikes))*100-5)/5*5), - ) - -} - -func max(x, y int) int { - if x > y { - return x - } - return y -} - -func min(x, y int) int { - if x > y { - return y - } - return x -} - -templ CommentComponent(comment *store.Comment) { -
- -
-
- { comment.Text } - πŸ‘ { fmt.Sprintf("%d", comment.Likes) } πŸ‘Ž { fmt.Sprintf("%d", comment.Dislikes) } -
-
-
- - if comment.Deleted { -
DELETED
- } -
-
-} diff --git a/pkg/server/internal/ui/components/users_list.templ b/pkg/server/internal/ui/components/users_list.templ deleted file mode 100644 index 3549a42..0000000 --- a/pkg/server/internal/ui/components/users_list.templ +++ /dev/null @@ -1,9 +0,0 @@ -package components - -import "github.com/salt-today/salttoday2/pkg/store" - -templ UsersListComponent(users []*store.User) { - for _, user := range users { - @UserComponent(user) - } -} diff --git a/pkg/server/internal/ui/views/home.templ b/pkg/server/internal/ui/views/home.templ deleted file mode 100644 index b18ae99..0000000 --- a/pkg/server/internal/ui/views/home.templ +++ /dev/null @@ -1,17 +0,0 @@ -package views - -import "github.com/salt-today/salttoday2/pkg/server/internal/ui/components" -import "github.com/salt-today/salttoday2/pkg/store" - -templ Home(queryOpts *store.CommentQueryOptions, comments []*store.Comment, nextUrl string) { - @Page(true) { - @components.CommentsFormComponent("/comments", queryOpts) -
- if len(comments) > 0 { - @components.CommentsListComponent(comments, nextUrl) - } else { - @components.NoResultsFound("Comments") - } -
- } -} diff --git a/pkg/server/internal/ui/views/page_templ.go b/pkg/server/internal/ui/views/page_templ.go deleted file mode 100644 index b01ac6d..0000000 --- a/pkg/server/internal/ui/views/page_templ.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.636 -package views - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import "context" -import "io" -import "bytes" - -func Page(nav bool) templ.Component { - return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) - if !templ_7745c5c3_IsBuffer { - templ_7745c5c3_Buffer = templ.GetBuffer() - defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("SaltToday 2") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if nav { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
\"Pile
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if !templ_7745c5c3_IsBuffer { - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) - } - return templ_7745c5c3_Err - }) -} diff --git a/pkg/server/internal/ui/views/user.templ b/pkg/server/internal/ui/views/user.templ deleted file mode 100644 index 90a0bb6..0000000 --- a/pkg/server/internal/ui/views/user.templ +++ /dev/null @@ -1,20 +0,0 @@ -package views - -import ( - "fmt" - "github.com/salt-today/salttoday2/pkg/server/internal/ui/components" - "github.com/salt-today/salttoday2/pkg/store" -) - -templ User(user *store.User, queryOpts *store.CommentQueryOptions, comments []*store.Comment, nextUrl string) { - @Page(true) { - @components.CommentsFormComponent(fmt.Sprintf("/user/%d/comments", user.ID), queryOpts) -
- if len(comments) > 0 { - @components.CommentsListComponent(comments, nextUrl) - } else { - @components.NoResultsFound("User") - } -
- } -} diff --git a/public/images/SaltTodayLogoNoSalt.svg b/web/public/images/SaltTodayLogoNoSalt.svg similarity index 100% rename from public/images/SaltTodayLogoNoSalt.svg rename to web/public/images/SaltTodayLogoNoSalt.svg diff --git a/public/images/SaltTodayLogoRedBlue.psd b/web/public/images/SaltTodayLogoRedBlue.psd similarity index 100% rename from public/images/SaltTodayLogoRedBlue.psd rename to web/public/images/SaltTodayLogoRedBlue.psd diff --git a/public/images/footer-pile.png b/web/public/images/footer-pile.png similarity index 100% rename from public/images/footer-pile.png rename to web/public/images/footer-pile.png diff --git a/public/images/salt-falling.png b/web/public/images/salt-falling.png similarity index 100% rename from public/images/salt-falling.png rename to web/public/images/salt-falling.png diff --git a/public/output.css b/web/public/output.css similarity index 100% rename from public/output.css rename to web/public/output.css diff --git a/public/styles.css b/web/public/styles.css similarity index 100% rename from public/styles.css rename to web/public/styles.css