260702_155621

This commit is contained in:
Maciej J. Bowszys 2026-07-02 15:56:21 +02:00
parent 01bb14e465
commit 3bf6e7b828
10 changed files with 401 additions and 29 deletions

6
go.mod
View File

@ -1,3 +1,9 @@
module git.makemore.cloud/mjbow/moira_db
go 1.26.4
require (
github.com/tidwall/gjson v1.19.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
)

6
go.sum Normal file
View File

@ -0,0 +1,6 @@
github.com/tidwall/gjson v1.19.0 h1:xwxm7n691Uf3u5OFjzngavjGTh55KX5q/9w9xHW88JU=
github.com/tidwall/gjson v1.19.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=

View File

@ -1,11 +1,20 @@
package main
import (
//"fmt"
"fmt"
"html/template"
"io"
"log"
"net/http"
"net/url"
"os"
"strings"
"time"
"encoding/json"
"errors"
"github.com/tidwall/gjson"
//"path/filepath"
//"regexp"
//"strings"
//"maps"
@ -14,30 +23,189 @@ import (
var templates *template.Template = template.New("")
var client = &http.Client{Timeout: 2*time.Second}
func hdlr_renderHTML(in_leaderPath string, in_fileName string) http.HandlerFunc{
type Film struct{
Title_orig,
Title_EN,
Title_PL,
Desc,
Img,
Source string
Year int
}
//var db_film []Film
func resolve_redirs(in_url string) (string,error){
resp, err := client.Get(in_url)
if(err != nil){
return "", err
}
defer resp.Body.Close()
return resp.Request.URL.String(), nil
}
func fetch_filmInfo(in_url string) (_ Film, err error){
parsedUrl, err := url.Parse(in_url)
if err != nil{ return }
parsedUrl.RawQuery = ""
var in_url_api string
switch(parsedUrl.Hostname()){
case "www.filmweb.pl":
in_url_api = fmt.Sprintf(
"https://www.filmweb.pl/api/v1/film/%s/preview",
in_url[strings.LastIndex(in_url, "-")+1:],
)
case "www.imdb.com":
t_parsedUrl, _ := url.Parse(in_url)
t_parsedUrl.RawQuery = ""
t_parsedUrl.Host = "api.imdbapi.dev"
in_url_api = strings.Replace(t_parsedUrl.String(), "/title/", "/titles/", 1)
if in_url_api[len(in_url_api)-1] == '/'{
in_url_api = in_url_api[:len(in_url_api)-1]
}
default:
err = errors.New("[0] Film database unsupported " + parsedUrl.Hostname())
return
}
fmt.Println("in_url_api:", in_url_api);
req,err := http.NewRequest("GET", in_url_api, nil)
if err != nil{ return }
req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; MoiraBot/1.0)")
resp,err := client.Do(req)
if err != nil{ return }
defer resp.Body.Close()
resp_text, err := io.ReadAll(resp.Body)
if err != nil{ return }
//fmt.Printf("%+v\n", string(resp_text))
titles := make(map[string]string)
switch(parsedUrl.Hostname()){
case "www.filmweb.pl":
if(len(gjson.GetBytes(resp_text, "internationalTitle").String())>0){
titles[gjson.GetBytes(resp_text, "internationalTitle.lang").String()] = gjson.GetBytes(resp_text, "internationalTitle.title").String()
titles["_int"] = gjson.GetBytes(resp_text, "internationalTitle.title").String()
}
if(len(gjson.GetBytes(resp_text, "originalTitle").String())>0){
titles[gjson.GetBytes(resp_text, "originalTitle.lang").String()] = gjson.GetBytes(resp_text, "originalTitle.title").String()
titles["_orig"] = gjson.GetBytes(resp_text, "originalTitle.title").String()
}
if(len(gjson.GetBytes(resp_text, "title").String())>0){
titles[gjson.GetBytes(resp_text, "title.lang").String()] = gjson.GetBytes(resp_text, "title.title").String()
}
return Film{
Title_orig: (func()string{
if val,ok:=titles["_orig"]; ok{
return val
}else{
return ""
}
})(),
Title_EN: (func()string{
if val,ok:=titles["en"]; ok{
return val
}else{
return ""
}
})(),
Title_PL: (func()string{
if val,ok:=titles["pl"]; ok{
return val
}else{
return ""
}
})(),
Desc: gjson.GetBytes(resp_text, "plotOrDescriptionSynopsis").String(),
Year: int(gjson.GetBytes(resp_text,"year").Int()),
Img: "https://fwcdn.pl/fpo"+gjson.GetBytes(resp_text, "poster.path").String(),
Source: in_url,
}, err
case "www.imdb.com":
if(len(gjson.GetBytes(resp_text, "primaryTitle").String())>0){
titles["en"] = gjson.GetBytes(resp_text, "primaryTitle").String()
titles["_int"] = gjson.GetBytes(resp_text, "primaryTitle").String()
}
if(len(gjson.GetBytes(resp_text, "originalTitle").String())>0){
if(len(gjson.GetBytes(resp_text, "originCountries.0.code").String())>0){
titles[strings.ToLower(gjson.GetBytes(resp_text, "originCountries.0.code").String())] = gjson.GetBytes(resp_text, "originalTitle").String()
}
titles["_orig"] = gjson.GetBytes(resp_text, "originalTitle").String()
}else{
if val,ok:=titles["_int"]; ok{
titles["_orig"] = val
}
}
return Film{
Title_orig: (func()string{
if val,ok:=titles["_orig"]; ok{
return val
}else{
return ""
}
})(),
Title_EN: (func()string{
if val,ok:=titles["en"]; ok{
return val
}else{
return ""
}
})(),
Title_PL: (func()string{
if val,ok:=titles["pl"]; ok{
return val
}else{
return ""
}
})(),
Desc: gjson.GetBytes(resp_text, "plot").String(),
Year: int(gjson.GetBytes(resp_text,"startYear").Int()),
Img: gjson.GetBytes(resp_text, "primaryImage.url").String(),
Source: in_url,
}, err
default:
err = errors.New("[1] Film database unsupported " + parsedUrl.Hostname())
return
}
}
func hdlr_root(template_renders map[string]string) http.HandlerFunc{
fSrv := http.FileServer(http.Dir("./website/static"))
return func (resp http.ResponseWriter, req *http.Request){
err := templates.ExecuteTemplate(resp, in_fileName, nil) // resp, in_fileName, contextObj)
if fileName, ok := template_renders[req.URL.Path]; ok{
fmt.Println("[srv] template", req.URL.Path, fileName)
err := templates.ExecuteTemplate(resp, fileName, nil)
if(err != nil){
http.Error(resp, err.Error(), http.StatusInternalServerError)
}
}else{
fmt.Println("[srv] static", req.URL.Path)
fSrv.ServeHTTP(resp, req)
}
}
}
func main(){
http.Handle("/", http.FileServer(http.Dir("./website/static")))
template_renders := map[string]string {
"/film/view/": "film/index.html",
"/film/edit/": "index.html",
"/list/view/": "index.html",
"/list/edit/": "index.html",
"/group/view/": "index.html",
"/group/edit/": "index.html",
}
func templates_register(template_renders map[string]string){
for _,i_file := range template_renders{
text, err := os.ReadFile("./website/templates/" + i_file)
if(err != nil){
@ -46,11 +214,32 @@ func main(){
templates.New(i_file).Parse(string(text))
}
for i_path,i_file := range template_renders{
http.HandleFunc(i_path, hdlr_renderHTML(i_path, i_file))
}
func main(){
//t_film, _ := fetch_filmInfo("https://www.filmweb.pl/film/Spirited+Away%3A+W+krainie+Bog%C3%B3w-2001-33288")
//t_film, _ := fetch_filmInfo("https://www.filmweb.pl/film/Pulp+Fiction-1994-1039")
//t_film, _ := fetch_filmInfo("https://www.filmweb.pl/film/Kl%C4%85twa+Doliny+W%C4%99%C5%BCy-1987-6785")
//t_film, _ := fetch_filmInfo("https://www.imdb.com/title/tt0245429/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_spirited")
//t_film, _ := fetch_filmInfo("https://www.imdb.com/title/tt0110912/")
//t_film, _ := fetch_filmInfo("https://www.imdb.com/title/tt8814476/")
t_film, _ := fetch_filmInfo("https://www.imdb.com/title/tt0095456/?ref_=nv_sr_srsg_0_tt_1_nm_0_in_0_q_kl%C4%85twa%20doliny%20w%C4%99%C5%BC")
t_json, _ := json.MarshalIndent(t_film, "", " ")
fmt.Printf("%+v\n", string(t_json))
template_renders := map[string]string {
"/": "index.html",
"/film/view/": "index.html",
"/film/edit/": "index.html",
"/list/view/": "index.html",
"/list/edit/": "index.html",
"/group/view/": "index.html",
"/group/edit/": "index.html",
}
templates_register(template_renders)
http.HandleFunc("/", hdlr_root(template_renders))
//fmt.Println("Welcome to moira_db!");
log.Fatal(http.ListenAndServe(":8000", nil))

76
website/script.js Normal file
View File

@ -0,0 +1,76 @@
window.onload = () => {
var fetch_filmInfo = async (in_url)=>{
// pretty good test redirect: https://share.google/mSDJehdZm6hp6vTYy
var resp;
//resp = await fetch("https://www.imdb.com/title/tt0245429/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_spirited");
//resp = await fetch("https://www.filmweb.pl/film/Spirited+Away%3A+W+krainie+Bog%C3%B3w-2001-33288");
resp = await fetch(in_url);
//console.log("Redirected:", response.redirected);
console.log("Redirected URL:", resp.url);
noRed_URL = resp.url;
var api_URL = null;
noRed_URL = new URL(noRed_URL);
const db_host = noRed_URL.hostname;
noRed_URL.search = '';
switch(db_host){
case "www.filmweb.pl":
api_URL = `https://www.filmweb.pl/api/v1/film/${noRed_URL.href.slice(noRed_URL.href.lastIndexOf("-")+1)}/preview`;
break;
case "www.imdb.com":
// https://imdbapi.dev/
noRed_URL.hostname = "api.imdbapi.dev";
api_URL = noRed_URL.href.replace("/title/", "/titles/").slice(0, -1);
break;
}
console.log("API URL:", api_URL);
var resp = await fetch(api_URL)
var data = await resp.json();
console.log("Ext info:", data);
var film_info = null;
switch(db_host){
case "www.filmweb.pl":
film_info = {};
film_info["title_en"] = data["internationalTitle"] ? data["internationalTitle"]["title"] : data["originalTitle"]["title"];
film_info["title_pl"] = data["title"]["title"];
film_info["desc"] = data["plotOrDescriptionSynopsis"];
film_info["year"] = data["year"];
//film_info["img"] = data["coverPhoto"]["photo"]["sourcePath"];
film_info["img"] = "https://fwcdn.pl/fpo"+data["poster"]["path"];
//directors
//countries
//poster
break;
case "www.imdb.com":
film_info = {};
film_info["title_en"] = data["primaryTitle"];
film_info["title_pl"] = null;
film_info["desc"] = data["plot"];
film_info["year"] = data["startYear"];
film_info["img"] = data["primaryImage"]["url"];
break;
}
console.log("Film info:", film_info);
document.getElementById("filmInfo_title").innerHTML = film_info["title_pl"] ? film_info["title_pl"] : film_info["title_en"];
document.getElementById("filmInfo_year").innerHTML = film_info["year"];
document.getElementById("filmInfo_desc").innerHTML = film_info["desc"];
document.getElementById("filmInfo_img").src = film_info["img"];
};
document.getElementById("inEl").addEventListener("input", function(){
fetch_filmInfo(this.value);
});
};

View File

@ -1 +0,0 @@
aabbcc

76
website/static/script.js Normal file
View File

@ -0,0 +1,76 @@
window.onload = () => {
var fetch_filmInfo = async (in_url)=>{
// pretty good test redirect: https://share.google/mSDJehdZm6hp6vTYy
var resp;
//resp = await fetch("https://www.imdb.com/title/tt0245429/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_spirited");
//resp = await fetch("https://www.filmweb.pl/film/Spirited+Away%3A+W+krainie+Bog%C3%B3w-2001-33288");
resp = await fetch(in_url);
//console.log("Redirected:", response.redirected);
console.log("Redirected URL:", resp.url);
noRed_URL = resp.url;
var api_URL = null;
noRed_URL = new URL(noRed_URL);
const db_host = noRed_URL.hostname;
noRed_URL.search = '';
switch(db_host){
case "www.filmweb.pl":
api_URL = `https://www.filmweb.pl/api/v1/film/${noRed_URL.href.slice(noRed_URL.href.lastIndexOf("-")+1)}/preview`;
break;
case "www.imdb.com":
// https://imdbapi.dev/
noRed_URL.hostname = "api.imdbapi.dev";
api_URL = noRed_URL.href.replace("/title/", "/titles/").slice(0, -1);
break;
}
console.log("API URL:", api_URL);
var resp = await fetch(api_URL)
var data = await resp.json();
console.log("Ext info:", data);
var film_info = null;
switch(db_host){
case "www.filmweb.pl":
film_info = {};
film_info["title_en"] = data["internationalTitle"] ? data["internationalTitle"]["title"] : data["originalTitle"]["title"];
film_info["title_pl"] = data["title"]["title"];
film_info["desc"] = data["plotOrDescriptionSynopsis"];
film_info["year"] = data["year"];
//film_info["img"] = data["coverPhoto"]["photo"]["sourcePath"];
film_info["img"] = "https://fwcdn.pl/fpo"+data["poster"]["path"];
//directors
//countries
//poster
break;
case "www.imdb.com":
film_info = {};
film_info["title_en"] = data["primaryTitle"];
film_info["title_pl"] = null;
film_info["desc"] = data["plot"];
film_info["year"] = data["startYear"];
film_info["img"] = data["primaryImage"]["url"];
break;
}
console.log("Film info:", film_info);
document.getElementById("filmInfo_title").innerHTML = film_info["title_pl"] ? film_info["title_pl"] : film_info["title_en"];
document.getElementById("filmInfo_year").innerHTML = film_info["year"];
document.getElementById("filmInfo_desc").innerHTML = film_info["desc"];
document.getElementById("filmInfo_img").src = film_info["img"];
};
document.getElementById("inEl").addEventListener("input", function(){
fetch_filmInfo(this.value);
});
};

View File

@ -1 +0,0 @@
dis ys desd

View File

@ -0,0 +1,4 @@
body{
background-color: black;
color: white;
}

View File

@ -1 +0,0 @@
aaaabb

View File

@ -1,7 +1,25 @@
<h1 id="abc">Ttesttt</h1>
<h1>Ttesttt</h1>
<script>
window.onload = () => {
document.getElementById("abc").innerHTML = window.location.pathname.split("/").at(-1);
};
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>moira_db</title>
<link rel="shortcut icon" type="image/png" href="/favicon.png"/>
<link rel="stylesheet" type="text/css" href="./styles.css">
<script src="./script.js"></script>
</head>
<body>
<input type="text" id="inEl">
<div>
<h1 id="filmInfo_title"></h1>
<h3 id="filmInfo_year"></h3></br>
<p id="filmInfo_desc"></p></br>
<img id="filmInfo_img" width="300" />
</div>
</body>
</html>