Skip to content

Instantly share code, notes, and snippets.

@kujirahand
Last active June 8, 2022 16:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kujirahand/ef8e4828904aab8c333bcd150f749212 to your computer and use it in GitHub Desktop.
Save kujirahand/ef8e4828904aab8c333bcd150f749212 to your computer and use it in GitHub Desktop.
100行位内、標準ライブラリ以外使わないを目標にして作った掲示板
package main
import (
"encoding/json"
"fmt"
"html"
"io/ioutil"
"net/http"
"time"
)
const logFile = "logs.json" // データの保存先 --- (*1)
// Log 掲示板に保存するデータを構造体で定義 --- (*2)
type Log struct {
ID int `json:"id"`
Name string `json:"name"`
Body string `json:"body"`
CTime int64 `json:"ctime"`
}
// メインプログラム - サーバーを起動する --- (*3)
func main() {
println("server - http://localhost:8888")
// URIに対応するハンドラを登録 --- (*4)
http.HandleFunc("/", showHandler)
http.HandleFunc("/write", writeHandler)
// サーバーを起動 --- (*5)
http.ListenAndServe(":8888", nil)
}
// 書き込みログを画面に表示する --- (*6)
func showHandler(w http.ResponseWriter, r *http.Request) {
// ログを読み出してHTMLを生成 --- (*7)
htmlLog := ""
logs := loadLogs() // データを読み出す
for _, i := range logs {
htmlLog += fmt.Sprintf(
"<p>(%d) <span>%s</span>: %s --- %s</p>",
i.ID,
html.EscapeString(i.Name),
html.EscapeString(i.Body),
time.Unix(i.CTime, 0).Format("2006/1/2 15:04"))
}
// HTML全体を出力 --- (*8)
htmlBody := "<html><head><style>" +
"p { border: 1px solid silver; padding: 1em;} " +
"span { background-color: #eef; } " +
"</style></head><body><h1>BBS</h1>" +
getForm() + htmlLog + "</body></html>"
w.Write([]byte(htmlBody))
}
// フォームから送信された内容を書き込み --- (*9)
func writeHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // フォームを解析 --- (*10)
var log Log
log.Name = r.Form["name"][0]
log.Body = r.Form["body"][0]
if log.Name == "" {
log.Name = "名無し"
}
logs := loadLogs() // 既存のデータを読み出し --- (*11)
log.ID = len(logs) + 1
log.CTime = time.Now().Unix()
logs = append(logs, log) // 追記 --- (*12)
saveLogs(logs) // 保存
http.Redirect(w, r, "/", 302) // リダイレクト --- (*13)
}
// 書き込みフォームを返す --- (*14)
func getForm() string {
return "<div><form action='/write' method='POST'>" +
"名前: <input type='text' name='name'><br>" +
"本文: <input type='text' name='body' style='width:30em;'><br>" +
"<input type='submit' value='書込'>" +
"</form></div><hr>"
}
// ファイルからログファイルの読み込み --- (*15)
func loadLogs() []Log {
// ファイルを開く
text, err := ioutil.ReadFile(logFile)
if err != nil {
return make([]Log, 0)
}
// JSONをパース --- (*16)
var logs []Log
json.Unmarshal([]byte(text), &logs)
return logs
}
// ログファイルの書き込み --- (*17)
func saveLogs(logs []Log) {
// JSONにエンコード
bytes, _ := json.Marshal(logs)
// ファイルへ書き込む
ioutil.WriteFile(logFile, bytes, 0644)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment