Skip to content

Commit

Permalink
feat: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
believer committed Sep 21, 2023
0 parents commit adf4db4
Show file tree
Hide file tree
Showing 17 changed files with 388 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build]
kill_delay = "10s"
delay = 500
exclude_dir = ["public", "tmp", "vendor", "node_modules"]

18 changes: 18 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Release

on:
push:
branches:
- main

jobs:
deploy:
name: Deploy app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
.env
.DS_Store
tmp
Binary file added bun.lockb
Binary file not shown.
29 changes: 29 additions & 0 deletions db/db_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package db

import (
"os"

"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)

var Client *sqlx.DB

func InitializeConnection() {
connectionString := os.Getenv("DATABASE_URL")
db, err := sqlx.Connect("postgres", connectionString)

if err != nil {
panic(err)
}

// Check if connection is alive
err = db.Ping()

if err != nil {
panic(err)
}

// Set the global DBClient variable to the db connection
Client = db
}
22 changes: 22 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# fly.toml app configuration file generated for movies-go on 2023-09-21T13:59:11+02:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = "movies-go"
primary_region = "arn"

[build]
builder = "paketobuildpacks/builder:base"
buildpacks = ["gcr.io/paketo-buildpacks/go"]

[env]
PORT = "8080"

[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
processes = ["app"]
26 changes: 26 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module believer/movies

go 1.21.0

require (
github.com/gofiber/fiber/v2 v2.49.2
github.com/gofiber/template/html/v2 v2.0.5
github.com/jmoiron/sqlx v1.3.5
github.com/lib/pq v1.10.9
)

require (
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/gofiber/template v1.8.2 // indirect
github.com/gofiber/utils v1.1.0 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.50.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
golang.org/x/sys v0.12.0 // indirect
)
43 changes: 43 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/gofiber/fiber/v2 v2.49.2 h1:ONEN3/Vc+dUCxxDgZZwpqvhISgHqb+bu+isBiEyKEQs=
github.com/gofiber/fiber/v2 v2.49.2/go.mod h1:gNsKnyrmfEWFpJxQAV0qvW6l70K1dZGno12oLtukcts=
github.com/gofiber/template v1.8.2 h1:PIv9s/7Uq6m+Fm2MDNd20pAFFKt5wWs7ZBd8iV9pWwk=
github.com/gofiber/template v1.8.2/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
github.com/gofiber/template/html/v2 v2.0.5 h1:BKLJ6Qr940NjntbGmpO3zVa4nFNGDCi/IfUiDB9OC20=
github.com/gofiber/template/html/v2 v2.0.5/go.mod h1:RCF14eLeQDCSUPp0IGc2wbSSDv6yt+V54XB/+Unz+LM=
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M=
github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
27 changes: 27 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"believer/movies/db"
"believer/movies/routes"

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

func main() {
db.InitializeConnection()

engine := html.New("./views", ".html")

app := fiber.New(fiber.Config{
Views: engine,
ViewsLayout: "layouts/main",
})

app.Get("/", routes.FeedHandler)
app.Get("/movies/:id", routes.MovieHandler)

app.Static("/public", "./public")

app.Listen(":8080")
}
24 changes: 24 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "movies",
"version": "1.0.0",
"description": "",
"main": "tailwind.config.js",
"scripts": {
"css": "tailwindcss -i ./styles.css -o ./public/styles.css --watch --minify",
"start": "godotenv air"
},
"repository": {
"type": "git",
"url": "git+https://github.com/believer/movies-go.git"
},
"keywords": [],
"author": "Rickard Natt och Dag",
"license": "ISC",
"bugs": {
"url": "https://github.com/believer/movies-go/issues"
},
"homepage": "https://github.com/believer/movies-go#readme",
"devDependencies": {
"tailwindcss": "^3.3.3"
}
}
1 change: 1 addition & 0 deletions public/styles.css

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

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

import (
"believer/movies/db"
"database/sql"
"fmt"
"time"

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

type CastAndCrew struct {
Name string `db:"name"`
Job string `db:"job"`
}

type Movie struct {
Cast []CastAndCrew `db:"cast"`
CreatedAt time.Time `db:"created_at"`
Genres pq.StringArray `db:"genres"`
Id int `db:"id"`
ImdbId string `db:"imdb_id"`
ImdbRating sql.NullFloat64 `db:"imdb_rating"`
Overview string `db:"overview"`
Poster string `db:"poster"`
ReleaseDate time.Time `db:"release_date"`
Runtime int `db:"runtime"`
Tagline string `db:"tagline"`
Title string `db:"title"`
UpdatedAt time.Time `db:"updated_at"`
WatchedAt time.Time `db:"watched_at"`
}

// Format runtime in hours and minutes from minutes
func (m Movie) RuntimeFormatted() string {
hours := m.Runtime / 60
minutes := m.Runtime % 60

return fmt.Sprintf("%dh %dm", hours, minutes)
}

func FeedHandler(c *fiber.Ctx) error {
var movies []Movie

err := db.Client.Select(&movies, `
SELECT m.id, m.title, m.poster, m.release_date, s.date AS watched_at
FROM public.seen AS s
INNER JOIN public.movie AS m ON m.id = s.movie_id
WHERE
user_id = 1
AND EXTRACT(YEAR FROM s.date) = EXTRACT(YEAR FROM CURRENT_DATE)
ORDER BY s.date DESC
`)

if err != nil {
panic(err)
}

return c.Render("index", fiber.Map{
"Movies": movies,
})
}

func MovieHandler(c *fiber.Ctx) error {
var movie Movie

err := db.Client.Get(&movie, `
SELECT
m.*,
ARRAY_AGG(g.name) AS genres
FROM
public.movie AS m
INNER JOIN public.movie_genre AS mg ON mg.movie_id = m.id
INNER JOIN public.genre AS g ON g.id = mg.genre_id
WHERE m.id = $1
GROUP BY 1
`, c.Params("id"))

if err != nil {
panic(err)
}

return c.Render("movie", fiber.Map{
"Movie": movie,
})
}
7 changes: 7 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

.movie-poster-animation {
view-transition-name: var(--poster-transition);
}
8 changes: 8 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./views/**/*.html", "./**/*.go"],
theme: {
extend: {},
},
plugins: [],
};
24 changes: 24 additions & 0 deletions views/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<div class="max-w-6xl mx-auto py-8">
<ol class="grid grid-cols-4 gap-5">
{{ range .Movies }}
<li class="grid grid-rows-[subgrid] row-span-2 gap-2">
<a href="/movies/{{ .Id }}" hx-swap="innerHTML transition:true">
<img
alt="{{ .Title }} poster"
class="rounded-lg w-full h-full object-cover shadow-lg object-center movie-poster-animation"
src="https://image.tmdb.org/t/p/w500{{ .Poster }}"
style="--poster-transition: movie-poster-{{ .Id }}"
/>
</a>
<div class="grid gap-1">
<h2 class="font-semibold text-sm truncate text-slate-700">
{{ .Title }}
</h2>
<p class="text-xs text-slate-500">
{{ .ReleaseDate.Format "2006" }} - {{ .WatchedAt.Format "Jan 02" }}
</p>
</div>
</li>
{{ end }}
</ol>
</div>
17 changes: 17 additions & 0 deletions views/layouts/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Movies</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="/public/styles.css" rel="stylesheet" />
<script
src="https://unpkg.com/htmx.org@1.9.5"
integrity="sha384-xcuj3WpfgjlKF+FXhSQFQ0ZNr39ln+hwjN3npfM9VBnUskLolQAcN80McRIVOPuO"
crossorigin="anonymous"
></script>
</head>
<body class="text-slate-800" hx-boost="true">
<main>{{embed}}</main>
</body>
</html>
Loading

0 comments on commit adf4db4

Please sign in to comment.