Skip to content
This repository was archived by the owner on Sep 22, 2022. It is now read-only.

Commit 4b8ce86

Browse files
committed
init
0 parents  commit 4b8ce86

File tree

93 files changed

+17353
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+17353
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.exe
2+
posts/*.[mM][Dd]
3+
public/uploads/

mdserver.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/bmizerany/pat"
6+
"github.com/russross/blackfriday"
7+
"html/template"
8+
"io/ioutil"
9+
"log"
10+
"net/http"
11+
"os"
12+
"path"
13+
"strings"
14+
)
15+
16+
type Post struct {
17+
Title string
18+
Body template.HTML
19+
}
20+
21+
var (
22+
// компилируем шаблоны, если не удалось, то выходим
23+
post_template = template.Must(template.ParseFiles(path.Join("templates", "layout.html"), path.Join("templates", "post.html")))
24+
error_template = template.Must(template.ParseFiles(path.Join("templates", "layout.html"), path.Join("templates", "error.html")))
25+
)
26+
27+
func main() {
28+
// для отдачи сервером статичных файлов из папки public/static
29+
fs := noDirListing(http.FileServer(http.Dir("./public/static")))
30+
http.Handle("/static/", http.StripPrefix("/static/", fs))
31+
32+
uploads := noDirListing(http.FileServer(http.Dir("./public/uploads")))
33+
http.Handle("/uploads/", http.StripPrefix("/uploads/", uploads))
34+
35+
mux := pat.New()
36+
mux.Get("/:page", http.HandlerFunc(postHandler))
37+
mux.Get("/:page/", http.HandlerFunc(postHandler))
38+
mux.Get("/", http.HandlerFunc(postHandler))
39+
40+
http.Handle("/", mux)
41+
log.Println("Listening...")
42+
http.ListenAndServe(":3000", nil)
43+
}
44+
45+
func postHandler(w http.ResponseWriter, r *http.Request) {
46+
params := r.URL.Query()
47+
// Извлекаем параметр
48+
// Например, в http://127.0.0.1:3000/p1 page = "p1"
49+
// в http://127.0.0.1:3000/ page = ""
50+
page := params.Get(":page")
51+
// Путь к файлу (без расширения)
52+
// Например, posts/p1
53+
p := path.Join("posts", page)
54+
55+
var post_md string
56+
if page != "" {
57+
// если page не пусто, то считаем, что запрашивается файл
58+
// получим posts/p1.md
59+
post_md = p + ".md"
60+
} else {
61+
// если page пусто, то выдаем главную
62+
post_md = p + "/index.md"
63+
}
64+
65+
post, status, err := load_post(post_md)
66+
if err != nil {
67+
errorHandler(w, r, status)
68+
return
69+
}
70+
if err := post_template.ExecuteTemplate(w, "layout", post); err != nil {
71+
log.Println(err.Error())
72+
errorHandler(w, r, 500)
73+
}
74+
}
75+
76+
// Загружает markdown-файл и конвертирует его в HTML
77+
// Возвращает объект типа Post
78+
// Если путь не существует или является каталогом, то возвращаем ошибку
79+
func load_post(md string) (Post, int, error) {
80+
info, err := os.Stat(md)
81+
if err != nil {
82+
if os.IsNotExist(err) {
83+
// файл не существует
84+
return Post{}, http.StatusNotFound, err
85+
}
86+
}
87+
if info.IsDir() {
88+
// не файл, а папка
89+
return Post{}, http.StatusNotFound, fmt.Errorf("dir")
90+
}
91+
fileread, _ := ioutil.ReadFile(md)
92+
lines := strings.Split(string(fileread), "\n")
93+
title := string(lines[0])
94+
body := strings.Join(lines[1:len(lines)], "\n")
95+
body = string(blackfriday.MarkdownCommon([]byte(body)))
96+
post := Post{title, template.HTML(body)}
97+
return post, 200, nil
98+
}
99+
100+
func errorHandler(w http.ResponseWriter, r *http.Request, status int) {
101+
w.WriteHeader(status)
102+
if err := error_template.ExecuteTemplate(w, "layout", map[string]interface{}{"Error": http.StatusText(status), "Status": status}); err != nil {
103+
log.Println(err.Error())
104+
http.Error(w, http.StatusText(500), 500)
105+
return
106+
}
107+
}
108+
109+
// обертка для http.FileServer, чтобы она не выдавала список файлов
110+
// например, если открыть http://127.0.0.1:3000/static/,
111+
// то будет видно список файлов внутри каталога.
112+
// noDirListing - вернет 404 ошибку в этом случае.
113+
func noDirListing(h http.Handler) http.HandlerFunc {
114+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
115+
if strings.HasSuffix(r.URL.Path, "/") || r.URL.Path == "" {
116+
http.NotFound(w, r)
117+
return
118+
}
119+
h.ServeHTTP(w, r)
120+
})
121+
}

posts/save_posts_here

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
�������� � ���� ����� �������
2+
��������, index.md

0 commit comments

Comments
 (0)