From c946b9daba0fdd3396a88cdc96fa216c87ec8dd1 Mon Sep 17 00:00:00 2001 From: Arnas Udovicius Date: Sun, 21 Aug 2022 01:33:27 +0300 Subject: [PATCH] all left pages --- README.md | 26 ++--------- formatter.go | 12 ++--- main.go | 101 +++++++++++++++++++++------------------- templates/all_texts.gmi | 7 +++ templates/category.gmi | 16 +++++-- templates/macros.tpl | 6 +-- templates/page.gmi | 13 ++++++ templates/tag.gmi | 9 ++++ tree.pb.go | 23 ++++++++- tree.proto | 2 + 10 files changed, 126 insertions(+), 89 deletions(-) create mode 100644 templates/all_texts.gmi create mode 100644 templates/page.gmi create mode 100644 templates/tag.gmi diff --git a/README.md b/README.md index 6bc49d9..ceffe6f 100644 --- a/README.md +++ b/README.md @@ -5,36 +5,16 @@ My capsule in Gemini space. Built with zord-tree support -## URL plan - -* / - redirect to /sgs -* /sgs or /en - index template by language. Links to other language, about, search, root categories, all tags, last 10 post, link to all posts -* /[sgs|en]/a - about page -* /[sgs|en]/s - search -* /[sgs|en]/f/ - display files, subcategories, subtags. If exists index.gmi - display its text -* /[sgs|en]/f/// - display category path as: -``` -=> /sgs/f/c1 c1 -=> /sgs/f/c1/c2 └─ c2 -=> /sgs/f/c1/c2/c3 , └─ c3 ---- -> c1 -> └─ c2 -> , └─ c3 -``` -display tags, date, copyright - - ## TODO -* add category view -* add tag view -* add file view * add image or other file not `gmi` download * feed * security * citata from some file __DONE__ +* add category view +* add tag view +* add file view * about * migrate to gRPC * routing, not found diff --git a/formatter.go b/formatter.go index c217c73..7d6a244 100644 --- a/formatter.go +++ b/formatter.go @@ -20,6 +20,10 @@ func (file *TreeFile) GmiName() string { return strings.Replace(file.Name, ".md", ".gmi", 1) } +func (file *TreeFile) CategoryPath() string { + return "/" + strings.Join(file.Category, "/") +} + func (tree *Tree) GetIndexFile() (*TreeFile, error) { for _, file := range tree.RootFiles { if file.Name == "index.md" { @@ -29,14 +33,6 @@ func (tree *Tree) GetIndexFile() (*TreeFile, error) { return nil, errors.New("index file not found") } -func (tree *Tree) HasIndexFile() bool { - _, err := tree.GetIndexFile() - if err != nil { - return false - } - - return true -} func GetLastFiles(files []*TreeFile) []*TreeFile { sortingFiles := make(map[string]*TreeFile) diff --git a/main.go b/main.go index e03250e..fe43b99 100644 --- a/main.go +++ b/main.go @@ -100,6 +100,9 @@ func process(_ context.Context, w gemini.ResponseWriter, r *gemini.Request) { renderFile(lang, w, r, client) case regexp.MustCompile(`^/(sgs|en)/f/[\p{L}\d_+.]+(/[\p{L}\d_+.]+)*/?$`).MatchString(r.URL.Path): renderCategory(lang, w, r, client) + case regexp.MustCompile(`^/(sgs|en)/t/[\p{L}\d_+.]+/?$`).MatchString(r.URL.Path): + renderTag(lang, w, r, client) + // case abruozdelee default: w.WriteHeader(gemini.StatusNotFound, "Out of space") } @@ -214,7 +217,6 @@ func renderCategory(lang string, w gemini.ResponseWriter, r *gemini.Request, cli w.SetMediaType("text/gemini") tpl := pongo2.Must(pongo2.FromFile("templates/category.gmi")) - fmt.Println(file, &file) page, err := tpl.Execute(pongo2.Context{"lang": lang, "tree": tree, "path": path, "indexFile": file}) if err != nil { log.Fatalf("template failed: %v", err) @@ -240,29 +242,19 @@ func renderFile(lang string, w gemini.ResponseWriter, r *gemini.Request, client return } - category := "" - for i, cat := range file.File.Category { - category = category + fmt.Sprintf("=> /%s/f/%s .%s└─ %s\n", - lang, - strings.Join(file.File.Category[:i+1], "/"), - strings.Repeat(" ", i), - cat, - ) + w.SetMediaType("text/gemini") + tpl := pongo2.Must(pongo2.FromFile("templates/page.gmi")) + page, err := tpl.Execute(pongo2.Context{"lang": lang, "file": file}) + if err != nil { + log.Fatalf("template failed: %v", err) + return } - content := fmt.Sprintf( - "# %s\n\n"+ - "%s\n\n"+ - "%s\n%s\n\n"+ - "%s\n\n[ %s ]", - file.File.Description, - file.Content, - file.File.Created, - file.File.Copyright, - category, - strings.Join(file.File.Tags, " "), - ) - w.Write([]byte(content)) + _, err = w.Write([]byte(page)) + if err != nil { + w.WriteHeader(gemini.StatusTemporaryFailure, "Internal server error") + return + } } func renderAllFiles(lang string, w gemini.ResponseWriter, client TreeManagerClient) { @@ -274,40 +266,51 @@ func renderAllFiles(lang string, w gemini.ResponseWriter, client TreeManagerClie tree, err := client.GetSummery(context.Background(), &tr) if err != nil { - log.Fatalf("client.GetSummery failed: %v", err) w.WriteHeader(gemini.StatusTemporaryFailure, "Internal server error") return } - content := "# Arnas alkierios :: " - if lang == "sgs" { - content = content + "vėsė tekstā\n\n" - } else { - content = content + "all texts\n\n" + w.SetMediaType("text/gemini") + tpl := pongo2.Must(pongo2.FromFile("templates/all_texts.gmi")) + page, err := tpl.Execute(pongo2.Context{"lang": lang, "tree": tree}) + if err != nil { + log.Fatalf("template failed: %v", err) + return } - for _, f := range tree.Files { - content = appendFileLink(lang, content, f) + _, err = w.Write([]byte(page)) + if err != nil { + w.WriteHeader(gemini.StatusTemporaryFailure, "Internal server error") + return } - - if lang == "sgs" { - content = content + "\n=> /sgs ← grīžtė" - } else { - content = content + "\n=> /en ← back" - } - - w.Write([]byte(content)) } -func appendFileLink(lang string, content string, f *TreeFile) string { - content = content + fmt.Sprintf( - "=> /%s/f/%s/%s/%s %s (%s)\n", - lang, - strings.Join(f.Category, "/"), - f.Id, - strings.Replace(f.Name, ".md", ".gmi", 1), - f.Description, - f.Created, - ) - return content +func renderTag(lang string, w gemini.ResponseWriter, r *gemini.Request, client TreeManagerClient) { + urlParts := strings.Split(strings.Trim(r.URL.Path, "/"), "/") + tag := urlParts[len(urlParts)-1] + tagFilter := TreeRequest_Filter{Key: "tag", Value: tag} + filters := []*TreeRequest_Filter{&tagFilter} + + path := "" + tr := TreeRequest{Path: &path, Filter: filters} + + tree, err := client.GetSummery(context.Background(), &tr) + if err != nil { + w.WriteHeader(gemini.StatusTemporaryFailure, "Internal server error") + return + } + + w.SetMediaType("text/gemini") + tpl := pongo2.Must(pongo2.FromFile("templates/tag.gmi")) + page, err := tpl.Execute(pongo2.Context{"lang": lang, "tree": tree, "tag": tag}) + if err != nil { + log.Fatalf("template failed: %v", err) + return + } + + _, err = w.Write([]byte(page)) + if err != nil { + w.WriteHeader(gemini.StatusTemporaryFailure, "Internal server error") + return + } } diff --git a/templates/all_texts.gmi b/templates/all_texts.gmi new file mode 100644 index 0000000..00193a0 --- /dev/null +++ b/templates/all_texts.gmi @@ -0,0 +1,7 @@ +{% import "macros.tpl" category_url, tag_url, text_url %} +# Arna alkierios :: {% if lang == "sgs" %}Vėsė tekstā{% else %}All texts{% endif %} + +{% for file in tree.Files %}{{ text_url(lang, file) }} +{% endfor %} + +=> {% if lang == "sgs" %}/sgs 🏠 grīžtė{% else %}/en ← back{% endif %} diff --git a/templates/category.gmi b/templates/category.gmi index 761ce5c..1612a29 100644 --- a/templates/category.gmi +++ b/templates/category.gmi @@ -1,10 +1,18 @@ -{% import "macros.tpl" category_url, text_url %} +{% import "macros.tpl" category_url, tag_url, text_url %} # Arna alkierios :: {{ path }} -{% if indexFile %}{{ indexFile.Content }}{% endif %} +{% if indexFile %}{{ indexFile.Content }} -{% for file in tree.RootFiles %}{{ text_url(lang, file) }} {% endfor %} +🌙 {{ indexFile.File.Created}} +{{ indexFile.File.Copyright }}{% endif %} + +{% for file in tree.RootFiles %}{{ text_url(lang, file) }} +{% endfor %} {% if tree.Categories %}### {% if lang == "sgs" %}Kateguorėjės{% else %}Categories{% endif %} -{% for cat, count in tree.Categories %}{{ category_url(lang, cat, cat, count) }} +{% for cat, count in tree.Categories %}{{ category_url(lang, tree.Path|add:"/"|add:cat, cat, count) }} {% endfor %} {% endif %} +{% if tree.Tags %}### {% if lang == "sgs" %}Žīmas{% else %}Tags{% endif %} +{% for tag, count in tree.Tags %}{{ tag_url(lang, tag, count) }} +{% endfor %} {% endif %} +{% if tree.RootPath %}{{ category_url(lang, tree.RootPath, tree.RootPath, 0) }}{% endif %} => {% if lang == "sgs" %}/sgs 🏠 nomėi{% else %}/en 🏠 home{% endif %} diff --git a/templates/macros.tpl b/templates/macros.tpl index fcafb98..4742fc1 100644 --- a/templates/macros.tpl +++ b/templates/macros.tpl @@ -1,5 +1,5 @@ -{% macro category_url(lang, path, category, count) export %}=> /{{ lang }}/f/{{ path }} {{ category }} ({{ count }}) {% endmacro %} +{% macro category_url(lang, path, category, count) export %}=> /{{ lang }}/f/{{ path }} 🌿 {{ category }}{% if count %} ({{ count }}){% endif %} {% endmacro %} -{% macro tag_url(lang, tag, count) export %}=> /{{ lang }}/t/{{ tag }} {{ tag }} ({{ count }}) {% endmacro %} +{% macro tag_url(lang, tag, count) export %}=> /{{ lang }}/t/{{ tag }} 🏷 {{ tag }} ({{ count }}) {% endmacro %} -{% macro text_url(lang, file) export %}=> /{{ lang }}/f/{{ file.CategoriesAsUrl() }}/{{ file.Id }}/{{ file.GmiName() }} {{ file.Description }} ({{ file.Created }}) {% endmacro %} +{% macro text_url(lang, file) export %}=> /{{ lang }}/f/{{ file.CategoriesAsUrl() }}/{{ file.Id }}/{{ file.GmiName() }} ✒ {{ file.Description }} ({{ file.Created }}) {% endmacro %} diff --git a/templates/page.gmi b/templates/page.gmi new file mode 100644 index 0000000..c73a61b --- /dev/null +++ b/templates/page.gmi @@ -0,0 +1,13 @@ +{% import "macros.tpl" category_url, tag_url, text_url %} +# Arna alkierios :: {{ file.File.Description }} + +{{ file.Content }} + +🌙 {{ file.File.Created}} +{{ file.File.Copyright }} + +{% if file.File.Tags %}### {% if lang == "sgs" %}Žīmas{% else %}Tags{% endif %} +{% for tag in file.File.Tags %}{{ tag_url(lang, tag, 0) }} +{% endfor %} {% endif %} +{{ category_url(lang, file.File.CategoryPath, file.File.Category|last, 0) }} +=> {% if lang == "sgs" %}/sgs 🏠 nomėi{% else %}/en 🏠 home{% endif %} diff --git a/templates/tag.gmi b/templates/tag.gmi new file mode 100644 index 0000000..9b4ac92 --- /dev/null +++ b/templates/tag.gmi @@ -0,0 +1,9 @@ +{% import "macros.tpl" category_url, tag_url, text_url %} +# Arna alkierios :: [{{ tag }}] + +{% for file in tree.Files %}{{ text_url(lang, file) }} +{% endfor %} +{% if tree.Tags %}### {% if lang == "sgs" %}Žīmas{% else %}Tags{% endif %} +{% for tag, count in tree.Tags %}{{ tag_url(lang, tag, count) }} +{% endfor %} {% endif %} +=> {% if lang == "sgs" %}/sgs 🏠 nomėi{% else %}/en 🏠 home{% endif %} diff --git a/tree.pb.go b/tree.pb.go index d20e8b9..2e63684 100644 --- a/tree.pb.go +++ b/tree.pb.go @@ -234,6 +234,8 @@ type Tree struct { RootFiles []*TreeFile `protobuf:"bytes,4,rep,name=rootFiles,proto3" json:"rootFiles,omitempty"` Tags map[string]int32 `protobuf:"bytes,2,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` Categories map[string]int32 `protobuf:"bytes,3,rep,name=categories,proto3" json:"categories,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + RootPath string `protobuf:"bytes,6,opt,name=rootPath,proto3" json:"rootPath,omitempty"` } func (x *Tree) Reset() { @@ -296,6 +298,20 @@ func (x *Tree) GetCategories() map[string]int32 { return nil } +func (x *Tree) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *Tree) GetRootPath() string { + if x != nil { + return x.RootPath + } + return "" +} + type FileContent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -434,7 +450,7 @@ var file_tree_proto_rawDesc = []byte{ 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xb8, 0x02, 0x0a, 0x04, 0x54, 0x72, 0x65, 0x65, 0x12, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xe8, 0x02, 0x0a, 0x04, 0x54, 0x72, 0x65, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x46, 0x69, 0x6c, @@ -446,7 +462,10 @@ var file_tree_proto_rawDesc = []byte{ 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x63, - 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, diff --git a/tree.proto b/tree.proto index 9e91889..a79d771 100644 --- a/tree.proto +++ b/tree.proto @@ -42,6 +42,8 @@ message Tree { repeated TreeFile rootFiles = 4; map tags = 2; map categories = 3; + string path = 5; + string rootPath = 6; } message FileContent {