hozonsite/src/srv.go

292 行
6.8 KiB
Go
Raw Blame 履歴

このファイルには曖昧(ambiguous)なUnicode文字が含まれています

このファイルには、他の文字と見間違える可能性があるUnicode文字が含まれています。 それが意図的なものと考えられる場合は、この警告を無視して構いません。 それらの文字を表示するにはエスケープボタンを使用します。

package src
import (
"text/template"
"fmt"
"net/http"
"strings"
"strconv"
"time"
"os"
"encoding/json"
"gitler.moe/suwako/hozonsite/common"
"gitler.moe/suwako/goliblocale"
)
type (
Page struct {
Err, Lan, Ver, Ves, Url, Body string
i18n map[string]string
Ext []Exist // 既に存在する場合
}
Stat struct { // APIのみ
Url, Ver string
}
Exist struct {
Date, Url string
}
)
var ftmpl []string
var data *Page
func (p Page) T (key string) string {
return p.i18n[key]
}
// 言語設定、デフォルトja
func initloc (r *http.Request) string {
supportedLanguages := map[string]bool{
"ja": true,
"en": true,
}
cookie, err := r.Cookie("lang")
if err != nil {
return "ja"
}
if _, ok := supportedLanguages[cookie.Value]; ok {
return cookie.Value
} else {
return "ja"
}
}
func tspath (p string) string {
pc := strings.Split(p, "/")
for i := len(pc) - 1; i >= 0; i-- {
if _, err := strconv.Atoi(pc[i]); err == nil {
return pc[i]
}
}
return ""
}
func handleStatic(path string, cnf Config, w http.ResponseWriter, r *http.Request) {
if !strings.HasSuffix(path, ".css") &&
!strings.HasSuffix(path, ".png") &&
!strings.HasSuffix(path, ".jpeg") &&
!strings.HasSuffix(path, ".jpg") &&
!strings.HasSuffix(path, ".webm") &&
!strings.HasSuffix(path, ".gif") &&
!strings.HasSuffix(path, ".js") {
http.NotFound(w, r)
return
}
fpath := cnf.Datapath + "/archive/" + path
http.ServeFile(w, r, fpath)
}
func handlePost(w http.ResponseWriter, r *http.Request, cnf Config) {
err := r.ParseForm()
if err != nil {
fmt.Println(err)
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
// 言語変更
if lang := r.PostFormValue("lang"); lang != "" {
http.SetCookie(
w,
&http.Cookie{Name: "lang", Value: lang, MaxAge: 31536000, Path: "/"},
)
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
var exist []string
langu := initloc(r)
i18n, err := goliblocale.GetLocale(cnf.Webpath + "/locale/" + langu)
if err != nil {
fmt.Printf("liblocaleエラー%v", err)
return
}
if r.PostForm.Get("hozonsite") == "" {
data.Err = i18n["errfusei"]
ftmpl[0] = cnf.Webpath + "/view/404.html"
return
}
url := r.PostForm.Get("hozonsite")
// HTTPかHTTPSじゃない場合
if !Checkprefix(url) {
data.Err = i18n["errfuseiurl"]
ftmpl[0] = cnf.Webpath + "/view/404.html"
return
}
eurl := Stripurl(url)
exist = Checkexist(eurl, cnf.Datapath)
if len(exist) == 0 || r.PostForm.Get("agree") == "1" {
path := Mkdirs(eurl, cnf.Datapath)
Getpage(url, path)
Scanpage(path, eurl, cnf.Datapath)
http.Redirect(
w,
r,
cnf.Domain + strings.Replace(path, cnf.Datapath, "", 1),
http.StatusSeeOther,
)
return
}
ftmpl[0] = cnf.Webpath + "/view/check.html"
data.Url = url
var existing []Exist
e := Exist{}
for _, ex := range exist {
ti, err := strconv.ParseInt(tspath(ex), 10, 64)
if err != nil {
fmt.Println(err)
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
t := time.Unix(ti, 0)
e.Date = t.Format("2006年01月02日 15:04:05")
e.Url = strings.Replace(ex, cnf.Datapath, cnf.Domain, 1)
existing = append(existing, e)
}
data.Ext = existing
}
// ホームページ
func siteHandler (cnf Config) func (http.ResponseWriter, *http.Request) {
return func (w http.ResponseWriter, r *http.Request) {
ftmpl = []string{
cnf.Webpath + "/view/index.html",
cnf.Webpath + "/view/header.html",
cnf.Webpath + "/view/footer.html",
}
version := common.GetVersion()
data = &Page{
Ver: version,
Ves: strings.ReplaceAll(version, ".", ""),
}
lang := initloc(r)
data.Lan = lang
i18n, err := goliblocale.GetLocale(cnf.Webpath + "/locale/" + lang)
if err != nil {
fmt.Printf("liblocaleエラー%v", err)
return
}
data.i18n = i18n
ftmpl[0] = cnf.Webpath + "/view/index.html"
tmpl := template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2]))
if r.Method == "POST" {
handlePost(w, r, cnf)
}
tmpl = template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2]))
tmpl.Execute(w, data)
}
}
// /api TODO
func apiHandler (cnf Config) func (http.ResponseWriter, *http.Request) {
return func (w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(200)
version := common.GetVersion()
buf, _ := json.MarshalIndent(
&Stat{Url: cnf.Domain, Ver: version},
"",
" ",
)
_, _ = w.Write(buf)
}
}
// /archive
func archiveHandler (cnf Config) func (http.ResponseWriter, *http.Request) {
return func (w http.ResponseWriter, r *http.Request) {
version := common.GetVersion()
ftmpl := []string{
cnf.Webpath + "/view/index.html",
cnf.Webpath + "/view/header.html",
cnf.Webpath + "/view/footer.html",
}
data := &Page{Ver: version, Ves: strings.ReplaceAll(version, ".", "")}
lang := initloc(r)
data.Lan = lang
i18n, err := goliblocale.GetLocale(cnf.Webpath + "/locale/" + lang)
if err != nil {
fmt.Printf("liblocaleエラー%v", err)
return
}
data.i18n = i18n
ftmpl[0] = cnf.Webpath + "/view/index.html"
tmpl := template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2]))
path := strings.TrimPrefix(r.URL.Path, "/archive/")
if strings.Contains(path, "/static/") {
handleStatic(path, cnf, w, r)
return
}
pth := r.URL.Path
if !strings.HasSuffix(pth, "/") &&
!strings.HasSuffix(pth, "index.html") {
pth += "/index.html"
} else if strings.HasSuffix(pth, "/") &&
!strings.HasSuffix(pth, "index.html") {
pth += "index.html"
}
file := cnf.Datapath + pth
if _, err := os.Stat(file); os.IsNotExist(err) {
http.Redirect(w, r, "/404", http.StatusSeeOther)
return
}
bdy, err := os.ReadFile(file)
if err != nil {
http.Redirect(w, r, "/404", http.StatusSeeOther)
return
}
data.Body = string(bdy)
tmpl = template.Must(
template.ParseFiles(cnf.Webpath + "/view/archive.html"),
)
tmpl.Execute(w, data)
data = nil
}
}
// サーバー
func Serv (cnf Config, port int) {
http.Handle(
"/static/",
http.StripPrefix("/static/",
http.FileServer(http.Dir(cnf.Webpath + "/static"))),
)
http.HandleFunc("/api/", apiHandler(cnf))
http.HandleFunc("/archive/", archiveHandler(cnf))
http.HandleFunc("/", siteHandler(cnf))
fmt.Println(fmt.Sprint(
"http://" + cnf.IP + ":",
port,
" でサーバーを実行中。終了するには、CTRL+Cを押して下さい。"),
)
http.ListenAndServe(fmt.Sprint(cnf.IP + ":", port), nil)
}