Move a lot of files into internal dir

Outside of it are web and stuff that needs further refactoring
This commit is contained in:
Timur Ismagilov 2024-06-04 23:26:49 +03:00
parent 5522542a7f
commit 4c31c8cc32
93 changed files with 513 additions and 518 deletions

View File

@ -1,5 +1,5 @@
{% import "net/http" %} {% import "net/http" %}
{% import "github.com/bouncepaw/mycorrhiza/cfg" %} {% import "github.com/bouncepaw/mycorrhiza/internal/cfg" %}
{% import "github.com/bouncepaw/mycorrhiza/l18n" %} {% import "github.com/bouncepaw/mycorrhiza/l18n" %}
{% func Register(rq *http.Request) %} {% func Register(rq *http.Request) %}

View File

@ -8,7 +8,7 @@ package auth
import "net/http" import "net/http"
//line auth/auth.qtpl:2 //line auth/auth.qtpl:2
import "github.com/bouncepaw/mycorrhiza/cfg" import "github.com/bouncepaw/mycorrhiza/internal/cfg"
//line auth/auth.qtpl:3 //line auth/auth.qtpl:3
import "github.com/bouncepaw/mycorrhiza/l18n" import "github.com/bouncepaw/mycorrhiza/l18n"

View File

@ -2,13 +2,14 @@ package categories
import ( import (
"encoding/json" "encoding/json"
"github.com/bouncepaw/mycorrhiza/files"
"github.com/bouncepaw/mycorrhiza/util"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"log" "log"
"os" "os"
"sort" "sort"
"sync" "sync"
"github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/util"
) )
var categoryToHyphae = map[string]*categoryNode{} var categoryToHyphae = map[string]*categoryNode{}

View File

