260706_235045

This commit is contained in:
Maciej J. Bowszys 2026-07-06 23:50:45 +02:00
parent 760bb7e3a3
commit dc910c981b
9 changed files with 613 additions and 99 deletions

View File

@ -241,7 +241,18 @@ func sessions_is_loggedIn(resp http.ResponseWriter, req *http.Request) (ret bool
return false, nil return false, nil
} }
val_str, ok := val.(string)
if !ok{
fmt.Println("non-string user")
return false, nil
}
//if val not in user_db: false,nil //if val not in user_db: false,nil
if _,ok:=db_user[val_str]; !ok{
fmt.Println("user not in db")
return false, nil
}
fmt.Println(val) fmt.Println(val)
return true, nil return true, nil
} }
@ -257,7 +268,7 @@ type Film struct{
Year int Year int
} }
var db_film = make(map[string]any) var db_film = make(map[string]any) // the any is *Film
func findURL_in_msg(in_msg string) (_ string,err error){ func findURL_in_msg(in_msg string) (_ string,err error){
@ -285,7 +296,7 @@ func resolve_redirs(in_url string) (string,error){
return resp.Request.URL.String(), nil return resp.Request.URL.String(), nil
} }
func fetch_filmInfo(in_url string) (_ Film, err error){ func fetch_filmInfo(in_url string) (_ *Film, err error){
parsedUrl, err := url.Parse(in_url) parsedUrl, err := url.Parse(in_url)
if err != nil{ return } if err != nil{ return }
parsedUrl.RawQuery = "" parsedUrl.RawQuery = ""
@ -342,7 +353,7 @@ func fetch_filmInfo(in_url string) (_ Film, err error){
if(len(gjson.GetBytes(resp_text, "title").String())>0){ if(len(gjson.GetBytes(resp_text, "title").String())>0){
titles[gjson.GetBytes(resp_text, "title.lang").String()] = gjson.GetBytes(resp_text, "title.title").String() titles[gjson.GetBytes(resp_text, "title.lang").String()] = gjson.GetBytes(resp_text, "title.title").String()
} }
return Film{ return &Film{
Title_orig: (func()string{ Title_orig: (func()string{
if val,ok:=titles["_orig"]; ok{ if val,ok:=titles["_orig"]; ok{
return val return val
@ -386,7 +397,7 @@ func fetch_filmInfo(in_url string) (_ Film, err error){
titles["_orig"] = val titles["_orig"] = val
} }
} }
return Film{ return &Film{
Title_orig: (func()string{ Title_orig: (func()string{
if val,ok:=titles["_orig"]; ok{ if val,ok:=titles["_orig"]; ok{
return val return val
@ -421,6 +432,21 @@ func fetch_filmInfo(in_url string) (_ Film, err error){
} }
} }
type List struct{
Name,
Desc,
Img string
FilmIDs []*Film
CreatedTS,
UpdatedTS int64 // UNIX timestamps
}
var db_list = make(map[string]any) // the any is *List
func hdlr_root(template_renders map[string]struct{Template string;Context *map[string]any}) http.HandlerFunc{ func hdlr_root(template_renders map[string]struct{Template string;Context *map[string]any}) http.HandlerFunc{
fSrv := http.FileServer(http.Dir("./website/static")) fSrv := http.FileServer(http.Dir("./website/static"))
@ -472,10 +498,28 @@ func hdlr_film_parseMsg(resp http.ResponseWriter, req *http.Request){
fmt.Println(t_url) fmt.Println(t_url)
t_url_noRed, _ := resolve_redirs(t_url) t_url_noRed, _ := resolve_redirs(t_url)
fmt.Println(t_url_noRed) fmt.Println(t_url_noRed)
film_already_in_db := false
var film_found_id string
for i,i_film := range db_film{
if i_film.(*Film).Source == t_url_noRed{
film_already_in_db = true
film_found_id = i
break
}
}
if(film_already_in_db){
http.Redirect(resp, req, "/film/view/?id="+film_found_id, http.StatusFound)
return
}
t_film, _ := fetch_filmInfo(t_url_noRed) t_film, _ := fetch_filmInfo(t_url_noRed)
db_film[fmt.Sprintf("%d",len(db_film))] = t_film db_film[fmt.Sprintf("%d",len(db_film))] = t_film
db_list["0"].(*List).FilmIDs = append(db_list["0"].(*List).FilmIDs, db_film[fmt.Sprintf("%d",len(db_film)-1)].(*Film))
t_json, _ := json.MarshalIndent(db_film, "", " ") t_json, _ := json.MarshalIndent(db_film, "", " ")
fmt.Printf("%+v\n", string(t_json)) fmt.Printf("%+v\n", string(t_json))
fmt.Println("/film/view/?id="+fmt.Sprintf("%d",len(db_film)-1)) fmt.Println("/film/view/?id="+fmt.Sprintf("%d",len(db_film)-1))
@ -488,6 +532,14 @@ func main(){
fmt.Println("CLIENT_SECRET:", oauth2_dc_config.ClientSecret); fmt.Println("CLIENT_SECRET:", oauth2_dc_config.ClientSecret);
fmt.Println("SESSIONS_SECRET:", os.Getenv("SESSIONS_SECRET")); fmt.Println("SESSIONS_SECRET:", os.Getenv("SESSIONS_SECRET"));
db_list["0"] = &List{
Name: "film_dump_watchlist",
FilmIDs: []*Film{},
CreatedTS: 0,
UpdatedTS: 0,
}
//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/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/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.filmweb.pl/film/Kl%C4%85twa+Doliny+W%C4%99%C5%BCy-1987-6785")
@ -514,9 +566,9 @@ func main(){
template_renders := map[string]struct{Template string;Context *map[string]any} { template_renders := map[string]struct{Template string;Context *map[string]any} {
"/": {"index.html", nil}, "/": {"index.html", nil},
"/film/view/": {"film/view/index.html", &db_film}, "/film/view/": {"film/view/index.html", &db_film},
"/film/edit/": {"index.html", nil}, "/film/edit/": {"index.html", &db_film},
//"/list/view/": {"index.html", nil}, "/list/view/": {"list/view/index.html", &db_list},
//"/list/edit/": {"index.html", nil}, "/list/edit/": {"index.html", &db_list},
//"/group/view/": {"index.html", nil}, //"/group/view/": {"index.html", nil},
//"/group/edit/": {"index.html", nil}, //"/group/edit/": {"index.html", nil},
} }

View File

@ -1,3 +1,8 @@
a{
color: black;
text-decoration: none;
}
body{ body{
margin: 0; margin: 0;

View File

View File

@ -0,0 +1,206 @@
a{
color: black;
text-decoration: none;
}
body{
margin: 0;
width: 100%;
}
*{
font-family: "Kode Mono", monospace;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
/*overflow-x: hidden;*/
}
b{
font-family: "Kode Mono", monospace;
font-optical-sizing: auto;
font-weight: 700;
font-style: normal;
/*overflow-x: hidden;*/
}
#sectHeader, #sectFilm{
width: 100%;
}
#sectHeader{
height: 10vh;
display: flex;
flex-direction: row;
align-items: center;
}
#sectHeader_logo{
height: 95%;
aspect-ratio: 1/1;
background-image: url("/icons/moira_db_192.png");
background-repeat: no-repeat;
background-size: contain;
}
#sectHeader_pageInfo{
height: 100%;
padding-left: 5vw;
display: flex;
flex-direction: column;
justify-content: center;
}
#sectHeader_pageInfo_pageTypeName{
font-size: 1.5em;
}
#sectFilm{
display: flex;
flex-direction: column;
}
#sectFilmInfo_top{
width: 100%;
display: flex;
flex-direction: row;
}
#sectFilmInfo_top_left{
width: 50%;
--sectFilmInfo_top_left_HEIGHT: min(calc(50vw * 192 / 108), 60vh);
height: var(--sectFilmInfo_top_left_HEIGHT);
display: flex;
flex-direction: column;
}
.sectFilmInfo_top_left_title{
width: 100%;
height: calc(var(--sectFilmInfo_top_left_HEIGHT) / 3);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(var(--sectFilmInfo_top_left_HEIGHT) / 24);
}
.sectFilmInfo_top_left_title > div{
width: 100%;
height: calc(var(--sectFilmInfo_top_left_HEIGHT) / 8);
display: flex;
flex-direction: row;
align-items: center;
position: relative;
overflow: hidden;
}
.marquee_text0, .marquee_text1{
width: 100%;
position: absolute;
padding-left: 100%;
}
.marquee_text0 > *, .marquee_text1 > *{
width: fit-content;
position: relative;
white-space: nowrap;
animation: marquee_scroll 12s linear infinite;
}
.sectFilmInfo_top_left_title_line0 > .marquee_text1 > *{
animation-delay: 6s;
}
.sectFilmInfo_top_left_title_line1 > .marquee_text0 > *{
animation-delay: 3s;
}
.sectFilmInfo_top_left_title_line1 > .marquee_text1 > *{
animation-delay: 9s;
}
@keyframes marquee_scroll{
0%{
transform: translateX(0);
}
100%{
transform: translateX(-200%);
}
}
#sectFilmInfo_top_right{
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
#sectFilmInfo_top_right_poster{
width: 100%;
max-height: 60vh;
aspect-ratio: 108/192;
background-repeat: no-repeat;
background-size: contain;
background-position: center center;
}
#sectFilmInfo_bttm{
width: 100%;
display: flex;
flex-direction: row;
}
#sectFilmInfo_bttm_left{
width: 50%;
display: flex;
flex-direction: column;
}
#sectFilmInfo_bttm_right{
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
}
.sectDivider, .sectDivider_empty{
width: 100%;
height: 5vh;
margin-top: 10px;
margin-bottom: 10px;
}
.sectDivider{
background-image: url("/img/divider.png");
background-size: contain;
background-repeat: repeat-x;
}

View File

@ -1,12 +1,6 @@
var installPromptEvnt = null; var installPromptEvnt = null;
window.onload = () => { window.onload = () => {
/*if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/empty_sw.js')
.then((reg) => console.log('SW registered:', reg.scope))
.catch((err) => console.error('SW registration failed:', err));
}*/
window.addEventListener("beforeinstallprompt", (e) => { window.addEventListener("beforeinstallprompt", (e) => {
installPromptEvnt = e; installPromptEvnt = e;
document.getElementById("inp_bttn").disabled = false; document.getElementById("inp_bttn").disabled = false;
@ -16,79 +10,4 @@ window.onload = () => {
installPromptEvnt.prompt(); installPromptEvnt.prompt();
this.disabled = true; this.disabled = true;
}); });
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,4 +1,206 @@
body{ a{
background-color: black; color: black;
color: white; text-decoration: none;
} }
body{
margin: 0;
width: 100%;
}
*{
font-family: "Kode Mono", monospace;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
/*overflow-x: hidden;*/
}
b{
font-family: "Kode Mono", monospace;
font-optical-sizing: auto;
font-weight: 700;
font-style: normal;
/*overflow-x: hidden;*/
}
#sectHeader, #sectFilm{
width: 100%;
}
#sectHeader{
height: 10vh;
display: flex;
flex-direction: row;
align-items: center;
}
#sectHeader_logo{
height: 95%;
aspect-ratio: 1/1;
background-image: url("/icons/moira_db_192.png");
background-repeat: no-repeat;
background-size: contain;
}
#sectHeader_pageInfo{
height: 100%;
padding-left: 5vw;
display: flex;
flex-direction: column;
justify-content: center;
}
#sectHeader_pageInfo_pageTypeName{
font-size: 1.5em;
}
#sectFilm{
display: flex;
flex-direction: column;
}
#sectFilmInfo_top{
width: 100%;
display: flex;
flex-direction: row;
}
#sectFilmInfo_top_left{
width: 50%;
--sectFilmInfo_top_left_HEIGHT: min(calc(50vw * 192 / 108), 60vh);
height: var(--sectFilmInfo_top_left_HEIGHT);
display: flex;
flex-direction: column;
}
.sectFilmInfo_top_left_title{
width: 100%;
height: calc(var(--sectFilmInfo_top_left_HEIGHT) / 3);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(var(--sectFilmInfo_top_left_HEIGHT) / 24);
}
.sectFilmInfo_top_left_title > div{
width: 100%;
height: calc(var(--sectFilmInfo_top_left_HEIGHT) / 8);
display: flex;
flex-direction: row;
align-items: center;
position: relative;
overflow: hidden;
}
.marquee_text0, .marquee_text1{
width: 100%;
position: absolute;
padding-left: 100%;
}
.marquee_text0 > *, .marquee_text1 > *{
width: fit-content;
position: relative;
white-space: nowrap;
animation: marquee_scroll 12s linear infinite;
}
.sectFilmInfo_top_left_title_line0 > .marquee_text1 > *{
animation-delay: 6s;
}
.sectFilmInfo_top_left_title_line1 > .marquee_text0 > *{
animation-delay: 3s;
}
.sectFilmInfo_top_left_title_line1 > .marquee_text1 > *{
animation-delay: 9s;
}
@keyframes marquee_scroll{
0%{
transform: translateX(0);
}
100%{
transform: translateX(-200%);
}
}
#sectFilmInfo_top_right{
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
#sectFilmInfo_top_right_poster{
width: 100%;
max-height: 60vh;
aspect-ratio: 108/192;
background-repeat: no-repeat;
background-size: contain;
background-position: center center;
}
#sectFilmInfo_bttm{
width: 100%;
display: flex;
flex-direction: row;
}
#sectFilmInfo_bttm_left{
width: 50%;
display: flex;
flex-direction: column;
}
#sectFilmInfo_bttm_right{
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
}
.sectDivider, .sectDivider_empty{
width: 100%;
height: 5vh;
margin-top: 10px;
margin-bottom: 10px;
}
.sectDivider{
background-image: url("/img/divider.png");
background-size: contain;
background-repeat: repeat-x;
}

