Compare commits

...

10 Commits

Author SHA1 Message Date
諏訪子 b8a1c8f1ec GUI 2023-06-23 18:09:23 +09:00
諏訪子 ff81340d99 ちんこ 2023-06-23 13:06:33 +09:00
諏訪子 498043a6a7 アーカイブをアクセス #4 & CLIモード #3 2023-06-23 12:48:13 +09:00
諏訪子 cea43b4326 NetBSD対応 2023-06-23 12:43:13 +09:00
諏訪子 53fb8560c5 . 2023-05-21 08:03:43 +09:00
テクニカル諏訪子 dba933ece1 . 2023-05-19 11:53:02 +09:00
諏訪子 3a63caff2e コンフィグ 2023-05-14 11:44:09 +09:00
諏訪子 5bf5a468dc ちんちん 2023-05-14 11:37:15 +09:00
諏訪子 dab171d533 まだ 2023-05-12 16:34:02 +09:00
諏訪子 8d64bdd11c 読みやすくに 2023-05-12 14:18:37 +09:00
15 changed files with 486 additions and 199 deletions

6
CHANGELOG.md Normal file
View File

@ -0,0 +1,6 @@
# 1.0.0
* PHPからGoに交換しました
* 今度からバージョンを付きます
# それ以前
* 色々

View File

@ -1,30 +1,58 @@
NAME=hozonsite
VERSION=1.0.0
# Linux、Cruxの場合は必須。他のディストリビューションはどうでも良い
VERSION := $(shell cat main.go | grep "var version" | awk '{print $$4}' | sed "s/\"//g")
# Linux、Illumos
PREFIX=/usr
# FreeBSDとOpenBSD
#PREFIX=/usr/local
# NetBSD
#PREFIX=/usr/pkg
MANPREFIX=${PREFIX}/share/man
# LinuxとOpenBSD
# Linux、Illumos、とOpenBSD
CNFPREFIX=/etc
# FreeBSD
#CNFPREFIX=/usr/local/etc
# NetBSD
#CNFPREFIX=/usr/pkg/etc
CC=CGO_ENABLED=0 go build
# リリース。なし=デバッグ。
RELEASE=-ldflags="-s -w" -buildvcs=false
all:
${CC} ${RELEASE} -o ${NAME} $<
${CC} ${RELEASE} -o ${NAME}
release:
env GOOS=linux GOARCH=amd64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-linux-amd64
env GOOS=linux GOARCH=arm64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-linux-arm64
env GOOS=linux GOARCH=arm ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-linux-arm
env GOOS=linux GOARCH=riscv64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-linux-riscv64
env GOOS=linux GOARCH=386 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-linux-386
env GOOS=linux GOARCH=ppc64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-linux-ppc64
env GOOS=linux GOARCH=mips64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-linux-mips64
env GOOS=openbsd GOARCH=amd64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-openbsd-amd64
env GOOS=openbsd GOARCH=386 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-openbsd-386
env GOOS=openbsd GOARCH=arm64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-openbsd-arm64
env GOOS=openbsd GOARCH=arm ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-openbsd-arm
env GOOS=openbsd GOARCH=mips64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-openbsd-mips64
env GOOS=freebsd GOARCH=amd64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-freebsd-amd64
env GOOS=freebsd GOARCH=386 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-freebsd-386
env GOOS=freebsd GOARCH=arm ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-freebsd-arm4
env GOOS=freebsd GOARCH=arm64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-freebsd-arm64
env GOOS=freebsd GOARCH=riscv64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-freebsd-riscv64
env GOOS=netbsd GOARCH=amd64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-netbsd-amd64
env GOOS=netbsd GOARCH=386 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-netbsd-386
env GOOS=netbsd GOARCH=arm ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-netbsd-arm4
env GOOS=netbsd GOARCH=arm64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-netbsd-arm64
env GOOS=illumos GOARCH=amd64 ${CC} ${RELEASE} -o bin/${NAME}-${VERSION}-illumos-amd64
clean:
rm -f ${NAME} ${NAME}-${VERSION}.tar.gz
dist: clean
mkdir -p ${NAME}${VERSION}
mkdir -p ${NAME}-${VERSION}
cp -R LICENSE.txt Makefile README.md CHANGELOG.md\
view static logo.jpg\
${NAME}.1 *.go *.json ${NAME}-${VERSION}
tar -zcfv ${NAME}-${VERSION}.tar.gz ${NAME}-${VERSION}
${NAME}.1 *.go *.json go.mod ${NAME}-${VERSION}
tar zcfv ${NAME}-${VERSION}.tar.gz ${NAME}-${VERSION}
rm -rf ${NAME}-${VERSION}
install: all
@ -45,4 +73,4 @@ uninstall:
${DESTDIR}${CNFPREFIX}/${NAME}\
${DESTDIR}${PREFIX}/share/${NAME}
.PHONY: all options clean dist install uninstall
.PHONY: all release clean dist install uninstall