@ -1,9 +1,9 @@
package categories package categories
import ( import (
"github.com/bouncepaw/mycorrhiza/user" "github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil" "github.com/bouncepaw/mycorrhiza/web/viewutil"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"io" "io"
"log" "log"

View File

@ -2,7 +2,7 @@ package categories
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/viewutil" viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"log" "log"
"sort" "sort"
"strings" "strings"
@ -31,14 +31,14 @@ const ruTranslation = `
var ( var (
//go:embed *.html //go:embed *.html
fs embed.FS fs embed.FS
viewListChain, viewPageChain, viewCardChain, viewEditChain viewutil.Chain viewListChain, viewPageChain, viewCardChain, viewEditChain viewutil2.Chain
) )
func prepareViews() { func prepareViews() {
viewCardChain = viewutil.CopyEnRuWith(fs, "view_card.html", ruTranslation) viewCardChain = viewutil2.CopyEnRuWith(fs, "view_card.html", ruTranslation)
viewListChain = viewutil.CopyEnRuWith(fs, "view_list.html", ruTranslation) viewListChain = viewutil2.CopyEnRuWith(fs, "view_list.html", ruTranslation)
viewPageChain = viewutil.CopyEnRuWith(fs, "view_page.html", ruTranslation) viewPageChain = viewutil2.CopyEnRuWith(fs, "view_page.html", ruTranslation)
viewEditChain = viewutil.CopyEnRuWith(fs, "view_edit.html", ruTranslation) viewEditChain = viewutil2.CopyEnRuWith(fs, "view_edit.html", ruTranslation)
} }
type cardData struct { type cardData struct {
@ -48,7 +48,7 @@ type cardData struct {
} }
// CategoryCard is the little sidebar that is shown nearby the hypha view. // CategoryCard is the little sidebar that is shown nearby the hypha view.
func CategoryCard(meta viewutil.Meta, hyphaName string) string { func CategoryCard(meta viewutil2.Meta, hyphaName string) string {
var buf strings.Builder var buf strings.Builder
err := viewCardChain.Get(meta).ExecuteTemplate(&buf, "category card", cardData{ err := viewCardChain.Get(meta).ExecuteTemplate(&buf, "category card", cardData{
HyphaName: hyphaName, HyphaName: hyphaName,
@ -62,15 +62,15 @@ func CategoryCard(meta viewutil.Meta, hyphaName string) string {
} }
type catData struct { type catData struct {
*viewutil.BaseData *viewutil2.BaseData
CatName string CatName string
Hyphae []string Hyphae []string
GivenPermissionToModify bool GivenPermissionToModify bool
} }
func categoryEdit(meta viewutil.Meta, catName string) { func categoryEdit(meta viewutil2.Meta, catName string) {
viewutil.ExecutePage(meta, viewEditChain, catData{ viewutil2.ExecutePage(meta, viewEditChain, catData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/edit-category/" + catName, Addr: "/edit-category/" + catName,
}, },
CatName: catName, CatName: catName,
@ -79,9 +79,9 @@ func categoryEdit(meta viewutil.Meta, catName string) {
}) })
} }
func categoryPage(meta viewutil.Meta, catName string) { func categoryPage(meta viewutil2.Meta, catName string) {
viewutil.ExecutePage(meta, viewPageChain, catData{ viewutil2.ExecutePage(meta, viewPageChain, catData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/category/" + catName, Addr: "/category/" + catName,
}, },
CatName: catName, CatName: catName,
@ -91,15 +91,15 @@ func categoryPage(meta viewutil.Meta, catName string) {
} }
type listData struct { type listData struct {
*viewutil.BaseData *viewutil2.BaseData
Categories []string Categories []string
} }
func categoryList(meta viewutil.Meta) { func categoryList(meta viewutil2.Meta) {
cats := listOfCategories() cats := listOfCategories()
sort.Strings(cats) sort.Strings(cats)
viewutil.ExecutePage(meta, viewListChain, listData{ viewutil2.ExecutePage(meta, viewListChain, listData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/category", Addr: "/category",
}, },
Categories: cats, Categories: cats,

14
flag.go
View File

@ -12,17 +12,17 @@ import (
"golang.org/x/term" "golang.org/x/term"
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/files" "github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/user" user2 "github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/version" "github.com/bouncepaw/mycorrhiza/internal/version"
) )
// CLI options are read and parsed here. // CLI options are read and parsed here.
// printHelp prints the help message. // printHelp prints the help message.
func printHelp() { func printHelp() {
fmt.Fprintf( _, _ = fmt.Fprintf(
flag.CommandLine.Output(), flag.CommandLine.Output(),
"Usage: %s WIKI_PATH\n", "Usage: %s WIKI_PATH\n",
os.Args[0], os.Args[0],
@ -70,13 +70,13 @@ func createAdminCommand(name string) {
} }
cfg.UseAuth = true cfg.UseAuth = true
cfg.AllowRegistration = true cfg.AllowRegistration = true
user.InitUserDatabase() user2.InitUserDatabase()
password, err := askPass("Password") password, err := askPass("Password")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if err := user.Register(name, password, "admin", "local", true); err != nil { if err := user2.Register(name, password, "admin", "local", true); err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }

View File

@ -4,7 +4,7 @@ package help
import ( import (
"git.sr.ht/~bouncepaw/mycomarkup/v5" "git.sr.ht/~bouncepaw/mycomarkup/v5"
"github.com/bouncepaw/mycorrhiza/mycoopts" "github.com/bouncepaw/mycorrhiza/mycoopts"
"github.com/bouncepaw/mycorrhiza/viewutil" viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"io" "io"
"net/http" "net/http"
@ -14,7 +14,7 @@ import (
) )
var ( var (
chain viewutil.Chain chain viewutil2.Chain
ruTranslation = ` ruTranslation = `
{{define "title"}}Справка{{end}} {{define "title"}}Справка{{end}}
{{define "entry not found"}}Статья не найдена{{end}} {{define "entry not found"}}Статья не найдена{{end}}
@ -46,14 +46,14 @@ var (
func InitHandlers(r *mux.Router) { func InitHandlers(r *mux.Router) {
r.PathPrefix("/help").HandlerFunc(handlerHelp) r.PathPrefix("/help").HandlerFunc(handlerHelp)
chain = viewutil.CopyEnRuWith(fs, "view_help.html", ruTranslation) chain = viewutil2.CopyEnRuWith(fs, "view_help.html", ruTranslation)
} }
// handlerHelp gets the appropriate documentation or tells you where you (personally) have failed. // handlerHelp gets the appropriate documentation or tells you where you (personally) have failed.
func handlerHelp(w http.ResponseWriter, rq *http.Request) { func handlerHelp(w http.ResponseWriter, rq *http.Request) {
// See the history of this file to resurrect the old algorithm that supported multiple languages // See the history of this file to resurrect the old algorithm that supported multiple languages
var ( var (
meta = viewutil.MetaFrom(w, rq) meta = viewutil2.MetaFrom(w, rq)
articlePath = strings.TrimPrefix(strings.TrimPrefix(rq.URL.Path, "/help/"), "/help") articlePath = strings.TrimPrefix(strings.TrimPrefix(rq.URL.Path, "/help/"), "/help")
lang = "en" lang = "en"
) )
@ -88,14 +88,14 @@ func handlerHelp(w http.ResponseWriter, rq *http.Request) {
} }
type helpData struct { type helpData struct {
*viewutil.BaseData *viewutil2.BaseData
ContentsHTML string ContentsHTML string
Lang string Lang string
} }
func viewHelp(meta viewutil.Meta, lang, contentsHTML, articlePath string) { func viewHelp(meta viewutil2.Meta, lang, contentsHTML, articlePath string) {
viewutil.ExecutePage(meta, chain, helpData{ viewutil2.ExecutePage(meta, chain, helpData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/help/" + articlePath, Addr: "/help/" + articlePath,
}, },
ContentsHTML: contentsHTML, ContentsHTML: contentsHTML,

View File

@ -3,12 +3,11 @@ package history
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
"net/url" "net/url"
"strings" "strings"
"time" "time"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/gorilla/feeds" "github.com/gorilla/feeds"
) )

View File

@ -9,7 +9,7 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"github.com/bouncepaw/mycorrhiza/files" "github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )

View File

@ -4,12 +4,12 @@ package histweb
import ( import (
"embed" "embed"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/files"
"github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/internal/files"
hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil" viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"html/template" "html/template"
"log" "log"
@ -30,9 +30,9 @@ func InitHandlers(rtr *mux.Router) {
rtr.HandleFunc("/recent-changes-atom", handlerRecentChangesAtom) rtr.HandleFunc("/recent-changes-atom", handlerRecentChangesAtom)
rtr.HandleFunc("/recent-changes-json", handlerRecentChangesJSON) rtr.HandleFunc("/recent-changes-json", handlerRecentChangesJSON)
chainPrimitiveDiff = viewutil.CopyEnRuWith(fs, "view_primitive_diff.html", ruTranslation) chainPrimitiveDiff = viewutil2.CopyEnRuWith(fs, "view_primitive_diff.html", ruTranslation)
chainRecentChanges = viewutil.CopyEnRuWith(fs, "view_recent_changes.html", ruTranslation) chainRecentChanges = viewutil2.CopyEnRuWith(fs, "view_recent_changes.html", ruTranslation)
chainHistory = viewutil.CopyEnRuWith(fs, "view_history.html", ruTranslation) chainHistory = viewutil2.CopyEnRuWith(fs, "view_history.html", ruTranslation)
} }
func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) { func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) {
@ -45,12 +45,12 @@ func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) {
} }
var ( var (
mycoFilePath string mycoFilePath string
h = hyphae.ByName(util.CanonicalName(slug)) h = hyphae2.ByName(util.CanonicalName(slug))
) )
switch h := h.(type) { switch h := h.(type) {
case hyphae.ExistingHypha: case hyphae2.ExistingHypha:
mycoFilePath = h.TextFilePath() mycoFilePath = h.TextFilePath()
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
mycoFilePath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco") mycoFilePath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco")
} }
text, err := history.PrimitiveDiffAtRevision(mycoFilePath, revHash) text, err := history.PrimitiveDiffAtRevision(mycoFilePath, revHash)
@ -58,7 +58,7 @@ func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
primitiveDiff(viewutil.MetaFrom(w, rq), h, revHash, text) primitiveDiff(viewutil2.MetaFrom(w, rq), h, revHash, text)
} }
// handlerRecentChanges displays the /recent-changes/ page. // handlerRecentChanges displays the /recent-changes/ page.
@ -68,7 +68,7 @@ func handlerRecentChanges(w http.ResponseWriter, rq *http.Request) {
if editCount > 100 { if editCount > 100 {
return return
} }
recentChanges(viewutil.MetaFrom(w, rq), editCount, history.RecentChanges(editCount)) recentChanges(viewutil2.MetaFrom(w, rq), editCount, history.RecentChanges(editCount))
} }
// handlerHistory lists all revisions of a hypha. // handlerHistory lists all revisions of a hypha.
@ -83,7 +83,7 @@ func handlerHistory(w http.ResponseWriter, rq *http.Request) {
} }
log.Println("Found", len(revs), "revisions for", hyphaName) log.Println("Found", len(revs), "revisions for", hyphaName)
historyView(viewutil.MetaFrom(w, rq), hyphaName, list) historyView(viewutil2.MetaFrom(w, rq), hyphaName, list)
} }
// genericHandlerOfFeeds is a helper function for the web feed handlers. // genericHandlerOfFeeds is a helper function for the web feed handlers.
@ -135,20 +135,20 @@ var (
{{define "n recent changes"}}{{.}} свеж{{if eq . 1}}ая правка{{else if le . 4}}их правок{{else}}их правок{{end}}{{end}} {{define "n recent changes"}}{{.}} свеж{{if eq . 1}}ая правка{{else if le . 4}}их правок{{else}}их правок{{end}}{{end}}
{{define "recent empty"}}Правки не найдены.{{end}} {{define "recent empty"}}Правки не найдены.{{end}}
` `
chainPrimitiveDiff, chainRecentChanges, chainHistory viewutil.Chain chainPrimitiveDiff, chainRecentChanges, chainHistory viewutil2.Chain
) )
type recentChangesData struct { type recentChangesData struct {
*viewutil.BaseData *viewutil2.BaseData
EditCount int EditCount int
Changes []history.Revision Changes []history.Revision
UserHypha string UserHypha string
Stops []int Stops []int
} }
func recentChanges(meta viewutil.Meta, editCount int, changes []history.Revision) { func recentChanges(meta viewutil2.Meta, editCount int, changes []history.Revision) {
viewutil.ExecutePage(meta, chainRecentChanges, recentChangesData{ viewutil2.ExecutePage(meta, chainRecentChanges, recentChangesData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
EditCount: editCount, EditCount: editCount,
Changes: changes, Changes: changes,
UserHypha: cfg.UserHypha, UserHypha: cfg.UserHypha,
@ -157,13 +157,13 @@ func recentChanges(meta viewutil.Meta, editCount int, changes []history.Revision
} }
type primitiveDiffData struct { type primitiveDiffData struct {
*viewutil.BaseData *viewutil2.BaseData
HyphaName string HyphaName string
Hash string Hash string
Text template.HTML Text template.HTML
} }
func primitiveDiff(meta viewutil.Meta, h hyphae.Hypha, hash, text string) { func primitiveDiff(meta viewutil2.Meta, h hyphae2.Hypha, hash, text string) {
hunks := history.SplitPrimitiveDiff(text) hunks := history.SplitPrimitiveDiff(text)
if len(hunks) > 0 { if len(hunks) > 0 {
var buf strings.Builder var buf strings.Builder
@ -198,8 +198,8 @@ func primitiveDiff(meta viewutil.Meta, h hyphae.Hypha, hash, text string) {
text = fmt.Sprintf( text = fmt.Sprintf(
`<pre class="codeblock"><code>%s</code></pre>`, text) `<pre class="codeblock"><code>%s</code></pre>`, text)
} }
viewutil.ExecutePage(meta, chainPrimitiveDiff, primitiveDiffData{ viewutil2.ExecutePage(meta, chainPrimitiveDiff, primitiveDiffData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
HyphaName: h.CanonicalName(), HyphaName: h.CanonicalName(),
Hash: hash, Hash: hash,
Text: template.HTML(text), Text: template.HTML(text),
@ -207,14 +207,14 @@ func primitiveDiff(meta viewutil.Meta, h hyphae.Hypha, hash, text string) {
} }
type historyData struct { type historyData struct {
*viewutil.BaseData *viewutil2.BaseData
HyphaName string HyphaName string
Contents string Contents string
} }
func historyView(meta viewutil.Meta, hyphaName, contents string) { func historyView(meta viewutil2.Meta, hyphaName, contents string) {
viewutil.ExecutePage(meta, chainHistory, historyData{ viewutil2.ExecutePage(meta, chainHistory, historyData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/history/" + util.CanonicalName(hyphaName), Addr: "/history/" + util.CanonicalName(hyphaName),
}, },
HyphaName: hyphaName, HyphaName: hyphaName,

View File

@ -64,7 +64,7 @@
</p> </p>
<p> <p>
<img class="icon" width="20" height="20" src="/static/icon/feed.svg" aria-hidden="true" alt="RSS icon"> <img class="icon" width="20" height="20" src="/web/static/icon/feed.svg" aria-hidden="true" alt="RSS icon">
{{block "subscribe via" .}}Subscribe via <a href="/recent-changes-rss">RSS</a>, <a href="/recent-changes-atom">Atom</a> or <a href="/recent-changes-json">JSON feed</a>.{{end}} {{block "subscribe via" .}}Subscribe via <a href="/recent-changes-rss">RSS</a>, <a href="/recent-changes-atom">Atom</a> or <a href="/recent-changes-json">JSON feed</a>.{{end}}
</p> </p>
</main> </main>

View File

@ -4,11 +4,11 @@ package history
// Things related to writing history. // Things related to writing history.
import ( import (
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/internal/user"
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )

View File

@ -8,7 +8,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/bouncepaw/mycorrhiza/files" "github.com/bouncepaw/mycorrhiza/internal/files"
) )
// Revision represents a revision, duh. Hash is usually short. Username is extracted from email. // Revision represents a revision, duh. Hash is usually short. Username is extracted from email.

View File

@ -1,5 +1,5 @@
{% import "fmt" %} {% import "fmt" %}
{% import "github.com/bouncepaw/mycorrhiza/cfg" %} {% import "github.com/bouncepaw/mycorrhiza/internal/cfg" %}
HyphaeLinksHTML returns a comma-separated list of hyphae that were affected by this revision as HTML string. HyphaeLinksHTML returns a comma-separated list of hyphae that were affected by this revision as HTML string.
{% func (rev Revision) HyphaeLinksHTML() %} {% func (rev Revision) HyphaeLinksHTML() %}

View File

@ -8,7 +8,7 @@ package history
import "fmt" import "fmt"
//line history/view.qtpl:2 //line history/view.qtpl:2
import "github.com/bouncepaw/mycorrhiza/cfg" import "github.com/bouncepaw/mycorrhiza/internal/cfg"
// HyphaeLinksHTML returns a comma-separated list of hyphae that were affected by this revision as HTML string. // HyphaeLinksHTML returns a comma-separated list of hyphae that were affected by this revision as HTML string.

View File

@ -1,14 +1,13 @@
package main package main
import ( import (
"github.com/bouncepaw/mycorrhiza/internal/cfg"
"log" "log"
"net" "net"
"net/http" "net/http"
"os" "os"
"strings" "strings"
"time" "time"
"github.com/bouncepaw/mycorrhiza/cfg"
) )
func serveHTTP(handler http.Handler) { func serveHTTP(handler http.Handler) {

View File

@ -2,13 +2,12 @@ package hypview
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/backlinks" "github.com/bouncepaw/mycorrhiza/internal/backlinks"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"html/template" "html/template"
"log" "log"
"strings" "strings"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/viewutil"
) )
var ( var (
@ -77,25 +76,25 @@ var (
{{define "remove media from [[x]]?"}}Убрать медиа у <a href="/hypha/{{.MatchedHyphaName}}">{{beautifulName .MatchedHyphaName}}</a>?{{end}} {{define "remove media from [[x]]?"}}Убрать медиа у <a href="/hypha/{{.MatchedHyphaName}}">{{beautifulName .MatchedHyphaName}}</a>?{{end}}
{{define "remove media for real?"}}Вы точно хотите убрать медиа у гифы «{{beautifulName .MatchedHyphaName}}»?{{end}} {{define "remove media for real?"}}Вы точно хотите убрать медиа у гифы «{{beautifulName .MatchedHyphaName}}»?{{end}}
` `
chainNaviTitle viewutil.Chain chainNaviTitle viewutil2.Chain
chainEditHypha viewutil.Chain chainEditHypha viewutil2.Chain
chainEmptyHypha viewutil.Chain chainEmptyHypha viewutil2.Chain
chainDeleteHypha viewutil.Chain chainDeleteHypha viewutil2.Chain
chainRenameHypha viewutil.Chain chainRenameHypha viewutil2.Chain
chainRemoveMedia viewutil.Chain chainRemoveMedia viewutil2.Chain
) )
func Init() { func Init() {
chainNaviTitle = viewutil.CopyEnRuWith(fs, "view_navititle.html", "") chainNaviTitle = viewutil2.CopyEnRuWith(fs, "view_navititle.html", "")
chainEditHypha = viewutil.CopyEnRuWith(fs, "view_edit.html", ruTranslation) chainEditHypha = viewutil2.CopyEnRuWith(fs, "view_edit.html", ruTranslation)
chainEmptyHypha = viewutil.CopyEnRuWith(fs, "view_empty_hypha.html", ruTranslation) chainEmptyHypha = viewutil2.CopyEnRuWith(fs, "view_empty_hypha.html", ruTranslation)
chainDeleteHypha = viewutil.CopyEnRuWith(fs, "view_delete.html", ruTranslation) chainDeleteHypha = viewutil2.CopyEnRuWith(fs, "view_delete.html", ruTranslation)
chainRenameHypha = viewutil.CopyEnRuWith(fs, "view_rename.html", ruTranslation) chainRenameHypha = viewutil2.CopyEnRuWith(fs, "view_rename.html", ruTranslation)
chainRemoveMedia = viewutil.CopyEnRuWith(fs, "view_remove_media.html", ruTranslation) chainRemoveMedia = viewutil2.CopyEnRuWith(fs, "view_remove_media.html", ruTranslation)
} }
type editData struct { type editData struct {
*viewutil.BaseData *viewutil2.BaseData
HyphaName string HyphaName string
IsNew bool IsNew bool
Content string Content string
@ -103,9 +102,9 @@ type editData struct {
Preview template.HTML Preview template.HTML
} }
func EditHypha(meta viewutil.Meta, hyphaName string, isNew bool, content string, message string, preview template.HTML) { func EditHypha(meta viewutil2.Meta, hyphaName string, isNew bool, content string, message string, preview template.HTML) {
viewutil.ExecutePage(meta, chainEditHypha, editData{ viewutil2.ExecutePage(meta, chainEditHypha, editData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/edit/" + hyphaName, Addr: "/edit/" + hyphaName,
EditScripts: cfg.EditScripts, EditScripts: cfg.EditScripts,
}, },
@ -118,14 +117,14 @@ func EditHypha(meta viewutil.Meta, hyphaName string, isNew bool, content string,
} }
type renameData struct { type renameData struct {
*viewutil.BaseData *viewutil2.BaseData
HyphaName string HyphaName string
LeaveRedirectionDefault bool LeaveRedirectionDefault bool
} }
func RenameHypha(meta viewutil.Meta, hyphaName string) { func RenameHypha(meta viewutil2.Meta, hyphaName string) {
viewutil.ExecutePage(meta, chainRenameHypha, renameData{ viewutil2.ExecutePage(meta, chainRenameHypha, renameData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/rename/" + hyphaName, Addr: "/rename/" + hyphaName,
}, },
HyphaName: hyphaName, HyphaName: hyphaName,
@ -134,22 +133,22 @@ func RenameHypha(meta viewutil.Meta, hyphaName string) {
} }
type deleteRemoveMediaData struct { type deleteRemoveMediaData struct {
*viewutil.BaseData *viewutil2.BaseData
HyphaName string HyphaName string
} }
func DeleteHypha(meta viewutil.Meta, hyphaName string) { func DeleteHypha(meta viewutil2.Meta, hyphaName string) {
viewutil.ExecutePage(meta, chainDeleteHypha, deleteRemoveMediaData{ viewutil2.ExecutePage(meta, chainDeleteHypha, deleteRemoveMediaData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/delete/" + hyphaName, Addr: "/delete/" + hyphaName,
}, },
HyphaName: hyphaName, HyphaName: hyphaName,
}) })
} }
func RemoveMedia(meta viewutil.Meta, hyphaName string) { func RemoveMedia(meta viewutil2.Meta, hyphaName string) {
viewutil.ExecutePage(meta, chainRemoveMedia, deleteRemoveMediaData{ viewutil2.ExecutePage(meta, chainRemoveMedia, deleteRemoveMediaData{
BaseData: &viewutil.BaseData{ BaseData: &viewutil2.BaseData{
Addr: "/remove-media/" + hyphaName, Addr: "/remove-media/" + hyphaName,
}, },
HyphaName: hyphaName, HyphaName: hyphaName,
@ -157,13 +156,13 @@ func RemoveMedia(meta viewutil.Meta, hyphaName string) {
} }
type emptyHyphaData struct { type emptyHyphaData struct {
Meta viewutil.Meta Meta viewutil2.Meta
HyphaName string HyphaName string
AllowRegistration bool AllowRegistration bool
UseAuth bool UseAuth bool
} }
func EmptyHypha(meta viewutil.Meta, hyphaName string) string { func EmptyHypha(meta viewutil2.Meta, hyphaName string) string {
var buf strings.Builder var buf strings.Builder
if err := chainEmptyHypha.Get(meta).ExecuteTemplate(&buf, "empty hypha card", emptyHyphaData{ if err := chainEmptyHypha.Get(meta).ExecuteTemplate(&buf, "empty hypha card", emptyHyphaData{
Meta: meta, Meta: meta,
@ -183,7 +182,7 @@ type naviTitleData struct {
HomeHypha string HomeHypha string
} }
func NaviTitle(meta viewutil.Meta, hyphaName string) string { func NaviTitle(meta viewutil2.Meta, hyphaName string) string {
parts, partsWithParents := naviTitleify(hyphaName) parts, partsWithParents := naviTitleify(hyphaName)
var buf strings.Builder var buf strings.Builder
err := chainNaviTitle.Get(meta).ExecuteTemplate(&buf, "navititle", naviTitleData{ err := chainNaviTitle.Get(meta).ExecuteTemplate(&buf, "navititle", naviTitleData{

View File

@ -1,9 +1,9 @@
{% import "github.com/bouncepaw/mycorrhiza/backlinks" %} {% import "github.com/bouncepaw/mycorrhiza/internal/backlinks" %}
{% import "github.com/bouncepaw/mycorrhiza/cfg" %} {% import "github.com/bouncepaw/mycorrhiza/internal/cfg" %}
{% import "github.com/bouncepaw/mycorrhiza/hyphae" %} {% import "github.com/bouncepaw/mycorrhiza/internal/hyphae" %}
{% import "github.com/bouncepaw/mycorrhiza/user" %} {% import "github.com/bouncepaw/mycorrhiza/internal/user" %}
{% import "github.com/bouncepaw/mycorrhiza/util" %} {% import "github.com/bouncepaw/mycorrhiza/util" %}
{% import "github.com/bouncepaw/mycorrhiza/viewutil" %} {% import "github.com/bouncepaw/mycorrhiza/web/viewutil" %}
{% func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action string, hasToExist bool, displayText string) %} {% func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action string, hasToExist bool, displayText string) %}
{% code flag := true %} {% code flag := true %}

View File

@ -5,22 +5,22 @@
package hypview package hypview
//line hypview/nav.qtpl:1 //line hypview/nav.qtpl:1
import "github.com/bouncepaw/mycorrhiza/backlinks" import "github.com/bouncepaw/mycorrhiza/internal/backlinks"
//line hypview/nav.qtpl:2 //line hypview/nav.qtpl:2
import "github.com/bouncepaw/mycorrhiza/cfg" import "github.com/bouncepaw/mycorrhiza/internal/cfg"
//line hypview/nav.qtpl:3 //line hypview/nav.qtpl:3
import "github.com/bouncepaw/mycorrhiza/hyphae" import "github.com/bouncepaw/mycorrhiza/internal/hyphae"
//line hypview/nav.qtpl:4 //line hypview/nav.qtpl:4
import "github.com/bouncepaw/mycorrhiza/user" import "github.com/bouncepaw/mycorrhiza/internal/user"
//line hypview/nav.qtpl:5 //line hypview/nav.qtpl:5
import "github.com/bouncepaw/mycorrhiza/util" import "github.com/bouncepaw/mycorrhiza/util"
//line hypview/nav.qtpl:6 //line hypview/nav.qtpl:6
import "github.com/bouncepaw/mycorrhiza/viewutil" import "github.com/bouncepaw/mycorrhiza/web/viewutil"
//line hypview/nav.qtpl:8 //line hypview/nav.qtpl:8
import ( import (

View File

@ -3,15 +3,15 @@
{% import "path" %} {% import "path" %}
{% import "os" %} {% import "os" %}
{% import "github.com/bouncepaw/mycorrhiza/cfg" %} {% import "github.com/bouncepaw/mycorrhiza/internal/cfg" %}
{% import "github.com/bouncepaw/mycorrhiza/hyphae" %} {% import "github.com/bouncepaw/mycorrhiza/internal/hyphae" %}
{% import "github.com/bouncepaw/mycorrhiza/categories" %} {% import "github.com/bouncepaw/mycorrhiza/categories" %}
{% import "github.com/bouncepaw/mycorrhiza/l18n" %} {% import "github.com/bouncepaw/mycorrhiza/l18n" %}
{% import "github.com/bouncepaw/mycorrhiza/mimetype" %} {% import "github.com/bouncepaw/mycorrhiza/internal/mimetype" %}
{% import "github.com/bouncepaw/mycorrhiza/tree" %} {% import "github.com/bouncepaw/mycorrhiza/tree" %}
{% import "github.com/bouncepaw/mycorrhiza/user" %} {% import "github.com/bouncepaw/mycorrhiza/internal/user" %}
{% import "github.com/bouncepaw/mycorrhiza/util" %} {% import "github.com/bouncepaw/mycorrhiza/util" %}
{% import "github.com/bouncepaw/mycorrhiza/viewutil" %} {% import "github.com/bouncepaw/mycorrhiza/web/viewutil" %}
{% func MediaMenu(rq *http.Request, h hyphae.Hypha, u *user.User) %} {% func MediaMenu(rq *http.Request, h hyphae.Hypha, u *user.User) %}
{% code {% code

View File

@ -17,10 +17,10 @@ import "path"
import "os" import "os"
//line hypview/readers.qtpl:6 //line hypview/readers.qtpl:6
import "github.com/bouncepaw/mycorrhiza/cfg" import "github.com/bouncepaw/mycorrhiza/internal/cfg"
//line hypview/readers.qtpl:7 //line hypview/readers.qtpl:7
import "github.com/bouncepaw/mycorrhiza/hyphae" import "github.com/bouncepaw/mycorrhiza/internal/hyphae"
//line hypview/readers.qtpl:8 //line hypview/readers.qtpl:8
import "github.com/bouncepaw/mycorrhiza/categories" import "github.com/bouncepaw/mycorrhiza/categories"
@ -29,19 +29,19 @@ import "github.com/bouncepaw/mycorrhiza/categories"
import "github.com/bouncepaw/mycorrhiza/l18n" import "github.com/bouncepaw/mycorrhiza/l18n"
//line hypview/readers.qtpl:10 //line hypview/readers.qtpl:10
import "github.com/bouncepaw/mycorrhiza/mimetype" import "github.com/bouncepaw/mycorrhiza/internal/mimetype"
//line hypview/readers.qtpl:11 //line hypview/readers.qtpl:11
import "github.com/bouncepaw/mycorrhiza/tree" import "github.com/bouncepaw/mycorrhiza/tree"
//line hypview/readers.qtpl:12 //line hypview/readers.qtpl:12
import "github.com/bouncepaw/mycorrhiza/user" import "github.com/bouncepaw/mycorrhiza/internal/user"
//line hypview/readers.qtpl:13 //line hypview/readers.qtpl:13
import "github.com/bouncepaw/mycorrhiza/util" import "github.com/bouncepaw/mycorrhiza/util"
//line hypview/readers.qtpl:14 //line hypview/readers.qtpl:14
import "github.com/bouncepaw/mycorrhiza/viewutil" import "github.com/bouncepaw/mycorrhiza/web/viewutil"
//line hypview/readers.qtpl:16 //line hypview/readers.qtpl:16
import ( import (

View File

@ -39,7 +39,7 @@
{{end}} {{end}}
</section> </section>
</aside> </aside>
<script src="/static/toolbar.js"></script> <script src="/web/static/toolbar.js"></script>
{{end}} {{end}}
{{define "editing hypha"}}Edit {{beautifulName .}}{{end}} {{define "editing hypha"}}Edit {{beautifulName .}}{{end}}
@ -98,7 +98,7 @@
{{end}} {{end}}
</main> </main>
{{template "toolbar" .}} {{template "toolbar" .}}
<script src="/static/editor.js"></script> <script src="/web/static/editor.js"></script>
{{range .EditScripts}} {{range .EditScripts}}
<script src="{{.}}"></script> <script src="{{.}}"></script>
{{end}} {{end}}

View File

@ -2,11 +2,11 @@
package backlinks package backlinks
import ( import (
hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"log" "log"
"os" "os"
"sort" "sort"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )
@ -14,7 +14,7 @@ import (
func yieldHyphaBacklinks(hyphaName string) <-chan string { func yieldHyphaBacklinks(hyphaName string) <-chan string {
hyphaName = util.CanonicalName(hyphaName) hyphaName = util.CanonicalName(hyphaName)
out := make(chan string) out := make(chan string)
sorted := hyphae.PathographicSort(out) sorted := hyphae2.PathographicSort(out)
go func() { go func() {
backlinks, exists := backlinkIndex[hyphaName] backlinks, exists := backlinkIndex[hyphaName]
if exists { if exists {
@ -43,7 +43,7 @@ var backlinkIndex = make(map[string]linkSet)
// IndexBacklinks traverses all text hyphae, extracts links from them and forms an initial index. Call it when indexing and reindexing hyphae. // IndexBacklinks traverses all text hyphae, extracts links from them and forms an initial index. Call it when indexing and reindexing hyphae.
func IndexBacklinks() { func IndexBacklinks() {
// It is safe to ignore the mutex, because there is only one worker. // It is safe to ignore the mutex, because there is only one worker.
for h := range hyphae.FilterHyphaeWithText(hyphae.YieldExistingHyphae()) { for h := range hyphae2.FilterHyphaeWithText(hyphae2.YieldExistingHyphae()) {
foundLinks := extractHyphaLinksFromContent(h.CanonicalName(), fetchText(h)) foundLinks := extractHyphaLinksFromContent(h.CanonicalName(), fetchText(h))
for _, link := range foundLinks { for _, link := range foundLinks {
if _, exists := backlinkIndex[link]; !exists { if _, exists := backlinkIndex[link]; !exists {
@ -72,7 +72,7 @@ func BacklinksFor(hyphaName string) []string {
func Orphans() []string { func Orphans() []string {
var orphans []string var orphans []string
for h := range hyphae.YieldExistingHyphae() { for h := range hyphae2.YieldExistingHyphae() {
if BacklinksCount(h.CanonicalName()) == 0 { if BacklinksCount(h.CanonicalName()) == 0 {
orphans = append(orphans, h.CanonicalName()) orphans = append(orphans, h.CanonicalName())
} }
@ -92,14 +92,14 @@ func toLinkSet(xs []string) linkSet {
return result return result
} }
func fetchText(h hyphae.Hypha) string { func fetchText(h hyphae2.Hypha) string {
var path string var path string
switch h := h.(type) { switch h := h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
return "" return ""
case *hyphae.TextualHypha: case *hyphae2.TextualHypha:
path = h.TextFilePath() path = h.TextFilePath()
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
if !h.HasTextFile() { if !h.HasTextFile() {
return "" return ""
} }

View File

@ -5,7 +5,7 @@ import (
"git.sr.ht/~bouncepaw/mycomarkup/v5/links" "git.sr.ht/~bouncepaw/mycomarkup/v5/links"
"git.sr.ht/~bouncepaw/mycomarkup/v5/mycocontext" "git.sr.ht/~bouncepaw/mycomarkup/v5/mycocontext"
"git.sr.ht/~bouncepaw/mycomarkup/v5/tools" "git.sr.ht/~bouncepaw/mycomarkup/v5/tools"
"github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/mycoopts" "github.com/bouncepaw/mycorrhiza/mycoopts"
) )

View File

@ -2,12 +2,11 @@
package files package files
import ( import (
"github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/web/static"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/static"
) )
var paths struct { var paths struct {

View File

@ -1,11 +1,10 @@
package hyphae package hyphae
import ( import (
"github.com/bouncepaw/mycorrhiza/internal/mimetype"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"github.com/bouncepaw/mycorrhiza/mimetype"
) )
// Index finds all hypha files in the full `path` and saves them to the hypha storage. // Index finds all hypha files in the full `path` and saves them to the hypha storage.

View File

@ -1,9 +1,10 @@
package hyphae package hyphae
import ( import (
"github.com/bouncepaw/mycorrhiza/files"
"path/filepath" "path/filepath"
"sync" "sync"
"github.com/bouncepaw/mycorrhiza/internal/files"
) )
type MediaHypha struct { type MediaHypha struct {

View File

@ -2,7 +2,7 @@ package migration
import ( import (
"git.sr.ht/~bouncepaw/mycomarkup/v5/tools" "git.sr.ht/~bouncepaw/mycomarkup/v5/tools"
"github.com/bouncepaw/mycorrhiza/files" "github.com/bouncepaw/mycorrhiza/internal/files"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"

View File

@ -8,13 +8,14 @@
package migration package migration
import ( import (
"github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/user"
"io" "io"
"log" "log"
"os" "os"
"strings" "strings"
"github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/internal/hyphae"
) )
func genericLineMigrator( func genericLineMigrator(

View File

@ -2,7 +2,7 @@ package migration
import ( import (
"git.sr.ht/~bouncepaw/mycomarkup/v5/tools" "git.sr.ht/~bouncepaw/mycomarkup/v5/tools"
"github.com/bouncepaw/mycorrhiza/files" "github.com/bouncepaw/mycorrhiza/internal/files"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"

View File

@ -2,23 +2,23 @@ package shroom
import ( import (
"errors" "errors"
hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/l18n" "github.com/bouncepaw/mycorrhiza/l18n"
"github.com/bouncepaw/mycorrhiza/user"
) )
// TODO: get rid of this abomination // TODO: get rid of this abomination
func canFactory( func canFactory(
rejectLogger func(hyphae.Hypha, *user.User, string), rejectLogger func(hyphae2.Hypha, *user.User, string),
action string, action string,
dispatcher func(hyphae.Hypha, *user.User, *l18n.Localizer) (string, string), dispatcher func(hyphae2.Hypha, *user.User, *l18n.Localizer) (string, string),
noRightsMsg string, noRightsMsg string,
notExistsMsg string, notExistsMsg string,
mustExist bool, mustExist bool,
) func(*user.User, hyphae.Hypha, *l18n.Localizer) error { ) func(*user.User, hyphae2.Hypha, *l18n.Localizer) error {
return func(u *user.User, h hyphae.Hypha, lc *l18n.Localizer) error { return func(u *user.User, h hyphae2.Hypha, lc *l18n.Localizer) error {
if !u.CanProceed(action) { if !u.CanProceed(action) {
rejectLogger(h, u, "no rights") rejectLogger(h, u, "no rights")
return errors.New(noRightsMsg) return errors.New(noRightsMsg)
@ -26,7 +26,7 @@ func canFactory(
if mustExist { if mustExist {
switch h.(type) { switch h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
rejectLogger(h, u, "does not exist") rejectLogger(h, u, "does not exist")
return errors.New(notExistsMsg) return errors.New(notExistsMsg)
} }

View File

@ -2,29 +2,29 @@ package shroom
import ( import (
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/backlinks"
"github.com/bouncepaw/mycorrhiza/categories" "github.com/bouncepaw/mycorrhiza/categories"
"github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/internal/backlinks"
"github.com/bouncepaw/mycorrhiza/user" hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/internal/user"
) )
// Delete deletes the hypha and makes a history record about that. // Delete deletes the hypha and makes a history record about that.
func Delete(u *user.User, h hyphae.ExistingHypha) error { func Delete(u *user.User, h hyphae2.ExistingHypha) error {
hop := history. hop := history.
Operation(history.TypeDeleteHypha). Operation(history.TypeDeleteHypha).
WithMsg(fmt.Sprintf("Delete %s", h.CanonicalName())). WithMsg(fmt.Sprintf("Delete %s", h.CanonicalName())).
WithUser(u) WithUser(u)
originalText, _ := hyphae.FetchMycomarkupFile(h) originalText, _ := hyphae2.FetchMycomarkupFile(h)
switch h := h.(type) { switch h := h.(type) {
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
if h.HasTextFile() { if h.HasTextFile() {
hop.WithFilesRemoved(h.MediaFilePath(), h.TextFilePath()) hop.WithFilesRemoved(h.MediaFilePath(), h.TextFilePath())
} else { } else {
hop.WithFilesRemoved(h.MediaFilePath()) hop.WithFilesRemoved(h.MediaFilePath())
} }
case *hyphae.TextualHypha: case *hyphae2.TextualHypha:
hop.WithFilesRemoved(h.TextFilePath()) hop.WithFilesRemoved(h.TextFilePath())
} }
if hop.Apply().HasErrors() { if hop.Apply().HasErrors() {
@ -32,6 +32,6 @@ func Delete(u *user.User, h hyphae.ExistingHypha) error {
} }
backlinks.UpdateBacklinksAfterDelete(h, originalText) backlinks.UpdateBacklinksAfterDelete(h, originalText)
categories.RemoveHyphaFromAllCategories(h.CanonicalName()) categories.RemoveHyphaFromAllCategories(h.CanonicalName())
hyphae.DeleteHypha(h) hyphae2.DeleteHypha(h)
return nil return nil
} }

View File

@ -4,19 +4,19 @@ import (
"git.sr.ht/~bouncepaw/mycomarkup/v5" "git.sr.ht/~bouncepaw/mycomarkup/v5"
"git.sr.ht/~bouncepaw/mycomarkup/v5/blocks" "git.sr.ht/~bouncepaw/mycomarkup/v5/blocks"
"git.sr.ht/~bouncepaw/mycomarkup/v5/mycocontext" "git.sr.ht/~bouncepaw/mycomarkup/v5/mycocontext"
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/hyphae" hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/mycoopts" "github.com/bouncepaw/mycorrhiza/mycoopts"
"github.com/bouncepaw/mycorrhiza/viewutil" "github.com/bouncepaw/mycorrhiza/web/viewutil"
"os" "os"
) )
// SetHeaderLinks initializes header links by reading the configured hypha, if there is any, or resorting to default values. // SetHeaderLinks initializes header links by reading the configured hypha, if there is any, or resorting to default values.
func SetHeaderLinks() { func SetHeaderLinks() {
switch userLinksHypha := hyphae.ByName(cfg.HeaderLinksHypha).(type) { switch userLinksHypha := hyphae2.ByName(cfg.HeaderLinksHypha).(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
setDefaultHeaderLinks() setDefaultHeaderLinks()
case hyphae.ExistingHypha: case hyphae2.ExistingHypha:
contents, err := os.ReadFile(userLinksHypha.TextFilePath()) contents, err := os.ReadFile(userLinksHypha.TextFilePath())
if err != nil || len(contents) == 0 { if err != nil || len(contents) == 0 {
setDefaultHeaderLinks() setDefaultHeaderLinks()

View File

@ -1,10 +1,9 @@
package shroom package shroom
import ( import (
"github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/internal/user"
"log" "log"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/user"
) )
func rejectRenameLog(h hyphae.Hypha, u *user.User, errmsg string) { func rejectRenameLog(h hyphae.Hypha, u *user.User, errmsg string) {

View File

@ -3,36 +3,36 @@ package shroom
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/backlinks"
"github.com/bouncepaw/mycorrhiza/categories" "github.com/bouncepaw/mycorrhiza/categories"
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/internal/backlinks"
"github.com/bouncepaw/mycorrhiza/files" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/internal/files"
hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/internal/user"
"path" "path"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )
// Rename renames the old hypha to the new name and makes a history record about that. Call if and only if the user has the permission to rename. // Rename renames the old hypha to the new name and makes a history record about that. Call if and only if the user has the permission to rename.
func Rename(oldHypha hyphae.ExistingHypha, newName string, recursive bool, leaveRedirections bool, u *user.User) error { func Rename(oldHypha hyphae2.ExistingHypha, newName string, recursive bool, leaveRedirections bool, u *user.User) error {
// * bouncepaw hates this function and related renaming functions // * bouncepaw hates this function and related renaming functions
if newName == "" { if newName == "" {
rejectRenameLog(oldHypha, u, "no new name given") rejectRenameLog(oldHypha, u, "no new name given")
return errors.New("ui.rename_noname_tip") return errors.New("ui.rename_noname_tip")
} }
if !hyphae.IsValidName(newName) { if !hyphae2.IsValidName(newName) {
rejectRenameLog(oldHypha, u, fmt.Sprintf("new name %s invalid", newName)) rejectRenameLog(oldHypha, u, fmt.Sprintf("new name %s invalid", newName))
return errors.New("ui.rename_badname_tip") // FIXME: There is a bug related to this. return errors.New("ui.rename_badname_tip") // FIXME: There is a bug related to this.
} }
switch targetHypha := hyphae.ByName(newName); targetHypha.(type) { switch targetHypha := hyphae2.ByName(newName); targetHypha.(type) {
case hyphae.ExistingHypha: case hyphae2.ExistingHypha:
if targetHypha.CanonicalName() == oldHypha.CanonicalName() { if targetHypha.CanonicalName() == oldHypha.CanonicalName() {
return nil return nil
} }
@ -81,7 +81,7 @@ func Rename(oldHypha hyphae.ExistingHypha, newName string, recursive bool, leave
oldName = h.CanonicalName() oldName = h.CanonicalName()
newName = re.ReplaceAllString(oldName, newName) newName = re.ReplaceAllString(oldName, newName)
) )
hyphae.RenameHyphaTo(h, newName, replaceName) hyphae2.RenameHyphaTo(h, newName, replaceName)
backlinks.UpdateBacklinksAfterRename(h, oldName) backlinks.UpdateBacklinksAfterRename(h, oldName)
categories.RenameHyphaInAllCategories(oldName, newName) categories.RenameHyphaInAllCategories(oldName, newName)
if leaveRedirections { if leaveRedirections {
@ -104,12 +104,12 @@ const redirectionTemplate = `=> %[1]s | 👁️➡️ %[2]s
func leaveRedirection(oldName, newName string, hop *history.Op) error { func leaveRedirection(oldName, newName string, hop *history.Op) error {
var ( var (
text = fmt.Sprintf(redirectionTemplate, newName, util.BeautifulName(newName)) text = fmt.Sprintf(redirectionTemplate, newName, util.BeautifulName(newName))
emptyHypha = hyphae.ByName(oldName) emptyHypha = hyphae2.ByName(oldName)
) )
switch emptyHypha := emptyHypha.(type) { switch emptyHypha := emptyHypha.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
h := hyphae.ExtendEmptyToTextual(emptyHypha, filepath.Join(files.HyphaeDir(), oldName+".myco")) h := hyphae2.ExtendEmptyToTextual(emptyHypha, filepath.Join(files.HyphaeDir(), oldName+".myco"))
hyphae.Insert(h) hyphae2.Insert(h)
categories.AddHyphaToCategory(oldName, cfg.RedirectionCategory) categories.AddHyphaToCategory(oldName, cfg.RedirectionCategory)
defer backlinks.UpdateBacklinksAfterEdit(h, "") defer backlinks.UpdateBacklinksAfterEdit(h, "")
return writeTextToDisk(h, []byte(text), hop) return writeTextToDisk(h, []byte(text), hop)
@ -118,15 +118,15 @@ func leaveRedirection(oldName, newName string, hop *history.Op) error {
} }
} }
func findHyphaeToRename(superhypha hyphae.ExistingHypha, recursive bool) []hyphae.ExistingHypha { func findHyphaeToRename(superhypha hyphae2.ExistingHypha, recursive bool) []hyphae2.ExistingHypha {
hyphaList := []hyphae.ExistingHypha{superhypha} hyphaList := []hyphae2.ExistingHypha{superhypha}
if recursive { if recursive {
hyphaList = append(hyphaList, hyphae.Subhyphae(superhypha)...) hyphaList = append(hyphaList, hyphae2.Subhyphae(superhypha)...)
} }
return hyphaList return hyphaList
} }
func renamingPairs(hyphaeToRename []hyphae.ExistingHypha, replaceName func(string) string) (map[string]string, error) { func renamingPairs(hyphaeToRename []hyphae2.ExistingHypha, replaceName func(string) string) (map[string]string, error) {
var ( var (
renameMap = make(map[string]string) renameMap = make(map[string]string)
newNames = make([]string, len(hyphaeToRename)) newNames = make([]string, len(hyphaeToRename))
@ -138,12 +138,12 @@ func renamingPairs(hyphaeToRename []hyphae.ExistingHypha, replaceName func(strin
renameMap[h.TextFilePath()] = replaceName(h.TextFilePath()) renameMap[h.TextFilePath()] = replaceName(h.TextFilePath())
} }
switch h := h.(type) { switch h := h.(type) {
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
renameMap[h.MediaFilePath()] = replaceName(h.MediaFilePath()) renameMap[h.MediaFilePath()] = replaceName(h.MediaFilePath())
} }
h.Unlock() h.Unlock()
} }
if firstFailure, ok := hyphae.AreFreeNames(newNames...); !ok { if firstFailure, ok := hyphae2.AreFreeNames(newNames...); !ok {
return nil, errors.New("Hypha " + firstFailure + " already exists") return nil, errors.New("Hypha " + firstFailure + " already exists")
} }
return renameMap, nil return renameMap, nil

View File

@ -1,9 +1,9 @@
package shroom package shroom
import ( import (
"github.com/bouncepaw/mycorrhiza/internal/hyphae"
"strings" "strings"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )

View File

@ -2,14 +2,14 @@ package shroom
import ( import (
"fmt" "fmt"
hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/user"
) )
// RemoveMedia removes media from the media hypha and makes a history record about that. If it only had media, the hypha will be deleted. If it also had text, the hypha will become textual. // RemoveMedia removes media from the media hypha and makes a history record about that. If it only had media, the hypha will be deleted. If it also had text, the hypha will become textual.
func RemoveMedia(u *user.User, h *hyphae.MediaHypha) error { func RemoveMedia(u *user.User, h *hyphae2.MediaHypha) error {
hop := history. hop := history.
Operation(history.TypeRemoveMedia). Operation(history.TypeRemoveMedia).
WithFilesRemoved(h.MediaFilePath()). WithFilesRemoved(h.MediaFilePath()).
@ -24,9 +24,9 @@ func RemoveMedia(u *user.User, h *hyphae.MediaHypha) error {
} }
if h.HasTextFile() { if h.HasTextFile() {
hyphae.Insert(hyphae.ShrinkMediaToTextual(h)) hyphae2.Insert(hyphae2.ShrinkMediaToTextual(h))
} else { } else {
hyphae.DeleteHypha(h) hyphae2.DeleteHypha(h)
} }
return nil return nil
} }

View File

@ -4,12 +4,12 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/backlinks"
"github.com/bouncepaw/mycorrhiza/files"
"github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/internal/backlinks"
"github.com/bouncepaw/mycorrhiza/mimetype" "github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/user" hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/internal/mimetype"
"github.com/bouncepaw/mycorrhiza/internal/user"
"io" "io"
"log" "log"
"mime/multipart" "mime/multipart"
@ -17,10 +17,10 @@ import (
"path/filepath" "path/filepath"
) )
func historyMessageForTextUpload(h hyphae.Hypha, userMessage string) string { func historyMessageForTextUpload(h hyphae2.Hypha, userMessage string) string {
var verb string var verb string
switch h.(type) { switch h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
verb = "Create" verb = "Create"
default: default:
verb = "Edit" verb = "Edit"
@ -32,8 +32,8 @@ func historyMessageForTextUpload(h hyphae.Hypha, userMessage string) string {
return fmt.Sprintf("%s %s: %s", verb, h.CanonicalName(), userMessage) return fmt.Sprintf("%s %s: %s", verb, h.CanonicalName(), userMessage)
} }
func writeTextToDisk(h hyphae.ExistingHypha, data []byte, hop *history.Op) error { func writeTextToDisk(h hyphae2.ExistingHypha, data []byte, hop *history.Op) error {
if err := hyphae.WriteToMycoFile(h, data); err != nil { if err := hyphae2.WriteToMycoFile(h, data); err != nil {
return err return err
} }
hop.WithFiles(h.TextFilePath()) hop.WithFiles(h.TextFilePath())
@ -42,7 +42,7 @@ func writeTextToDisk(h hyphae.ExistingHypha, data []byte, hop *history.Op) error
} }
// UploadText edits the hypha's text part and makes a history record about that. // UploadText edits the hypha's text part and makes a history record about that.
func UploadText(h hyphae.Hypha, data []byte, userMessage string, u *user.User) error { func UploadText(h hyphae2.Hypha, data []byte, userMessage string, u *user.User) error {
hop := history. hop := history.
Operation(history.TypeEditText). Operation(history.TypeEditText).
WithMsg(historyMessageForTextUpload(h, userMessage)). WithMsg(historyMessageForTextUpload(h, userMessage)).
@ -56,13 +56,13 @@ func UploadText(h hyphae.Hypha, data []byte, userMessage string, u *user.User) e
} }
// Hypha name exploit check // Hypha name exploit check
if !hyphae.IsValidName(h.CanonicalName()) { if !hyphae2.IsValidName(h.CanonicalName()) {
// We check for the name only. I suppose the filepath would be valid as well. // We check for the name only. I suppose the filepath would be valid as well.
hop.Abort() hop.Abort()
return errors.New("invalid hypha name") return errors.New("invalid hypha name")
} }
oldText, err := hyphae.FetchMycomarkupFile(h) oldText, err := hyphae2.FetchMycomarkupFile(h)
if err != nil { if err != nil {
hop.Abort() hop.Abort()
return err return err
@ -77,8 +77,8 @@ func UploadText(h hyphae.Hypha, data []byte, userMessage string, u *user.User) e
// At this point, we have a savable user-generated Mycomarkup document. Gotta save it. // At this point, we have a savable user-generated Mycomarkup document. Gotta save it.
switch h := h.(type) { switch h := h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
H := hyphae.ExtendEmptyToTextual(h, filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco")) H := hyphae2.ExtendEmptyToTextual(h, filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco"))
err := writeTextToDisk(H, data, hop) err := writeTextToDisk(H, data, hop)
if err != nil { if err != nil {
@ -86,9 +86,9 @@ func UploadText(h hyphae.Hypha, data []byte, userMessage string, u *user.User) e
return err return err
} }
hyphae.Insert(H) hyphae2.Insert(H)
backlinks.UpdateBacklinksAfterEdit(H, "") backlinks.UpdateBacklinksAfterEdit(H, "")
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
// TODO: that []byte(...) part should be removed // TODO: that []byte(...) part should be removed
if bytes.Equal(data, []byte(oldText)) { if bytes.Equal(data, []byte(oldText)) {
// No changes! Just like cancel button // No changes! Just like cancel button
@ -103,8 +103,8 @@ func UploadText(h hyphae.Hypha, data []byte, userMessage string, u *user.User) e
} }
backlinks.UpdateBacklinksAfterEdit(h, oldText) backlinks.UpdateBacklinksAfterEdit(h, oldText)
case *hyphae.TextualHypha: case *hyphae2.TextualHypha:
oldText, err := hyphae.FetchMycomarkupFile(h) oldText, err := hyphae2.FetchMycomarkupFile(h)
if err != nil { if err != nil {
hop.Abort() hop.Abort()
return err return err
@ -130,12 +130,12 @@ func UploadText(h hyphae.Hypha, data []byte, userMessage string, u *user.User) e
return nil return nil
} }
func historyMessageForMediaUpload(h hyphae.Hypha, mime string) string { func historyMessageForMediaUpload(h hyphae2.Hypha, mime string) string {
return fmt.Sprintf("Upload media for %s with type %s", h.CanonicalName(), mime) return fmt.Sprintf("Upload media for %s with type %s", h.CanonicalName(), mime)
} }
// writeMediaToDisk saves the given data with the given mime type for the given hypha to the disk and returns the path to the saved file and an error, if any. // writeMediaToDisk saves the given data with the given mime type for the given hypha to the disk and returns the path to the saved file and an error, if any.
func writeMediaToDisk(h hyphae.Hypha, mime string, data []byte) (string, error) { func writeMediaToDisk(h hyphae2.Hypha, mime string, data []byte) (string, error) {
var ( var (
ext = mimetype.ToExtension(mime) ext = mimetype.ToExtension(mime)
// That's where the file will go // That's where the file will go
@ -153,7 +153,7 @@ func writeMediaToDisk(h hyphae.Hypha, mime string, data []byte) (string, error)
} }
// UploadBinary edits the hypha's media part and makes a history record about that. // UploadBinary edits the hypha's media part and makes a history record about that.
func UploadBinary(h hyphae.Hypha, mime string, file multipart.File, u *user.User) error { func UploadBinary(h hyphae2.Hypha, mime string, file multipart.File, u *user.User) error {
// Privilege check // Privilege check
if !u.CanProceed("upload-binary") { if !u.CanProceed("upload-binary") {
@ -162,7 +162,7 @@ func UploadBinary(h hyphae.Hypha, mime string, file multipart.File, u *user.User
} }
// Hypha name exploit check // Hypha name exploit check
if !hyphae.IsValidName(h.CanonicalName()) { if !hyphae2.IsValidName(h.CanonicalName()) {
// We check for the name only. I suppose the filepath would be valid as well. // We check for the name only. I suppose the filepath would be valid as well.
return errors.New("invalid hypha name") return errors.New("invalid hypha name")
} }
@ -185,12 +185,12 @@ func UploadBinary(h hyphae.Hypha, mime string, file multipart.File, u *user.User
} }
switch h := h.(type) { switch h := h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
H := hyphae.ExtendEmptyToMedia(h, uploadedFilePath) H := hyphae2.ExtendEmptyToMedia(h, uploadedFilePath)
hyphae.Insert(H) hyphae2.Insert(H)
case *hyphae.TextualHypha: case *hyphae2.TextualHypha:
hyphae.Insert(hyphae.ExtendTextualToMedia(h, uploadedFilePath)) hyphae2.Insert(hyphae2.ExtendTextualToMedia(h, uploadedFilePath))
case *hyphae.MediaHypha: // If this is not the first media the hypha gets case *hyphae2.MediaHypha: // If this is not the first media the hypha gets
prevFilePath := h.MediaFilePath() prevFilePath := h.MediaFilePath()
if prevFilePath != uploadedFilePath { if prevFilePath != uploadedFilePath {
if err := history.Rename(prevFilePath, uploadedFilePath); err != nil { if err := history.Rename(prevFilePath, uploadedFilePath); err != nil {

View File

@ -3,11 +3,11 @@ package user
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
"log" "log"
"os" "os"
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/files"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )

View File

@ -6,6 +6,7 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
"log" "log"
"net/http" "net/http"
"sort" "sort"
@ -14,7 +15,6 @@ import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )

View File

@ -2,12 +2,12 @@ package user
import ( import (
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
"net/http" "net/http"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/bouncepaw/mycorrhiza/cfg"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )

View File

@ -5,7 +5,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"git.sr.ht/~bouncepaw/mycomarkup/v5/options" "git.sr.ht/~bouncepaw/mycomarkup/v5/options"
"github.com/bouncepaw/mycorrhiza/files" "github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"log" "log"
"os" "os"

View File

@ -2,7 +2,7 @@ package interwiki
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/viewutil" viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"log" "log"
"net/http" "net/http"
@ -29,13 +29,13 @@ var (
{{define "edit separately."}}Изменяйте записи по отдельности.{{end}} {{define "edit separately."}}Изменяйте записи по отдельности.{{end}}
{{define "add interwiki entry"}}Добавить запись в интеркарту{{end}} {{define "add interwiki entry"}}Добавить запись в интеркарту{{end}}
` `
chainInterwiki viewutil.Chain chainInterwiki viewutil2.Chain
chainNameTaken viewutil.Chain chainNameTaken viewutil2.Chain
) )
func InitHandlers(rtr *mux.Router) { func InitHandlers(rtr *mux.Router) {
chainInterwiki = viewutil.CopyEnRuWith(fs, "view_interwiki.html", ruTranslation) chainInterwiki = viewutil2.CopyEnRuWith(fs, "view_interwiki.html", ruTranslation)
chainNameTaken = viewutil.CopyEnRuWith(fs, "view_name_taken.html", ruTranslation) chainNameTaken = viewutil2.CopyEnRuWith(fs, "view_name_taken.html", ruTranslation)
rtr.HandleFunc("/interwiki", handlerInterwiki) rtr.HandleFunc("/interwiki", handlerInterwiki)
rtr.HandleFunc("/interwiki/add-entry", handlerAddEntry).Methods(http.MethodPost) rtr.HandleFunc("/interwiki/add-entry", handlerAddEntry).Methods(http.MethodPost)
rtr.HandleFunc("/interwiki/modify-entry/{target}", handlerModifyEntry).Methods(http.MethodPost) rtr.HandleFunc("/interwiki/modify-entry/{target}", handlerModifyEntry).Methods(http.MethodPost)
@ -64,13 +64,13 @@ func handlerModifyEntry(w http.ResponseWriter, rq *http.Request) {
if oldData, ok = entriesByName[name]; !ok { if oldData, ok = entriesByName[name]; !ok {
log.Printf("Could not modify interwiki entry %s because it does not exist", name) log.Printf("Could not modify interwiki entry %s because it does not exist", name)
viewutil.HandlerNotFound(w, rq) viewutil2.HandlerNotFound(w, rq)
return return
} }
if err := replaceEntry(oldData, &newData); err != nil { if err := replaceEntry(oldData, &newData); err != nil {
log.Printf("Could not modify interwiki entry %s because one of the proposed aliases/name is taken\n", name) log.Printf("Could not modify interwiki entry %s because one of the proposed aliases/name is taken\n", name)
viewNameTaken(viewutil.MetaFrom(w, rq), oldData, err.Error(), "modify-entry/"+name) viewNameTaken(viewutil2.MetaFrom(w, rq), oldData, err.Error(), "modify-entry/"+name)
return return
} }
@ -82,7 +82,7 @@ func handlerModifyEntry(w http.ResponseWriter, rq *http.Request) {
func handlerAddEntry(w http.ResponseWriter, rq *http.Request) { func handlerAddEntry(w http.ResponseWriter, rq *http.Request) {
wiki := readInterwikiEntryFromRequest(rq) wiki := readInterwikiEntryFromRequest(rq)
if err := addEntry(&wiki); err != nil { if err := addEntry(&wiki); err != nil {
viewNameTaken(viewutil.MetaFrom(w, rq), &wiki, err.Error(), "add-entry") viewNameTaken(viewutil2.MetaFrom(w, rq), &wiki, err.Error(), "add-entry")
return return
} }
saveInterwikiJson() saveInterwikiJson()
@ -90,15 +90,15 @@ func handlerAddEntry(w http.ResponseWriter, rq *http.Request) {
} }
type nameTakenData struct { type nameTakenData struct {
*viewutil.BaseData *viewutil2.BaseData
*Wiki *Wiki
TakenName string TakenName string
Action string Action string
} }
func viewNameTaken(meta viewutil.Meta, wiki *Wiki, takenName, action string) { func viewNameTaken(meta viewutil2.Meta, wiki *Wiki, takenName, action string) {
viewutil.ExecutePage(meta, chainNameTaken, nameTakenData{ viewutil2.ExecutePage(meta, chainNameTaken, nameTakenData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
Wiki: wiki, Wiki: wiki,
TakenName: takenName, TakenName: takenName,
Action: action, Action: action,
@ -106,19 +106,19 @@ func viewNameTaken(meta viewutil.Meta, wiki *Wiki, takenName, action string) {
} }
func handlerInterwiki(w http.ResponseWriter, rq *http.Request) { func handlerInterwiki(w http.ResponseWriter, rq *http.Request) {
viewInterwiki(viewutil.MetaFrom(w, rq)) viewInterwiki(viewutil2.MetaFrom(w, rq))
} }
type interwikiData struct { type interwikiData struct {
*viewutil.BaseData *viewutil2.BaseData
Entries []*Wiki Entries []*Wiki
CanEdit bool CanEdit bool
Error string Error string
} }
func viewInterwiki(meta viewutil.Meta) { func viewInterwiki(meta viewutil2.Meta) {
viewutil.ExecutePage(meta, chainInterwiki, interwikiData{ viewutil2.ExecutePage(meta, chainInterwiki, interwikiData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
Entries: listOfEntries, Entries: listOfEntries,
CanEdit: meta.U.Group == "admin", CanEdit: meta.U.Group == "admin",
Error: "", Error: "",

32
main.go
View File

@ -8,23 +8,23 @@
package main package main
import ( import (
"github.com/bouncepaw/mycorrhiza/backlinks"
"github.com/bouncepaw/mycorrhiza/categories"
"github.com/bouncepaw/mycorrhiza/interwiki"
"github.com/bouncepaw/mycorrhiza/migration"
"github.com/bouncepaw/mycorrhiza/version"
"github.com/bouncepaw/mycorrhiza/viewutil"
"log" "log"
"os" "os"
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/categories"
"github.com/bouncepaw/mycorrhiza/files"
"github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/internal/backlinks"
"github.com/bouncepaw/mycorrhiza/shroom" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/static" "github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/user" "github.com/bouncepaw/mycorrhiza/internal/hyphae"
migration2 "github.com/bouncepaw/mycorrhiza/internal/migration"
"github.com/bouncepaw/mycorrhiza/internal/shroom"
user2 "github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/internal/version"
"github.com/bouncepaw/mycorrhiza/interwiki"
"github.com/bouncepaw/mycorrhiza/web" "github.com/bouncepaw/mycorrhiza/web"
"github.com/bouncepaw/mycorrhiza/web/static"
"github.com/bouncepaw/mycorrhiza/web/viewutil"
) )
func main() { func main() {
@ -49,11 +49,11 @@ func main() {
hyphae.Index(files.HyphaeDir()) hyphae.Index(files.HyphaeDir())
backlinks.IndexBacklinks() backlinks.IndexBacklinks()
go backlinks.RunBacklinksConveyor() go backlinks.RunBacklinksConveyor()
user.InitUserDatabase() user2.InitUserDatabase()
history.Start() history.Start()
history.InitGitRepo() history.InitGitRepo()
migration.MigrateRocketsMaybe() migration2.MigrateRocketsMaybe()
migration.MigrateHeadingsMaybe() migration2.MigrateHeadingsMaybe()
shroom.SetHeaderLinks() shroom.SetHeaderLinks()
categories.Init() categories.Init()
interwiki.Init() interwiki.Init()
@ -61,7 +61,7 @@ func main() {
// Static files: // Static files:
static.InitFS(files.StaticFiles()) static.InitFS(files.StaticFiles())
if !user.HasAnyAdmins() { if !user2.HasAnyAdmins() {
log.Println("Your wiki has no admin yet. Run Mycorrhiza with -create-admin <username> option to create an admin.") log.Println("Your wiki has no admin yet. Run Mycorrhiza with -create-admin <username> option to create an admin.")
} }

View File

@ -1,10 +1,10 @@
package misc package misc
import ( import (
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/internal/version"
"github.com/bouncepaw/mycorrhiza/l18n" "github.com/bouncepaw/mycorrhiza/l18n"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/version"
"log" "log"
"strings" "strings"
"text/template" // sic! "text/template" // sic!

View File

@ -2,6 +2,13 @@
package misc package misc
import ( import (
"github.com/bouncepaw/mycorrhiza/internal/backlinks"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
shroom2 "github.com/bouncepaw/mycorrhiza/internal/shroom"
"github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/web/static"
viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"io" "io"
"log" "log"
"math/rand" "math/rand"
@ -11,16 +18,9 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/bouncepaw/mycorrhiza/backlinks" "github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/files"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/l18n" "github.com/bouncepaw/mycorrhiza/l18n"
"github.com/bouncepaw/mycorrhiza/shroom"
"github.com/bouncepaw/mycorrhiza/static"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil"
) )
func InitAssetHandlers(rtr *mux.Router) { func InitAssetHandlers(rtr *mux.Router) {
@ -49,22 +49,22 @@ func handlerList(w http.ResponseWriter, rq *http.Request) {
// TODO: make this more effective, there are too many loops and vars // TODO: make this more effective, there are too many loops and vars
var ( var (
hyphaNames = make(chan string) hyphaNames = make(chan string)
sortedHypha = hyphae.PathographicSort(hyphaNames) sortedHypha = hyphae2.PathographicSort(hyphaNames)
entries []listDatum entries []listDatum
) )
for hypha := range hyphae.YieldExistingHyphae() { for hypha := range hyphae2.YieldExistingHyphae() {
hyphaNames <- hypha.CanonicalName() hyphaNames <- hypha.CanonicalName()
} }
close(hyphaNames) close(hyphaNames)
for hyphaName := range sortedHypha { for hyphaName := range sortedHypha {
switch h := hyphae.ByName(hyphaName).(type) { switch h := hyphae2.ByName(hyphaName).(type) {
case *hyphae.TextualHypha: case *hyphae2.TextualHypha:
entries = append(entries, listDatum{h.CanonicalName(), ""}) entries = append(entries, listDatum{h.CanonicalName(), ""})
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
entries = append(entries, listDatum{h.CanonicalName(), filepath.Ext(h.MediaFilePath())[1:]}) entries = append(entries, listDatum{h.CanonicalName(), filepath.Ext(h.MediaFilePath())[1:]})
} }
} }
viewList(viewutil.MetaFrom(w, rq), entries) viewList(viewutil2.MetaFrom(w, rq), entries)
} }
// handlerReindex reindexes all hyphae by checking the wiki storage directory anew. // handlerReindex reindexes all hyphae by checking the wiki storage directory anew.
@ -72,13 +72,13 @@ func handlerReindex(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if ok := user.CanProceed(rq, "reindex"); !ok { if ok := user.CanProceed(rq, "reindex"); !ok {
var lc = l18n.FromRequest(rq) var lc = l18n.FromRequest(rq)
viewutil.HttpErr(viewutil.MetaFrom(w, rq), http.StatusForbidden, cfg.HomeHypha, lc.Get("ui.reindex_no_rights")) viewutil2.HttpErr(viewutil2.MetaFrom(w, rq), http.StatusForbidden, cfg.HomeHypha, lc.Get("ui.reindex_no_rights"))
log.Println("Rejected", rq.URL) log.Println("Rejected", rq.URL)
return return
} }
hyphae.ResetCount() hyphae2.ResetCount()
log.Println("Reindexing hyphae in", files.HyphaeDir()) log.Println("Reindexing hyphae in", files.HyphaeDir())
hyphae.Index(files.HyphaeDir()) hyphae2.Index(files.HyphaeDir())
backlinks.IndexBacklinks() backlinks.IndexBacklinks()
http.Redirect(w, rq, "/", http.StatusSeeOther) http.Redirect(w, rq, "/", http.StatusSeeOther)
} }
@ -88,11 +88,11 @@ func handlerUpdateHeaderLinks(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if ok := user.CanProceed(rq, "update-header-links"); !ok { if ok := user.CanProceed(rq, "update-header-links"); !ok {
var lc = l18n.FromRequest(rq) var lc = l18n.FromRequest(rq)
viewutil.HttpErr(viewutil.MetaFrom(w, rq), http.StatusForbidden, cfg.HomeHypha, lc.Get("ui.header_no_rights")) viewutil2.HttpErr(viewutil2.MetaFrom(w, rq), http.StatusForbidden, cfg.HomeHypha, lc.Get("ui.header_no_rights"))
log.Println("Rejected", rq.URL) log.Println("Rejected", rq.URL)
return return
} }
shroom.SetHeaderLinks() shroom2.SetHeaderLinks()
http.Redirect(w, rq, "/", http.StatusSeeOther) http.Redirect(w, rq, "/", http.StatusSeeOther)
} }
@ -101,15 +101,15 @@ func handlerRandom(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
var ( var (
randomHyphaName string randomHyphaName string
amountOfHyphae = hyphae.Count() amountOfHyphae = hyphae2.Count()
) )
if amountOfHyphae == 0 { if amountOfHyphae == 0 {
var lc = l18n.FromRequest(rq) var lc = l18n.FromRequest(rq)
viewutil.HttpErr(viewutil.MetaFrom(w, rq), http.StatusNotFound, cfg.HomeHypha, lc.Get("ui.random_no_hyphae_tip")) viewutil2.HttpErr(viewutil2.MetaFrom(w, rq), http.StatusNotFound, cfg.HomeHypha, lc.Get("ui.random_no_hyphae_tip"))
return return
} }
i := rand.Intn(amountOfHyphae) i := rand.Intn(amountOfHyphae)
for h := range hyphae.YieldExistingHyphae() { for h := range hyphae2.YieldExistingHyphae() {
if i == 0 { if i == 0 {
randomHyphaName = h.CanonicalName() randomHyphaName = h.CanonicalName()
} }
@ -126,8 +126,8 @@ func handlerAbout(w http.ResponseWriter, rq *http.Request) {
lc = l18n.FromRequest(rq) lc = l18n.FromRequest(rq)
title = lc.Get("ui.about_title", &l18n.Replacements{"name": cfg.WikiName}) title = lc.Get("ui.about_title", &l18n.Replacements{"name": cfg.WikiName})
) )
_, err := io.WriteString(w, viewutil.Base( _, err := io.WriteString(w, viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
title, title,
AboutHTML(lc), AboutHTML(lc),
map[string]string{}, map[string]string{},
@ -174,12 +174,12 @@ func handlerTitleSearch(w http.ResponseWriter, rq *http.Request) {
var ( var (
query = rq.FormValue("q") query = rq.FormValue("q")
hyphaName = util.CanonicalName(query) hyphaName = util.CanonicalName(query)
_, nameFree = hyphae.AreFreeNames(hyphaName) _, nameFree = hyphae2.AreFreeNames(hyphaName)
results []string results []string
) )
for hyphaName := range shroom.YieldHyphaNamesContainingString(query) { for hyphaName := range shroom2.YieldHyphaNamesContainingString(query) {
results = append(results, hyphaName) results = append(results, hyphaName)
} }
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
viewTitleSearch(viewutil.MetaFrom(w, rq), query, hyphaName, !nameFree, results) viewTitleSearch(viewutil2.MetaFrom(w, rq), query, hyphaName, !nameFree, results)
} }

View File

@ -2,14 +2,14 @@ package misc
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/viewutil" viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
) )
var ( var (
//go:embed *html //go:embed *html
fs embed.FS fs embed.FS
chainList, chainTitleSearch viewutil.Chain chainList, chainTitleSearch viewutil2.Chain
ruTranslation = ` ruTranslation = `
{{define "list of hyphae"}}Список гиф{{end}} {{define "list of hyphae"}}Список гиф{{end}}
{{define "search:"}}Поиск: {{.}}{{end}} {{define "search:"}}Поиск: {{.}}{{end}}
@ -21,8 +21,8 @@ var (
) )
func initViews() { func initViews() {
chainList = viewutil.CopyEnRuWith(fs, "view_list.html", ruTranslation) chainList = viewutil2.CopyEnRuWith(fs, "view_list.html", ruTranslation)
chainTitleSearch = viewutil.CopyEnRuWith(fs, "view_title_search.html", ruTranslation) chainTitleSearch = viewutil2.CopyEnRuWith(fs, "view_title_search.html", ruTranslation)
} }
type listDatum struct { type listDatum struct {
@ -31,30 +31,30 @@ type listDatum struct {
} }
type listData struct { type listData struct {
*viewutil.BaseData *viewutil2.BaseData
Entries []listDatum Entries []listDatum
HyphaCount int HyphaCount int
} }
func viewList(meta viewutil.Meta, entries []listDatum) { func viewList(meta viewutil2.Meta, entries []listDatum) {
viewutil.ExecutePage(meta, chainList, listData{ viewutil2.ExecutePage(meta, chainList, listData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
Entries: entries, Entries: entries,
HyphaCount: hyphae.Count(), HyphaCount: hyphae.Count(),
}) })
} }
type titleSearchData struct { type titleSearchData struct {
*viewutil.BaseData *viewutil2.BaseData
Query string Query string
Results []string Results []string
MatchedHyphaName string MatchedHyphaName string
HasExactMatch bool HasExactMatch bool
} }
func viewTitleSearch(meta viewutil.Meta, query string, hyphaName string, hasExactMatch bool, results []string) { func viewTitleSearch(meta viewutil2.Meta, query string, hyphaName string, hasExactMatch bool, results []string) {
viewutil.ExecutePage(meta, chainTitleSearch, titleSearchData{ viewutil2.ExecutePage(meta, chainTitleSearch, titleSearchData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
Query: query, Query: query,
Results: results, Results: results,
MatchedHyphaName: hyphaName, MatchedHyphaName: hyphaName,

View File

@ -3,8 +3,8 @@ package mycoopts
import ( import (
"errors" "errors"
"git.sr.ht/~bouncepaw/mycomarkup/v5/options" "git.sr.ht/~bouncepaw/mycomarkup/v5/options"
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/hyphae" hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/interwiki" "github.com/bouncepaw/mycorrhiza/interwiki"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )
@ -17,26 +17,26 @@ func MarkupOptions(hyphaName string) options.Options {
RedLinksSupported: true, RedLinksSupported: true,
InterwikiSupported: true, InterwikiSupported: true,
HyphaExists: func(hyphaName string) bool { HyphaExists: func(hyphaName string) bool {
switch hyphae.ByName(hyphaName).(type) { switch hyphae2.ByName(hyphaName).(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
return false return false
default: default:
return true return true
} }
}, },
IterateHyphaNamesWith: func(λ func(string)) { IterateHyphaNamesWith: func(λ func(string)) {
for h := range hyphae.YieldExistingHyphae() { for h := range hyphae2.YieldExistingHyphae() {
λ(h.CanonicalName()) λ(h.CanonicalName())
} }
}, },
HyphaHTMLData: func(hyphaName string) (rawText, binaryBlock string, err error) { HyphaHTMLData: func(hyphaName string) (rawText, binaryBlock string, err error) {
switch h := hyphae.ByName(hyphaName).(type) { switch h := hyphae2.ByName(hyphaName).(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
err = errors.New("Hypha " + hyphaName + " does not exist") err = errors.New("Hypha " + hyphaName + " does not exist")
case *hyphae.TextualHypha: case *hyphae2.TextualHypha:
rawText, err = hyphae.FetchMycomarkupFile(h) rawText, err = hyphae2.FetchMycomarkupFile(h)
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
rawText, err = hyphae.FetchMycomarkupFile(h) rawText, err = hyphae2.FetchMycomarkupFile(h)
binaryBlock = mediaRaw(h) binaryBlock = mediaRaw(h)
} }
return return

View File

@ -1,6 +1,6 @@
{% import "path/filepath" %} {% import "path/filepath" %}
{% import "github.com/bouncepaw/mycorrhiza/hyphae" %} {% import "github.com/bouncepaw/mycorrhiza/internal/hyphae" %}
{% import "github.com/bouncepaw/mycorrhiza/l18n" %} {% import "github.com/bouncepaw/mycorrhiza/l18n" %}
{% func mediaRaw(h *hyphae.MediaHypha) %}{%= Media(h, l18n.New("en", "en")) %}{% endfunc %} {% func mediaRaw(h *hyphae.MediaHypha) %}{%= Media(h, l18n.New("en", "en")) %}{% endfunc %}

View File

@ -8,7 +8,7 @@ package mycoopts
import "path/filepath" import "path/filepath"
//line mycoopts/view.qtpl:3 //line mycoopts/view.qtpl:3
import "github.com/bouncepaw/mycorrhiza/hyphae" import "github.com/bouncepaw/mycorrhiza/internal/hyphae"
//line mycoopts/view.qtpl:4 //line mycoopts/view.qtpl:4
import "github.com/bouncepaw/mycorrhiza/l18n" import "github.com/bouncepaw/mycorrhiza/l18n"

View File

@ -1,7 +1,7 @@
package tree package tree
import ( import (
"github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"path" "path"
"sort" "sort"
"strings" "strings"

View File

@ -3,13 +3,14 @@ package util
import ( import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"github.com/bouncepaw/mycorrhiza/files"
"log" "log"
"net/http" "net/http"
"strings" "strings"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/internal/files"
"git.sr.ht/~bouncepaw/mycomarkup/v5/util" "git.sr.ht/~bouncepaw/mycomarkup/v5/util"
"github.com/bouncepaw/mycorrhiza/cfg"
) )
// PrepareRq strips the trailing / in rq.URL.Path. In the future it might do more stuff for making all request structs uniform. // PrepareRq strips the trailing / in rq.URL.Path. In the future it might do more stuff for making all request structs uniform.

View File

@ -2,10 +2,10 @@ package web
import ( import (
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/user" user2 "github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil" viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"log" "log"
"mime" "mime"
@ -52,53 +52,53 @@ const adminTranslationRu = `
{{define "delete user warning"}}Вы уверены, что хотите удалить этого пользователя из базы данных? Это действие нельзя отменить.{{end}} {{define "delete user warning"}}Вы уверены, что хотите удалить этого пользователя из базы данных? Это действие нельзя отменить.{{end}}
` `
func viewPanel(meta viewutil.Meta) { func viewPanel(meta viewutil2.Meta) {
viewutil.ExecutePage(meta, panelChain, &viewutil.BaseData{}) viewutil2.ExecutePage(meta, panelChain, &viewutil2.BaseData{})
} }
type listData struct { type listData struct {
*viewutil.BaseData *viewutil2.BaseData
UserHypha string UserHypha string
Users []*user.User Users []*user2.User
} }
func viewList(meta viewutil.Meta, users []*user.User) { func viewList(meta viewutil2.Meta, users []*user2.User) {
viewutil.ExecutePage(meta, listChain, listData{ viewutil2.ExecutePage(meta, listChain, listData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
UserHypha: cfg.UserHypha, UserHypha: cfg.UserHypha,
Users: users, Users: users,
}) })
} }
type newUserData struct { type newUserData struct {
*viewutil.BaseData *viewutil2.BaseData
Form util.FormData Form util.FormData
} }
func viewNewUser(meta viewutil.Meta, form util.FormData) { func viewNewUser(meta viewutil2.Meta, form util.FormData) {
viewutil.ExecutePage(meta, newUserChain, newUserData{ viewutil2.ExecutePage(meta, newUserChain, newUserData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
Form: form, Form: form,
}) })
} }
type editDeleteUserData struct { type editDeleteUserData struct {
*viewutil.BaseData *viewutil2.BaseData
Form util.FormData Form util.FormData
U *user.User U *user2.User
} }
func viewEditUser(meta viewutil.Meta, form util.FormData, u *user.User) { func viewEditUser(meta viewutil2.Meta, form util.FormData, u *user2.User) {
viewutil.ExecutePage(meta, editUserChain, editDeleteUserData{ viewutil2.ExecutePage(meta, editUserChain, editDeleteUserData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
Form: form, Form: form,
U: u, U: u,
}) })
} }
func viewDeleteUser(meta viewutil.Meta, form util.FormData, u *user.User) { func viewDeleteUser(meta viewutil2.Meta, form util.FormData, u *user2.User) {
viewutil.ExecutePage(meta, deleteUserChain, editDeleteUserData{ viewutil2.ExecutePage(meta, deleteUserChain, editDeleteUserData{
BaseData: &viewutil.BaseData{}, BaseData: &viewutil2.BaseData{},
Form: form, Form: form,
U: u, U: u,
}) })
@ -108,12 +108,12 @@ func viewDeleteUser(meta viewutil.Meta, form util.FormData, u *user.User) {
func handlerAdmin(w http.ResponseWriter, rq *http.Request) { func handlerAdmin(w http.ResponseWriter, rq *http.Request) {
w.Header().Set("Content-Type", "text/html;charset=utf-8") w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
viewPanel(viewutil.MetaFrom(w, rq)) viewPanel(viewutil2.MetaFrom(w, rq))
} }
// handlerAdminShutdown kills the wiki. // handlerAdminShutdown kills the wiki.
func handlerAdminShutdown(w http.ResponseWriter, rq *http.Request) { func handlerAdminShutdown(w http.ResponseWriter, rq *http.Request) {
if user.CanProceed(rq, "admin/shutdown") { if user2.CanProceed(rq, "admin/shutdown") {
log.Println("An admin commanded the wiki to shutdown") log.Println("An admin commanded the wiki to shutdown")
os.Exit(0) os.Exit(0)
} }
@ -121,7 +121,7 @@ func handlerAdminShutdown(w http.ResponseWriter, rq *http.Request) {
// handlerAdminReindexUsers reinitialises the user system. // handlerAdminReindexUsers reinitialises the user system.
func handlerAdminReindexUsers(w http.ResponseWriter, rq *http.Request) { func handlerAdminReindexUsers(w http.ResponseWriter, rq *http.Request) {
user.ReadUsersFromFilesystem() user2.ReadUsersFromFilesystem()
redirectTo := rq.Referer() redirectTo := rq.Referer()
if redirectTo == "" { if redirectTo == "" {
redirectTo = "/hypha/" + cfg.UserHypha redirectTo = "/hypha/" + cfg.UserHypha
@ -131,8 +131,8 @@ func handlerAdminReindexUsers(w http.ResponseWriter, rq *http.Request) {
func handlerAdminUsers(w http.ResponseWriter, rq *http.Request) { func handlerAdminUsers(w http.ResponseWriter, rq *http.Request) {
// Get a sorted list of users // Get a sorted list of users
var users []*user.User var users []*user2.User
for u := range user.YieldUsers() { for u := range user2.YieldUsers() {
users = append(users, u) users = append(users, u)
} }
@ -140,12 +140,12 @@ func handlerAdminUsers(w http.ResponseWriter, rq *http.Request) {
less := users[i].RegisteredAt.Before(users[j].RegisteredAt) less := users[i].RegisteredAt.Before(users[j].RegisteredAt)
return less return less
}) })
viewList(viewutil.MetaFrom(w, rq), users) viewList(viewutil2.MetaFrom(w, rq), users)
} }
func handlerAdminUserEdit(w http.ResponseWriter, rq *http.Request) { func handlerAdminUserEdit(w http.ResponseWriter, rq *http.Request) {
vars := mux.Vars(rq) vars := mux.Vars(rq)
u := user.ByName(vars["username"]) u := user2.ByName(vars["username"])
if u == nil { if u == nil {
util.HTTP404Page(w, "404 page not found") util.HTTP404Page(w, "404 page not found")
return return
@ -157,9 +157,9 @@ func handlerAdminUserEdit(w http.ResponseWriter, rq *http.Request) {
oldGroup := u.Group oldGroup := u.Group
newGroup := f.Get("group") newGroup := f.Get("group")
if user.ValidGroup(newGroup) { if user2.ValidGroup(newGroup) {
u.Group = newGroup u.Group = newGroup
if err := user.SaveUserDatabase(); err != nil { if err := user2.SaveUserDatabase(); err != nil {
u.Group = oldGroup u.Group = oldGroup
log.Println(err) log.Println(err)
f = f.WithError(err) f = f.WithError(err)
@ -179,12 +179,12 @@ func handlerAdminUserEdit(w http.ResponseWriter, rq *http.Request) {
} }
w.Header().Set("Content-Type", mime.TypeByExtension(".html")) w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
viewEditUser(viewutil.MetaFrom(w, rq), f, u) viewEditUser(viewutil2.MetaFrom(w, rq), f, u)
} }
func handlerAdminUserChangePassword(w http.ResponseWriter, rq *http.Request) { func handlerAdminUserChangePassword(w http.ResponseWriter, rq *http.Request) {
vars := mux.Vars(rq) vars := mux.Vars(rq)
u := user.ByName(vars["username"]) u := user2.ByName(vars["username"])
if u == nil { if u == nil {
util.HTTP404Page(w, "404 page not found") util.HTTP404Page(w, "404 page not found")
return return
@ -204,7 +204,7 @@ func handlerAdminUserChangePassword(w http.ResponseWriter, rq *http.Request) {
if err := u.ChangePassword(password); err != nil { if err := u.ChangePassword(password); err != nil {
f = f.WithError(err) f = f.WithError(err)
} else { } else {
if err := user.SaveUserDatabase(); err != nil { if err := user2.SaveUserDatabase(); err != nil {
u.Password = previousPassword u.Password = previousPassword
f = f.WithError(err) f = f.WithError(err)
} else { } else {
@ -222,12 +222,12 @@ func handlerAdminUserChangePassword(w http.ResponseWriter, rq *http.Request) {
} }
w.Header().Set("Content-Type", mime.TypeByExtension(".html")) w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
viewEditUser(viewutil.MetaFrom(w, rq), f, u) viewEditUser(viewutil2.MetaFrom(w, rq), f, u)
} }
func handlerAdminUserDelete(w http.ResponseWriter, rq *http.Request) { func handlerAdminUserDelete(w http.ResponseWriter, rq *http.Request) {
vars := mux.Vars(rq) vars := mux.Vars(rq)
u := user.ByName(vars["username"]) u := user2.ByName(vars["username"])
if u == nil { if u == nil {
util.HTTP404Page(w, "404 page not found") util.HTTP404Page(w, "404 page not found")
return return
@ -236,7 +236,7 @@ func handlerAdminUserDelete(w http.ResponseWriter, rq *http.Request) {
f := util.NewFormData() f := util.NewFormData()
if rq.Method == http.MethodPost { if rq.Method == http.MethodPost {
f = f.WithError(user.DeleteUser(u.Name)) f = f.WithError(user2.DeleteUser(u.Name))
if !f.HasError() { if !f.HasError() {
http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther) http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther)
} else { } else {
@ -248,23 +248,23 @@ func handlerAdminUserDelete(w http.ResponseWriter, rq *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
} }
w.Header().Set("Content-Type", mime.TypeByExtension(".html")) w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
viewDeleteUser(viewutil.MetaFrom(w, rq), f, u) viewDeleteUser(viewutil2.MetaFrom(w, rq), f, u)
} }
func handlerAdminUserNew(w http.ResponseWriter, rq *http.Request) { func handlerAdminUserNew(w http.ResponseWriter, rq *http.Request) {
if rq.Method == http.MethodGet { if rq.Method == http.MethodGet {
w.Header().Set("Content-Type", mime.TypeByExtension(".html")) w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
viewNewUser(viewutil.MetaFrom(w, rq), util.NewFormData()) viewNewUser(viewutil2.MetaFrom(w, rq), util.NewFormData())
} else if rq.Method == http.MethodPost { } else if rq.Method == http.MethodPost {
// Create a user // Create a user
f := util.FormDataFromRequest(rq, []string{"name", "password", "group"}) f := util.FormDataFromRequest(rq, []string{"name", "password", "group"})
err := user.Register(f.Get("name"), f.Get("password"), f.Get("group"), "local", true) err := user2.Register(f.Get("name"), f.Get("password"), f.Get("group"), "local", true)
if err != nil { if err != nil {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", mime.TypeByExtension(".html")) w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
viewNewUser(viewutil.MetaFrom(w, rq), f.WithError(err)) viewNewUser(viewutil2.MetaFrom(w, rq), f.WithError(err))
} else { } else {
http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther) http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther)
} }

View File

@ -2,22 +2,21 @@ package web
import ( import (
"git.sr.ht/~bouncepaw/mycomarkup/v5" "git.sr.ht/~bouncepaw/mycomarkup/v5"
hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
shroom2 "github.com/bouncepaw/mycorrhiza/internal/shroom"
"github.com/bouncepaw/mycorrhiza/internal/user"
viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"html/template" "html/template"
"log" "log"
"net/http" "net/http"
"git.sr.ht/~bouncepaw/mycomarkup/v5/mycocontext"
"github.com/bouncepaw/mycorrhiza/hypview" "github.com/bouncepaw/mycorrhiza/hypview"
"github.com/bouncepaw/mycorrhiza/mycoopts" "github.com/bouncepaw/mycorrhiza/mycoopts"
"github.com/bouncepaw/mycorrhiza/viewutil"
"git.sr.ht/~bouncepaw/mycomarkup/v5/mycocontext"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/l18n" "github.com/bouncepaw/mycorrhiza/l18n"
"github.com/bouncepaw/mycorrhiza/shroom"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )
@ -36,24 +35,24 @@ func handlerRemoveMedia(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
var ( var (
u = user.FromRequest(rq) u = user.FromRequest(rq)
h = hyphae.ByName(util.HyphaNameFromRq(rq, "remove-media")) h = hyphae2.ByName(util.HyphaNameFromRq(rq, "remove-media"))
meta = viewutil.MetaFrom(w, rq) meta = viewutil2.MetaFrom(w, rq)
) )
if !u.CanProceed("remove-media") { if !u.CanProceed("remove-media") {
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no rights") viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no rights")
return return
} }
if rq.Method == "GET" { if rq.Method == "GET" {
hypview.RemoveMedia(viewutil.MetaFrom(w, rq), h.CanonicalName()) hypview.RemoveMedia(viewutil2.MetaFrom(w, rq), h.CanonicalName())
return return
} }
switch h := h.(type) { switch h := h.(type) {
case *hyphae.EmptyHypha, *hyphae.TextualHypha: case *hyphae2.EmptyHypha, *hyphae2.TextualHypha:
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no media to remove") viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no media to remove")
return return
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
if err := shroom.RemoveMedia(u, h); err != nil { if err := shroom2.RemoveMedia(u, h); err != nil {
viewutil.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error()) viewutil2.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error())
return return
} }
} }
@ -64,21 +63,21 @@ func handlerDelete(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
var ( var (
u = user.FromRequest(rq) u = user.FromRequest(rq)
h = hyphae.ByName(util.HyphaNameFromRq(rq, "delete")) h = hyphae2.ByName(util.HyphaNameFromRq(rq, "delete"))
meta = viewutil.MetaFrom(w, rq) meta = viewutil2.MetaFrom(w, rq)
) )
if !u.CanProceed("delete") { if !u.CanProceed("delete") {
log.Printf("%s has no rights to delete %s\n", u.Name, h.CanonicalName()) log.Printf("%s has no rights to delete %s\n", u.Name, h.CanonicalName())
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights") viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights")
return return
} }
switch h.(type) { switch h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
log.Printf("%s tries to delete empty hypha %s\n", u.Name, h.CanonicalName()) log.Printf("%s tries to delete empty hypha %s\n", u.Name, h.CanonicalName())
// TODO: localize // TODO: localize
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot delete an empty hypha") viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot delete an empty hypha")
return return
} }
@ -87,9 +86,9 @@ func handlerDelete(w http.ResponseWriter, rq *http.Request) {
return return
} }
if err := shroom.Delete(u, h.(hyphae.ExistingHypha)); err != nil { if err := shroom2.Delete(u, h.(hyphae2.ExistingHypha)); err != nil {
log.Println(err) log.Println(err)
viewutil.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error()) viewutil2.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error())
return return
} }
http.Redirect(w, rq, "/hypha/"+h.CanonicalName(), http.StatusSeeOther) http.Redirect(w, rq, "/hypha/"+h.CanonicalName(), http.StatusSeeOther)
@ -100,25 +99,25 @@ func handlerRename(w http.ResponseWriter, rq *http.Request) {
var ( var (
u = user.FromRequest(rq) u = user.FromRequest(rq)
lc = l18n.FromRequest(rq) lc = l18n.FromRequest(rq)
h = hyphae.ByName(util.HyphaNameFromRq(rq, "rename")) h = hyphae2.ByName(util.HyphaNameFromRq(rq, "rename"))
meta = viewutil.MetaFrom(w, rq) meta = viewutil2.MetaFrom(w, rq)
) )
switch h.(type) { switch h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
log.Printf("%s tries to rename empty hypha %s", u.Name, h.CanonicalName()) log.Printf("%s tries to rename empty hypha %s", u.Name, h.CanonicalName())
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot rename an empty hypha") // TODO: localize viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot rename an empty hypha") // TODO: localize
return return
} }
if !u.CanProceed("rename") { if !u.CanProceed("rename") {
log.Printf("%s has no rights to rename %s\n", u.Name, h.CanonicalName()) log.Printf("%s has no rights to rename %s\n", u.Name, h.CanonicalName())
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights") viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights")
return return
} }
var ( var (
oldHypha = h.(hyphae.ExistingHypha) oldHypha = h.(hyphae2.ExistingHypha)
newName = util.CanonicalName(rq.PostFormValue("new-name")) newName = util.CanonicalName(rq.PostFormValue("new-name"))
recursive = rq.PostFormValue("recursive") == "true" recursive = rq.PostFormValue("recursive") == "true"
leaveRedirections = rq.PostFormValue("redirection") == "true" leaveRedirections = rq.PostFormValue("redirection") == "true"
@ -129,9 +128,9 @@ func handlerRename(w http.ResponseWriter, rq *http.Request) {
return return
} }
if err := shroom.Rename(oldHypha, newName, recursive, leaveRedirections, u); err != nil { if err := shroom2.Rename(oldHypha, newName, recursive, leaveRedirections, u); err != nil {
log.Printf("%s tries to rename %s: %s", u.Name, oldHypha.CanonicalName(), err.Error()) log.Printf("%s tries to rename %s: %s", u.Name, oldHypha.CanonicalName(), err.Error())
viewutil.HttpErr(meta, http.StatusForbidden, oldHypha.CanonicalName(), lc.Get(err.Error())) // TODO: localize viewutil2.HttpErr(meta, http.StatusForbidden, oldHypha.CanonicalName(), lc.Get(err.Error())) // TODO: localize
return return
} }
http.Redirect(w, rq, "/hypha/"+newName, http.StatusSeeOther) http.Redirect(w, rq, "/hypha/"+newName, http.StatusSeeOther)
@ -143,29 +142,29 @@ func handlerEdit(w http.ResponseWriter, rq *http.Request) {
var ( var (
u = user.FromRequest(rq) u = user.FromRequest(rq)
lc = l18n.FromRequest(rq) lc = l18n.FromRequest(rq)
meta = viewutil.MetaFrom(w, rq) meta = viewutil2.MetaFrom(w, rq)
hyphaName = util.HyphaNameFromRq(rq, "edit") hyphaName = util.HyphaNameFromRq(rq, "edit")
h = hyphae.ByName(hyphaName) h = hyphae2.ByName(hyphaName)
isNew bool isNew bool
content string content string
err error err error
) )
if err := shroom.CanEdit(u, h, lc); err != nil { if err := shroom2.CanEdit(u, h, lc); err != nil {
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error()) viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
return return
} }
switch h.(type) { switch h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
isNew = true isNew = true
default: default:
content, err = hyphae.FetchMycomarkupFile(h) content, err = hyphae2.FetchMycomarkupFile(h)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, lc.Get("ui.error_text_fetch")) viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, lc.Get("ui.error_text_fetch"))
return return
} }
} }
@ -177,11 +176,11 @@ func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
var ( var (
u = user.FromRequest(rq) u = user.FromRequest(rq)
meta = viewutil.MetaFrom(w, rq) meta = viewutil2.MetaFrom(w, rq)
hyphaName = util.HyphaNameFromRq(rq, "upload-text") hyphaName = util.HyphaNameFromRq(rq, "upload-text")
h = hyphae.ByName(hyphaName) h = hyphae2.ByName(hyphaName)
_, isNew = h.(*hyphae.EmptyHypha) _, isNew = h.(*hyphae2.EmptyHypha)
textData = rq.PostFormValue("text") textData = rq.PostFormValue("text")
action = rq.PostFormValue("action") action = rq.PostFormValue("action")
@ -195,8 +194,8 @@ func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
return return
} }
if err := shroom.UploadText(h, []byte(textData), message, u); err != nil { if err := shroom2.UploadText(h, []byte(textData), message, u); err != nil {
viewutil.HttpErr(meta, http.StatusForbidden, hyphaName, err.Error()) viewutil2.HttpErr(meta, http.StatusForbidden, hyphaName, err.Error())
return return
} }
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther) http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)
@ -208,17 +207,17 @@ func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) {
rq.ParseMultipartForm(10 << 20) // Set upload limit rq.ParseMultipartForm(10 << 20) // Set upload limit
var ( var (
hyphaName = util.HyphaNameFromRq(rq, "upload-binary") hyphaName = util.HyphaNameFromRq(rq, "upload-binary")
h = hyphae.ByName(hyphaName) h = hyphae2.ByName(hyphaName)
u = user.FromRequest(rq) u = user.FromRequest(rq)
lc = l18n.FromRequest(rq) lc = l18n.FromRequest(rq)
file, handler, err = rq.FormFile("binary") file, handler, err = rq.FormFile("binary")
meta = viewutil.MetaFrom(w, rq) meta = viewutil2.MetaFrom(w, rq)
) )
if err != nil { if err != nil {
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error()) viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
} }
if err := shroom.CanAttach(u, h, lc); err != nil { if err := shroom2.CanAttach(u, h, lc); err != nil {
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error()) viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
} }
// If file is not passed: // If file is not passed:
@ -235,8 +234,8 @@ func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) {
mime = handler.Header.Get("Content-Type") mime = handler.Header.Get("Content-Type")
) )
if err := shroom.UploadBinary(h, mime, file, u); err != nil { if err := shroom2.UploadBinary(h, mime, file, u); err != nil {
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error()) viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
return return
} }
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther) http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)

View File

@ -10,8 +10,8 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{block "title" .}}{{end}}</title> <title>{{block "title" .}}{{end}}</title>
<link rel="icon" href="/static/favicon.ico"> <link rel="icon" href="/web/static/favicon.ico">
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="/web/static/style.css">
{{range .HeadElements}}{{.}}{{end}} {{range .HeadElements}}{{.}}{{end}}
</head> </head>
<body data-rrh-addr="{{if .Addr}}{{.Addr}}{{else}}{{.Meta.Addr}}{{end}}"{{range $key, $value := .BodyAttributes}} data-rrh-{{$key}}="{{$value}}"{{end}}> <body data-rrh-addr="{{if .Addr}}{{.Addr}}{{else}}{{.Meta.Addr}}{{end}}"{{range $key, $value := .BodyAttributes}} data-rrh-{{$key}}="{{$value}}"{{end}}>
@ -45,9 +45,9 @@
</nav> </nav>
</header> </header>
{{block "body" .}}{{end}} {{block "body" .}}{{end}}
<script src="/static/common.js"></script> <script src="/web/static/common.js"></script>
<script src="/static/shortcuts.js"></script> <script src="/web/static/shortcuts.js"></script>
<script src="/static/view.js"></script> <script src="/web/static/view.js"></script>
{{range .CommonScripts}} {{range .CommonScripts}}
<script src="{{.}}"></script> <script src="{{.}}"></script>
{{end}} {{end}}

View File

@ -3,12 +3,11 @@ package newtmpl
import ( import (
"embed" "embed"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"html/template" "html/template"
"strings" "strings"
"github.com/bouncepaw/mycorrhiza/viewutil"
) )
//go:embed *.html //go:embed *.html
@ -85,13 +84,13 @@ func translationsIntoTemplates(m map[string]string) string {
return sb.String() return sb.String()
} }
func (p *Page) RenderTo(meta viewutil.Meta, data map[string]any) error { func (p *Page) RenderTo(meta viewutil2.Meta, data map[string]any) error {
data["Meta"] = meta data["Meta"] = meta
data["HeadElements"] = meta.HeadElements data["HeadElements"] = meta.HeadElements
data["BodyAttributes"] = meta.BodyAttributes data["BodyAttributes"] = meta.BodyAttributes
data["CommonScripts"] = cfg.CommonScripts data["CommonScripts"] = cfg.CommonScripts
data["EditScripts"] = cfg.EditScripts data["EditScripts"] = cfg.EditScripts
data["HeaderLinks"] = viewutil.HeaderLinks data["HeaderLinks"] = viewutil2.HeaderLinks
tmpl := p.TemplateEnglish tmpl := p.TemplateEnglish
if meta.LocaleIsRussian() { if meta.LocaleIsRussian() {

View File

@ -2,8 +2,8 @@ package web
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/bouncepaw/mycorrhiza/web/newtmpl" "github.com/bouncepaw/mycorrhiza/web/newtmpl"
viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
) )
//go:embed views/*.html //go:embed views/*.html
@ -11,15 +11,15 @@ var fs embed.FS
var pageOrphans, pageBacklinks, pageUserList, pageChangePassword *newtmpl.Page var pageOrphans, pageBacklinks, pageUserList, pageChangePassword *newtmpl.Page
var panelChain, listChain, newUserChain, editUserChain, deleteUserChain viewutil.Chain var panelChain, listChain, newUserChain, editUserChain, deleteUserChain viewutil2.Chain
func initPages() { func initPages() {
panelChain = viewutil.CopyEnRuWith(fs, "views/admin-panel.html", adminTranslationRu) panelChain = viewutil2.CopyEnRuWith(fs, "views/admin-panel.html", adminTranslationRu)
listChain = viewutil.CopyEnRuWith(fs, "views/admin-user-list.html", adminTranslationRu) listChain = viewutil2.CopyEnRuWith(fs, "views/admin-user-list.html", adminTranslationRu)
newUserChain = viewutil.CopyEnRuWith(fs, "views/admin-new-user.html", adminTranslationRu) newUserChain = viewutil2.CopyEnRuWith(fs, "views/admin-new-user.html", adminTranslationRu)
editUserChain = viewutil.CopyEnRuWith(fs, "views/admin-edit-user.html", adminTranslationRu) editUserChain = viewutil2.CopyEnRuWith(fs, "views/admin-edit-user.html", adminTranslationRu)
deleteUserChain = viewutil.CopyEnRuWith(fs, "views/admin-delete-user.html", adminTranslationRu) deleteUserChain = viewutil2.CopyEnRuWith(fs, "views/admin-delete-user.html", adminTranslationRu)
pageOrphans = newtmpl.NewPage(fs, "views/orphans.html", map[string]string{ pageOrphans = newtmpl.NewPage(fs, "views/orphans.html", map[string]string{
"orphaned hyphae": "Гифы-сироты", "orphaned hyphae": "Гифы-сироты",

View File

@ -2,19 +2,18 @@ package web
import ( import (
"fmt" "fmt"
user2 "github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil" "github.com/bouncepaw/mycorrhiza/web/viewutil"
"mime" "mime"
"net/http" "net/http"
"reflect" "reflect"
"github.com/bouncepaw/mycorrhiza/user"
) )
func handlerUserChangePassword(w http.ResponseWriter, rq *http.Request) { func handlerUserChangePassword(w http.ResponseWriter, rq *http.Request) {
u := user.FromRequest(rq) u := user2.FromRequest(rq)
// TODO: is there a better way? // TODO: is there a better way?
if reflect.DeepEqual(u, user.EmptyUser()) || u == nil { if reflect.DeepEqual(u, user2.EmptyUser()) || u == nil {
util.HTTP404Page(w, "404 page not found") util.HTTP404Page(w, "404 page not found")
return return
} }
@ -22,7 +21,7 @@ func handlerUserChangePassword(w http.ResponseWriter, rq *http.Request) {
f := util.FormDataFromRequest(rq, []string{"current_password", "password", "password_confirm"}) f := util.FormDataFromRequest(rq, []string{"current_password", "password", "password_confirm"})
currentPassword := f.Get("current_password") currentPassword := f.Get("current_password")
if user.CredentialsOK(u.Name, currentPassword) { if user2.CredentialsOK(u.Name, currentPassword) {
password := f.Get("password") password := f.Get("password")
passwordConfirm := f.Get("password_confirm") passwordConfirm := f.Get("password_confirm")
// server side validation // server side validation
@ -35,7 +34,7 @@ func handlerUserChangePassword(w http.ResponseWriter, rq *http.Request) {
if err := u.ChangePassword(password); err != nil { if err := u.ChangePassword(password); err != nil {
f = f.WithError(err) f = f.WithError(err)
} else { } else {
if err := user.SaveUserDatabase(); err != nil { if err := user2.SaveUserDatabase(); err != nil {
u.Password = previousPassword u.Password = previousPassword
f = f.WithError(err) f = f.WithError(err)
} else { } else {

View File

@ -3,12 +3,15 @@ package web
import ( import (
"fmt" "fmt"
"git.sr.ht/~bouncepaw/mycomarkup/v5" "git.sr.ht/~bouncepaw/mycomarkup/v5"
"github.com/bouncepaw/mycorrhiza/backlinks"
"github.com/bouncepaw/mycorrhiza/categories" "github.com/bouncepaw/mycorrhiza/categories"
"github.com/bouncepaw/mycorrhiza/files"
views2 "github.com/bouncepaw/mycorrhiza/hypview" views2 "github.com/bouncepaw/mycorrhiza/hypview"
"github.com/bouncepaw/mycorrhiza/internal/backlinks"
"github.com/bouncepaw/mycorrhiza/internal/files"
hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/internal/mimetype"
"github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/mycoopts" "github.com/bouncepaw/mycorrhiza/mycoopts"
"github.com/bouncepaw/mycorrhiza/viewutil" viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"io" "io"
"log" "log"
"net/http" "net/http"
@ -22,10 +25,7 @@ import (
"git.sr.ht/~bouncepaw/mycomarkup/v5/mycocontext" "git.sr.ht/~bouncepaw/mycomarkup/v5/mycocontext"
"git.sr.ht/~bouncepaw/mycomarkup/v5/tools" "git.sr.ht/~bouncepaw/mycomarkup/v5/tools"
"github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/l18n" "github.com/bouncepaw/mycorrhiza/l18n"
"github.com/bouncepaw/mycorrhiza/mimetype"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )
@ -59,13 +59,13 @@ func handlerMedia(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
var ( var (
hyphaName = util.HyphaNameFromRq(rq, "media") hyphaName = util.HyphaNameFromRq(rq, "media")
h = hyphae.ByName(hyphaName) h = hyphae2.ByName(hyphaName)
u = user.FromRequest(rq) u = user.FromRequest(rq)
lc = l18n.FromRequest(rq) lc = l18n.FromRequest(rq)
) )
util.HTTP200Page(w, util.HTTP200Page(w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
lc.Get("ui.media_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName)}), lc.Get("ui.media_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName)}),
views2.MediaMenu(rq, h, u), views2.MediaMenu(rq, h, u),
map[string]string{}, map[string]string{},
@ -85,11 +85,11 @@ func handlerRevisionText(w http.ResponseWriter, rq *http.Request) {
} }
var ( var (
hyphaName = util.CanonicalName(slug) hyphaName = util.CanonicalName(slug)
h = hyphae.ByName(hyphaName) h = hyphae2.ByName(hyphaName)
) )
w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Header().Set("Content-Type", "text/plain; charset=utf-8")
switch h := h.(type) { switch h := h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
var mycoFilePath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco") var mycoFilePath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco")
var textContents, err = history.FileAtRevision(mycoFilePath, revHash) var textContents, err = history.FileAtRevision(mycoFilePath, revHash)
@ -102,7 +102,7 @@ func handlerRevisionText(w http.ResponseWriter, rq *http.Request) {
log.Printf("Serving text of %s from %s at revision %s\n", hyphaName, mycoFilePath, revHash) log.Printf("Serving text of %s from %s at revision %s\n", hyphaName, mycoFilePath, revHash)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
_, _ = io.WriteString(w, textContents) _, _ = io.WriteString(w, textContents)
case hyphae.ExistingHypha: case hyphae2.ExistingHypha:
if !h.HasTextFile() { if !h.HasTextFile() {
log.Printf(`Media hypha %s has no text`) log.Printf(`Media hypha %s has no text`)
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
@ -133,16 +133,16 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
} }
var ( var (
hyphaName = util.CanonicalName(slug) hyphaName = util.CanonicalName(slug)
h = hyphae.ByName(hyphaName) h = hyphae2.ByName(hyphaName)
contents = fmt.Sprintf(`<p>%s</p>`, lc.Get("ui.revision_no_text")) contents = fmt.Sprintf(`<p>%s</p>`, lc.Get("ui.revision_no_text"))
textContents string textContents string
err error err error
mycoFilePath string mycoFilePath string
) )
switch h := h.(type) { switch h := h.(type) {
case hyphae.ExistingHypha: case hyphae2.ExistingHypha:
mycoFilePath = h.TextFilePath() mycoFilePath = h.TextFilePath()
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
mycoFilePath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco") mycoFilePath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco")
} }
textContents, err = history.FileAtRevision(mycoFilePath, revHash) textContents, err = history.FileAtRevision(mycoFilePath, revHash)
@ -152,7 +152,7 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
} }
page := views2.Revision( page := views2.Revision(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
h, h,
contents, contents,
revHash, revHash,
@ -161,8 +161,8 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprint( _, _ = fmt.Fprint(
w, w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
lc.Get("ui.revision_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName), "rev": revHash}), lc.Get("ui.revision_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName), "rev": revHash}),
page, page,
map[string]string{}, map[string]string{},
@ -174,8 +174,8 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
func handlerText(w http.ResponseWriter, rq *http.Request) { func handlerText(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
hyphaName := util.HyphaNameFromRq(rq, "text") hyphaName := util.HyphaNameFromRq(rq, "text")
switch h := hyphae.ByName(hyphaName).(type) { switch h := hyphae2.ByName(hyphaName).(type) {
case hyphae.ExistingHypha: case hyphae2.ExistingHypha:
log.Println("Serving", h.TextFilePath()) log.Println("Serving", h.TextFilePath())
w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Header().Set("Content-Type", "text/plain; charset=utf-8")
http.ServeFile(w, rq, h.TextFilePath()) http.ServeFile(w, rq, h.TextFilePath())
@ -186,12 +186,12 @@ func handlerText(w http.ResponseWriter, rq *http.Request) {
func handlerBinary(w http.ResponseWriter, rq *http.Request) { func handlerBinary(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
hyphaName := util.HyphaNameFromRq(rq, "binary") hyphaName := util.HyphaNameFromRq(rq, "binary")
switch h := hyphae.ByName(hyphaName).(type) { switch h := hyphae2.ByName(hyphaName).(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
case *hyphae.TextualHypha: case *hyphae2.TextualHypha:
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
log.Printf("Textual hypha %s has no media, cannot serve\n", h.CanonicalName()) log.Printf("Textual hypha %s has no media, cannot serve\n", h.CanonicalName())
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
log.Println("Serving", h.MediaFilePath()) log.Println("Serving", h.MediaFilePath())
w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(h.MediaFilePath()))) w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(h.MediaFilePath())))
http.ServeFile(w, rq, h.MediaFilePath()) http.ServeFile(w, rq, h.MediaFilePath())
@ -203,22 +203,22 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
var ( var (
hyphaName = util.HyphaNameFromRq(rq, "page", "hypha") hyphaName = util.HyphaNameFromRq(rq, "page", "hypha")
h = hyphae.ByName(hyphaName) h = hyphae2.ByName(hyphaName)
contents string contents string
openGraph string openGraph string
lc = l18n.FromRequest(rq) lc = l18n.FromRequest(rq)
) )
switch h := h.(type) { switch h := h.(type) {
case *hyphae.EmptyHypha: case *hyphae2.EmptyHypha:
util.HTTP404Page(w, util.HTTP404Page(w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
util.BeautifulName(hyphaName), util.BeautifulName(hyphaName),
views2.Hypha(viewutil.MetaFrom(w, rq), h, contents), views2.Hypha(viewutil2.MetaFrom(w, rq), h, contents),
map[string]string{}, map[string]string{},
openGraph)) openGraph))
case hyphae.ExistingHypha: case hyphae2.ExistingHypha:
fileContentsT, errT := os.ReadFile(h.TextFilePath()) fileContentsT, errT := os.ReadFile(h.TextFilePath())
if errT == nil { if errT == nil {
ctx, _ := mycocontext.ContextFromStringInput(string(fileContentsT), mycoopts.MarkupOptions(hyphaName)) ctx, _ := mycocontext.ContextFromStringInput(string(fileContentsT), mycoopts.MarkupOptions(hyphaName))
@ -228,17 +228,17 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
openGraph = getOpenGraph() openGraph = getOpenGraph()
} }
switch h := h.(type) { switch h := h.(type) {
case *hyphae.MediaHypha: case *hyphae2.MediaHypha:
contents = mycoopts.Media(h, lc) + contents contents = mycoopts.Media(h, lc) + contents
} }
category_list := ":" + strings.Join(categories.CategoriesWithHypha(h.CanonicalName()), ":") + ":" category_list := ":" + strings.Join(categories.CategoriesWithHypha(h.CanonicalName()), ":") + ":"
util.HTTP200Page(w, util.HTTP200Page(w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
util.BeautifulName(hyphaName), util.BeautifulName(hyphaName),
views2.Hypha(viewutil.MetaFrom(w, rq), h, contents), views2.Hypha(viewutil2.MetaFrom(w, rq), h, contents),
map[string]string{"cats": category_list}, map[string]string{"cats": category_list},
openGraph)) openGraph))
} }
@ -248,7 +248,7 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
func handlerBacklinks(w http.ResponseWriter, rq *http.Request) { func handlerBacklinks(w http.ResponseWriter, rq *http.Request) {
hyphaName := util.HyphaNameFromRq(rq, "backlinks") hyphaName := util.HyphaNameFromRq(rq, "backlinks")
_ = pageBacklinks.RenderTo(viewutil.MetaFrom(w, rq), _ = pageBacklinks.RenderTo(viewutil2.MetaFrom(w, rq),
map[string]any{ map[string]any{
"Addr": "/backlinks/" + hyphaName, "Addr": "/backlinks/" + hyphaName,
"HyphaName": hyphaName, "HyphaName": hyphaName,
@ -257,7 +257,7 @@ func handlerBacklinks(w http.ResponseWriter, rq *http.Request) {
} }
func handlerOrphans(w http.ResponseWriter, rq *http.Request) { func handlerOrphans(w http.ResponseWriter, rq *http.Request) {
_ = pageOrphans.RenderTo(viewutil.MetaFrom(w, rq), _ = pageOrphans.RenderTo(viewutil2.MetaFrom(w, rq),
map[string]any{ map[string]any{
"Addr": "/orphans", "Addr": "/orphans",
"Orphans": backlinks.Orphans(), "Orphans": backlinks.Orphans(),

View File

@ -108,11 +108,11 @@ main h1:not(.navi-title) {font-size:1.7rem;}
blockquote { margin: 0; padding-left: .75rem; } blockquote { margin: 0; padding-left: .75rem; }
.wikilink_external::before { display: inline-block; width: 18px; height: 16px; vertical-align: sub; } .wikilink_external::before { display: inline-block; width: 18px; height: 16px; vertical-align: sub; }
/* .wikilink_external { padding-left: 16px; } */ /* .wikilink_external { padding-left: 16px; } */
.wikilink_gopher::before { content: url("/static/icon/gopher-proto.svg"); } .wikilink_gopher::before { content: url("/web/staticatic/icon/gopher-proto.svg"); }
.wikilink_http::before, .wikilink_https::before { content: url("/static/icon/http-proto.svg"); } .wikilink_http::before, .wikilink_https::before { content: url("/web/staticatic/icon/http-proto.svg"); }
/* .wikilink_https { background: transparent url("/static/icon/http-proto.svg") center left no-repeat; } */ /* .wikilink_https { background: transparent url("/static/icon/http-proto.svg") center left no-repeat; } */
.wikilink_gemini::before { content: url("/static/icon/gemini-proto.svg"); } .wikilink_gemini::before { content: url("/web/staticatic/icon/gemini-proto.svg"); }
.wikilink_mailto::before { content: url("/static/icon/mailto-proto.svg"); } .wikilink_mailto::before { content: url("/web/staticatic/icon/mailto-proto.svg"); }
article { overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; line-height: 150%; } article { overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; line-height: 150%; }
main h1 { margin: .5rem 0 0 0; } main h1 { margin: .5rem 0 0 0; }
@ -356,7 +356,7 @@ kbd {
margin: 0; margin: 0;
padding: 8px; padding: 8px;
border: none; border: none;
background: url(/static/icon/x.svg) no-repeat 8px 8px / 16px 16px; background: url(/web/static/icon/x.svg) no-repeat 8px 8px / 16px 16px;
width: 32px; width: 32px;
height: 32px; height: 32px;
cursor: pointer; cursor: pointer;

View File

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 531 B

View File

Before

Width:  |  Height:  |  Size: 473 B

After

Width:  |  Height:  |  Size: 473 B

View File

Before

Width:  |  Height:  |  Size: 951 B

After

Width:  |  Height:  |  Size: 951 B

View File

Before

Width:  |  Height:  |  Size: 627 B

After

Width:  |  Height:  |  Size: 627 B

View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

View File

Before

Width:  |  Height:  |  Size: 888 B

After

Width:  |  Height:  |  Size: 888 B

View File

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 139 B

View File

@ -10,8 +10,8 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{block "title" .}}{{end}}</title> <title>{{block "title" .}}{{end}}</title>
<link rel="icon" href="/static/favicon.ico"> <link rel="icon" href="/web/static/favicon.ico">
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="/web/static/style.css">
{{range .HeadElements}}{{.}}{{end}} {{range .HeadElements}}{{.}}{{end}}
</head> </head>
<body data-rrh-addr="{{if .Addr}}{{.Addr}}{{else}}{{.Meta.Addr}}{{end}}"{{range $key, $value := .BodyAttributes}} data-rrh-{{$key}}="{{$value}}"{{end}}> <body data-rrh-addr="{{if .Addr}}{{.Addr}}{{else}}{{.Meta.Addr}}{{end}}"{{range $key, $value := .BodyAttributes}} data-rrh-{{$key}}="{{$value}}"{{end}}>
@ -45,9 +45,9 @@
</nav> </nav>
</header> </header>
{{block "body" .}}{{end}} {{block "body" .}}{{end}}
<script src="/static/common.js"></script> <script src="/web/static/common.js"></script>
<script src="/static/shortcuts.js"></script> <script src="/web/static/shortcuts.js"></script>
<script src="/static/view.js"></script> <script src="/web/static/view.js"></script>
{{range .CommonScripts}} {{range .CommonScripts}}
<script src="{{.}}"></script> <script src="{{.}}"></script>
{{end}} {{end}}

View File

@ -1,8 +1,8 @@
package viewutil package viewutil
import ( import (
user2 "github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/l18n" "github.com/bouncepaw/mycorrhiza/l18n"
"github.com/bouncepaw/mycorrhiza/user"
"io" "io"
"net/http" "net/http"
) )
@ -10,7 +10,7 @@ import (
// Meta is a bundle of common stuffs used by views, templates. // Meta is a bundle of common stuffs used by views, templates.
type Meta struct { type Meta struct {
Lc *l18n.Localizer Lc *l18n.Localizer
U *user.User U *user2.User
W io.Writer W io.Writer
Addr string Addr string
@ -23,7 +23,7 @@ type Meta struct {
func MetaFrom(w http.ResponseWriter, rq *http.Request) Meta { func MetaFrom(w http.ResponseWriter, rq *http.Request) Meta {
return Meta{ return Meta{
Lc: l18n.FromRequest(rq), Lc: l18n.FromRequest(rq),
U: user.FromRequest(rq), U: user2.FromRequest(rq),
W: w, W: w,
Addr: rq.URL.Path, Addr: rq.URL.Path,
} }

View File

@ -4,12 +4,12 @@ package viewutil
import ( import (
"embed" "embed"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
"io/fs" "io/fs"
"log" "log"
"strings" "strings"
"text/template" // TODO: save the world "text/template" // TODO: save the world
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )

View File

@ -4,8 +4,10 @@ package web
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
user2 "github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/l18n" "github.com/bouncepaw/mycorrhiza/l18n"
"github.com/bouncepaw/mycorrhiza/viewutil" viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
"io" "io"
"log" "log"
"mime" "mime"
@ -22,8 +24,6 @@ import (
"github.com/bouncepaw/mycorrhiza/misc" "github.com/bouncepaw/mycorrhiza/misc"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
) )
@ -63,7 +63,7 @@ func Handler() http.Handler {
r := router.PathPrefix("").Subrouter() r := router.PathPrefix("").Subrouter()
r.Use(func(next http.Handler) http.Handler { r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, rq *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, rq *http.Request) {
user := user.FromRequest(rq) user := user2.FromRequest(rq)
if !user.ShowLockMaybe(w, rq) { if !user.ShowLockMaybe(w, rq) {
next.ServeHTTP(w, rq) next.ServeHTTP(w, rq)
} }
@ -117,7 +117,7 @@ func Handler() http.Handler {
func groupMiddleware(group string) func(http.Handler) http.Handler { func groupMiddleware(group string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, rq *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, rq *http.Request) {
if cfg.UseAuth && user.CanProceed(rq, group) { if cfg.UseAuth && user2.CanProceed(rq, group) {
next.ServeHTTP(w, rq) next.ServeHTTP(w, rq)
return return
} }
@ -133,8 +133,8 @@ func groupMiddleware(group string) func(http.Handler) http.Handler {
// Auth // Auth
func handlerUserList(w http.ResponseWriter, rq *http.Request) { func handlerUserList(w http.ResponseWriter, rq *http.Request) {
admins, moderators, editors, readers := user.UsersInGroups() admins, moderators, editors, readers := user2.UsersInGroups()
_ = pageUserList.RenderTo(viewutil.MetaFrom(w, rq), _ = pageUserList.RenderTo(viewutil2.MetaFrom(w, rq),
map[string]any{ map[string]any{
"Admins": admins, "Admins": admins,
"Moderators": moderators, "Moderators": moderators,
@ -154,8 +154,8 @@ func handlerRegister(w http.ResponseWriter, rq *http.Request) {
if rq.Method == http.MethodGet { if rq.Method == http.MethodGet {
_, _ = io.WriteString( _, _ = io.WriteString(
w, w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
lc.Get("auth.register_title"), lc.Get("auth.register_title"),
auth.Register(rq), auth.Register(rq),
map[string]string{}, map[string]string{},
@ -167,7 +167,7 @@ func handlerRegister(w http.ResponseWriter, rq *http.Request) {
var ( var (
username = rq.PostFormValue("username") username = rq.PostFormValue("username")
password = rq.PostFormValue("password") password = rq.PostFormValue("password")
err = user.Register(username, password, "editor", "local", false) err = user2.Register(username, password, "editor", "local", false)
) )
if err != nil { if err != nil {
log.Printf("Failed to register %s: %s", username, err.Error()) log.Printf("Failed to register %s: %s", username, err.Error())
@ -175,8 +175,8 @@ func handlerRegister(w http.ResponseWriter, rq *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
_, _ = io.WriteString( _, _ = io.WriteString(
w, w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
lc.Get("auth.register_title"), lc.Get("auth.register_title"),
fmt.Sprintf( fmt.Sprintf(
`<main class="main-width"><p>%s</p><p><a href="/register">%s<a></p></main>`, `<main class="main-width"><p>%s</p><p><a href="/register">%s<a></p></main>`,
@ -190,7 +190,7 @@ func handlerRegister(w http.ResponseWriter, rq *http.Request) {
} }
log.Printf("Successfully registered %s", username) log.Printf("Successfully registered %s", username)
if err := user.LoginDataHTTP(w, username, password); err != nil { if err := user2.LoginDataHTTP(w, username, password); err != nil {
return return
} }
http.Redirect(w, rq, "/"+rq.URL.RawQuery, http.StatusSeeOther) http.Redirect(w, rq, "/"+rq.URL.RawQuery, http.StatusSeeOther)
@ -200,7 +200,7 @@ func handlerRegister(w http.ResponseWriter, rq *http.Request) {
func handlerLogout(w http.ResponseWriter, rq *http.Request) { func handlerLogout(w http.ResponseWriter, rq *http.Request) {
if rq.Method == http.MethodGet { if rq.Method == http.MethodGet {
var ( var (
u = user.FromRequest(rq) u = user2.FromRequest(rq)
can = u != nil can = u != nil
lc = l18n.FromRequest(rq) lc = l18n.FromRequest(rq)
) )
@ -214,10 +214,10 @@ func handlerLogout(w http.ResponseWriter, rq *http.Request) {
} }
_, _ = io.WriteString( _, _ = io.WriteString(
w, w,
viewutil.Base(viewutil.MetaFrom(w, rq), lc.Get("auth.logout_title"), auth.Logout(can, lc), map[string]string{}), viewutil2.Base(viewutil2.MetaFrom(w, rq), lc.Get("auth.logout_title"), auth.Logout(can, lc), map[string]string{}),
) )
} else if rq.Method == http.MethodPost { } else if rq.Method == http.MethodPost {
user.LogoutFromRequest(w, rq) user2.LogoutFromRequest(w, rq)
http.Redirect(w, rq, "/", http.StatusSeeOther) http.Redirect(w, rq, "/", http.StatusSeeOther)
} }
} }
@ -230,8 +230,8 @@ func handlerLogin(w http.ResponseWriter, rq *http.Request) {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
_, _ = io.WriteString( _, _ = io.WriteString(
w, w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
lc.Get("auth.login_title"), lc.Get("auth.login_title"),
auth.Login(lc), auth.Login(lc),
map[string]string{}, map[string]string{},
@ -241,12 +241,12 @@ func handlerLogin(w http.ResponseWriter, rq *http.Request) {
var ( var (
username = util.CanonicalName(rq.PostFormValue("username")) username = util.CanonicalName(rq.PostFormValue("username"))
password = rq.PostFormValue("password") password = rq.PostFormValue("password")
err = user.LoginDataHTTP(w, username, password) err = user2.LoginDataHTTP(w, username, password)
) )
if err != nil { if err != nil {
w.Header().Set("Content-Type", "text/html;charset=utf-8") w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
_, _ = io.WriteString(w, viewutil.Base(viewutil.MetaFrom(w, rq), err.Error(), auth.LoginError(err.Error(), lc), map[string]string{})) _, _ = io.WriteString(w, viewutil2.Base(viewutil2.MetaFrom(w, rq), err.Error(), auth.LoginError(err.Error(), lc), map[string]string{}))
return return
} }
http.Redirect(w, rq, "/", http.StatusSeeOther) http.Redirect(w, rq, "/", http.StatusSeeOther)
@ -261,8 +261,8 @@ func handlerTelegramLogin(w http.ResponseWriter, rq *http.Request) {
var ( var (
values = rq.URL.Query() values = rq.URL.Query()
username = strings.ToLower(values.Get("username")) username = strings.ToLower(values.Get("username"))
seemsValid = user.TelegramAuthParamsAreValid(values) seemsValid = user2.TelegramAuthParamsAreValid(values)
err = user.Register( err = user2.Register(
username, username,
"", // Password matters not "", // Password matters not
"editor", "editor",
@ -272,7 +272,7 @@ func handlerTelegramLogin(w http.ResponseWriter, rq *http.Request) {
) )
// If registering a user via Telegram failed, because a Telegram user with this name // If registering a user via Telegram failed, because a Telegram user with this name
// has already registered, then everything is actually ok! // has already registered, then everything is actually ok!
if user.HasUsername(username) && user.ByName(username).Source == "telegram" { if user2.HasUsername(username) && user2.ByName(username).Source == "telegram" {
err = nil err = nil
} }
@ -285,8 +285,8 @@ func handlerTelegramLogin(w http.ResponseWriter, rq *http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
_, _ = io.WriteString( _, _ = io.WriteString(
w, w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
lc.Get("ui.error"), lc.Get("ui.error"),
fmt.Sprintf( fmt.Sprintf(
`<main class="main-width"><p>%s</p><p>%s</p><p><a href="/login">%s<a></p></main>`, `<main class="main-width"><p>%s</p><p>%s</p><p><a href="/login">%s<a></p></main>`,
@ -300,14 +300,14 @@ func handlerTelegramLogin(w http.ResponseWriter, rq *http.Request) {
return return
} }
errmsg := user.LoginDataHTTP(w, username, "") errmsg := user2.LoginDataHTTP(w, username, "")
if errmsg != nil { if errmsg != nil {
log.Printf("Failed to login %s using Telegram: %s", username, err.Error()) log.Printf("Failed to login %s using Telegram: %s", username, err.Error())
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
_, _ = io.WriteString( _, _ = io.WriteString(
w, w,
viewutil.Base( viewutil2.Base(
viewutil.MetaFrom(w, rq), viewutil2.MetaFrom(w, rq),
"Error", "Error",
fmt.Sprintf( fmt.Sprintf(
`<main class="main-width"><p>%s</p><p>%s</p><p><a href="/login">%s<a></p></main>`, `<main class="main-width"><p>%s</p><p>%s</p><p><a href="/login">%s<a></p></main>`,