View File

@ -19,12 +19,16 @@
<body> <body>
<div id="sectHeader"> <div id="sectHeader">
<a href="/" style="height:100%;display:block;">
<div id="sectHeader_logo"></div> <div id="sectHeader_logo"></div>
</a>
<a href="/list/view/?id=0" style="height:100%;display:block;">
<div id="sectHeader_pageInfo"> <div id="sectHeader_pageInfo">
<span id="sectHeader_pageInfo_pageType">LIST</span> <span id="sectHeader_pageInfo_pageType">LIST</span>
<span id="sectHeader_pageInfo_pageTypeName"><b>film_dump_watchlist</b></span> <span id="sectHeader_pageInfo_pageTypeName"><b>film_dump_watchlist</b></span>
</div> </div>
</a>
</div> </div>
<div class="sectDivider"></div> <div class="sectDivider"></div>

View File

@ -9,20 +9,46 @@
<link rel="shortcut icon" type="image/png" href="/icons/favicon.png"/> <link rel="shortcut icon" type="image/png" href="/icons/favicon.png"/>
<link rel="manifest" href="/manifest.json"/> <link rel="manifest" href="/manifest.json"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Kode+Mono:wght@400..700&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./styles.css"> <link rel="stylesheet" type="text/css" href="./styles.css">
<script src="./script.js"></script> <script src="./script.js"></script>
</head> </head>
<body> <body>
<input type="text" id="inEl"> <div id="sectHeader">
</br> <a href="/" style="height:100%;display:block;">
<input type="button" id="inp_bttn" value="Install" disabled> <div id="sectHeader_logo"></div>
</a>
<div> <div id="sectHeader_pageInfo">
<h1 id="filmInfo_title"></h1> <input type="button" id="inp_bttn" value="Install" disabled>
<h3 id="filmInfo_year"></h3></br> </div>
<p id="filmInfo_desc"></p></br>
<img id="filmInfo_img" width="300" />
</div> </div>
<div class="sectDivider"></div>
<div class="sectFilm">
<a href="/list/view/?id=0">
<div id="sectHeader_pageInfo">
<span id="sectHeader_pageInfo_pageType">LIST</span>
<span id="sectHeader_pageInfo_pageTypeName"><b>film_dump_watchlist</b></span>
</div>
</a>
</div>
<div class="sectDivider"></div>
<div class="sectDivider_empty"></div>
<div class="sectDivider_empty"></div>
<div class="sectDivider_empty"></div>
<div class="sectDivider_empty"></div>
<div class="sectDivider_empty"></div>
<div class="sectDivider_empty"></div>
<div class="sectDivider_empty"></div>
<div class="sectDivider"></div>
<div class="sectDivider"></div>
</body> </body>
</html> </html>