View File

@ -21,13 +21,15 @@ func getconf () Config {
prefix := "/usr"
if runtime.GOOS == "freebsd" || runtime.GOOS == "openbsd" {
prefix += "/local"
} else if runtime.GOOS == "netbsd" {
prefix += "/pkg"
}
cnf.configpath = "/etc/hozonsite.json"
cnf.configpath = "/etc/hozonsite/config.json"
//_, err = os.Stat(cnf.configpath)
cnf.datapath = prefix + "/share/hozonsite"
if runtime.GOOS == "freebsd" {
if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" {
cnf.configpath = prefix + cnf.configpath
}

4
config.json Normal file
View File

@ -0,0 +1,4 @@
{
"webpath": "/var/www/htdocs/hozonsite",
"domain": "https://hozon.site"
}

42
getpage.go Normal file
View File

@ -0,0 +1,42 @@
package main
import (
"os"
"fmt"
"net/http"
"io"
"strings"
)
func stripurl (url string) string {
res := strings.ReplaceAll(url, "?", "")
res = strings.ReplaceAll(res, "=", "")
return res
}
func getpage (url string, path string) {
curl, err := http.Get(url)
if err != nil {
fmt.Println("CURLエラー", err)
return
}
defer curl.Body.Close()
body, err2 := io.ReadAll(curl.Body)
if err2 != nil {
fmt.Println("読込エラー:", err2)
return
}
fn, err3 := os.Create(path + "/index.html")
if err3 != nil {
fmt.Println("ファイルの創作エラー:", err3)
return
}
defer fn.Close()
_, err4 := fn.WriteString(string(body))
if err4 != nil {
fmt.Println("ファイル書込エラー:", err4)
}
}

2
go.mod
View File

@ -1,3 +1,3 @@
module hozonsite
module 076/hozonsite
go 1.20

39
lang.go Normal file
View File

@ -0,0 +1,39 @@
package main
import (
"encoding/json"
"fmt"
)
func getlist (lang string) []byte {
var jloc = []byte(`{
"top": "トップ",
"errfuseiurl": "URLは「http://」又は「https://」で始めます。",
"errfusei": "不正なエラー。"
}`)
var eloc = []byte(`{
"top": "Top",
"errfuseiurl": "The URL should start with \"http://\" or \"https://\".",
"errfusei": "Unknown error."
}`)
if lang == "en" { return eloc }
return jloc
}
func getloc (str string, lang string) string {
var payload map[string]interface{}
err := json.Unmarshal(getlist(lang), &payload)
if err != nil {
fmt.Println("loc:", err)
return ""
}
for k, v := range payload {
if str == k {
return v.(string)
}
}
return ""
}

12
main.go
View File

@ -9,10 +9,6 @@ import (
var version = "1.0.0"
func checkprefix (url string) bool {
return strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://")
}
func help () {
fmt.Println("使い方:");
fmt.Println("hozonsite -v :バージョンを表示");
@ -35,7 +31,8 @@ func main () {
return
} else {
if checkprefix(args[1]) {
exist := checkexist(args[1], cnf.datapath)
eurl := stripurl(args[1])
exist := checkexist(eurl, cnf.datapath)
var confirm string
if len(exist) > 0 {
fmt.Println("このページが既に保存されているみたいです。")
@ -46,10 +43,9 @@ func main () {
fmt.Scanf("%s", &confirm)
}
if len(exist) == 0 || confirm == "y" || confirm == "Y" {
path := mkdirs(args[1], cnf.datapath)
path := mkdirs(eurl, cnf.datapath)
getpage(args[1], path)
// TODO: ページの確認
scanpage(path, args[1], cnf.datapath)
scanpage(path, eurl, cnf.datapath)
fmt.Println(cnf.domain + strings.Replace(path, cnf.datapath, "", 1))
}
return

15
mime.go Normal file
View File

@ -0,0 +1,15 @@
package main
func getmime () map[string]string {
return map[string]string {
"text/css": ".css",
"text/javascript": ".js",
"image/png": ".png",
"image/jpeg": ".jpg",
"image/webp": ".webp",
"image/gif": ".gif",
"font/ttf": ".ttf",
"font/woff2": ".woff2",
"image/vnd.microsoft.icon": ".ico",
}
}

View File

@ -1,7 +0,0 @@
package main
//func scanurl (url string, resnum int) {}
//func scanpage (url string, path string) {}
//func getpage (url string, path string) int {}

96
prep.go
View File

@ -6,11 +6,12 @@ import (
"fmt"
"strings"
"path/filepath"
"net/http"
"io"
"regexp"
)
func checkprefix (url string) bool {
return strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://")
}
func checkexist (url string, prefix string) []string {
res, err := filepath.Glob(prefix + "/archive/*" + url2path(url))
if err != nil {
@ -46,92 +47,3 @@ func mkdirs (url string, prefix string) string {
return path
}
func getpage (url string, path string) {
curl, err := http.Get(url)
if err != nil {
fmt.Println("CURLエラー", err)
return
}
defer curl.Body.Close()
body, err2 := io.ReadAll(curl.Body)
if err2 != nil {
fmt.Println("読込エラ:", err2)
return
}
fn, err3 := os.Create(path + "/index.html")
if err3 != nil {
fmt.Println("ファイルの創作エラー:", err3)
return
}
defer fn.Close()
_, err4 := fn.WriteString(string(body))
if err4 != nil {
fmt.Println("ファイル書込エラー:", err4)
}
}
func scanpage (path string, domain string, thisdomain string) {
fn, err := os.ReadFile(path + "/index.html")
if err != nil {
fmt.Println("ファイルを開けられなかった:", err)
return
}
/* 削除 */
var script = regexp.MustCompile(`(<script.*</script>)`).ReplaceAllString(string(fn), "")
var noscript = regexp.MustCompile(`(<noscript.*</noscript>)`).ReplaceAllString(string(script), "")
var audio = regexp.MustCompile(`(<audio.*</audio>)`).ReplaceAllString(string(noscript), "")
var video = regexp.MustCompile(`(<video.*</video>)`).ReplaceAllString(string(audio), "")
var iframe = regexp.MustCompile(`(<iframe.*</iframe>)`).ReplaceAllString(string(video), "")
/* 追加ダウンロード+ローカル化 */
var ass = regexp.MustCompile(`(<img.*src="|<meta.*content="|<link.*href=")(.*\.)(png|webm|jpg|jpeg|gif|css)`)
for _, cssx := range ass.FindAllString(iframe, -1) {
s := regexp.MustCompile(`(.*src="|.*content="|.*href=")`).Split(cssx, -1)
ss := regexp.MustCompile(`(".*)`).Split(s[1], -1)
if strings.HasPrefix(ss[0], "http://") || strings.HasPrefix(ss[0], "https://") {
// TODO
} else {
fss := strings.Split(ss[0], "/")
filename := fss[len(fss)-1]
if filename == "" {
continue
}
f, err := os.Create(path + "/" + filename)
if err != nil {
fmt.Println("2. 作成失敗:", err)
return
}
defer f.Close()
af := domain + ss[0]
if !strings.HasPrefix(ss[0], "/") {
af = domain + "/" + ss[0]
}
i, err := http.Get(af)
if err != nil {
fmt.Println("2. ダウンロードに失敗:", err)
return
}
defer i.Body.Close()
_, err = io.Copy(f, i.Body)
if err != nil {
fmt.Println("2. コピーに失敗:", err)
return
}
iframe = strings.Replace(iframe, ss[0], "/" + filename, -1)
}
err := os.WriteFile(path + "/index.html", []byte(iframe), 0644)
if err != nil {
fmt.Println("書込に失敗")
return
}
}
}

162
scanpage.go Normal file
View File

@ -0,0 +1,162 @@
package main
import (
"os"
"fmt"
"strings"
"net/http"
"net/url"
"io"
"regexp"
"errors"
"path/filepath"
)
func scanpage (path string, domain string, thisdomain string) error {
fn, err := os.ReadFile(path + "/index.html")
if err != nil {
return err
}
/* 削除 */
var script = regexp.MustCompile(`(<script.*</script>)`).ReplaceAllString(string(fn), "")
var noscript = regexp.MustCompile(`(<noscript.*</noscript>)`).ReplaceAllString(string(script), "")
var audio = regexp.MustCompile(`(<audio.*</audio>)`).ReplaceAllString(string(noscript), "")
var video = regexp.MustCompile(`(<video.*</video>)`).ReplaceAllString(string(audio), "")
var iframe = regexp.MustCompile(`(<iframe.*</iframe>)`).ReplaceAllString(string(video), "")
/* 追加ダウンロード+ローカル化 */
var ass = regexp.MustCompile(`(<img.*src=['"]|<meta.*content=['"]|<link.*href=['"])(.*\.)(png|webp|jpg|jpeg|gif|css|js|ico|svg|ttf|woff2)(\?[^'"]*)?`)
spath := "static/"
if !strings.HasSuffix(path, "/") {
spath = "/" + spath
}
spath = path + spath
err = os.Mkdir(spath, 0755)
if err != nil {
return err
}
repmap := make(map[string]string)
for _, cssx := range ass.FindAllString(iframe, -1) {
s := regexp.MustCompile(`(.*src=['"]|.*content=['"]|.*href=['"])`).Split(cssx, -1)
ss := regexp.MustCompile(`(['"].*)`).Split(s[1], -1)
ogurl := ss[0]
if strings.HasPrefix(ss[0], "//") {
ss[0] = "https:" + ss[0]
}
fss := strings.Split(ss[0], "/")
assdom := ""
filename := fss[len(fss)-1]
if strings.HasPrefix(ss[0], "http://") || strings.HasPrefix(ss[0], "https://") {
assdom = fss[2]
}
asspath := path + "/static/" + assdom
err = os.MkdirAll(asspath, 0755)
if err != nil {
return err
}
if filename == "" {
continue
}
if strings.HasPrefix(ss[0], "http://") || strings.HasPrefix(ss[0], "https://") {
err = dlres(ss[0], filepath.Join(asspath, filename))
if err != nil {
return err
}
} else {
u, err := url.Parse(domain)
if err != nil {
return err
}
rel, err := url.Parse(ss[0])
if err != nil {
return err
}
af := u.ResolveReference(rel).String()
err = dlres(af, filepath.Join(asspath, filename))
if err != nil {
return err
}
}
repmap[ogurl] = filepath.Join("/static", assdom, filename)
if assdom == "" {
repmap[ogurl] = filepath.Join("/static", filename)
}
if err != nil {
fmt.Println(err)
return errors.New("2. ダウンロードに失敗:")
}
}
for ourl, lurl := range repmap {
aurl := strings.ReplaceAll(path, thisdomain, "") + stripver(lurl)
iframe = strings.ReplaceAll(iframe, ourl, aurl)
}
err = os.WriteFile(path + "/index.html", []byte(iframe), 0644)
if err != nil {
fmt.Println(err)
return errors.New("書込に失敗")
}
return nil
}
func stripver (durl string) string {
u, err := url.Parse(durl)
if err != nil {
fmt.Println("エラー:", err)
return ""
}
u.RawQuery = ""
return u.Path
}
func dlres (durl string, dest string) error {
// ダウンロード
res, err := http.Get(durl)
if err != nil {
return err
}
defer res.Body.Close()
dest = stripver(dest)
// MIMEタイプを確認
ct := res.Header.Get("Content-Type")
for mime, ext := range getmime() {
if strings.Contains(ct, mime) && !strings.HasSuffix(dest, ext) {
dest += ext
break
}
}
// ファイルを作成
f, err := os.Create(dest)
if err != nil {
return err
}
defer f.Close()
// ファイルを書き込む
_, err = io.Copy(f, res.Body)
if err != nil {
return err
}
return nil
}

224
srv.go
View File

@ -5,105 +5,187 @@ import (
"fmt"
"net/http"
"strings"
"strconv"
"time"
"os"
"encoding/json"
)
type Page struct {
Tit string
Err string
Lan string
Ver string
Ext []string // 既に存在する場合
Url string // 確認ページ用
Body string // 保存したページ用
type (
Page struct {
Tit, Err, Lan, Ver, Ves, Url, Body string
Ext []Exist // 既に存在する場合
}
Stat struct {
Url, Ver string
}
Exist struct {
Date, Url string
}
)
func initloc (r *http.Request) string {
cookie, err := r.Cookie("lang")
if err == nil && cookie.Value == "en" {
return "en"
}
return "ja"
}
func serv (cnf Config, port int) {
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
func tspath (p string) string {
pc := strings.Split(p, "/")
ftmpl := []string{cnf.webpath + "/view/index.html", cnf.webpath + "/view/header.html", cnf.webpath + "/view/footer.html"}
/*http.HandleFunc("/exist", func(w http.ResponseWriter, r *http.Request) {
data := &Page{Tit: "トップ", Ver: version}
cookie, err := r.Cookie("lang")
if err != nil {
data.Lan = "ja"
} else {
data.Lan = cookie.Value
for i := len(pc) - 1; i >= 0; i-- {
if _, err := strconv.Atoi(pc[i]); err == nil {
return pc[i]
}
}
if data.Lan == "en" {
data.Tit = "Top"
}
})*/
return ""
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
data := &Page{Tit: "トップ", Ver: version}
cookie, err := r.Cookie("lang")
if err != nil {
data.Lan = "ja"
} else {
data.Lan = cookie.Value
}
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"}
data := &Page{Ver: version, Ves: strings.ReplaceAll(version, ".", "")}
if data.Lan == "en" {
data.Tit = "Top"
}
lang := initloc(r)
data.Lan = lang
ftmpl[0] = cnf.webpath + "/view/index.html"
tmpl := template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2]))
if strings.HasPrefix(r.URL.Path, "/archive") {
data.Tit = getloc("top", lang)
if r.Method == "POST" {
err := r.ParseForm()
if err != nil {
fmt.Println(err)
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
// クッキー
if r.PostForm.Get("langchange") != "" {
cookie, err := r.Cookie("lang")
if err != nil || cookie.Value == "ja" {
http.SetCookie(w, &http.Cookie {Name: "lang", Value: "en", MaxAge: 31536000, Path: "/"})
} else {
http.SetCookie(w, &http.Cookie {Name: "lang", Value: "ja", MaxAge: 31536000, Path: "/"})
}
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
var exist []string
if r.PostForm.Get("hozonsite") != "" {
url := r.PostForm.Get("hozonsite")
// HTTPかHTTPSじゃない場合
if !checkprefix(url) {
data.Err = getloc("errfuseiurl", lang)
ftmpl[0] = cnf.webpath + "/view/404.html"
} else {
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)
} else if len(exist) > 0 {
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
} else {
data.Err = getloc("errfusei", lang)
ftmpl[0] = cnf.webpath + "/view/404.html"
}
}
}
}
tmpl = template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2]))
tmpl.Execute(w, data)
}
}
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)
buf, _ := json.MarshalIndent(&Stat{Url: cnf.domain, Ver: version}, "", " ")
_, _ = w.Write(buf)
}
}
func archiveHandler (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"}
data := &Page{Ver: version, Ves: strings.ReplaceAll(version, ".", "")}
lang := initloc(r)
data.Lan = lang
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/") {
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)
} else {
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"
}
bdy, err := os.ReadFile(cnf.datapath + pth)
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"))
} else {
if r.Method == "POST" {
err := r.ParseForm()
if err != nil { fmt.Println(err) }
// クッキー
if r.PostForm.Get("langchange") != "" {
cookie, err := r.Cookie("lang")
if err != nil || cookie.Value == "ja" {
http.SetCookie(w, &http.Cookie {Name: "lang", Value: "en", MaxAge: 31536000, Path: "/"})
} else {
http.SetCookie(w, &http.Cookie {Name: "lang", Value: "ja", MaxAge: 31536000, Path: "/"})
}
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
if r.PostForm.Get("hozonsite") != "" {
url := r.PostForm.Get("hozonsite")
// HTTPかHTTPSじゃない場合
if !checkprefix(url) {
if data.Lan == "ja" {
data.Err = "URLは「http://」又は「https://」で始めます。"
} else {
data.Err = "The URL should start with \"http://\" or \"https://\"."
}
ftmpl[0] = cnf.webpath + "/view/404.html"
tmpl = template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2]))
} else {
//if r.PostForm.Get("sosin") != "" {}
}
}
}
tmpl.Execute(w, data)
data = nil
}
}
}
tmpl.Execute(w, data)
data = nil
})
func serv (cnf Config, port int) {
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
http.HandleFunc("/api/", apiHandler(cnf))
http.HandleFunc("/archive/", archiveHandler(cnf))
http.HandleFunc("/", siteHandler(cnf))
fmt.Println(fmt.Sprint("http://127.0.0.1:", port, " でサーバーを実行中。終了するには、CTRL+Cを押して下さい。"))
http.ListenAndServe(fmt.Sprint(":", port), nil)

View File

@ -13,9 +13,10 @@
position: fixed !important;
left: 0 !important;
top: 0 !important;
font-size: 14px !important;
font-size: 18px !important;
font-family: unset !important;
width: 100% !important;
text-align: left !important;
}
.archbody {
padding-top: 74px !important;

View File

@ -1,23 +1,28 @@
{{template "header" .}}
{{if eq .Lan "ja"}}既に保存されたページ:{{else}}Pages that already got archived:{{end}}
{{range .Ext}}
<!--a href="/archive/'.$e.'/'.$url.'">
date('Y年m月d日 H:i:s', $e)
<h3>{{.Url}}</h3>
{{if eq .Lan "en"}}
Pages that already got archived:
{{else}}
既に保存されたページ:
{{end}}<br />
{{range $i, $e := .Ext}}
<a href="{{$e.Url}}">
{{$e.Date}}
</a>
<br /-->
<br />
{{end}}
<p>
{{if eq .Lan "ja"}}
このページが既に保存されているみたいです。<br />本当に手続きましょうか?
{{else}}
{{if eq .Lan "en"}}
This page seems to have been already archived.<br />Do you really want to proceed?
{{else}}
このページが既に保存されているみたいです。<br />本当に手続きましょうか?
{{end}}
</p>
<form action="/" method="post">
<input type="hidden" name="hozonsite" value="{{.Url}}" />
<input type="hidden" name="agree" value="1" />
<div class="submit">
<input type="submit" name="submit" value="{{if eq .Lan "ja"}}はい保存して下さい{{else}}Yes, please archive!!{{end}}" />
<input type="submit" name="submit" value="{{if eq .Lan "en"}}Yes, please archive!!{{else}}はい保存して下さい{{end}}" />
</div>
</form>
{{template "footer" .}}