Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat) split into different pages, add plex settings page #3

Merged
merged 4 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ func initializePlexMovies() []types.Movie {
}

var allMovies []types.Movie
allMovies = append(allMovies, plex.GetPlexMovies(ipAddress, libraryID, "sd", plexToken, nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(ipAddress, libraryID, "480", plexToken, nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(ipAddress, libraryID, "576", plexToken, nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(ipAddress, libraryID, "720", plexToken, nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(ipAddress, libraryID, plexToken, "sd", nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(ipAddress, libraryID, plexToken, "480", nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(ipAddress, libraryID, plexToken, "576", nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(ipAddress, libraryID, plexToken, "720", nil)...)

fmt.Printf("\nThere are a total of %d movies in the library.\n\nMovies available:\n", len(allMovies))
return allMovies
Expand Down
11 changes: 10 additions & 1 deletion cmd/web.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package cmd

import (
"os"

"github.com/spf13/cobra"
"github.com/tphoney/plex-lookup/types"
"github.com/tphoney/plex-lookup/web"
)

Expand All @@ -15,5 +18,11 @@ var webCmd = &cobra.Command{
}

func startServer() {
web.StartServer()
plexInformation := types.PlexInformation{}
// read environment variables
plexInformation.IP = os.Getenv("PLEX_IP")
plexInformation.MovieLibraryID = os.Getenv("PLEX_LIBRARY_ID")
plexInformation.Token = os.Getenv("PLEX_TOKEN")

web.StartServer(plexInformation)
}
5 changes: 3 additions & 2 deletions plex/plex.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ type Filter struct {
Modifier string
}

func GetPlexMovies(ipAddress, libraryID, resolution, plexToken string, filters []Filter) (movieList []types.Movie) {
func GetPlexMovies(ipAddress, libraryID, plexToken, resolution string, filters []Filter) (movieList []types.Movie) {
url := fmt.Sprintf("http://%s:32400/library/sections/%s", ipAddress, libraryID)
if resolution == "" {
url += "/all"
Expand Down Expand Up @@ -242,7 +242,8 @@ func extractMovies(xmlString string) (movieList []types.Movie) {
}

for i := range container.Video {
movieList = append(movieList, types.Movie{Title: container.Video[i].Title, Year: container.Video[i].Year})
movieList = append(movieList, types.Movie{
Title: container.Video[i].Title, Year: container.Video[i].Year, DateAdded: container.Video[i].AddedAt})
}
return movieList
}
11 changes: 9 additions & 2 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ const (
)

type Movie struct {
Title string
Year string
Title string
Year string
DateAdded string
}

type MovieSearchResults struct {
Expand All @@ -33,3 +34,9 @@ type PlexLibrary struct {
Type string
ID string
}

type PlexInformation struct {
IP string
Token string
MovieLibraryID string
}
57 changes: 9 additions & 48 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,57 +6,18 @@
<script src="//unpkg.com/htmx.org@1.8.2"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
<!-- from https://github.com/picocss/pico -->
<style>
[data-sort]:hover {
cursor: pointer;
}
[data-dir="asc"]:after {
content: ' ↗';
}
[data-dir="desc"]:after {
content: ' ↘';
}
</style>
</head>

<body>
<h1 class="container">Plex lookup</h1>
<p class="container">Connect to your Plex library and scan your movies. Then search for Higher quality
versions of them (Blu-ray, 4k Blu-ray) on Amazon or CinemaParadiso.</p>
<form hx-post="/process" class="container" >
<p class="container">Enter the <em
data-tooltip="Find your Plex server IP by going to your server then go to settings, then remote-access. It is the private IP address."><a
href="https://plex.tv/web" target="_blank">Plex
Server IP</a></em>, <em data-tooltip="Find your X-Plex-Token by following this guide.
"><a href="https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/"
target="_blank">Plex X-Plex-Token </a></em> and <em
data-tooltip="Use the same approach as for the X-Plex-Token. Select a Movie, view its XML then look for `librarySectionID` it should be a number.">Plex
Movie Library ID</em> and to get started.
</p>
<input type="text" placeholder="Plex Server IP" name="plexIP" id="plexIP">
<input type="text" placeholder="Plex X-Plex-Token" name="plexToken" id="plexToken">
<input type="text" placeholder="Plex Library Section ID" name="plexLibraryID" id="plexLibraryID">
<fieldset>
<legend><strong>Lookup</strong></legend>
<label for="amazon">
<input type="radio" id="amazon" name="lookup" value="amazon" />
Amazon
</label>
<label for="cinemaParadiso">
<input type="radio" id="cinemaParadiso" name="lookup" value="cinemaParadiso" checked />
Cinema Paradiso
</label>
</fieldset>
<fieldset>
<legend><strong>Filter</strong></legend>
<label for="german">
<input type="checkbox" id="german" name="german" value="true">
German audio
</label>
</fieldset>
<button type="submit">Submit</button>
</form>
<div hx-get="/progress" hx-trigger="every 500ms" class="container"></div>
<div class="container">
<h1 class="container">Plex lookup</h1>
Connect to your Plex library and scan your movies. Then search for Higher quality
versions of them (Blu-ray, 4k Blu-ray) on Amazon or CinemaParadiso
<br>
<a href="/plex" class="container">Plex configuration</a>
<br>
<a href="/movies" class="container">Lookup movies</a>
</div>
</body>

</html>
91 changes: 35 additions & 56 deletions web/web.go → web/movies.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
//go:generate templ generate
//go:generate tailwindcss -i assets/input.css -o assets/dist.css --minify

package web

import (
_ "embed"
"fmt"
"html/template"
"net"
"net/http"

"github.com/tphoney/plex-lookup/amazon"
Expand All @@ -17,51 +13,45 @@ import (
)

var (
//go:embed index.html
indexHTML string
port string = "9090"
numberOfMoviesProcessed int = 0
jobRunning bool = false
totalMovies int = 0
)

func StartServer() {
// find the local IP address
ipAddress := GetOutboundIP()
fmt.Printf("Starting server on http://%s:%s\n", ipAddress.String(), port)
http.HandleFunc("/", index)

http.HandleFunc("/process", processMoviesHTML)

http.HandleFunc("/progress", progressBarHTML)
//go:embed movies.html
moviesPage string

err := http.ListenAndServe(fmt.Sprintf(":%s", port), nil) //nolint: gosec
if err != nil {
fmt.Printf("Failed to start server on port %s: %s\n", port, err)
panic(err)
}
}
numberOfMoviesProcessed int = 0
jobRunning bool = false
totalMovies int = 0
)

func index(w http.ResponseWriter, _ *http.Request) {
tmpl := template.Must(template.New("index").Parse(indexHTML))
func moviesHandler(w http.ResponseWriter, _ *http.Request) {
tmpl := template.Must(template.New("movies").Parse(moviesPage))
err := tmpl.Execute(w, nil)
if err != nil {
http.Error(w, "Failed to render index", http.StatusInternalServerError)
http.Error(w, "Failed to render plex page", http.StatusInternalServerError)
return
}
}

// nolint: lll, nolintlint
func processMoviesHTML(w http.ResponseWriter, r *http.Request) {
// Retrieve form fields (replace with proper values)
plexIP := r.FormValue("plexIP")
plexLibraryID := r.FormValue("plexLibraryID")
plexToken := r.FormValue("plexToken")
lookup := r.FormValue("lookup")
german := r.FormValue("german")

// plex resolutions
sd := r.FormValue("sd")
r240 := r.FormValue("240p")
r480 := r.FormValue("480p")
r576 := r.FormValue("576p")
r720 := r.FormValue("720p")
r1080 := r.FormValue("1080p")
r4k := r.FormValue("4k")
plexResolutions := []string{sd, r240, r480, r576, r720, r1080, r4k}
// remove empty resolutions
var filteredResolutions []string
for _, resolution := range plexResolutions {
if resolution != "" {
filteredResolutions = append(filteredResolutions, resolution)
}
}
// Prepare table data
data := fetchPlexMovies(plexIP, plexLibraryID, plexToken, german)
data := fetchPlexMovies(PlexInformation.IP, PlexInformation.MovieLibraryID, PlexInformation.Token, filteredResolutions, german)
var movieResults []types.MovieSearchResults
var movieResult types.MovieSearchResults
jobRunning = true
Expand Down Expand Up @@ -120,9 +110,10 @@ func renderTable(movieCollection []types.MovieSearchResults) (tableRows string)
return tableRows // Return the generated HTML for table rows
}

func fetchPlexMovies(plexIP, plexLibraryID, plexToken, german string) (allMovies []types.Movie) {
func fetchPlexMovies(plexIP, plexLibraryID, plexToken string, plexResolutions []string, german string) (allMovies []types.Movie) {
filter := []plex.Filter{}
if german == "true" {
filter := []plex.Filter{
filter = []plex.Filter{
{
Name: "audioLanguage",
Value: "de",
Expand All @@ -134,25 +125,13 @@ func fetchPlexMovies(plexIP, plexLibraryID, plexToken, german string) (allMovies
// Modifier: "=",
// },
}
allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexLibraryID, "", plexToken, filter)...)
}
if len(plexResolutions) == 0 {
allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexLibraryID, plexToken, "", filter)...)
} else {
allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexLibraryID, "sd", plexToken, nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexLibraryID, "480", plexToken, nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexLibraryID, "576", plexToken, nil)...)
allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexLibraryID, "720", plexToken, nil)...)
for _, resolution := range plexResolutions {
allMovies = append(allMovies, plex.GetPlexMovies(plexIP, plexLibraryID, plexToken, resolution, filter)...)
}
}
return allMovies
}

func GetOutboundIP() net.IP {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
fmt.Println("Failed to get local IP address")
return nil
}
defer conn.Close()

localAddr := conn.LocalAddr().(*net.UDPAddr)

return localAddr.IP
}
82 changes: 82 additions & 0 deletions web/movies.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>

<head>
<title>Movies</title>
<script src="//unpkg.com/htmx.org@1.8.2"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
<!-- from https://github.com/picocss/pico -->
<style>
[data-sort]:hover {
cursor: pointer;
}

[data-dir="asc"]:after {
content: ' ↗';
}

[data-dir="desc"]:after {
content: ' ↘';
}
</style>
</head>

<body>
<h1 class="container">Movies</h1>
<div hx-get="/plexinfook" class="container" hx-trigger="load"></div>
<form hx-post="/processmovies" class="container">
<fieldset>
<legend><strong>Lookup</strong></legend>
<label for="amazon">
<input type="radio" id="amazon" name="lookup" value="amazon" />
Amazon
</label>
<label for="cinemaParadiso">
<input type="radio" id="cinemaParadiso" name="lookup" value="cinemaParadiso" checked />
Cinema Paradiso
</label>
</fieldset>
<fieldset>
<legend><strong>Filter Plex:</strong> only return movies that match the following criteria</legend>
<label for="title" data-sort="title">
<input type="checkbox" id="sd" name="sd" value="sd">
SD
</label>
<label for="title" data-sort="title">
<input type="checkbox" id="480p" name="480p" value="480">
480p
</label>
<label for="title" data-sort="title">
<input type="checkbox" id="576p" name="576p" value="576">
576p
</label>
<label for="title" data-sort="title">
<input type="checkbox" id="720p" name="720p" value="720">
720p
</label>
<label for="title" data-sort="title">
<input type="checkbox" id="1080p" name="1080p" value="1080">
1080p
</label>
<label for="title" data-sort="title">
<input type="checkbox" id="4k" name="4k" value="4k">
4k
</label>
</fieldset>
<fieldset>
<legend><strong>Filter Lookup:</strong></legend>
<label for="german">
<input type="checkbox" id="german" name="german" value="true">
German audio
</label>
<!-- <label for="newerVersion">
<input type="checkbox" id="newerVersion" name="newerVersion" value="true">
Newer Version, release date is after when the movie was added to Plex.
</label> -->
</fieldset>
<button type="submit">Submit</button>
</form>
<div hx-get="/progress" hx-trigger="every 500ms" class="container"></div>
</body>

</html>
Loading
Loading