package main import ( "fmt" "html/template" "io" "log" "net/http" "net/url" "os" "strings" "time" "encoding/json" "errors" "github.com/tidwall/gjson" //"path/filepath" //"regexp" //"strings" //"maps" //"slices" ) var templates *template.Template = template.New("") var client = &http.Client{Timeout: 2*time.Second} type Film struct{ Title_orig, Title_EN, Title_PL, Desc, Img, Source string Year int } var db_film []Film func findURL_in_msg(in_msg string) (_ string,err error){ i := strings.Index(in_msg, "http") if(i == -1){ err = errors.New("No URL found in: " + in_msg) return } j := strings.Index(in_msg[i:], " ") if(j == -1){ j = len(in_msg)-i } return in_msg[i:i+j], nil } 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){ if fileName, ok := template_renders[req.URL.Path]; ok{ fmt.Println("[srv] template", req.URL.Path, fileName) url_query := req.URL.Query() url_query_id := url_query.Get("id") var context any if(url_query_id != ""){ context = db_film[int(url_query_id)] }else{ context = nil } err := templates.ExecuteTemplate(resp, fileName, context) if(err != nil){ http.Error(resp, err.Error(), http.StatusInternalServerError) } }else{ fmt.Println("[srv] static", req.URL.Path) fSrv.ServeHTTP(resp, req) } } } 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){ panic(err) } templates.New(i_file).Parse(string(text)) } } func hdlr_film_parseMsg(resp http.ResponseWriter, req *http.Request){ fmt.Println("[srv] util", req.URL) url_query := req.URL.Query() t_url, _ := findURL_in_msg(url_query.Get("text")) fmt.Println(t_url) t_url_noRed, _ := resolve_redirs(t_url) fmt.Println(t_url_noRed) t_film, _ := fetch_filmInfo(t_url_noRed) db_film = append(db_film, t_film) t_json, _ := json.MarshalIndent(t_film, "", " ") fmt.Printf("%+v\n", string(t_json)) http.Redirect(resp, req, "/film/view/"+string(len(db_film)-1), http.StatusFound) } 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_url_noRed, _ := resolve_redirs("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_url_noRed, _ := resolve_redirs("https://share.google/EsMXhLYol3eQTKcQH") //t_url, _ := findURL_in_msg("https://share.google/EsMXhLYol3eQTKcQH") //t_url, _ := findURL_in_msg("abcabc https://share.google/EsMXhLYol3eQTKcQH abcabc") //t_url, _ := findURL_in_msg("abcabchttps://share.google/EsMXhLYol3eQTKcQH abcabc") //t_url, _ := findURL_in_msg("abcabchttps://share.google/EsMXhLYol3eQTKcQH") //t_url, _ := findURL_in_msg("Fantastyczny Pan Lis (2009) - Filmweb https://share.google/EsMXhLYol3eQTKcQH") //fmt.Println(t_url) //t_url_noRed, _ := resolve_redirs(t_url) //fmt.Println(t_url_noRed) //t_film, _ := fetch_filmInfo(t_url_noRed) //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)) http.HandleFunc("/film/parse_msg/", hdlr_film_parseMsg) //fmt.Println("Welcome to moira_db!"); log.Fatal(http.ListenAndServe("127.0.0.1:8099", nil)) }