mirror of
https://github.com/Itsig0/pocketmovie.git
synced 2026-01-22 08:24:38 +00:00
+ baseline to the git
This commit is contained in:
178
internal/apis/tmdb.go
Normal file
178
internal/apis/tmdb.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package apis
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
)
|
||||
|
||||
var (
|
||||
token = os.Getenv("TMDB_API_KEY")
|
||||
apiurl = "https://api.themoviedb.org/3/"
|
||||
)
|
||||
|
||||
func request(requrl string) (*http.Response, []byte) {
|
||||
req, _ := http.NewRequest("GET", apiurl+requrl, nil)
|
||||
|
||||
req.Header.Add("authorization", "Bearer "+token)
|
||||
req.Header.Add("accept", "application/json")
|
||||
|
||||
res, _ := http.DefaultClient.Do(req)
|
||||
|
||||
body, _ := io.ReadAll(res.Body)
|
||||
|
||||
res.Body.Close()
|
||||
return res, body
|
||||
}
|
||||
|
||||
func buildQuery(opts map[string]string) string {
|
||||
query := url.Values{}
|
||||
for k, v := range opts {
|
||||
query.Add(k, v)
|
||||
}
|
||||
return query.Encode()
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Results []Movie `json:"results"`
|
||||
}
|
||||
|
||||
type Movie struct {
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
OriginalTitle string `json:"original_title"`
|
||||
PosterPath string `json:"poster_path"`
|
||||
ReleaseDate string `json:"release_date"`
|
||||
ImdbID string `json:"imdb_id"`
|
||||
Lenght int `json:"runtime"`
|
||||
Genres []Genre `json:"genres"`
|
||||
Overview string `json:"overview"`
|
||||
Director string
|
||||
}
|
||||
|
||||
type Genre struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Crew struct {
|
||||
Person []Person `json:"crew"`
|
||||
}
|
||||
|
||||
type Person struct {
|
||||
Name string `json:"name"`
|
||||
Department string `json:"job"`
|
||||
}
|
||||
|
||||
type WatchProviders struct {
|
||||
ID int `json:"id"`
|
||||
Results map[string]Country `json:"results"`
|
||||
}
|
||||
|
||||
type Country struct {
|
||||
Link string `json:"link"`
|
||||
Flatrate []Provider `json:"flatrate,omitempty"`
|
||||
Free []Provider `json:"free,omitempty"`
|
||||
Rent []Provider `json:"rent,omitempty"`
|
||||
Buy []Provider `json:"buy,omitempty"`
|
||||
}
|
||||
|
||||
type Provider struct {
|
||||
LogoPath string `json:"logo_path"`
|
||||
ProviderID int `json:"provider_id"`
|
||||
ProviderName string `json:"provider_name"`
|
||||
DisplayPriority int `json:"display_priority"`
|
||||
}
|
||||
|
||||
func SearchTmdbMovie(search string) []Movie {
|
||||
opts := map[string]string{"query": search, "page": "1"}
|
||||
url := fmt.Sprintf("search/movie?%s", buildQuery(opts))
|
||||
|
||||
_, body := request(url)
|
||||
|
||||
var responseObjekt Response
|
||||
json.Unmarshal(body, &responseObjekt)
|
||||
|
||||
return responseObjekt.Results
|
||||
}
|
||||
|
||||
func getMovieDirector(id string) string {
|
||||
url := fmt.Sprintf("movie/%s/credits", id)
|
||||
_, body := request(url)
|
||||
|
||||
var crewObjekt Crew
|
||||
json.Unmarshal(body, &crewObjekt)
|
||||
|
||||
for _, v := range crewObjekt.Person {
|
||||
if v.Department == "Director" {
|
||||
return v.Name
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetMovieStreamingServices(id int, lang string) Country {
|
||||
url := fmt.Sprintf("movie/%d/watch/providers", id)
|
||||
_, body := request(url)
|
||||
|
||||
var responseObjekt WatchProviders
|
||||
json.Unmarshal(body, &responseObjekt)
|
||||
|
||||
// Returning the available streaming services
|
||||
return responseObjekt.Results[lang]
|
||||
}
|
||||
|
||||
func GetTmdbMovie(id string) Movie {
|
||||
url := fmt.Sprintf("movie/%s", id)
|
||||
_, body := request(url)
|
||||
|
||||
getMovieDirector(id)
|
||||
|
||||
var responseObjekt Movie
|
||||
json.Unmarshal(body, &responseObjekt)
|
||||
|
||||
responseObjekt.Director = getMovieDirector(id)
|
||||
|
||||
return responseObjekt
|
||||
}
|
||||
|
||||
type WatchResults struct {
|
||||
Results []Provider `json:"results,omitempty"`
|
||||
}
|
||||
|
||||
func GetMovieProviders(region string) []Provider {
|
||||
opts := map[string]string{"language": "en_US", "watch_region": region}
|
||||
url := fmt.Sprintf("watch/providers/movie?%s", buildQuery(opts))
|
||||
|
||||
_, body := request(url)
|
||||
|
||||
var responseObjekt WatchResults
|
||||
json.Unmarshal(body, &responseObjekt)
|
||||
|
||||
return responseObjekt.Results
|
||||
}
|
||||
|
||||
type RegionResults struct {
|
||||
Results []Region `json:"results"`
|
||||
}
|
||||
|
||||
type Region struct {
|
||||
Iso string `json:"iso_3166_1"`
|
||||
EnglishName string `json:"english_name"`
|
||||
NativeName string `json:"native_name"`
|
||||
}
|
||||
|
||||
func GetAvailableRegions() []Region {
|
||||
url := "watch/providers/regions"
|
||||
|
||||
_, body := request(url)
|
||||
|
||||
var responseObjekt RegionResults
|
||||
json.Unmarshal(body, &responseObjekt)
|
||||
|
||||
return responseObjekt.Results
|
||||
}
|
||||
32
internal/database/database.go
Normal file
32
internal/database/database.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
_ "embed"
|
||||
"log"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
var (
|
||||
dburl = "./data/data.db"
|
||||
)
|
||||
|
||||
//go:embed schema.sql
|
||||
var ddl string
|
||||
|
||||
func Init() *Queries {
|
||||
ctx := context.Background()
|
||||
|
||||
db, err := sql.Open("sqlite3", dburl)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := db.ExecContext(ctx, ddl); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return New(db)
|
||||
}
|
||||
73
internal/database/movies.sql
Normal file
73
internal/database/movies.sql
Normal file
@@ -0,0 +1,73 @@
|
||||
-- name: ListMovies :many
|
||||
SELECT * FROM movie
|
||||
ORDER BY title ASC;
|
||||
|
||||
-- name: ListMovie :one
|
||||
SELECT * FROM movie
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: ListWatchlist :many
|
||||
SELECT * FROM movie
|
||||
WHERE status = 0
|
||||
ORDER BY
|
||||
CASE WHEN streaming_services = '' OR streaming_services IS NULL THEN 1 ELSE 0 END,
|
||||
title;
|
||||
|
||||
-- name: ListSettings :many
|
||||
SELECT * FROM settings;
|
||||
|
||||
-- name: ListSetting :one
|
||||
SELECT * FROM settings
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: ListSreamingServices :many
|
||||
SELECT * FROM streaming_services;
|
||||
|
||||
-- name: CreateMovie :one
|
||||
INSERT INTO movie (
|
||||
title, original_title, imdbid, tmdbid, length, genre, streaming_services, director, year, watchcount, rating, status, owned, owned_type, ripped, review, overview
|
||||
) VALUES (
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
-- name: AddSreamingService :exec
|
||||
INSERT INTO streaming_services (title) VALUES ( ? );
|
||||
|
||||
-- name: DeleteSreamingService :exec
|
||||
DELETE FROM streaming_services
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: DeleteMovie :exec
|
||||
DELETE FROM movie
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: ChangeMovieStatus :exec
|
||||
UPDATE movie
|
||||
SET status = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: ChangeMovieRating :exec
|
||||
UPDATE movie
|
||||
SET rating = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: ChangeMovieOwned :exec
|
||||
UPDATE movie
|
||||
SET owned = ?, owned_type = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: ChangeMovieStreamingServices :exec
|
||||
UPDATE movie
|
||||
SET streaming_services = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: ChangeMovieRipped :exec
|
||||
UPDATE movie
|
||||
SET ripped = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: ChangeSettingValue :exec
|
||||
UPDATE settings
|
||||
SET value = ?
|
||||
WHERE id = ?;
|
||||
51
internal/database/schema.sql
Normal file
51
internal/database/schema.sql
Normal file
@@ -0,0 +1,51 @@
|
||||
CREATE TABLE IF NOT EXISTS movie (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
original_title VARCHAR(255) NOT NULL,
|
||||
imdbid VARCHAR(25) NOT NULL,
|
||||
tmdbid INTEGER NOT NULL,
|
||||
length INTEGER NOT NULL,
|
||||
genre VARCHAR(255) NOT NULL,
|
||||
streaming_services VARCHAR(255) NOT NULL,
|
||||
director VARCHAR(255) NOT NULL,
|
||||
year VARCHAR(10) NOT NULL,
|
||||
watchcount INTEGER NOT NULL,
|
||||
rating INTEGER NOT NULL,
|
||||
status INTEGER NOT NULL,
|
||||
owned INTEGER NOT NULL,
|
||||
owned_type VARCHAR(255) NOT NULL,
|
||||
ripped INTEGER NOT NULL,
|
||||
review TEXT NOT NULL,
|
||||
overview TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS genres (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title VARCHAR(30) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS streaming_services (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title VARCHAR(30) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
value VARCHAR(100) NOT NULL,
|
||||
description VARCHAR(255) NOT NULL
|
||||
);
|
||||
|
||||
INSERT OR IGNORE INTO streaming_services
|
||||
VALUES
|
||||
("1", "Netflix"),
|
||||
("2", "Disney Plus"),
|
||||
("3", "Amazon Prime Video"),
|
||||
("4", "Apple TV+");
|
||||
|
||||
|
||||
INSERT OR IGNORE INTO settings
|
||||
VALUES
|
||||
("1", "HOME_GRID_VIEW", "false", "Grid or no grid on the Homepage"),
|
||||
("2", "TMDB_API_KEY", "", "Your TMDB api key"),
|
||||
("3", "REGION", "DE", "Your Region");
|
||||
28
internal/middleware/apikeychecker/apikeychecker.go
Normal file
28
internal/middleware/apikeychecker/apikeychecker.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package apikeychecker
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.itsigo.dev/istigo/pocketmovie/internal/database"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
DB database.Queries
|
||||
}
|
||||
|
||||
func configDefault(config ...Config) Config {
|
||||
cfg := config[0]
|
||||
return cfg
|
||||
}
|
||||
|
||||
func New(config Config) fiber.Handler {
|
||||
return func(c fiber.Ctx) error {
|
||||
setting, _ := config.DB.ListSetting(c, 2)
|
||||
referer := string(c.Request().Header.Referer())
|
||||
if setting.Value == "" && !strings.Contains(referer, "apikey") {
|
||||
return c.Redirect().Status(fiber.StatusMovedPermanently).To("/apikey")
|
||||
}
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
40
internal/server/index.go
Normal file
40
internal/server/index.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"git.itsigo.dev/istigo/pocketmovie/cmd/web"
|
||||
"git.itsigo.dev/istigo/pocketmovie/internal/apis"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func (s *FiberServer) Index(c fiber.Ctx) error {
|
||||
movies, _ := s.db.ListMovies(c)
|
||||
settings, _ := s.db.ListSettings(c)
|
||||
return render(c, web.Show(movies, settings))
|
||||
}
|
||||
|
||||
func (s *FiberServer) Watchlist(c fiber.Ctx) error {
|
||||
movies, _ := s.db.ListWatchlist(c)
|
||||
return render(c, web.WatchList(movies))
|
||||
}
|
||||
|
||||
func (s *FiberServer) Settings(c fiber.Ctx) error {
|
||||
ls, _ := s.db.ListSreamingServices(c)
|
||||
_, ts := s.getAllStreamingServices(c)
|
||||
slices.Sort(ts)
|
||||
|
||||
reg := apis.GetAvailableRegions()
|
||||
selectedreg, _ := s.db.ListSetting(c, 3)
|
||||
key, _ := s.db.ListSetting(c, 2)
|
||||
|
||||
config := web.SettingsConfig{
|
||||
Providers: ls,
|
||||
AvailableProviders: ts,
|
||||
Regions: reg,
|
||||
SelectedRegion: selectedreg.Value,
|
||||
APIKey: key.Value,
|
||||
}
|
||||
|
||||
return render(c, web.Settings(config))
|
||||
}
|
||||
357
internal/server/routes.go
Normal file
357
internal/server/routes.go
Normal file
@@ -0,0 +1,357 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/jpeg"
|
||||
"net/http"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"git.itsigo.dev/istigo/pocketmovie/cmd/web"
|
||||
"git.itsigo.dev/istigo/pocketmovie/internal/apis"
|
||||
"git.itsigo.dev/istigo/pocketmovie/internal/database"
|
||||
"git.itsigo.dev/istigo/pocketmovie/internal/middleware/apikeychecker"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/log"
|
||||
"github.com/gofiber/fiber/v3/middleware/static"
|
||||
)
|
||||
|
||||
func (s *FiberServer) RegisterFiberRoutes() {
|
||||
s.App.Use("/apikey", s.apikeyinput)
|
||||
|
||||
s.App.Use("/assets", static.New("./assets", static.Config{
|
||||
FS: web.Files,
|
||||
Browse: false,
|
||||
}))
|
||||
|
||||
s.App.Use("/movie/posters", static.New("./data/img"))
|
||||
|
||||
s.App.Use(
|
||||
//basicauth.New(basicauth.Config{
|
||||
// Users: map[string]string{
|
||||
// // "doe" hashed using SHA-256
|
||||
// "john": "{SHA256}eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=",
|
||||
// },
|
||||
//}),
|
||||
//compress.New(compress.Config{
|
||||
// Level: compress.LevelBestSpeed, // 1
|
||||
//}),
|
||||
apikeychecker.New(apikeychecker.Config{DB: *s.db}),
|
||||
)
|
||||
|
||||
s.App.Get("/", s.Index)
|
||||
s.App.Get("/watchlist", s.Watchlist)
|
||||
s.App.Get("/settings", s.Settings)
|
||||
s.App.Get("/movie/:id", s.movieDetails)
|
||||
|
||||
s.App.Get("/components/mediaTypeSelect/:id", s.mediaTypeSelect)
|
||||
|
||||
s.App.Post("/apis/tmdb/searchMovie", s.searchMovie)
|
||||
s.App.Post("/db/addMovie/:id", s.addMovieToDb)
|
||||
s.App.Post("/db/changeMovieStatus/:id.:status", s.changeMovieStatus)
|
||||
s.App.Post("/db/changeMovieRating/:id.:rating", s.changeMovieRating)
|
||||
s.App.Post("/db/changeMovieOwned/:id", s.changeMovieOwned)
|
||||
s.App.Post("/db/changeMovieRipped/:id.:ripped", s.changeMovieRipped)
|
||||
s.App.Post("/db/updateStreamingServices", s.updateMovieStreamingServices)
|
||||
s.App.Post("/db/updateTableView", s.updateTableView)
|
||||
s.App.Post("/db/updateRegion", s.updateRegion)
|
||||
s.App.Post("/db/updateApiKey", s.updateApiKey)
|
||||
s.App.Delete("/db/deleteMovie/:id", s.deleteMovie)
|
||||
|
||||
s.App.Post("/db/addStreamingService", s.addStreamingService)
|
||||
s.App.Delete("/db/deleteStreamingService/:id", s.deleteStreamingService)
|
||||
}
|
||||
|
||||
func (s *FiberServer) apikeyinput(c fiber.Ctx) error {
|
||||
key := c.FormValue("apikey")
|
||||
apierror := ""
|
||||
if key != "" {
|
||||
url := "https://api.themoviedb.org/3/authentication"
|
||||
req, _ := http.NewRequest("GET", url, nil)
|
||||
req.Header.Add("accept", "application/json")
|
||||
req.Header.Add("Authorization", "Bearer "+key)
|
||||
res, _ := http.DefaultClient.Do(req)
|
||||
|
||||
if res.StatusCode == 200 {
|
||||
s.db.ChangeSettingValue(c, database.ChangeSettingValueParams{
|
||||
ID: 2,
|
||||
Value: key,
|
||||
})
|
||||
c.Redirect().Status(fiber.StatusMovedPermanently).To("/")
|
||||
}
|
||||
apierror = "Could not certify API Read Access Token"
|
||||
}
|
||||
return render(c, web.Apikeyinput(apierror))
|
||||
}
|
||||
|
||||
func (s *FiberServer) updateApiKey(c fiber.Ctx) error {
|
||||
key := c.FormValue("apikey")
|
||||
s.db.ChangeSettingValue(c, database.ChangeSettingValueParams{
|
||||
ID: 2,
|
||||
Value: key,
|
||||
})
|
||||
|
||||
config := web.SettingsConfig{
|
||||
APIKey: key,
|
||||
}
|
||||
return render(c, web.ApiKey(config))
|
||||
}
|
||||
|
||||
func (s *FiberServer) movieDetails(c fiber.Ctx) error {
|
||||
id, _ := strconv.ParseInt(c.Params("id"), 10, 64)
|
||||
movie, _ := s.db.ListMovie(c, id)
|
||||
return render(c, web.MovieDetails(movie))
|
||||
}
|
||||
|
||||
func (s *FiberServer) mediaTypeSelect(c fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
return render(c, web.MovieDetailsOwnedSelect(int8(id)))
|
||||
}
|
||||
|
||||
func (s *FiberServer) searchMovie(c fiber.Ctx) error {
|
||||
res := apis.SearchTmdbMovie(c.FormValue("search"))
|
||||
return render(c, web.SearchMovie(res))
|
||||
}
|
||||
|
||||
func (s *FiberServer) changeMovieStatus(c fiber.Ctx) error {
|
||||
id, _ := strconv.ParseInt(c.Params("id"), 10, 64)
|
||||
status, _ := strconv.ParseInt(c.Params("status"), 10, 64)
|
||||
|
||||
s.db.ChangeMovieStatus(c, database.ChangeMovieStatusParams{
|
||||
ID: id,
|
||||
Status: status,
|
||||
})
|
||||
|
||||
return render(c, web.MovieDetailsWatched(id, status))
|
||||
}
|
||||
|
||||
func (s *FiberServer) changeMovieRating(c fiber.Ctx) error {
|
||||
id, _ := strconv.ParseInt(c.Params("id"), 10, 64)
|
||||
rating, _ := strconv.ParseInt(c.Params("rating"), 10, 64)
|
||||
|
||||
s.db.ChangeMovieRating(c, database.ChangeMovieRatingParams{
|
||||
ID: id,
|
||||
Rating: rating,
|
||||
})
|
||||
|
||||
return render(c, web.MovieDetailsRating(id, rating))
|
||||
}
|
||||
|
||||
func (s *FiberServer) changeMovieOwned(c fiber.Ctx) error {
|
||||
id, _ := strconv.ParseInt(c.Params("id"), 10, 64)
|
||||
option := c.FormValue("option")
|
||||
var owned int64 = 0
|
||||
if option != "" {
|
||||
owned = 1
|
||||
}
|
||||
|
||||
s.db.ChangeMovieOwned(c, database.ChangeMovieOwnedParams{
|
||||
ID: id,
|
||||
Owned: owned,
|
||||
OwnedType: option,
|
||||
})
|
||||
|
||||
return render(c, web.MovieDetailsOwned(id, option))
|
||||
}
|
||||
|
||||
func (s *FiberServer) changeMovieRipped(c fiber.Ctx) error {
|
||||
id, _ := strconv.ParseInt(c.Params("id"), 10, 64)
|
||||
ripped, _ := strconv.ParseInt(c.Params("ripped"), 10, 64)
|
||||
|
||||
s.db.ChangeMovieRipped(c, database.ChangeMovieRippedParams{
|
||||
ID: id,
|
||||
Ripped: ripped,
|
||||
})
|
||||
|
||||
return render(c, web.MovieDetailsRipped(id, ripped))
|
||||
}
|
||||
|
||||
func (s *FiberServer) updateMovieStreamingServices(c fiber.Ctx) error {
|
||||
movies, _ := s.db.ListMovies(c)
|
||||
for _, v := range movies {
|
||||
s.db.ChangeMovieStreamingServices(c, database.ChangeMovieStreamingServicesParams{
|
||||
ID: v.ID,
|
||||
StreamingServices: s.getStreamingServicesForMovie(c, v.Tmdbid),
|
||||
})
|
||||
}
|
||||
movies, _ = s.db.ListWatchlist(c)
|
||||
return render(c, web.List(movies))
|
||||
}
|
||||
|
||||
func (s *FiberServer) updateTableView(c fiber.Ctx) error {
|
||||
setting, _ := s.db.ListSetting(c, 1)
|
||||
v := "false"
|
||||
if setting.Value == "false" {
|
||||
v = "true"
|
||||
}
|
||||
s.db.ChangeSettingValue(c, database.ChangeSettingValueParams{
|
||||
Value: v,
|
||||
ID: 1,
|
||||
})
|
||||
movies, _ := s.db.ListMovies(c)
|
||||
if v == "true" {
|
||||
return render(c, web.MovieTiles(movies))
|
||||
}
|
||||
return render(c, web.MovieList(movies))
|
||||
}
|
||||
|
||||
func (s *FiberServer) updateRegion(c fiber.Ctx) error {
|
||||
region := c.FormValue("region")
|
||||
s.db.ChangeSettingValue(c, database.ChangeSettingValueParams{
|
||||
Value: region,
|
||||
ID: 3,
|
||||
})
|
||||
|
||||
regions := apis.GetAvailableRegions()
|
||||
|
||||
config := web.SettingsConfig{
|
||||
Regions: regions,
|
||||
SelectedRegion: region,
|
||||
}
|
||||
return render(c, web.Region(config))
|
||||
}
|
||||
|
||||
func (s *FiberServer) addStreamingService(c fiber.Ctx) error {
|
||||
title := c.FormValue("service")
|
||||
|
||||
s.db.AddSreamingService(c, title)
|
||||
|
||||
ls, _ := s.db.ListSreamingServices(c)
|
||||
_, ts := s.getAllStreamingServices(c)
|
||||
slices.Sort(ts)
|
||||
|
||||
config := web.SettingsConfig{
|
||||
Providers: ls,
|
||||
AvailableProviders: ts,
|
||||
}
|
||||
|
||||
return render(c, web.ProviderTable(config))
|
||||
}
|
||||
|
||||
func (s *FiberServer) deleteStreamingService(c fiber.Ctx) error {
|
||||
id := fiber.Params[int64](c, "id")
|
||||
|
||||
s.db.DeleteSreamingService(c, id)
|
||||
|
||||
ls, _ := s.db.ListSreamingServices(c)
|
||||
_, ts := s.getAllStreamingServices(c)
|
||||
slices.Sort(ts)
|
||||
|
||||
config := web.SettingsConfig{
|
||||
Providers: ls,
|
||||
AvailableProviders: ts,
|
||||
}
|
||||
|
||||
return render(c, web.ProviderTable(config))
|
||||
}
|
||||
|
||||
func (s *FiberServer) deleteMovie(c fiber.Ctx) error {
|
||||
id := fiber.Params[int64](c, "id")
|
||||
|
||||
s.db.DeleteMovie(c, id)
|
||||
|
||||
movies, _ := s.db.ListMovies(c)
|
||||
return render(c, web.MovieList(movies))
|
||||
}
|
||||
|
||||
func (s *FiberServer) addMovieToDb(c fiber.Ctx) error {
|
||||
|
||||
res := apis.GetTmdbMovie(c.Params("id"))
|
||||
referer := string(c.Request().Header.Referer())
|
||||
|
||||
// Combine Genres
|
||||
genres := []string{}
|
||||
for _, v := range res.Genres {
|
||||
genres = append(genres, v.Name)
|
||||
}
|
||||
|
||||
// Get the streaming providers
|
||||
streamingservices := s.getStreamingServicesForMovie(c, int64(res.Id))
|
||||
|
||||
rating := 0
|
||||
if c.FormValue("rating") != "" {
|
||||
rating, _ = strconv.Atoi(c.FormValue("rating"))
|
||||
}
|
||||
watched := 0
|
||||
if c.FormValue("watched") == "on" {
|
||||
watched = 1
|
||||
}
|
||||
watchcount := 0
|
||||
if c.FormValue("watchcount") != "" {
|
||||
watchcount, _ = strconv.Atoi(c.FormValue("watchcount"))
|
||||
}
|
||||
owned := 0
|
||||
if c.FormValue("owned") == "on" {
|
||||
owned = 1
|
||||
}
|
||||
ownedType := ""
|
||||
if c.FormValue("version") != "" {
|
||||
ownedType = c.FormValue("version")
|
||||
}
|
||||
ripped := 0
|
||||
if c.FormValue("ripped") == "on" {
|
||||
ripped = 1
|
||||
}
|
||||
|
||||
movie, err := s.db.CreateMovie(c, database.CreateMovieParams{
|
||||
Title: res.Title,
|
||||
OriginalTitle: res.OriginalTitle,
|
||||
Imdbid: res.ImdbID,
|
||||
Tmdbid: int64(res.Id),
|
||||
Length: int64(res.Lenght),
|
||||
Genre: strings.Join(genres, ", "),
|
||||
StreamingServices: streamingservices,
|
||||
Director: res.Director,
|
||||
Year: res.ReleaseDate,
|
||||
Watchcount: int64(watchcount),
|
||||
Rating: int64(rating),
|
||||
Status: int64(watched),
|
||||
Owned: int64(owned),
|
||||
OwnedType: ownedType,
|
||||
Ripped: int64(ripped),
|
||||
Review: "",
|
||||
Overview: res.Overview,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
// Get the movie poster
|
||||
resp, err := http.Get("https://image.tmdb.org/t/p/original" + res.PosterPath)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
tmp, err := jpeg.Decode(resp.Body)
|
||||
if err == nil {
|
||||
path := fmt.Sprintf("./data/img/%d.jpg", movie.ID)
|
||||
log.Info(path)
|
||||
outputFile, err := os.Create(path)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
jpeg.Encode(outputFile, tmp, nil)
|
||||
|
||||
outputFile.Close()
|
||||
}
|
||||
|
||||
if strings.Contains(referer, "watchlist") {
|
||||
movies, _ := s.db.ListWatchlist(c)
|
||||
return render(c, web.List(movies))
|
||||
}
|
||||
|
||||
gridSetting, _ := s.db.ListSetting(c, 1)
|
||||
movies, _ := s.db.ListMovies(c)
|
||||
componet := web.MovieList(movies)
|
||||
|
||||
if gridSetting.Value == "true" {
|
||||
componet = web.MovieTiles(movies)
|
||||
}
|
||||
|
||||
return render(c, componet)
|
||||
}
|
||||
23
internal/server/server.go
Normal file
23
internal/server/server.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"git.itsigo.dev/istigo/pocketmovie/internal/database"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type FiberServer struct {
|
||||
*fiber.App
|
||||
|
||||
db *database.Queries
|
||||
}
|
||||
|
||||
func New() *FiberServer {
|
||||
server := &FiberServer{
|
||||
App: fiber.New(fiber.Config{
|
||||
ServerHeader: "PocketMovie",
|
||||
AppName: "PocketMovie",
|
||||
}),
|
||||
db: database.Init(),
|
||||
}
|
||||
return server
|
||||
}
|
||||
70
internal/server/util.go
Normal file
70
internal/server/util.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"git.itsigo.dev/istigo/pocketmovie/internal/apis"
|
||||
"github.com/a-h/templ"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/session"
|
||||
)
|
||||
|
||||
var store = session.New()
|
||||
|
||||
func render(c fiber.Ctx, component templ.Component) error {
|
||||
// or templ wil bork...
|
||||
c.Set("Content-type", "text/html")
|
||||
return component.Render(c, c.Response().BodyWriter())
|
||||
}
|
||||
|
||||
// Gets the Streaming services for a movie as a string (service 1, service 2, ...)
|
||||
func (s *FiberServer) getStreamingServicesForMovie(c fiber.Ctx, id int64) string {
|
||||
// Get the streaming providers
|
||||
dbServicesSlice := s.getLocalStreamingServices(c)
|
||||
|
||||
region, _ := s.db.ListSetting(c, 3)
|
||||
|
||||
flatrate := apis.GetMovieStreamingServices(int(id), region.Value).Flatrate
|
||||
free := apis.GetMovieStreamingServices(int(id), region.Value).Free
|
||||
flatrate = append(flatrate, free...)
|
||||
streaningservices := []string{}
|
||||
for _, v := range flatrate {
|
||||
if slices.Contains(dbServicesSlice, v.ProviderName) {
|
||||
streaningservices = append(streaningservices, v.ProviderName)
|
||||
}
|
||||
}
|
||||
return strings.Join(streaningservices, ", ")
|
||||
}
|
||||
|
||||
func (s *FiberServer) getAllStreamingServices(c fiber.Ctx) ([]string, []string) {
|
||||
ls := s.getLocalStreamingServices(c)
|
||||
ts := s.getTmdbStreamingServices(c, ls)
|
||||
return ls, ts
|
||||
}
|
||||
|
||||
func (s *FiberServer) getLocalStreamingServices(c fiber.Ctx) []string {
|
||||
services, _ := s.db.ListSreamingServices(c)
|
||||
|
||||
sl := []string{}
|
||||
for _, p := range services {
|
||||
sl = append(sl, p.Title)
|
||||
}
|
||||
|
||||
return sl
|
||||
}
|
||||
|
||||
func (s *FiberServer) getTmdbStreamingServices(c fiber.Ctx, localservices []string) []string {
|
||||
region, _ := s.db.ListSetting(c, 3)
|
||||
services := apis.GetMovieProviders(region.Value)
|
||||
|
||||
sl := []string{}
|
||||
|
||||
for _, p := range services {
|
||||
if !slices.Contains(localservices, p.ProviderName) {
|
||||
sl = append(sl, p.ProviderName)
|
||||
}
|
||||
}
|
||||
|
||||
return sl
|
||||
}
|
||||
Reference in New Issue
Block a user