Skip to content

Commit

Permalink
feat: add genre pages and most seen genres stat
Browse files Browse the repository at this point in the history
  • Loading branch information
believer committed Sep 12, 2024
1 parent 604ed17 commit dd52a91
Show file tree
Hide file tree
Showing 19 changed files with 554 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
delay = 1000
include_dir = []
exclude_dir = ["public", "tmp", "vendor", "node_modules"]
include_ext = ["go", "tpl", "tmpl", "html", "templ", "css"]
include_ext = ["go", "tpl", "tmpl", "html", "templ", "css", "sql"]
exclude_regex = ["_test.go", ".*_templ.go"]
exclude_unchanged = false
follow_symlink = false
Expand Down
18 changes: 9 additions & 9 deletions components/list.templ
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
)

type ListItem struct {
ID string
Name string
Count int
Name string `db:"name"`
ID string `db:"id"`
Count int `db:"count"`
}

templ OrderedList(data []ListItem, listType string) {
Expand All @@ -19,15 +19,15 @@ templ OrderedList(data []ListItem, listType string) {
data-position={ strconv.Itoa(i + 1) }
>
if listType == "movie" {
@Link(LinkProps{
Href: fmt.Sprintf("/movies/%s", item.ID),
}) {
@Link(LinkProps{Href: fmt.Sprintf("/movies/%s", item.ID)}) {
{ item.Name }
}
} else if listType == "person" {
@Link(LinkProps{
Href: fmt.Sprintf("/person/%s", item.ID),
}) {
@Link(LinkProps{Href: fmt.Sprintf("/person/%s", item.ID)}) {
{ item.Name }
}
} else if listType == "genre" {
@Link(LinkProps{Href: fmt.Sprintf("/genre/%s", item.ID)}) {
{ item.Name }
}
}
Expand Down
52 changes: 38 additions & 14 deletions components/list_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions components/mostWatchedPerson.templ
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ templ MostWatchedPerson(data []ListItem, title string) {
@OrderedList(data, "person")
}
}

templ MostWatchedGenres(data []ListItem) {
@Section("Most watched genre", 0) {
@OrderedList(data, "genre")
}
}
44 changes: 44 additions & 0 deletions components/mostWatchedPerson_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 51 additions & 2 deletions db/queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ SELECT
m.overview,
m.tagline,
r.rating,
ARRAY_AGG(DISTINCT (g.name)) AS genres
ARRAY_TO_JSON(ARRAY_AGG(json_build_object('name', g.name, 'id', g.id))) AS genres
FROM
movie AS m
INNER JOIN movie_genre AS mg ON mg.movie_id = m.id
Expand All @@ -88,7 +88,7 @@ GROUP BY
SELECT
m.*,
r.rating,
ARRAY_AGG(DISTINCT (g.name)) AS genres
ARRAY_TO_JSON(ARRAY_AGG(json_build_object('name', g.name, 'id', g.id))) AS genres
FROM
movie AS m
INNER JOIN movie_genre AS mg ON mg.movie_id = m.id
Expand Down Expand Up @@ -348,3 +348,52 @@ UNION ALL (
m.runtime DESC
LIMIT 1);

-- name: stats-genres
SELECT
g.id,
g.name,
COUNT(DISTINCT s.movie_id) AS count
FROM
seen s
INNER JOIN movie_genre mg ON mg.movie_id = s.movie_id
INNER JOIN genre g ON mg.genre_id = g.id
WHERE
s.user_id = $1
GROUP BY
g.id
ORDER BY
count DESC
LIMIT 10;

-- name: genres-by-id
SELECT DISTINCT
(m.id),
m.title,
m.release_date,
(s.id IS NOT NULL) AS "seen"
FROM
movie_genre mg
INNER JOIN movie m ON m.id = mg.movie_id
LEFT JOIN ( SELECT DISTINCT ON (movie_id)
movie_id,
id
FROM
public.seen
WHERE
user_id = $2
ORDER BY
movie_id,
id) AS s ON m.id = s.movie_id
WHERE
mg.genre_id = $1
ORDER BY
m.release_date DESC;

-- name: genre-by-id
SELECT
name
FROM
genre
WHERE
id = $1;

44 changes: 44 additions & 0 deletions handlers/genre.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package handlers

import (
"believer/movies/db"
"believer/movies/types"
"believer/movies/utils"
"believer/movies/views"

"github.com/gofiber/fiber/v2"
)

func HandleGetGenre(c *fiber.Ctx) error {
var movies types.Movies
var genre types.MovieGenre

userId := c.Locals("UserId").(string)
genreId := c.Params("id")

err := db.Dot.Get(db.Client, &genre, "genre-by-id", genreId)

if err != nil {
return err
}

err = db.Dot.Select(db.Client, &movies, "genres-by-id", genreId, userId)

if err != nil {
return err
}

seen := 0

for _, movie := range movies {
if movie.Seen {
seen += 1
}
}

return utils.TemplRender(c, views.Genre(views.GenreProps{
Name: genre.Name,
Movies: movies,
Seen: seen,
}))
}
5 changes: 4 additions & 1 deletion handlers/movies.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ func HandleGetMovieByID(c *fiber.Ctx) error {

backParam := c.QueryBool("back", false)

err := db.Dot.Get(db.Client, &movie, "movie-by-id", c.Params("id"), c.Locals("UserId"))
movieId := c.Params("id")
userId := c.Locals("UserId")
log.Println("id", movieId, "user", userId)
err := db.Dot.Get(db.Client, &movie, "movie-by-id", movieId, userId)

if err != nil {
err := db.Dot.Get(db.Client, &movie, "movie-by-name", c.Params("id"))
Expand Down
14 changes: 14 additions & 0 deletions handlers/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,17 @@ func availableYears() []int {

return years
}

func HandleGetGenreStats(c *fiber.Ctx) error {
var genres []components.ListItem

userId := c.Locals("UserId").(string)

err := db.Dot.Select(db.Client, &genres, "stats-genres", userId)

if err != nil {
return err
}

return utils.TemplRender(c, components.MostWatchedGenres(genres))
}
8 changes: 8 additions & 0 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ func SetupRoutes(app *fiber.App) {
personGroup.Get("/", redirectToHome)
personGroup.Get("/:id", handlers.HandleGetPersonByID)

// Genre
// --------------------------
genreGroup := app.Group("/genre")

genreGroup.Get("/", redirectToHome)
genreGroup.Get("/:id", handlers.HandleGetGenre)

// Search
// --------------------------
app.Post("/search", handlers.HandleMovieSearch)
Expand All @@ -49,6 +56,7 @@ func SetupRoutes(app *fiber.App) {
statsGroup := app.Group("/stats")

statsGroup.Get("/", handlers.HandleGetStats)
statsGroup.Get("/genres", handlers.HandleGetGenreStats)
statsGroup.Get("/ratings", handlers.HandleGetRatingsByYear)
statsGroup.Get("/by-month", handlers.HandleGetThisYearByMonth)
statsGroup.Get("/most-watched-person/:job", handlers.HandleGetMostWatchedByJob)
Expand Down
Loading

0 comments on commit dd52a91

Please sign in to comment.