View File

@ -0,0 +1,100 @@
<!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="/icons/favicon.png"/>
<link rel="manifest" href="/manifest.json"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Kode+Mono:wght@400..700&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./styles.css">
<script src="./script.js"></script>
</head>
<body>
<div id="sectHeader">
<a href="/" style="height:100%;display:block;">
<div id="sectHeader_logo"></div>
</a>
<div id="sectHeader_pageInfo">
<span id="sectHeader_pageInfo_pageType">LIST</span>
<span id="sectHeader_pageInfo_pageTypeName"><b>{{.Name}}</b></span>
</div>
</div>
{{range .FilmIDs}}
<div class="sectDivider"></div>
<div class="sectFilm">
<div id="sectFilmInfo_top">
<div id="sectFilmInfo_top_left">
<div class="sectFilmInfo_top_left_title">
<div class="sectFilmInfo_top_left_title_line0">
<div class="marquee_text0"><h1><b>{{.Title_orig}} |&nbsp</b></h1></div>
<div class="marquee_text1"><h1><b>{{.Title_orig}} |&nbsp</b></h1></div>
</div>
<div class="sectFilmInfo_top_left_title_line1">
<div class="marquee_text0"><h1><b>{{.Title_orig}} |&nbsp</b></h1></div>
<div class="marquee_text1"><h1><b>{{.Title_orig}} |&nbsp</b></h1></div>
</div>
</div>
<div class="sectFilmInfo_top_left_title">
<div class="sectFilmInfo_top_left_title_line0">
<div class="marquee_text0"><h1><b>{{.Title_PL}} |&nbsp</b></h1></div>
<div class="marquee_text1"><h1><b>{{.Title_PL}} |&nbsp</b></h1></div>
</div>
<div class="sectFilmInfo_top_left_title_line1">
<div class="marquee_text0"><h1><b>{{.Title_PL}} |&nbsp</b></h1></div>
<div class="marquee_text1"><h1><b>{{.Title_PL}} |&nbsp</b></h1></div>
</div>
</div>
<div class="sectFilmInfo_top_left_title">
<div class="sectFilmInfo_top_left_title_line0">
<div class="marquee_text0"><h1><b>{{.Title_EN}} |&nbsp</b></h1></div>
<div class="marquee_text1"><h1><b>{{.Title_EN}} |&nbsp</b></h1></div>
</div>
<div class="sectFilmInfo_top_left_title_line1">
<div class="marquee_text0"><h1><b>{{.Title_EN}} |&nbsp</b></h1></div>
<div class="marquee_text1"><h1><b>{{.Title_EN}} |&nbsp</b></h1></div>
</div>
</div>
</div>
<div id="sectFilmInfo_top_right">
<div id="sectFilmInfo_top_right_poster" style='background-image: url("{{.Img}}");'></div>
</div>
</div>
<div id="sectFilmInfo_bttm">
<div id="sectFilmInfo_bttm_left">
</div>
<div id="sectFilmInfo_bttm_right">
<div id="sectFilmInfo_bttm_right_yearHldr">
<h2>{{.Year}}</h2>
</div>
</div>
</div>
</div>
{{end}}
<div class="sectDivider"></div>
<div class="sectDivider_empty"></div>
<div class="sectDivider"></div>
<div class="sectDivider"></div>
</body>
</html>