Compare commits
10 Commits
1c96ba9be9
...
b8a1c8f1ec
Author | SHA1 | Date |
---|---|---|
諏訪子 | b8a1c8f1ec | |
諏訪子 | ff81340d99 | |
諏訪子 | 498043a6a7 | |
諏訪子 | cea43b4326 | |
諏訪子 | 53fb8560c5 | |
テクニカル諏訪子 | dba933ece1 | |
諏訪子 | 3a63caff2e | |
諏訪子 | 5bf5a468dc | |
諏訪子 | dab171d533 | |
諏訪子 | 8d64bdd11c |
|
@ -0,0 +1,6 @@
|
|||
# 1.0.0
|
||||
* PHPからGoに交換しました
|
||||
* 今度からバージョンを付きます
|
||||
|
||||
# それ以前
|
||||
* 色々
|
44
Makefile
44
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"webpath": "/var/www/htdocs/hozonsite",
|
||||
"domain": "https://hozon.site"
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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
12
main.go
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
}
|
7
pager.go
7
pager.go
|
@ -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
96
prep.go
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
224
srv.go
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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" .}}
|
||||
|
|
Loading…
Reference in New Issue