mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-04 18:19:54 +00:00
Rename Hypher to Hypha
This commit is contained in:
parent
4890c21012
commit
c0ac87cdbd
@ -2,6 +2,7 @@
|
||||
package backlinks
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/hyphae"
|
||||
@ -53,7 +54,7 @@ func IndexBacklinks() {
|
||||
}
|
||||
|
||||
// BacklinksCount returns the amount of backlinks to the hypha.
|
||||
func BacklinksCount(h hyphae.Hypher) int {
|
||||
func BacklinksCount(h hyphae.Hypha) int {
|
||||
if links, exists := backlinkIndex[h.CanonicalName()]; exists {
|
||||
return len(links)
|
||||
}
|
||||
@ -71,15 +72,26 @@ func toLinkSet(xs []string) linkSet {
|
||||
return result
|
||||
}
|
||||
|
||||
func fetchText(h hyphae.Hypher) string {
|
||||
if !h.HasTextPart() {
|
||||
func fetchText(h hyphae.Hypha) string {
|
||||
var path string
|
||||
switch h := h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
return ""
|
||||
case *hyphae.TextualHypha:
|
||||
path = h.TextFilePath()
|
||||
case *hyphae.MediaHypha:
|
||||
if !h.HasTextFile() {
|
||||
return ""
|
||||
}
|
||||
path = h.TextFilePath()
|
||||
}
|
||||
|
||||
text, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return ""
|
||||
}
|
||||
text, err := os.ReadFile(h.TextPartPath())
|
||||
if err == nil {
|
||||
return string(text)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// backlinkIndexOperation is an operation for the backlink index. This operation is executed async-safe.
|
||||
|
@ -9,26 +9,26 @@ import (
|
||||
)
|
||||
|
||||
// UpdateBacklinksAfterEdit is a creation/editing hook for backlinks index
|
||||
func UpdateBacklinksAfterEdit(h hyphae.Hypher, oldText string) {
|
||||
func UpdateBacklinksAfterEdit(h hyphae.Hypha, oldText string) {
|
||||
oldLinks := extractHyphaLinksFromContent(h.CanonicalName(), oldText)
|
||||
newLinks := extractHyphaLinks(h)
|
||||
backlinkConveyor <- backlinkIndexEdit{h.CanonicalName(), oldLinks, newLinks}
|
||||
}
|
||||
|
||||
// UpdateBacklinksAfterDelete is a deletion hook for backlinks index
|
||||
func UpdateBacklinksAfterDelete(h hyphae.Hypher, oldText string) {
|
||||
func UpdateBacklinksAfterDelete(h hyphae.Hypha, oldText string) {
|
||||
oldLinks := extractHyphaLinksFromContent(h.CanonicalName(), oldText)
|
||||
backlinkConveyor <- backlinkIndexDeletion{h.CanonicalName(), oldLinks}
|
||||
}
|
||||
|
||||
// UpdateBacklinksAfterRename is a renaming hook for backlinks index
|
||||
func UpdateBacklinksAfterRename(h hyphae.Hypher, oldName string) {
|
||||
func UpdateBacklinksAfterRename(h hyphae.Hypha, oldName string) {
|
||||
actualLinks := extractHyphaLinks(h)
|
||||
backlinkConveyor <- backlinkIndexRenaming{oldName, h.CanonicalName(), actualLinks}
|
||||
}
|
||||
|
||||
// extractHyphaLinks extracts hypha links from a desired hypha
|
||||
func extractHyphaLinks(h hyphae.Hypher) []string {
|
||||
func extractHyphaLinks(h hyphae.Hypha) []string {
|
||||
return extractHyphaLinksFromContent(h.CanonicalName(), fetchText(h))
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ func ResetCount() {
|
||||
count.Unlock()
|
||||
}
|
||||
|
||||
// Count how many hyphae there are.
|
||||
// Count how many hyphae there are. This is a O(1), the number of hyphae is stored in memory.
|
||||
func Count() int {
|
||||
count.Lock()
|
||||
defer count.Unlock()
|
||||
|
@ -12,31 +12,17 @@ func (e *EmptyHypha) CanonicalName() string {
|
||||
return e.canonicalName
|
||||
}
|
||||
|
||||
func (e *EmptyHypha) HasTextPart() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *EmptyHypha) TextPartPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// NewEmptyHypha returns an empty hypha struct with given name.
|
||||
func NewEmptyHypha(hyphaName string) *EmptyHypha {
|
||||
return &EmptyHypha{
|
||||
canonicalName: hyphaName,
|
||||
func ExtendEmptyToTextual(e *EmptyHypha, mycoFilePath string) *TextualHypha {
|
||||
return &TextualHypha{
|
||||
canonicalName: e.CanonicalName(),
|
||||
mycoFilePath: mycoFilePath,
|
||||
}
|
||||
}
|
||||
|
||||
func FillEmptyHyphaUpToTextualHypha(e *EmptyHypha, textPath string) *NonEmptyHypha { // sic!
|
||||
return &NonEmptyHypha{
|
||||
name: e.CanonicalName(),
|
||||
TextPath: textPath,
|
||||
}
|
||||
}
|
||||
|
||||
func FillEmptyHyphaUpToMediaHypha(e *EmptyHypha, binaryPath string) *NonEmptyHypha { // sic!
|
||||
return &NonEmptyHypha{
|
||||
name: e.CanonicalName(),
|
||||
binaryPath: binaryPath,
|
||||
func ExtendEmptyToMedia(e *EmptyHypha, mediaFilePath string) *MediaHypha {
|
||||
return &MediaHypha{
|
||||
canonicalName: e.CanonicalName(),
|
||||
mycoFilePath: "",
|
||||
mediaFilePath: mediaFilePath,
|
||||
}
|
||||
}
|
||||
|
39
hyphae/existing_hypha.go
Normal file
39
hyphae/existing_hypha.go
Normal file
@ -0,0 +1,39 @@
|
||||
package hyphae
|
||||
|
||||
import (
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
)
|
||||
|
||||
// ExistingHypha is not EmptyHypha.
|
||||
type ExistingHypha interface {
|
||||
Hypha
|
||||
|
||||
// DoesExist does nothing except marks that the type is an ExistingHypha.
|
||||
DoesExist()
|
||||
|
||||
HasTextFile() bool
|
||||
TextFilePath() string
|
||||
}
|
||||
|
||||
// RenameHyphaTo renames a hypha and renames stored filepaths as needed. The actual files are not moved, move them yourself.
|
||||
func RenameHyphaTo(h ExistingHypha, newName string, replaceName func(string) string) {
|
||||
// TODO: that replaceName is suspicious.
|
||||
newName = util.CanonicalName(newName)
|
||||
byNamesMutex.Lock()
|
||||
h.Lock()
|
||||
delete(byNames, h.CanonicalName())
|
||||
|
||||
switch h := h.(type) {
|
||||
case *TextualHypha:
|
||||
h.canonicalName = newName
|
||||
h.mycoFilePath = replaceName(h.mycoFilePath)
|
||||
case *MediaHypha:
|
||||
h.canonicalName = newName
|
||||
h.mycoFilePath = replaceName(h.mediaFilePath)
|
||||
h.mediaFilePath = replaceName(h.mediaFilePath)
|
||||
}
|
||||
|
||||
byNames[h.CanonicalName()] = h
|
||||
byNamesMutex.Unlock()
|
||||
h.Unlock()
|
||||
}
|
@ -10,34 +10,45 @@ import (
|
||||
|
||||
// Index finds all hypha files in the full `path` and saves them to the hypha storage.
|
||||
func Index(path string) {
|
||||
byNames = make(map[string]Hypher)
|
||||
ch := make(chan Hypher, 5)
|
||||
byNames = make(map[string]ExistingHypha)
|
||||
ch := make(chan ExistingHypha, 5)
|
||||
|
||||
go func(ch chan Hypher) {
|
||||
go func(ch chan ExistingHypha) {
|
||||
indexHelper(path, 0, ch)
|
||||
close(ch)
|
||||
}(ch)
|
||||
|
||||
for nh := range ch {
|
||||
switch oh := ByName(nh.CanonicalName()).(type) {
|
||||
for foundHypha := range ch {
|
||||
switch storedHypha := ByName(foundHypha.CanonicalName()).(type) {
|
||||
case *EmptyHypha:
|
||||
Insert(nh)
|
||||
default:
|
||||
// In case of conflicts the newer hypha overwrites the previous
|
||||
switch nh, oh := nh.(*NonEmptyHypha), oh.(*NonEmptyHypha); {
|
||||
case (nh.Kind() == HyphaText) && (oh.Kind() == HyphaMedia):
|
||||
oh.TextPath = nh.TextPartPath()
|
||||
Insert(foundHypha)
|
||||
|
||||
case (nh.Kind() == HyphaText) && (oh.Kind() == HyphaText):
|
||||
log.Printf("File collision for hypha ‘%s’, using %s rather than %s\n", nh.CanonicalName(), nh.TextPartPath(), oh.TextPartPath())
|
||||
oh.TextPath = nh.TextPartPath()
|
||||
case *TextualHypha:
|
||||
switch foundHypha := foundHypha.(type) {
|
||||
case *TextualHypha: // conflict! overwrite
|
||||
storedHypha.mycoFilePath = foundHypha.mycoFilePath
|
||||
log.Printf(
|
||||
"File collision for hypha ‘%s’, using ‘%s’ rather than ‘%s’\n",
|
||||
foundHypha.CanonicalName(),
|
||||
foundHypha.TextFilePath(),
|
||||
storedHypha.TextFilePath(),
|
||||
)
|
||||
case *MediaHypha: // no conflict
|
||||
Insert(ExtendTextualToMedia(storedHypha, foundHypha.mediaFilePath))
|
||||
}
|
||||
|
||||
case (nh.Kind() == HyphaMedia) && (oh.Kind() == HyphaMedia):
|
||||
log.Printf("File collision for hypha ‘%s’, using %s rather than %s\n", nh.CanonicalName(), nh.BinaryPath(), oh.BinaryPath())
|
||||
oh.SetBinaryPath(nh.BinaryPath())
|
||||
|
||||
case (nh.Kind() == HyphaMedia) && (oh.Kind() == HyphaText):
|
||||
oh.SetBinaryPath(nh.BinaryPath())
|
||||
case *MediaHypha:
|
||||
switch foundHypha := foundHypha.(type) {
|
||||
case *TextualHypha: // no conflict
|
||||
storedHypha.mycoFilePath = foundHypha.mycoFilePath
|
||||
case *MediaHypha: // conflict! overwrite
|
||||
storedHypha.mediaFilePath = foundHypha.mediaFilePath
|
||||
log.Printf(
|
||||
"File collision for hypha ‘%s’, using ‘%s’ rather than ‘%s’\n",
|
||||
foundHypha.CanonicalName(),
|
||||
foundHypha.MediaFilePath(),
|
||||
storedHypha.MediaFilePath(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,7 +58,7 @@ func Index(path string) {
|
||||
// indexHelper finds all hypha files in the full `path` and sends them to the
|
||||
// channel. Handling of duplicate entries and attachment and counting them is
|
||||
// up to the caller.
|
||||
func indexHelper(path string, nestLevel uint, ch chan Hypher) {
|
||||
func indexHelper(path string, nestLevel uint, ch chan ExistingHypha) {
|
||||
nodes, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -64,15 +75,20 @@ func indexHelper(path string, nestLevel uint, ch chan Hypher) {
|
||||
var (
|
||||
hyphaPartPath = filepath.Join(path, node.Name())
|
||||
hyphaName, isText, skip = mimetype.DataFromFilename(hyphaPartPath)
|
||||
hypha = &NonEmptyHypha{name: hyphaName, Exists: true}
|
||||
)
|
||||
if !skip {
|
||||
if isText {
|
||||
hypha.TextPath = hyphaPartPath
|
||||
} else {
|
||||
hypha.SetBinaryPath(hyphaPartPath)
|
||||
ch <- &TextualHypha{
|
||||
canonicalName: hyphaName,
|
||||
mycoFilePath: hyphaPartPath,
|
||||
}
|
||||
} else {
|
||||
ch <- &MediaHypha{
|
||||
canonicalName: hyphaName,
|
||||
mycoFilePath: "",
|
||||
mediaFilePath: hyphaPartPath,
|
||||
}
|
||||
}
|
||||
ch <- hypha
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,25 +22,15 @@ func IsValidName(hyphaName string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type HyphaKind int
|
||||
|
||||
const (
|
||||
HyphaText HyphaKind = iota
|
||||
HyphaMedia
|
||||
)
|
||||
|
||||
// Hypher is a temporary name for this interface. The name will become NonEmptyHypha, once the struct with the said name is deprecated for good.
|
||||
type Hypher interface {
|
||||
// Hypha is a hypha you know and love.
|
||||
type Hypha interface {
|
||||
sync.Locker
|
||||
|
||||
CanonicalName() string
|
||||
|
||||
HasTextPart() bool
|
||||
TextPartPath() string
|
||||
}
|
||||
|
||||
// DeleteHypha deletes the hypha from the storage.
|
||||
func DeleteHypha(h Hypher) {
|
||||
func DeleteHypha(h ExistingHypha) {
|
||||
byNamesMutex.Lock()
|
||||
h.Lock()
|
||||
delete(byNames, h.CanonicalName())
|
||||
@ -49,19 +39,8 @@ func DeleteHypha(h Hypher) {
|
||||
h.Unlock()
|
||||
}
|
||||
|
||||
// RenameHyphaTo renames a hypha and performs respective changes in the storage.
|
||||
func RenameHyphaTo(h Hypher, newName string) {
|
||||
byNamesMutex.Lock()
|
||||
h.Lock()
|
||||
delete(byNames, h.CanonicalName())
|
||||
h.(*NonEmptyHypha).SetName(newName)
|
||||
byNames[h.CanonicalName()] = h.(*NonEmptyHypha)
|
||||
byNamesMutex.Unlock()
|
||||
h.Unlock()
|
||||
}
|
||||
|
||||
// Insert inserts the hypha into the storage, possibly overwriting the previous hypha with the same name. Count incrementation is done if needed.
|
||||
func Insert(h Hypher) (madeNewRecord bool) {
|
||||
// Insert inserts the hypha into the storage, possibly overwriting the previous hypha with the same name. Count incrementation is done if needed. You cannot insert an empty hypha.
|
||||
func Insert(h ExistingHypha) (madeNewRecord bool) {
|
||||
_, recorded := byNames[h.CanonicalName()]
|
||||
|
||||
byNamesMutex.Lock()
|
||||
@ -75,23 +54,15 @@ func Insert(h Hypher) (madeNewRecord bool) {
|
||||
return !recorded
|
||||
}
|
||||
|
||||
// InsertIfNew checks whether the hypha exists and returns `true` if it didn't and has been created.
|
||||
func InsertIfNew(h Hypher) (madeNewRecord bool) {
|
||||
switch ByName(h.CanonicalName()).(type) {
|
||||
case *EmptyHypha:
|
||||
return Insert(h)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ByName returns a hypha by name. It returns an *EmptyHypha if there is no such hypha. This function is the only source of empty hyphae.
|
||||
func ByName(hyphaName string) (h Hypher) {
|
||||
func ByName(hyphaName string) (h Hypha) {
|
||||
byNamesMutex.Lock()
|
||||
defer byNamesMutex.Unlock()
|
||||
h, recorded := byNames[hyphaName]
|
||||
if recorded {
|
||||
return h
|
||||
}
|
||||
return NewEmptyHypha(hyphaName)
|
||||
return &EmptyHypha{
|
||||
canonicalName: hyphaName,
|
||||
}
|
||||
}
|
@ -7,20 +7,20 @@ import (
|
||||
// Iteration represents an iteration over all hyphae in the storage. You may use it instead of directly iterating using hyphae.YieldExistingHyphae when you want to do n checks at once instead of iterating n times.
|
||||
type Iteration struct {
|
||||
sync.Mutex
|
||||
iterator func() chan Hypher
|
||||
checks []func(h Hypher) CheckResult
|
||||
iterator func() chan ExistingHypha
|
||||
checks []func(h Hypha) CheckResult
|
||||
}
|
||||
|
||||
// NewIteration constructs an iteration without checks.
|
||||
func NewIteration() *Iteration {
|
||||
return &Iteration{
|
||||
iterator: YieldExistingHyphae,
|
||||
checks: make([]func(h Hypher) CheckResult, 0),
|
||||
checks: make([]func(h Hypha) CheckResult, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// AddCheck adds the check to the iteration. It is concurrent-safe.
|
||||
func (i7n *Iteration) AddCheck(check func(h Hypher) CheckResult) {
|
||||
func (i7n *Iteration) AddCheck(check func(h Hypha) CheckResult) {
|
||||
i7n.Lock()
|
||||
i7n.checks = append(i7n.checks, check)
|
||||
i7n.Unlock()
|
||||
|
@ -8,16 +8,15 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var byNames = make(map[string]Hypher)
|
||||
var byNames = make(map[string]ExistingHypha)
|
||||
var byNamesMutex = sync.Mutex{}
|
||||
|
||||
// YieldExistingHyphae iterates over all hyphae and yields all existing ones.
|
||||
func YieldExistingHyphae() chan Hypher {
|
||||
ch := make(chan Hypher)
|
||||
func YieldExistingHyphae() chan ExistingHypha {
|
||||
ch := make(chan ExistingHypha)
|
||||
go func() {
|
||||
for _, h := range byNames {
|
||||
switch h.(type) {
|
||||
case *EmptyHypha:
|
||||
default:
|
||||
ch <- h
|
||||
}
|
||||
@ -28,13 +27,18 @@ func YieldExistingHyphae() chan Hypher {
|
||||
}
|
||||
|
||||
// FilterHyphaeWithText filters the source channel and yields only those hyphae than have text parts.
|
||||
func FilterHyphaeWithText(src chan Hypher) chan Hypher {
|
||||
func FilterHyphaeWithText(src chan ExistingHypha) chan ExistingHypha {
|
||||
// TODO: reimplement as a function with a callback?
|
||||
sink := make(chan Hypher)
|
||||
sink := make(chan ExistingHypha)
|
||||
go func() {
|
||||
for h := range src {
|
||||
if h.HasTextPart() {
|
||||
switch h := h.(type) {
|
||||
case *TextualHypha:
|
||||
sink <- h
|
||||
case *MediaHypha:
|
||||
if h.HasTextFile() {
|
||||
sink <- h
|
||||
}
|
||||
}
|
||||
}
|
||||
close(sink)
|
||||
@ -85,8 +89,8 @@ func PathographicSort(src chan string) <-chan string {
|
||||
}
|
||||
|
||||
// Subhyphae returns slice of subhyphae.
|
||||
func Subhyphae(h Hypher) []Hypher {
|
||||
var hyphae []Hypher
|
||||
func Subhyphae(h Hypha) []ExistingHypha {
|
||||
var hyphae []ExistingHypha
|
||||
for subh := range YieldExistingHyphae() {
|
||||
if strings.HasPrefix(subh.CanonicalName(), h.CanonicalName()+"/") {
|
||||
hyphae = append(hyphae, subh)
|
||||
|
48
hyphae/media_hypha.go
Normal file
48
hyphae/media_hypha.go
Normal file
@ -0,0 +1,48 @@
|
||||
package hyphae
|
||||
|
||||
import (
|
||||
"github.com/bouncepaw/mycorrhiza/files"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type MediaHypha struct {
|
||||
sync.RWMutex
|
||||
|
||||
canonicalName string
|
||||
mycoFilePath string
|
||||
mediaFilePath string
|
||||
}
|
||||
|
||||
func (m *MediaHypha) DoesExist() {
|
||||
}
|
||||
|
||||
func (m *MediaHypha) CanonicalName() string {
|
||||
return m.canonicalName
|
||||
}
|
||||
|
||||
func (m *MediaHypha) TextFilePath() string {
|
||||
if m.mycoFilePath == "" {
|
||||
return filepath.Join(files.HyphaeDir(), m.CanonicalName()+".myco")
|
||||
}
|
||||
return m.mycoFilePath
|
||||
}
|
||||
|
||||
func (m *MediaHypha) HasTextFile() bool {
|
||||
return m.mycoFilePath != ""
|
||||
}
|
||||
|
||||
func (m *MediaHypha) MediaFilePath() string {
|
||||
return m.mediaFilePath
|
||||
}
|
||||
|
||||
func (m *MediaHypha) SetMediaFilePath(newPath string) {
|
||||
m.mediaFilePath = newPath
|
||||
}
|
||||
|
||||
func ShrinkMediaToTextual(m *MediaHypha) *TextualHypha {
|
||||
return &TextualHypha{
|
||||
canonicalName: m.CanonicalName(),
|
||||
mycoFilePath: m.TextFilePath(),
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
// Package hyphae is for the NonEmptyHypha type, hypha storage and stuff like that. It shall not depend on mycorrhiza modules other than util.
|
||||
package hyphae
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/files"
|
||||
)
|
||||
|
||||
// NonEmptyHypha keeps vital information about a media hypha
|
||||
type NonEmptyHypha struct {
|
||||
sync.RWMutex
|
||||
|
||||
name string // Canonical name
|
||||
Exists bool
|
||||
TextPath string // == "" => no text part
|
||||
binaryPath string // == "" => no attachment
|
||||
}
|
||||
|
||||
func (h *NonEmptyHypha) SetName(s string) { h.name = s }
|
||||
|
||||
func (h *NonEmptyHypha) BinaryPath() string { return h.binaryPath }
|
||||
func (h *NonEmptyHypha) SetBinaryPath(s string) { h.binaryPath = s }
|
||||
|
||||
func (h *NonEmptyHypha) CanonicalName() string {
|
||||
return h.name
|
||||
}
|
||||
|
||||
func (h *NonEmptyHypha) Kind() HyphaKind { // sic!
|
||||
if h.HasAttachment() {
|
||||
return HyphaMedia
|
||||
}
|
||||
return HyphaText
|
||||
}
|
||||
|
||||
func (h *NonEmptyHypha) HasTextPart() bool {
|
||||
return h.TextPath != ""
|
||||
}
|
||||
|
||||
// TextPartPath returns rooted path to the file where the text part should be.
|
||||
func (h *NonEmptyHypha) TextPartPath() string {
|
||||
if h.TextPath == "" {
|
||||
return filepath.Join(files.HyphaeDir(), h.name+".myco")
|
||||
}
|
||||
return h.TextPath
|
||||
}
|
||||
|
||||
// HasAttachment is true if the hypha has an attachment.
|
||||
func (h *NonEmptyHypha) HasAttachment() bool {
|
||||
return h.binaryPath != ""
|
||||
}
|
35
hyphae/textual_hypha.go
Normal file
35
hyphae/textual_hypha.go
Normal file
@ -0,0 +1,35 @@
|
||||
package hyphae
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type TextualHypha struct {
|
||||
sync.RWMutex
|
||||
|
||||
canonicalName string
|
||||
mycoFilePath string
|
||||
}
|
||||
|
||||
func (t *TextualHypha) DoesExist() {
|
||||
}
|
||||
|
||||
func (t *TextualHypha) CanonicalName() string {
|
||||
return t.canonicalName
|
||||
}
|
||||
|
||||
func (t *TextualHypha) HasTextFile() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (t *TextualHypha) TextFilePath() string {
|
||||
return t.mycoFilePath
|
||||
}
|
||||
|
||||
func ExtendTextualToMedia(t *TextualHypha, mediaFilePath string) *MediaHypha {
|
||||
return &MediaHypha{
|
||||
canonicalName: t.CanonicalName(),
|
||||
mycoFilePath: t.TextFilePath(),
|
||||
mediaFilePath: mediaFilePath,
|
||||
}
|
||||
}
|
@ -41,10 +41,10 @@ func MigrateRocketsMaybe() {
|
||||
for hypha := range hyphae.FilterHyphaeWithText(hyphae.YieldExistingHyphae()) {
|
||||
/// Open file, read from file, modify file. If anything goes wrong, scream and shout.
|
||||
|
||||
file, err := os.OpenFile(hypha.TextPartPath(), os.O_RDWR, 0766)
|
||||
file, err := os.OpenFile(hypha.TextFilePath(), os.O_RDWR, 0766)
|
||||
if err != nil {
|
||||
hop.WithErrAbort(err)
|
||||
log.Fatal("Something went wrong when opening ", hypha.TextPartPath(), ": ", err.Error())
|
||||
log.Fatal("Something went wrong when opening ", hypha.TextFilePath(), ": ", err.Error())
|
||||
}
|
||||
|
||||
var buf strings.Builder
|
||||
@ -52,7 +52,7 @@ func MigrateRocketsMaybe() {
|
||||
if err != nil {
|
||||
hop.WithErrAbort(err)
|
||||
_ = file.Close()
|
||||
log.Fatal("Something went wrong when reading ", hypha.TextPartPath(), ": ", err.Error())
|
||||
log.Fatal("Something went wrong when reading ", hypha.TextFilePath(), ": ", err.Error())
|
||||
}
|
||||
|
||||
var (
|
||||
@ -60,27 +60,27 @@ func MigrateRocketsMaybe() {
|
||||
newText = tools.MigrateRocketLinks(oldText)
|
||||
)
|
||||
if oldText != newText { // This file right here is being migrated for real.
|
||||
mycoFiles = append(mycoFiles, hypha.TextPartPath())
|
||||
mycoFiles = append(mycoFiles, hypha.TextFilePath())
|
||||
|
||||
err = file.Truncate(0)
|
||||
if err != nil {
|
||||
hop.WithErrAbort(err)
|
||||
_ = file.Close()
|
||||
log.Fatal("Something went wrong when truncating ", hypha.TextPartPath(), ": ", err.Error())
|
||||
log.Fatal("Something went wrong when truncating ", hypha.TextFilePath(), ": ", err.Error())
|
||||
}
|
||||
|
||||
_, err = file.Seek(0, 0)
|
||||
if err != nil {
|
||||
hop.WithErrAbort(err)
|
||||
_ = file.Close()
|
||||
log.Fatal("Something went wrong when seeking in ", hypha.TextPartPath(), ": ", err.Error())
|
||||
log.Fatal("Something went wrong when seeking in ", hypha.TextFilePath(), ": ", err.Error())
|
||||
}
|
||||
|
||||
_, err = file.WriteString(newText)
|
||||
if err != nil {
|
||||
hop.WithErrAbort(err)
|
||||
_ = file.Close()
|
||||
log.Fatal("Something went wrong when writing to ", hypha.TextPartPath(), ": ", err.Error())
|
||||
log.Fatal("Something went wrong when writing to ", hypha.TextFilePath(), ": ", err.Error())
|
||||
}
|
||||
}
|
||||
_ = file.Close()
|
||||
|
@ -11,14 +11,14 @@ import (
|
||||
// TODO: get rid of this abomination
|
||||
|
||||
func canFactory(
|
||||
rejectLogger func(hyphae.Hypher, *user.User, string),
|
||||
rejectLogger func(hyphae.Hypha, *user.User, string),
|
||||
action string,
|
||||
dispatcher func(hyphae.Hypher, *user.User, *l18n.Localizer) (string, string),
|
||||
dispatcher func(hyphae.Hypha, *user.User, *l18n.Localizer) (string, string),
|
||||
noRightsMsg string,
|
||||
notExistsMsg string,
|
||||
mustExist bool,
|
||||
) func(*user.User, hyphae.Hypher, *l18n.Localizer) (string, error) {
|
||||
return func(u *user.User, h hyphae.Hypher, lc *l18n.Localizer) (string, error) {
|
||||
) func(*user.User, hyphae.Hypha, *l18n.Localizer) (string, error) {
|
||||
return func(u *user.User, h hyphae.Hypha, lc *l18n.Localizer) (string, error) {
|
||||
if !u.CanProceed(action) {
|
||||
rejectLogger(h, u, "no rights")
|
||||
return lc.Get("ui.act_no_rights"), errors.New(lc.Get(noRightsMsg))
|
||||
@ -66,15 +66,13 @@ var (
|
||||
CanUnattach = canFactory(
|
||||
rejectUnattachLog,
|
||||
"unattach-confirm",
|
||||
func(h hyphae.Hypher, u *user.User, lc *l18n.Localizer) (errmsg, errtitle string) {
|
||||
func(h hyphae.Hypha, u *user.User, lc *l18n.Localizer) (errmsg, errtitle string) {
|
||||
switch h := h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
case *hyphae.NonEmptyHypha:
|
||||
if h.Kind() != hyphae.HyphaMedia {
|
||||
case *hyphae.TextualHypha:
|
||||
rejectUnattachLog(h, u, "no amnt")
|
||||
return lc.Get("ui.act_noattachment_tip"), lc.Get("ui.act_noattachment")
|
||||
}
|
||||
}
|
||||
|
||||
return "", ""
|
||||
},
|
||||
|
@ -11,23 +11,30 @@ import (
|
||||
)
|
||||
|
||||
// DeleteHypha deletes hypha and makes a history record about that.
|
||||
func DeleteHypha(u *user.User, h hyphae.Hypher, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
||||
hop = history.Operation(history.TypeDeleteHypha)
|
||||
func DeleteHypha(u *user.User, h hyphae.Hypha, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
||||
hop = history.
|
||||
Operation(history.TypeDeleteHypha).
|
||||
WithMsg(fmt.Sprintf("Delete ‘%s’", h.CanonicalName())).
|
||||
WithUser(u)
|
||||
|
||||
if errtitle, err := CanDelete(u, h, lc); errtitle != "" {
|
||||
hop.WithErrAbort(err)
|
||||
return hop, errtitle
|
||||
}
|
||||
|
||||
originalText, _ := FetchTextPart(h)
|
||||
hop.
|
||||
WithFilesRemoved(h.TextPartPath(), h.(*hyphae.NonEmptyHypha).BinaryPath()).
|
||||
WithMsg(fmt.Sprintf("Delete ‘%s’", h.CanonicalName())).
|
||||
WithUser(u).
|
||||
Apply()
|
||||
switch h := h.(type) {
|
||||
case *hyphae.MediaHypha:
|
||||
hop.WithFilesRemoved(h.MediaFilePath(), h.TextFilePath())
|
||||
case *hyphae.TextualHypha:
|
||||
hop.WithFilesRemoved(h.TextFilePath())
|
||||
default:
|
||||
panic("impossible")
|
||||
}
|
||||
originalText, _ := FetchTextFile(h)
|
||||
hop.Apply()
|
||||
if !hop.HasErrors() {
|
||||
backlinks.UpdateBacklinksAfterDelete(h, originalText)
|
||||
hyphae.DeleteHypha(h)
|
||||
hyphae.DeleteHypha(h.(hyphae.ExistingHypha)) // we panicked before, so it's safe
|
||||
}
|
||||
return hop, ""
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
// TODO: clean this complete and utter mess
|
||||
globals.HyphaExists = func(hyphaName string) bool {
|
||||
switch hyphae.ByName(hyphaName).(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
@ -22,13 +23,12 @@ func init() {
|
||||
switch h := hyphae.ByName(hyphaName).(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
err = errors.New("Hypha " + hyphaName + " does not exist")
|
||||
default:
|
||||
rawText, err = FetchTextPart(h)
|
||||
if h := h.(*hyphae.NonEmptyHypha); h.Kind() == hyphae.HyphaMedia {
|
||||
// the view is localized, but we can't pass it, so...
|
||||
case *hyphae.TextualHypha:
|
||||
rawText, err = FetchTextFile(h)
|
||||
case *hyphae.MediaHypha:
|
||||
rawText, err = FetchTextFile(h)
|
||||
binaryBlock = views.AttachmentHTMLRaw(h)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
globals.HyphaIterate = func(λ func(string)) {
|
||||
|
@ -7,18 +7,18 @@ import (
|
||||
"github.com/bouncepaw/mycorrhiza/user"
|
||||
)
|
||||
|
||||
func rejectDeleteLog(h hyphae.Hypher, u *user.User, errmsg string) {
|
||||
func rejectDeleteLog(h hyphae.Hypha, u *user.User, errmsg string) {
|
||||
log.Printf("Reject delete ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg)
|
||||
}
|
||||
func rejectRenameLog(h hyphae.Hypher, u *user.User, errmsg string) {
|
||||
func rejectRenameLog(h hyphae.Hypha, u *user.User, errmsg string) {
|
||||
log.Printf("Reject rename ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg)
|
||||
}
|
||||
func rejectUnattachLog(h hyphae.Hypher, u *user.User, errmsg string) {
|
||||
func rejectUnattachLog(h hyphae.Hypha, u *user.User, errmsg string) {
|
||||
log.Printf("Reject unattach ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg)
|
||||
}
|
||||
func rejectEditLog(h hyphae.Hypher, u *user.User, errmsg string) {
|
||||
func rejectEditLog(h hyphae.Hypha, u *user.User, errmsg string) {
|
||||
log.Printf("Reject edit ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg)
|
||||
}
|
||||
func rejectAttachLog(h hyphae.Hypher, u *user.User, errmsg string) {
|
||||
func rejectAttachLog(h hyphae.Hypha, u *user.User, errmsg string) {
|
||||
log.Printf("Reject attach ‘%s’ by @%s: %s\n", h.CanonicalName(), u.Name, errmsg)
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
)
|
||||
|
||||
func canRenameThisToThat(oh hyphae.Hypher, nh hyphae.Hypher, u *user.User, lc *l18n.Localizer) (errtitle string, err error) {
|
||||
func canRenameThisToThat(oh hyphae.Hypha, nh hyphae.Hypha, u *user.User, lc *l18n.Localizer) (errtitle string, err error) {
|
||||
switch nh.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
default:
|
||||
@ -35,7 +35,7 @@ func canRenameThisToThat(oh hyphae.Hypher, nh hyphae.Hypher, u *user.User, lc *l
|
||||
}
|
||||
|
||||
// RenameHypha renames hypha from old name `hyphaName` to `newName` and makes a history record about that. If `recursive` is `true`, its subhyphae will be renamed the same way.
|
||||
func RenameHypha(h hyphae.Hypher, newHypha hyphae.Hypher, recursive bool, u *user.User, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
||||
func RenameHypha(h hyphae.Hypha, newHypha hyphae.Hypha, recursive bool, u *user.User, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
||||
newHypha.Lock()
|
||||
defer newHypha.Unlock()
|
||||
hop = history.Operation(history.TypeRenameHypha)
|
||||
@ -54,7 +54,7 @@ func RenameHypha(h hyphae.Hypher, newHypha hyphae.Hypher, recursive bool, u *use
|
||||
replaceName = func(str string) string {
|
||||
return re.ReplaceAllString(util.CanonicalName(str), newHypha.CanonicalName())
|
||||
}
|
||||
hyphaeToRename = findHyphaeToRename(h, recursive)
|
||||
hyphaeToRename = findHyphaeToRename(h.(hyphae.ExistingHypha), recursive)
|
||||
renameMap, err = renamingPairs(hyphaeToRename, replaceName)
|
||||
renameMsg = "Rename ‘%s’ to ‘%s’"
|
||||
)
|
||||
@ -70,47 +70,43 @@ func RenameHypha(h hyphae.Hypher, newHypha hyphae.Hypher, recursive bool, u *use
|
||||
WithUser(u).
|
||||
Apply()
|
||||
if len(hop.Errs) == 0 {
|
||||
for _, h := range hyphaeToRename {
|
||||
h := h.(*hyphae.NonEmptyHypha) // ontology think
|
||||
for _, H := range hyphaeToRename {
|
||||
h := H.(hyphae.ExistingHypha) // ontology think
|
||||
oldName := h.CanonicalName()
|
||||
hyphae.RenameHyphaTo(h, replaceName(h.CanonicalName()))
|
||||
h.Lock()
|
||||
h.TextPath = replaceName(h.TextPath)
|
||||
h.SetBinaryPath(replaceName(h.BinaryPath()))
|
||||
h.Unlock()
|
||||
hyphae.RenameHyphaTo(h, replaceName(h.CanonicalName()), replaceName)
|
||||
backlinks.UpdateBacklinksAfterRename(h, oldName)
|
||||
}
|
||||
}
|
||||
return hop, ""
|
||||
}
|
||||
|
||||
func findHyphaeToRename(superhypha hyphae.Hypher, recursive bool) []hyphae.Hypher {
|
||||
hyphaList := []hyphae.Hypher{superhypha}
|
||||
func findHyphaeToRename(superhypha hyphae.ExistingHypha, recursive bool) []hyphae.ExistingHypha {
|
||||
hyphaList := []hyphae.ExistingHypha{superhypha}
|
||||
if recursive {
|
||||
hyphaList = append(hyphaList, hyphae.Subhyphae(superhypha)...)
|
||||
}
|
||||
return hyphaList
|
||||
}
|
||||
|
||||
func renamingPairs(hyphaeToRename []hyphae.Hypher, replaceName func(string) string) (map[string]string, error) {
|
||||
renameMap := make(map[string]string)
|
||||
newNames := make([]string, len(hyphaeToRename))
|
||||
func renamingPairs(hyphaeToRename []hyphae.ExistingHypha, replaceName func(string) string) (map[string]string, error) {
|
||||
var (
|
||||
renameMap = make(map[string]string)
|
||||
newNames = make([]string, len(hyphaeToRename))
|
||||
)
|
||||
for _, h := range hyphaeToRename {
|
||||
h.Lock()
|
||||
newNames = append(newNames, replaceName(h.CanonicalName()))
|
||||
if h.HasTextPart() {
|
||||
renameMap[h.TextPartPath()] = replaceName(h.TextPartPath())
|
||||
if h.HasTextFile() {
|
||||
renameMap[h.TextFilePath()] = replaceName(h.TextFilePath())
|
||||
}
|
||||
switch h := h.(type) {
|
||||
case *hyphae.NonEmptyHypha:
|
||||
if h.Kind() == hyphae.HyphaMedia { // ontology think
|
||||
renameMap[h.BinaryPath()] = replaceName(h.BinaryPath())
|
||||
}
|
||||
case *hyphae.MediaHypha:
|
||||
renameMap[h.MediaFilePath()] = replaceName(h.MediaFilePath())
|
||||
}
|
||||
h.Unlock()
|
||||
}
|
||||
if firstFailure, ok := hyphae.AreFreeNames(newNames...); !ok {
|
||||
return nil, errors.New("NonEmptyHypha " + firstFailure + " already exists")
|
||||
return nil, errors.New("Hypha " + firstFailure + " already exists")
|
||||
}
|
||||
return renameMap, nil
|
||||
}
|
||||
|
@ -10,17 +10,17 @@ import (
|
||||
)
|
||||
|
||||
// UnattachHypha unattaches hypha and makes a history record about that.
|
||||
func UnattachHypha(u *user.User, h hyphae.Hypher, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
||||
func UnattachHypha(u *user.User, h hyphae.Hypha, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
||||
hop = history.Operation(history.TypeUnattachHypha)
|
||||
|
||||
if errtitle, err := CanUnattach(u, h, lc); errtitle != "" {
|
||||
hop.WithErrAbort(err)
|
||||
return hop, errtitle
|
||||
}
|
||||
H := h.(*hyphae.NonEmptyHypha)
|
||||
H := h.(*hyphae.MediaHypha)
|
||||
|
||||
hop.
|
||||
WithFilesRemoved(H.BinaryPath()).
|
||||
WithFilesRemoved(H.MediaFilePath()).
|
||||
WithMsg(fmt.Sprintf("Unattach ‘%s’", h.CanonicalName())).
|
||||
WithUser(u).
|
||||
Apply()
|
||||
@ -31,12 +31,10 @@ func UnattachHypha(u *user.User, h hyphae.Hypher, lc *l18n.Localizer) (hop *hist
|
||||
return hop.WithErrAbort(fmt.Errorf("Could not unattach this hypha due to internal server errors: <code>%v</code>", hop.Errs)), "Error"
|
||||
}
|
||||
|
||||
if H.BinaryPath() != "" {
|
||||
H.SetBinaryPath("")
|
||||
}
|
||||
// If nothing is left of the hypha
|
||||
if H.TextPath == "" {
|
||||
hyphae.DeleteHypha(h)
|
||||
if H.HasTextFile() {
|
||||
hyphae.Insert(hyphae.ShrinkMediaToTextual(H))
|
||||
} else {
|
||||
hyphae.DeleteHypha(H)
|
||||
}
|
||||
return hop, ""
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func historyMessageForTextUpload(h hyphae.Hypher, userMessage string) string {
|
||||
func historyMessageForTextUpload(h hyphae.Hypha, userMessage string) string {
|
||||
var verb string
|
||||
switch h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
@ -33,21 +33,21 @@ func historyMessageForTextUpload(h hyphae.Hypher, userMessage string) string {
|
||||
return fmt.Sprintf("%s ‘%s’: %s", verb, h.CanonicalName(), userMessage)
|
||||
}
|
||||
|
||||
func writeTextToDisk(h *hyphae.NonEmptyHypha, data []byte, hop *history.Op) error {
|
||||
if err := os.MkdirAll(filepath.Dir(h.TextPartPath()), 0777); err != nil {
|
||||
func writeTextToDisk(h hyphae.ExistingHypha, data []byte, hop *history.Op) error {
|
||||
if err := os.MkdirAll(filepath.Dir(h.TextFilePath()), 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(h.TextPartPath(), data, 0666); err != nil {
|
||||
if err := os.WriteFile(h.TextFilePath(), data, 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
hop.WithFiles(h.TextPartPath())
|
||||
hop.WithFiles(h.TextFilePath())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UploadText edits the hypha's text part and makes a history record about that.
|
||||
func UploadText(h hyphae.Hypher, data []byte, userMessage string, u *user.User, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
||||
func UploadText(h hyphae.Hypha, data []byte, userMessage string, u *user.User, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
||||
hop = history.
|
||||
Operation(history.TypeEditText).
|
||||
WithMsg(historyMessageForTextUpload(h, userMessage)).
|
||||
@ -68,27 +68,24 @@ func UploadText(h hyphae.Hypher, data []byte, userMessage string, u *user.User,
|
||||
|
||||
// Empty data check
|
||||
if len(bytes.TrimSpace(data)) == 0 { // if nothing but whitespace
|
||||
switch h := h.(type) {
|
||||
switch h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
// It's ok, just like cancel button.
|
||||
return hop.Abort(), ""
|
||||
case *hyphae.NonEmptyHypha:
|
||||
switch h.Kind() {
|
||||
case hyphae.HyphaMedia:
|
||||
case *hyphae.MediaHypha:
|
||||
// Writing no description, it's ok, just like cancel button.
|
||||
return hop.Abort(), ""
|
||||
case hyphae.HyphaText:
|
||||
case *hyphae.TextualHypha:
|
||||
// What do you want passing nothing for a textual hypha?
|
||||
return hop.WithErrAbort(errors.New("No data passed")), "Empty"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, we have a savable user-generated Mycomarkup document. Gotta save it.
|
||||
|
||||
switch h := h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
H := hyphae.FillEmptyHyphaUpToTextualHypha(h, filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco"))
|
||||
H := hyphae.ExtendEmptyToTextual(h, filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco"))
|
||||
|
||||
err := writeTextToDisk(H, data, hop)
|
||||
if err != nil {
|
||||
@ -96,8 +93,26 @@ func UploadText(h hyphae.Hypher, data []byte, userMessage string, u *user.User,
|
||||
}
|
||||
|
||||
hyphae.Insert(H)
|
||||
case *hyphae.NonEmptyHypha:
|
||||
oldText, err := FetchTextPart(h)
|
||||
case *hyphae.MediaHypha:
|
||||
oldText, err := FetchTextFile(h)
|
||||
if err != nil {
|
||||
return hop.WithErrAbort(err), err.Error()
|
||||
}
|
||||
|
||||
// TODO: that []byte(...) part should be removed
|
||||
if bytes.Compare(data, []byte(oldText)) == 0 {
|
||||
// No changes! Just like cancel button
|
||||
return hop.Abort(), ""
|
||||
}
|
||||
|
||||
err = writeTextToDisk(h, data, hop)
|
||||
if err != nil {
|
||||
return hop.WithErrAbort(err), err.Error()
|
||||
}
|
||||
|
||||
backlinks.UpdateBacklinksAfterEdit(h, oldText)
|
||||
case *hyphae.TextualHypha:
|
||||
oldText, err := FetchTextFile(h)
|
||||
if err != nil {
|
||||
return hop.WithErrAbort(err), err.Error()
|
||||
}
|
||||
@ -119,12 +134,12 @@ func UploadText(h hyphae.Hypher, data []byte, userMessage string, u *user.User,
|
||||
return hop.Apply(), ""
|
||||
}
|
||||
|
||||
func historyMessageForMediaUpload(h hyphae.Hypher, mime string) string {
|
||||
func historyMessageForMediaUpload(h hyphae.Hypha, mime string) string {
|
||||
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.
|
||||
func writeMediaToDisk(h hyphae.Hypher, mime string, data []byte) (string, error) {
|
||||
func writeMediaToDisk(h hyphae.Hypha, mime string, data []byte) (string, error) {
|
||||
var (
|
||||
ext = mimetype.ToExtension(mime)
|
||||
// That's where the file will go
|
||||
@ -142,7 +157,7 @@ func writeMediaToDisk(h hyphae.Hypher, mime string, data []byte) (string, error)
|
||||
}
|
||||
|
||||
// UploadBinary edits the hypha's media part and makes a history record about that.
|
||||
func UploadBinary(h hyphae.Hypher, mime string, file multipart.File, u *user.User, lc *l18n.Localizer) (*history.Op, string) {
|
||||
func UploadBinary(h hyphae.Hypha, mime string, file multipart.File, u *user.User, lc *l18n.Localizer) (*history.Op, string) {
|
||||
hop := history.
|
||||
Operation(history.TypeEditBinary).
|
||||
WithMsg(historyMessageForMediaUpload(h, mime)).
|
||||
@ -180,21 +195,18 @@ func UploadBinary(h hyphae.Hypher, mime string, file multipart.File, u *user.Use
|
||||
|
||||
switch h := h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
H := hyphae.FillEmptyHyphaUpToMediaHypha(h, uploadedFilePath)
|
||||
H := hyphae.ExtendEmptyToMedia(h, uploadedFilePath)
|
||||
hyphae.Insert(H)
|
||||
case *hyphae.NonEmptyHypha:
|
||||
switch h.Kind() {
|
||||
case hyphae.HyphaText:
|
||||
h.SetBinaryPath(uploadedFilePath)
|
||||
case hyphae.HyphaMedia: // If this is not the first media the hypha gets
|
||||
prevFilePath := h.BinaryPath()
|
||||
case *hyphae.TextualHypha:
|
||||
hyphae.Insert(hyphae.ExtendTextualToMedia(h, uploadedFilePath))
|
||||
case *hyphae.MediaHypha: // If this is not the first media the hypha gets
|
||||
prevFilePath := h.MediaFilePath()
|
||||
if prevFilePath != uploadedFilePath {
|
||||
if err := history.Rename(prevFilePath, uploadedFilePath); err != nil {
|
||||
return hop.WithErrAbort(err), err.Error()
|
||||
}
|
||||
log.Printf("Move ‘%s’ to ‘%s’\n", prevFilePath, uploadedFilePath)
|
||||
h.SetBinaryPath(uploadedFilePath)
|
||||
}
|
||||
h.SetMediaFilePath(uploadedFilePath)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,22 +8,32 @@ import (
|
||||
"github.com/bouncepaw/mycorrhiza/hyphae"
|
||||
)
|
||||
|
||||
// FetchTextPart tries to read text file of the given hypha. If there is no file, empty string is returned.
|
||||
func FetchTextPart(h hyphae.Hypher) (string, error) {
|
||||
switch h.(type) {
|
||||
// FetchTextFile tries to read text file of the given hypha. If there is no file, empty string is returned.
|
||||
func FetchTextFile(h hyphae.Hypha) (string, error) {
|
||||
switch h := h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
return "", errors.New("empty hyphae have no text")
|
||||
}
|
||||
if !h.HasTextPart() {
|
||||
case *hyphae.MediaHypha:
|
||||
if !h.HasTextFile() {
|
||||
return "", nil
|
||||
}
|
||||
text, err := os.ReadFile(h.TextPartPath())
|
||||
text, err := os.ReadFile(h.TextFilePath())
|
||||
if os.IsNotExist(err) {
|
||||
return "", nil
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(text), nil
|
||||
case *hyphae.TextualHypha:
|
||||
text, err := os.ReadFile(h.TextFilePath())
|
||||
if os.IsNotExist(err) {
|
||||
return "", nil
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(text), nil
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// SetHeaderLinks initializes header links by reading the configured hypha, if there is any, or resorting to default values.
|
||||
@ -31,8 +41,8 @@ func SetHeaderLinks() {
|
||||
switch userLinksHypha := hyphae.ByName(cfg.HeaderLinksHypha).(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
cfg.SetDefaultHeaderLinks()
|
||||
default:
|
||||
contents, err := os.ReadFile(userLinksHypha.TextPartPath())
|
||||
case hyphae.ExistingHypha:
|
||||
contents, err := os.ReadFile(userLinksHypha.TextFilePath())
|
||||
if err != nil || len(contents) == 0 {
|
||||
cfg.SetDefaultHeaderLinks()
|
||||
} else {
|
||||
|
@ -18,7 +18,7 @@ func findSiblings(hyphaName string) []*sibling {
|
||||
}
|
||||
var (
|
||||
siblingsMap = make(map[string]bool)
|
||||
siblingCheck = func(h hyphae.Hypher) hyphae.CheckResult {
|
||||
siblingCheck = func(h hyphae.Hypha) hyphae.CheckResult {
|
||||
switch {
|
||||
case h.CanonicalName() == hyphaName, // NonEmptyHypha is no sibling of itself
|
||||
h.CanonicalName() == parentHyphaName: // Parent hypha is no sibling of its child
|
||||
@ -63,7 +63,7 @@ func findSiblings(hyphaName string) []*sibling {
|
||||
|
||||
func countSubhyphae(siblings []*sibling) {
|
||||
var (
|
||||
subhyphaCheck = func(h hyphae.Hypher) hyphae.CheckResult {
|
||||
subhyphaCheck = func(h hyphae.Hypha) hyphae.CheckResult {
|
||||
for _, s := range siblings {
|
||||
if path.Dir(h.CanonicalName()) == s.name {
|
||||
s.directSubhyphaeCount++
|
||||
|
@ -9,10 +9,10 @@
|
||||
{% import "github.com/bouncepaw/mycorrhiza/history" %}
|
||||
|
||||
|
||||
{% func PrimitiveDiffHTML(rq *http.Request, h hyphae.Hypher, u *user.User, hash string) %}
|
||||
{% func PrimitiveDiffHTML(rq *http.Request, h hyphae.ExistingHypha, u *user.User, hash string) %}
|
||||
{% code
|
||||
lc := l18n.FromRequest(rq)
|
||||
text, err := history.PrimitiveDiffAtRevision(h.TextPartPath(), hash)
|
||||
text, err := history.PrimitiveDiffAtRevision(h.TextFilePath(), hash)
|
||||
if err != nil {
|
||||
text = err.Error()
|
||||
}
|
||||
|
@ -42,13 +42,13 @@ var (
|
||||
)
|
||||
|
||||
//line views/history.qtpl:12
|
||||
func StreamPrimitiveDiffHTML(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.Hypher, u *user.User, hash string) {
|
||||
func StreamPrimitiveDiffHTML(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.ExistingHypha, u *user.User, hash string) {
|
||||
//line views/history.qtpl:12
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/history.qtpl:14
|
||||
lc := l18n.FromRequest(rq)
|
||||
text, err := history.PrimitiveDiffAtRevision(h.TextPartPath(), hash)
|
||||
text, err := history.PrimitiveDiffAtRevision(h.TextFilePath(), hash)
|
||||
if err != nil {
|
||||
text = err.Error()
|
||||
}
|
||||
@ -76,7 +76,7 @@ func StreamPrimitiveDiffHTML(qw422016 *qt422016.Writer, rq *http.Request, h hyph
|
||||
}
|
||||
|
||||
//line views/history.qtpl:28
|
||||
func WritePrimitiveDiffHTML(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.Hypher, u *user.User, hash string) {
|
||||
func WritePrimitiveDiffHTML(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.ExistingHypha, u *user.User, hash string) {
|
||||
//line views/history.qtpl:28
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/history.qtpl:28
|
||||
@ -87,7 +87,7 @@ func WritePrimitiveDiffHTML(qq422016 qtio422016.Writer, rq *http.Request, h hyph
|
||||
}
|
||||
|
||||
//line views/history.qtpl:28
|
||||
func PrimitiveDiffHTML(rq *http.Request, h hyphae.Hypher, u *user.User, hash string) string {
|
||||
func PrimitiveDiffHTML(rq *http.Request, h hyphae.ExistingHypha, u *user.User, hash string) string {
|
||||
//line views/history.qtpl:28
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/history.qtpl:28
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
{% func mycoLink(lc *l18n.Localizer) %}<a href="/help/en/mycomarkup" class="shy-link">{%s lc.Get("ui.notexist_write_myco") %}</a>{% endfunc %}
|
||||
|
||||
{% func nonExistentHyphaNotice(h hyphae.Hypher, u *user.User, lc *l18n.Localizer) %}
|
||||
{% func nonExistentHyphaNotice(h hyphae.Hypha, u *user.User, lc *l18n.Localizer) %}
|
||||
<section class="non-existent-hypha">
|
||||
<h2 class="non-existent-hypha__title">{%s lc.Get("ui.notexist_heading") %}</h2>
|
||||
{% if cfg.UseAuth && u.Group == "anon" %}
|
||||
@ -47,7 +47,7 @@
|
||||
</section>
|
||||
{% endfunc %}
|
||||
|
||||
{% func NaviTitleHTML(h hyphae.Hypher) %}
|
||||
{% func NaviTitleHTML(h hyphae.Hypha) %}
|
||||
{% code
|
||||
var (
|
||||
prevAcc = "/hypha/"
|
||||
@ -75,10 +75,10 @@
|
||||
</h1>
|
||||
{% endfunc %}
|
||||
|
||||
{% func AttachmentHTMLRaw(h *hyphae.NonEmptyHypha) %}{%= AttachmentHTML(h, l18n.New("en", "en")) %}{% endfunc %}
|
||||
{% func AttachmentHTMLRaw(h *hyphae.MediaHypha) %}{%= AttachmentHTML(h, l18n.New("en", "en")) %}{% endfunc %}
|
||||
|
||||
{% func AttachmentHTML(h *hyphae.NonEmptyHypha, lc *l18n.Localizer) %}
|
||||
{% switch filepath.Ext(h.BinaryPath()) %}
|
||||
{% func AttachmentHTML(h *hyphae.MediaHypha, lc *l18n.Localizer) %}
|
||||
{% switch filepath.Ext(h.MediaFilePath()) %}
|
||||
|
||||
{% case ".jpg", ".gif", ".png", ".webp", ".svg", ".ico" %}
|
||||
<div class="binary-container binary-container_with-img">
|
||||
|
@ -117,7 +117,7 @@ func mycoLink(lc *l18n.Localizer) string {
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:14
|
||||
func streamnonExistentHyphaNotice(qw422016 *qt422016.Writer, h hyphae.Hypher, u *user.User, lc *l18n.Localizer) {
|
||||
func streamnonExistentHyphaNotice(qw422016 *qt422016.Writer, h hyphae.Hypha, u *user.User, lc *l18n.Localizer) {
|
||||
//line views/hypha.qtpl:14
|
||||
qw422016.N().S(`
|
||||
<section class="non-existent-hypha">
|
||||
@ -230,7 +230,7 @@ func streamnonExistentHyphaNotice(qw422016 *qt422016.Writer, h hyphae.Hypher, u
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:48
|
||||
func writenonExistentHyphaNotice(qq422016 qtio422016.Writer, h hyphae.Hypher, u *user.User, lc *l18n.Localizer) {
|
||||
func writenonExistentHyphaNotice(qq422016 qtio422016.Writer, h hyphae.Hypha, u *user.User, lc *l18n.Localizer) {
|
||||
//line views/hypha.qtpl:48
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/hypha.qtpl:48
|
||||
@ -241,7 +241,7 @@ func writenonExistentHyphaNotice(qq422016 qtio422016.Writer, h hyphae.Hypher, u
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:48
|
||||
func nonExistentHyphaNotice(h hyphae.Hypher, u *user.User, lc *l18n.Localizer) string {
|
||||
func nonExistentHyphaNotice(h hyphae.Hypha, u *user.User, lc *l18n.Localizer) string {
|
||||
//line views/hypha.qtpl:48
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/hypha.qtpl:48
|
||||
@ -256,7 +256,7 @@ func nonExistentHyphaNotice(h hyphae.Hypher, u *user.User, lc *l18n.Localizer) s
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:50
|
||||
func StreamNaviTitleHTML(qw422016 *qt422016.Writer, h hyphae.Hypher) {
|
||||
func StreamNaviTitleHTML(qw422016 *qt422016.Writer, h hyphae.Hypha) {
|
||||
//line views/hypha.qtpl:50
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
@ -323,7 +323,7 @@ func StreamNaviTitleHTML(qw422016 *qt422016.Writer, h hyphae.Hypher) {
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:76
|
||||
func WriteNaviTitleHTML(qq422016 qtio422016.Writer, h hyphae.Hypher) {
|
||||
func WriteNaviTitleHTML(qq422016 qtio422016.Writer, h hyphae.Hypha) {
|
||||
//line views/hypha.qtpl:76
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/hypha.qtpl:76
|
||||
@ -334,7 +334,7 @@ func WriteNaviTitleHTML(qq422016 qtio422016.Writer, h hyphae.Hypher) {
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:76
|
||||
func NaviTitleHTML(h hyphae.Hypher) string {
|
||||
func NaviTitleHTML(h hyphae.Hypha) string {
|
||||
//line views/hypha.qtpl:76
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/hypha.qtpl:76
|
||||
@ -349,14 +349,14 @@ func NaviTitleHTML(h hyphae.Hypher) string {
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:78
|
||||
func StreamAttachmentHTMLRaw(qw422016 *qt422016.Writer, h *hyphae.NonEmptyHypha) {
|
||||
func StreamAttachmentHTMLRaw(qw422016 *qt422016.Writer, h *hyphae.MediaHypha) {
|
||||
//line views/hypha.qtpl:78
|
||||
StreamAttachmentHTML(qw422016, h, l18n.New("en", "en"))
|
||||
//line views/hypha.qtpl:78
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:78
|
||||
func WriteAttachmentHTMLRaw(qq422016 qtio422016.Writer, h *hyphae.NonEmptyHypha) {
|
||||
func WriteAttachmentHTMLRaw(qq422016 qtio422016.Writer, h *hyphae.MediaHypha) {
|
||||
//line views/hypha.qtpl:78
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/hypha.qtpl:78
|
||||
@ -367,7 +367,7 @@ func WriteAttachmentHTMLRaw(qq422016 qtio422016.Writer, h *hyphae.NonEmptyHypha)
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:78
|
||||
func AttachmentHTMLRaw(h *hyphae.NonEmptyHypha) string {
|
||||
func AttachmentHTMLRaw(h *hyphae.MediaHypha) string {
|
||||
//line views/hypha.qtpl:78
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/hypha.qtpl:78
|
||||
@ -382,12 +382,12 @@ func AttachmentHTMLRaw(h *hyphae.NonEmptyHypha) string {
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:80
|
||||
func StreamAttachmentHTML(qw422016 *qt422016.Writer, h *hyphae.NonEmptyHypha, lc *l18n.Localizer) {
|
||||
func StreamAttachmentHTML(qw422016 *qt422016.Writer, h *hyphae.MediaHypha, lc *l18n.Localizer) {
|
||||
//line views/hypha.qtpl:80
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/hypha.qtpl:81
|
||||
switch filepath.Ext(h.BinaryPath()) {
|
||||
switch filepath.Ext(h.MediaFilePath()) {
|
||||
//line views/hypha.qtpl:83
|
||||
case ".jpg", ".gif", ".png", ".webp", ".svg", ".ico":
|
||||
//line views/hypha.qtpl:83
|
||||
@ -486,7 +486,7 @@ func StreamAttachmentHTML(qw422016 *qt422016.Writer, h *hyphae.NonEmptyHypha, lc
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:109
|
||||
func WriteAttachmentHTML(qq422016 qtio422016.Writer, h *hyphae.NonEmptyHypha, lc *l18n.Localizer) {
|
||||
func WriteAttachmentHTML(qq422016 qtio422016.Writer, h *hyphae.MediaHypha, lc *l18n.Localizer) {
|
||||
//line views/hypha.qtpl:109
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/hypha.qtpl:109
|
||||
@ -497,7 +497,7 @@ func WriteAttachmentHTML(qq422016 qtio422016.Writer, h *hyphae.NonEmptyHypha, lc
|
||||
}
|
||||
|
||||
//line views/hypha.qtpl:109
|
||||
func AttachmentHTML(h *hyphae.NonEmptyHypha, lc *l18n.Localizer) string {
|
||||
func AttachmentHTML(h *hyphae.MediaHypha, lc *l18n.Localizer) string {
|
||||
//line views/hypha.qtpl:109
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/hypha.qtpl:109
|
||||
|
@ -5,7 +5,7 @@
|
||||
{% import "github.com/bouncepaw/mycorrhiza/user" %}
|
||||
{% import "github.com/bouncepaw/mycorrhiza/hyphae" %}
|
||||
|
||||
{% func hyphaInfoEntry(h hyphae.Hypher, u *user.User, action, displayText string) %}
|
||||
{% func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action, displayText string) %}
|
||||
{% if u.CanProceed(action) %}
|
||||
<li class="hypha-info__entry hypha-info__entry_{%s action %}">
|
||||
<a class="hypha-info__link" href="/{%s action %}/{%s h.CanonicalName() %}">{%s displayText %}</a>
|
||||
@ -13,7 +13,7 @@
|
||||
{% endif %}
|
||||
{% endfunc %}
|
||||
|
||||
{% func hyphaInfo(rq *http.Request, h hyphae.Hypher) %}
|
||||
{% func hyphaInfo(rq *http.Request, h hyphae.Hypha) %}
|
||||
{% code
|
||||
u := user.FromRequest(rq)
|
||||
lc := l18n.FromRequest(rq)
|
||||
|
@ -36,7 +36,7 @@ var (
|
||||
)
|
||||
|
||||
//line views/nav.qtpl:8
|
||||
func streamhyphaInfoEntry(qw422016 *qt422016.Writer, h hyphae.Hypher, u *user.User, action, displayText string) {
|
||||
func streamhyphaInfoEntry(qw422016 *qt422016.Writer, h hyphae.Hypha, u *user.User, action, displayText string) {
|
||||
//line views/nav.qtpl:8
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
@ -73,7 +73,7 @@ func streamhyphaInfoEntry(qw422016 *qt422016.Writer, h hyphae.Hypher, u *user.Us
|
||||
}
|
||||
|
||||
//line views/nav.qtpl:14
|
||||
func writehyphaInfoEntry(qq422016 qtio422016.Writer, h hyphae.Hypher, u *user.User, action, displayText string) {
|
||||
func writehyphaInfoEntry(qq422016 qtio422016.Writer, h hyphae.Hypha, u *user.User, action, displayText string) {
|
||||
//line views/nav.qtpl:14
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/nav.qtpl:14
|
||||
@ -84,7 +84,7 @@ func writehyphaInfoEntry(qq422016 qtio422016.Writer, h hyphae.Hypher, u *user.Us
|
||||
}
|
||||
|
||||
//line views/nav.qtpl:14
|
||||
func hyphaInfoEntry(h hyphae.Hypher, u *user.User, action, displayText string) string {
|
||||
func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action, displayText string) string {
|
||||
//line views/nav.qtpl:14
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/nav.qtpl:14
|
||||
@ -99,7 +99,7 @@ func hyphaInfoEntry(h hyphae.Hypher, u *user.User, action, displayText string) s
|
||||
}
|
||||
|
||||
//line views/nav.qtpl:16
|
||||
func streamhyphaInfo(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.Hypher) {
|
||||
func streamhyphaInfo(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.Hypha) {
|
||||
//line views/nav.qtpl:16
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
@ -149,7 +149,7 @@ func streamhyphaInfo(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.Hyphe
|
||||
}
|
||||
|
||||
//line views/nav.qtpl:32
|
||||
func writehyphaInfo(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.Hypher) {
|
||||
func writehyphaInfo(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.Hypha) {
|
||||
//line views/nav.qtpl:32
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/nav.qtpl:32
|
||||
@ -160,7 +160,7 @@ func writehyphaInfo(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.Hyphe
|
||||
}
|
||||
|
||||
//line views/nav.qtpl:32
|
||||
func hyphaInfo(rq *http.Request, h hyphae.Hypher) string {
|
||||
func hyphaInfo(rq *http.Request, h hyphae.Hypha) string {
|
||||
//line views/nav.qtpl:32
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/nav.qtpl:32
|
||||
|
@ -11,25 +11,26 @@
|
||||
{% import "github.com/bouncepaw/mycorrhiza/user" %}
|
||||
{% import "github.com/bouncepaw/mycorrhiza/util" %}
|
||||
|
||||
{% func AttachmentMenuHTML(rq *http.Request, h *hyphae.NonEmptyHypha, u *user.User) %}
|
||||
{% func AttachmentMenuHTML(rq *http.Request, h hyphae.Hypha, u *user.User) %}
|
||||
{% code
|
||||
lc := l18n.FromRequest(rq)
|
||||
%}
|
||||
<div class="layout">
|
||||
<main class="main-width attachment-tab">
|
||||
<h1>{%s= lc.Get("ui.attach_title", &l18n.Replacements{"name": beautifulLink(h.CanonicalName())}) %}</h1>
|
||||
{% if h.BinaryPath() == "" %}
|
||||
<p class="explanation">{%s lc.Get("ui.attach_empty") %} <a href="/help/en/attachment" class="shy-link">{%s lc.Get("ui.attach_link") %}</a></p>
|
||||
{% else %}
|
||||
{% switch h.(type) %}
|
||||
{% case *hyphae.MediaHypha %}
|
||||
<p class="explanation">{%s lc.Get("ui.attach_tip") %} <a href="/help/en/attachment" class="shy-link">{%s lc.Get("ui.attach_link") %}</a></p>
|
||||
{% endif %}
|
||||
{% default %}
|
||||
<p class="explanation">{%s lc.Get("ui.attach_empty") %} <a href="/help/en/attachment" class="shy-link">{%s lc.Get("ui.attach_link") %}</a></p>
|
||||
{% endswitch %}
|
||||
|
||||
<section class="amnt-grid">
|
||||
|
||||
{% if h.BinaryPath() != "" %}
|
||||
{% switch h := h.(type) %}
|
||||
{% case *hyphae.MediaHypha %}
|
||||
{% code
|
||||
mime := mimetype.FromExtension(path.Ext(h.BinaryPath()))
|
||||
fileinfo, err := os.Stat(h.BinaryPath()) %}
|
||||
mime := mimetype.FromExtension(path.Ext(h.MediaFilePath()))
|
||||
fileinfo, err := os.Stat(h.MediaFilePath()) %}
|
||||
{% if err == nil %}
|
||||
<fieldset class="amnt-menu-block">
|
||||
<legend class="modal__title modal__title_small">{%s lc.Get("ui.attach_stat") %}</legend>
|
||||
@ -45,7 +46,7 @@
|
||||
<pre class="codeblock"><code>img { {%s h.CanonicalName() %} }</code></pre>
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endswitch %}
|
||||
|
||||
{% if u.CanProceed("upload-binary") %}
|
||||
<form action="/upload-binary/{%s h.CanonicalName() %}"
|
||||
@ -62,7 +63,10 @@
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% if h.BinaryPath() != "" && u.CanProceed("unattach-confirm") %}
|
||||
|
||||
{% switch h := h.(type) %}
|
||||
{% case *hyphae.MediaHypha %}
|
||||
{% if u.CanProceed("unattach-confirm") %}
|
||||
<form action="/unattach-confirm/{%s h.CanonicalName() %}" method="post" class="modal amnt-menu-block">
|
||||
<fieldset class="modal__fieldset">
|
||||
<legend class="modal__title modal__title_small">{%s lc.Get("ui.attach_remove") %}</legend>
|
||||
@ -71,6 +75,7 @@
|
||||
</fieldset>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endswitch %}
|
||||
|
||||
</section>
|
||||
</main>
|
||||
@ -80,7 +85,7 @@
|
||||
If `contents` == "", a helpful message is shown instead.
|
||||
|
||||
If you rename .prevnext, change the docs too.
|
||||
{% func HyphaHTML(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypher, contents string) %}
|
||||
{% func HyphaHTML(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents string) %}
|
||||
{% code
|
||||
siblings, subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName())
|
||||
u := user.FromRequest(rq)
|
||||
@ -131,7 +136,7 @@ If you rename .prevnext, change the docs too.
|
||||
{%= viewScripts() %}
|
||||
{% endfunc %}
|
||||
|
||||
{% func RevisionHTML(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypher, contents, revHash string) %}
|
||||
{% func RevisionHTML(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents, revHash string) %}
|
||||
{% code
|
||||
siblings, subhyphae, _, _ := tree.Tree(h.CanonicalName())
|
||||
%}
|
||||
|
@ -51,7 +51,7 @@ var (
|
||||
)
|
||||
|
||||
//line views/readers.qtpl:14
|
||||
func StreamAttachmentMenuHTML(qw422016 *qt422016.Writer, rq *http.Request, h *hyphae.NonEmptyHypha, u *user.User) {
|
||||
func StreamAttachmentMenuHTML(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.Hypha, u *user.User) {
|
||||
//line views/readers.qtpl:14
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
@ -69,562 +69,578 @@ func StreamAttachmentMenuHTML(qw422016 *qt422016.Writer, rq *http.Request, h *hy
|
||||
qw422016.N().S(`</h1>
|
||||
`)
|
||||
//line views/readers.qtpl:21
|
||||
if h.BinaryPath() == "" {
|
||||
//line views/readers.qtpl:21
|
||||
switch h.(type) {
|
||||
//line views/readers.qtpl:22
|
||||
case *hyphae.MediaHypha:
|
||||
//line views/readers.qtpl:22
|
||||
qw422016.N().S(`
|
||||
<p class="explanation">`)
|
||||
//line views/readers.qtpl:22
|
||||
qw422016.E().S(lc.Get("ui.attach_empty"))
|
||||
//line views/readers.qtpl:22
|
||||
qw422016.N().S(` <a href="/help/en/attachment" class="shy-link">`)
|
||||
//line views/readers.qtpl:22
|
||||
qw422016.E().S(lc.Get("ui.attach_link"))
|
||||
//line views/readers.qtpl:22
|
||||
qw422016.N().S(`</a></p>
|
||||
`)
|
||||
//line views/readers.qtpl:23
|
||||
} else {
|
||||
//line views/readers.qtpl:23
|
||||
qw422016.N().S(`
|
||||
<p class="explanation">`)
|
||||
//line views/readers.qtpl:24
|
||||
qw422016.E().S(lc.Get("ui.attach_tip"))
|
||||
//line views/readers.qtpl:24
|
||||
//line views/readers.qtpl:23
|
||||
qw422016.N().S(` <a href="/help/en/attachment" class="shy-link">`)
|
||||
//line views/readers.qtpl:24
|
||||
//line views/readers.qtpl:23
|
||||
qw422016.E().S(lc.Get("ui.attach_link"))
|
||||
//line views/readers.qtpl:24
|
||||
//line views/readers.qtpl:23
|
||||
qw422016.N().S(`</a></p>
|
||||
`)
|
||||
//line views/readers.qtpl:24
|
||||
default:
|
||||
//line views/readers.qtpl:24
|
||||
qw422016.N().S(`
|
||||
<p class="explanation">`)
|
||||
//line views/readers.qtpl:25
|
||||
qw422016.E().S(lc.Get("ui.attach_empty"))
|
||||
//line views/readers.qtpl:25
|
||||
qw422016.N().S(` <a href="/help/en/attachment" class="shy-link">`)
|
||||
//line views/readers.qtpl:25
|
||||
qw422016.E().S(lc.Get("ui.attach_link"))
|
||||
//line views/readers.qtpl:25
|
||||
qw422016.N().S(`</a></p>
|
||||
`)
|
||||
//line views/readers.qtpl:26
|
||||
}
|
||||
//line views/readers.qtpl:25
|
||||
//line views/readers.qtpl:26
|
||||
qw422016.N().S(`
|
||||
|
||||
<section class="amnt-grid">
|
||||
|
||||
`)
|
||||
//line views/readers.qtpl:29
|
||||
if h.BinaryPath() != "" {
|
||||
//line views/readers.qtpl:29
|
||||
switch h := h.(type) {
|
||||
//line views/readers.qtpl:30
|
||||
case *hyphae.MediaHypha:
|
||||
//line views/readers.qtpl:30
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:31
|
||||
mime := mimetype.FromExtension(path.Ext(h.BinaryPath()))
|
||||
fileinfo, err := os.Stat(h.BinaryPath())
|
||||
|
||||
//line views/readers.qtpl:32
|
||||
mime := mimetype.FromExtension(path.Ext(h.MediaFilePath()))
|
||||
fileinfo, err := os.Stat(h.MediaFilePath())
|
||||
|
||||
//line views/readers.qtpl:33
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:33
|
||||
//line views/readers.qtpl:34
|
||||
if err == nil {
|
||||
//line views/readers.qtpl:33
|
||||
//line views/readers.qtpl:34
|
||||
qw422016.N().S(`
|
||||
<fieldset class="amnt-menu-block">
|
||||
<legend class="modal__title modal__title_small">`)
|
||||
//line views/readers.qtpl:35
|
||||
//line views/readers.qtpl:36
|
||||
qw422016.E().S(lc.Get("ui.attach_stat"))
|
||||
//line views/readers.qtpl:35
|
||||
//line views/readers.qtpl:36
|
||||
qw422016.N().S(`</legend>
|
||||
<p class="modal__confirmation-msg"><b>`)
|
||||
//line views/readers.qtpl:36
|
||||
//line views/readers.qtpl:37
|
||||
qw422016.E().S(lc.Get("ui.attach_stat_size"))
|
||||
//line views/readers.qtpl:36
|
||||
//line views/readers.qtpl:37
|
||||
qw422016.N().S(`</b> `)
|
||||
//line views/readers.qtpl:36
|
||||
//line views/readers.qtpl:37
|
||||
qw422016.E().S(lc.GetPlural64("ui.attach_size_value", fileinfo.Size()))
|
||||
//line views/readers.qtpl:36
|
||||
//line views/readers.qtpl:37
|
||||
qw422016.N().S(`</p>
|
||||
<p><b>`)
|
||||
//line views/readers.qtpl:37
|
||||
//line views/readers.qtpl:38
|
||||
qw422016.E().S(lc.Get("ui.attach_stat_mime"))
|
||||
//line views/readers.qtpl:37
|
||||
//line views/readers.qtpl:38
|
||||
qw422016.N().S(`</b> `)
|
||||
//line views/readers.qtpl:37
|
||||
//line views/readers.qtpl:38
|
||||
qw422016.E().S(mime)
|
||||
//line views/readers.qtpl:37
|
||||
//line views/readers.qtpl:38
|
||||
qw422016.N().S(`</p>
|
||||
</fieldset>
|
||||
`)
|
||||
//line views/readers.qtpl:39
|
||||
//line views/readers.qtpl:40
|
||||
}
|
||||
//line views/readers.qtpl:39
|
||||
//line views/readers.qtpl:40
|
||||
qw422016.N().S(`
|
||||
|
||||
`)
|
||||
//line views/readers.qtpl:41
|
||||
//line views/readers.qtpl:42
|
||||
if strings.HasPrefix(mime, "image/") {
|
||||
//line views/readers.qtpl:41
|
||||
//line views/readers.qtpl:42
|
||||
qw422016.N().S(`
|
||||
<fieldset class="amnt-menu-block">
|
||||
<legend class="modal__title modal__title_small">`)
|
||||
//line views/readers.qtpl:43
|
||||
//line views/readers.qtpl:44
|
||||
qw422016.E().S(lc.Get("ui.attach_include"))
|
||||
//line views/readers.qtpl:43
|
||||
//line views/readers.qtpl:44
|
||||
qw422016.N().S(`</legend>
|
||||
<p class="modal__confirmation-msg">`)
|
||||
//line views/readers.qtpl:44
|
||||
//line views/readers.qtpl:45
|
||||
qw422016.E().S(lc.Get("ui.attach_include_tip"))
|
||||
//line views/readers.qtpl:44
|
||||
//line views/readers.qtpl:45
|
||||
qw422016.N().S(`</p>
|
||||
<pre class="codeblock"><code>img { `)
|
||||
//line views/readers.qtpl:45
|
||||
//line views/readers.qtpl:46
|
||||
qw422016.E().S(h.CanonicalName())
|
||||
//line views/readers.qtpl:45
|
||||
//line views/readers.qtpl:46
|
||||
qw422016.N().S(` }</code></pre>
|
||||
</fieldset>
|
||||
`)
|
||||
//line views/readers.qtpl:47
|
||||
//line views/readers.qtpl:48
|
||||
}
|
||||
//line views/readers.qtpl:47
|
||||
//line views/readers.qtpl:48
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:48
|
||||
//line views/readers.qtpl:49
|
||||
}
|
||||
//line views/readers.qtpl:48
|
||||
//line views/readers.qtpl:49
|
||||
qw422016.N().S(`
|
||||
|
||||
`)
|
||||
//line views/readers.qtpl:50
|
||||
//line views/readers.qtpl:51
|
||||
if u.CanProceed("upload-binary") {
|
||||
//line views/readers.qtpl:50
|
||||
//line views/readers.qtpl:51
|
||||
qw422016.N().S(`
|
||||
<form action="/upload-binary/`)
|
||||
//line views/readers.qtpl:51
|
||||
//line views/readers.qtpl:52
|
||||
qw422016.E().S(h.CanonicalName())
|
||||
//line views/readers.qtpl:51
|
||||
//line views/readers.qtpl:52
|
||||
qw422016.N().S(`"
|
||||
method="post" enctype="multipart/form-data"
|
||||
class="upload-binary modal amnt-menu-block">
|
||||
<fieldset class="modal__fieldset">
|
||||
<legend class="modal__title modal__title_small">`)
|
||||
//line views/readers.qtpl:55
|
||||
//line views/readers.qtpl:56
|
||||
qw422016.E().S(lc.Get("ui.attach_new"))
|
||||
//line views/readers.qtpl:55
|
||||
//line views/readers.qtpl:56
|
||||
qw422016.N().S(`</legend>
|
||||
<p class="modal__confirmation-msg">`)
|
||||
//line views/readers.qtpl:56
|
||||
//line views/readers.qtpl:57
|
||||
qw422016.E().S(lc.Get("ui.attach_new_tip"))
|
||||
//line views/readers.qtpl:56
|
||||
//line views/readers.qtpl:57
|
||||
qw422016.N().S(`</p>
|
||||
<label for="upload-binary__input"></label>
|
||||
<input type="file" id="upload-binary__input" name="binary">
|
||||
|
||||
<button type="submit" class="btn stick-to-bottom" value="Upload">`)
|
||||
//line views/readers.qtpl:60
|
||||
//line views/readers.qtpl:61
|
||||
qw422016.E().S(lc.Get("ui.attach_upload"))
|
||||
//line views/readers.qtpl:60
|
||||
//line views/readers.qtpl:61
|
||||
qw422016.N().S(`</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
`)
|
||||
//line views/readers.qtpl:63
|
||||
//line views/readers.qtpl:64
|
||||
}
|
||||
//line views/readers.qtpl:63
|
||||
//line views/readers.qtpl:64
|
||||
qw422016.N().S(`
|
||||
|
||||
|
||||
`)
|
||||
//line views/readers.qtpl:65
|
||||
if h.BinaryPath() != "" && u.CanProceed("unattach-confirm") {
|
||||
//line views/readers.qtpl:65
|
||||
//line views/readers.qtpl:67
|
||||
switch h := h.(type) {
|
||||
//line views/readers.qtpl:68
|
||||
case *hyphae.MediaHypha:
|
||||
//line views/readers.qtpl:68
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:69
|
||||
if u.CanProceed("unattach-confirm") {
|
||||
//line views/readers.qtpl:69
|
||||
qw422016.N().S(`
|
||||
<form action="/unattach-confirm/`)
|
||||
//line views/readers.qtpl:66
|
||||
//line views/readers.qtpl:70
|
||||
qw422016.E().S(h.CanonicalName())
|
||||
//line views/readers.qtpl:66
|
||||
//line views/readers.qtpl:70
|
||||
qw422016.N().S(`" method="post" class="modal amnt-menu-block">
|
||||
<fieldset class="modal__fieldset">
|
||||
<legend class="modal__title modal__title_small">`)
|
||||
//line views/readers.qtpl:68
|
||||
//line views/readers.qtpl:72
|
||||
qw422016.E().S(lc.Get("ui.attach_remove"))
|
||||
//line views/readers.qtpl:68
|
||||
//line views/readers.qtpl:72
|
||||
qw422016.N().S(`</legend>
|
||||
<p class="modal__confirmation-msg">`)
|
||||
//line views/readers.qtpl:69
|
||||
//line views/readers.qtpl:73
|
||||
qw422016.E().S(lc.Get("ui.attach_remove_tip"))
|
||||
//line views/readers.qtpl:69
|
||||
//line views/readers.qtpl:73
|
||||
qw422016.N().S(`</p>
|
||||
<button type="submit" class="btn" value="Unattach">`)
|
||||
//line views/readers.qtpl:70
|
||||
//line views/readers.qtpl:74
|
||||
qw422016.E().S(lc.Get("ui.attach_remove_button"))
|
||||
//line views/readers.qtpl:70
|
||||
//line views/readers.qtpl:74
|
||||
qw422016.N().S(`</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
`)
|
||||
//line views/readers.qtpl:73
|
||||
//line views/readers.qtpl:77
|
||||
}
|
||||
//line views/readers.qtpl:73
|
||||
//line views/readers.qtpl:77
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:78
|
||||
}
|
||||
//line views/readers.qtpl:78
|
||||
qw422016.N().S(`
|
||||
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
`)
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:78
|
||||
func WriteAttachmentMenuHTML(qq422016 qtio422016.Writer, rq *http.Request, h *hyphae.NonEmptyHypha, u *user.User) {
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
func WriteAttachmentMenuHTML(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.Hypha, u *user.User) {
|
||||
//line views/readers.qtpl:83
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
StreamAttachmentMenuHTML(qw422016, rq, h, u)
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:78
|
||||
func AttachmentMenuHTML(rq *http.Request, h *hyphae.NonEmptyHypha, u *user.User) string {
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
func AttachmentMenuHTML(rq *http.Request, h hyphae.Hypha, u *user.User) string {
|
||||
//line views/readers.qtpl:83
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
WriteAttachmentMenuHTML(qb422016, rq, h, u)
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
qs422016 := string(qb422016.B)
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
return qs422016
|
||||
//line views/readers.qtpl:78
|
||||
//line views/readers.qtpl:83
|
||||
}
|
||||
|
||||
// If `contents` == "", a helpful message is shown instead.
|
||||
//
|
||||
// If you rename .prevnext, change the docs too.
|
||||
|
||||
//line views/readers.qtpl:83
|
||||
func StreamHyphaHTML(qw422016 *qt422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypher, contents string) {
|
||||
//line views/readers.qtpl:83
|
||||
//line views/readers.qtpl:88
|
||||
func StreamHyphaHTML(qw422016 *qt422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents string) {
|
||||
//line views/readers.qtpl:88
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:85
|
||||
//line views/readers.qtpl:90
|
||||
siblings, subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName())
|
||||
u := user.FromRequest(rq)
|
||||
|
||||
//line views/readers.qtpl:87
|
||||
//line views/readers.qtpl:92
|
||||
qw422016.N().S(`
|
||||
<div class="layout">
|
||||
<main class="main-width">
|
||||
<section id="hypha">
|
||||
`)
|
||||
//line views/readers.qtpl:91
|
||||
//line views/readers.qtpl:96
|
||||
if u.CanProceed("edit") {
|
||||
//line views/readers.qtpl:91
|
||||
//line views/readers.qtpl:96
|
||||
qw422016.N().S(`
|
||||
<div class="btn btn_navititle">
|
||||
<a class="btn__link_navititle" href="/edit/`)
|
||||
//line views/readers.qtpl:93
|
||||
//line views/readers.qtpl:98
|
||||
qw422016.E().S(h.CanonicalName())
|
||||
//line views/readers.qtpl:93
|
||||
//line views/readers.qtpl:98
|
||||
qw422016.N().S(`">`)
|
||||
//line views/readers.qtpl:93
|
||||
//line views/readers.qtpl:98
|
||||
qw422016.E().S(lc.Get("ui.edit_link"))
|
||||
//line views/readers.qtpl:93
|
||||
//line views/readers.qtpl:98
|
||||
qw422016.N().S(`</a>
|
||||
</div>
|
||||
`)
|
||||
//line views/readers.qtpl:95
|
||||
//line views/readers.qtpl:100
|
||||
}
|
||||
//line views/readers.qtpl:95
|
||||
//line views/readers.qtpl:100
|
||||
qw422016.N().S(`
|
||||
|
||||
`)
|
||||
//line views/readers.qtpl:97
|
||||
//line views/readers.qtpl:102
|
||||
if cfg.UseAuth && util.IsProfileName(h.CanonicalName()) && u.Name == strings.TrimPrefix(h.CanonicalName(), cfg.UserHypha+"/") {
|
||||
//line views/readers.qtpl:97
|
||||
//line views/readers.qtpl:102
|
||||
qw422016.N().S(`
|
||||
<div class="btn btn_navititle">
|
||||
<a class="btn__link_navititle" href="/logout">`)
|
||||
//line views/readers.qtpl:99
|
||||
//line views/readers.qtpl:104
|
||||
qw422016.E().S(lc.Get("ui.logout_link"))
|
||||
//line views/readers.qtpl:99
|
||||
//line views/readers.qtpl:104
|
||||
qw422016.N().S(`</a>
|
||||
</div>
|
||||
`)
|
||||
//line views/readers.qtpl:101
|
||||
//line views/readers.qtpl:106
|
||||
if u.Group == "admin" {
|
||||
//line views/readers.qtpl:101
|
||||
//line views/readers.qtpl:106
|
||||
qw422016.N().S(`
|
||||
<div class="btn btn_navititle">
|
||||
<a class="btn__link_navititle" href="/admin">`)
|
||||
//line views/readers.qtpl:103
|
||||
//line views/readers.qtpl:108
|
||||
qw422016.E().S(lc.Get("ui.admin_panel"))
|
||||
//line views/readers.qtpl:103
|
||||
//line views/readers.qtpl:108
|
||||
qw422016.N().S(`<a>
|
||||
</div>
|
||||
`)
|
||||
//line views/readers.qtpl:105
|
||||
//line views/readers.qtpl:110
|
||||
}
|
||||
//line views/readers.qtpl:105
|
||||
//line views/readers.qtpl:110
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:106
|
||||
//line views/readers.qtpl:111
|
||||
}
|
||||
//line views/readers.qtpl:106
|
||||
//line views/readers.qtpl:111
|
||||
qw422016.N().S(`
|
||||
|
||||
`)
|
||||
//line views/readers.qtpl:108
|
||||
//line views/readers.qtpl:113
|
||||
qw422016.N().S(NaviTitleHTML(h))
|
||||
//line views/readers.qtpl:108
|
||||
//line views/readers.qtpl:113
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:109
|
||||
//line views/readers.qtpl:114
|
||||
switch h.(type) {
|
||||
//line views/readers.qtpl:110
|
||||
//line views/readers.qtpl:115
|
||||
case *hyphae.EmptyHypha:
|
||||
//line views/readers.qtpl:110
|
||||
//line views/readers.qtpl:115
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:111
|
||||
//line views/readers.qtpl:116
|
||||
streamnonExistentHyphaNotice(qw422016, h, u, lc)
|
||||
//line views/readers.qtpl:111
|
||||
//line views/readers.qtpl:116
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:112
|
||||
//line views/readers.qtpl:117
|
||||
default:
|
||||
//line views/readers.qtpl:112
|
||||
//line views/readers.qtpl:117
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:113
|
||||
//line views/readers.qtpl:118
|
||||
qw422016.N().S(contents)
|
||||
//line views/readers.qtpl:113
|
||||
//line views/readers.qtpl:118
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:114
|
||||
//line views/readers.qtpl:119
|
||||
}
|
||||
//line views/readers.qtpl:114
|
||||
//line views/readers.qtpl:119
|
||||
qw422016.N().S(`
|
||||
</section>
|
||||
<section class="prevnext">
|
||||
`)
|
||||
//line views/readers.qtpl:117
|
||||
//line views/readers.qtpl:122
|
||||
if prevHyphaName != "" {
|
||||
//line views/readers.qtpl:117
|
||||
//line views/readers.qtpl:122
|
||||
qw422016.N().S(`
|
||||
<a class="prevnext__el prevnext__prev" href="/hypha/`)
|
||||
//line views/readers.qtpl:118
|
||||
//line views/readers.qtpl:123
|
||||
qw422016.E().S(prevHyphaName)
|
||||
//line views/readers.qtpl:118
|
||||
//line views/readers.qtpl:123
|
||||
qw422016.N().S(`" rel="prev">← `)
|
||||
//line views/readers.qtpl:118
|
||||
//line views/readers.qtpl:123
|
||||
qw422016.E().S(util.BeautifulName(path.Base(prevHyphaName)))
|
||||
//line views/readers.qtpl:118
|
||||
//line views/readers.qtpl:123
|
||||
qw422016.N().S(`</a>
|
||||
`)
|
||||
//line views/readers.qtpl:119
|
||||
//line views/readers.qtpl:124
|
||||
}
|
||||
//line views/readers.qtpl:119
|
||||
//line views/readers.qtpl:124
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:120
|
||||
//line views/readers.qtpl:125
|
||||
if nextHyphaName != "" {
|
||||
//line views/readers.qtpl:120
|
||||
//line views/readers.qtpl:125
|
||||
qw422016.N().S(`
|
||||
<a class="prevnext__el prevnext__next" href="/hypha/`)
|
||||
//line views/readers.qtpl:121
|
||||
//line views/readers.qtpl:126
|
||||
qw422016.E().S(nextHyphaName)
|
||||
//line views/readers.qtpl:121
|
||||
//line views/readers.qtpl:126
|
||||
qw422016.N().S(`" rel="next">`)
|
||||
//line views/readers.qtpl:121
|
||||
//line views/readers.qtpl:126
|
||||
qw422016.E().S(util.BeautifulName(path.Base(nextHyphaName)))
|
||||
//line views/readers.qtpl:121
|
||||
//line views/readers.qtpl:126
|
||||
qw422016.N().S(` →</a>
|
||||
`)
|
||||
//line views/readers.qtpl:122
|
||||
//line views/readers.qtpl:127
|
||||
}
|
||||
//line views/readers.qtpl:122
|
||||
//line views/readers.qtpl:127
|
||||
qw422016.N().S(`
|
||||
</section>
|
||||
`)
|
||||
//line views/readers.qtpl:124
|
||||
//line views/readers.qtpl:129
|
||||
StreamSubhyphaeHTML(qw422016, subhyphae, lc)
|
||||
//line views/readers.qtpl:124
|
||||
//line views/readers.qtpl:129
|
||||
qw422016.N().S(`
|
||||
<section id="hypha-bottom">
|
||||
`)
|
||||
//line views/readers.qtpl:126
|
||||
//line views/readers.qtpl:131
|
||||
streamhyphaInfo(qw422016, rq, h)
|
||||
//line views/readers.qtpl:126
|
||||
//line views/readers.qtpl:131
|
||||
qw422016.N().S(`
|
||||
</section>
|
||||
</main>
|
||||
`)
|
||||
//line views/readers.qtpl:129
|
||||
//line views/readers.qtpl:134
|
||||
streamsiblingHyphaeHTML(qw422016, siblings, lc)
|
||||
//line views/readers.qtpl:129
|
||||
//line views/readers.qtpl:134
|
||||
qw422016.N().S(`
|
||||
</div>
|
||||
`)
|
||||
//line views/readers.qtpl:131
|
||||
streamviewScripts(qw422016)
|
||||
//line views/readers.qtpl:131
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:132
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:132
|
||||
func WriteHyphaHTML(qq422016 qtio422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypher, contents string) {
|
||||
//line views/readers.qtpl:132
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/readers.qtpl:132
|
||||
StreamHyphaHTML(qw422016, rq, lc, h, contents)
|
||||
//line views/readers.qtpl:132
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line views/readers.qtpl:132
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:132
|
||||
func HyphaHTML(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypher, contents string) string {
|
||||
//line views/readers.qtpl:132
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/readers.qtpl:132
|
||||
WriteHyphaHTML(qb422016, rq, lc, h, contents)
|
||||
//line views/readers.qtpl:132
|
||||
qs422016 := string(qb422016.B)
|
||||
//line views/readers.qtpl:132
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line views/readers.qtpl:132
|
||||
return qs422016
|
||||
//line views/readers.qtpl:132
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:134
|
||||
func StreamRevisionHTML(qw422016 *qt422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypher, contents, revHash string) {
|
||||
//line views/readers.qtpl:134
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:136
|
||||
siblings, subhyphae, _, _ := tree.Tree(h.CanonicalName())
|
||||
streamviewScripts(qw422016)
|
||||
//line views/readers.qtpl:136
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:137
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:137
|
||||
func WriteHyphaHTML(qq422016 qtio422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents string) {
|
||||
//line views/readers.qtpl:137
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/readers.qtpl:137
|
||||
StreamHyphaHTML(qw422016, rq, lc, h, contents)
|
||||
//line views/readers.qtpl:137
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line views/readers.qtpl:137
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:137
|
||||
func HyphaHTML(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents string) string {
|
||||
//line views/readers.qtpl:137
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/readers.qtpl:137
|
||||
WriteHyphaHTML(qb422016, rq, lc, h, contents)
|
||||
//line views/readers.qtpl:137
|
||||
qs422016 := string(qb422016.B)
|
||||
//line views/readers.qtpl:137
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line views/readers.qtpl:137
|
||||
return qs422016
|
||||
//line views/readers.qtpl:137
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:139
|
||||
func StreamRevisionHTML(qw422016 *qt422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents, revHash string) {
|
||||
//line views/readers.qtpl:139
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:141
|
||||
siblings, subhyphae, _, _ := tree.Tree(h.CanonicalName())
|
||||
|
||||
//line views/readers.qtpl:142
|
||||
qw422016.N().S(`
|
||||
<div class="layout">
|
||||
<main class="main-width">
|
||||
<section>
|
||||
<p>`)
|
||||
//line views/readers.qtpl:141
|
||||
//line views/readers.qtpl:146
|
||||
qw422016.E().S(lc.Get("ui.revision_warning"))
|
||||
//line views/readers.qtpl:141
|
||||
//line views/readers.qtpl:146
|
||||
qw422016.N().S(` <a href="/rev-text/`)
|
||||
//line views/readers.qtpl:141
|
||||
//line views/readers.qtpl:146
|
||||
qw422016.E().S(revHash)
|
||||
//line views/readers.qtpl:141
|
||||
//line views/readers.qtpl:146
|
||||
qw422016.N().S(`/`)
|
||||
//line views/readers.qtpl:141
|
||||
//line views/readers.qtpl:146
|
||||
qw422016.E().S(h.CanonicalName())
|
||||
//line views/readers.qtpl:141
|
||||
//line views/readers.qtpl:146
|
||||
qw422016.N().S(`">`)
|
||||
//line views/readers.qtpl:141
|
||||
//line views/readers.qtpl:146
|
||||
qw422016.E().S(lc.Get("ui.revision_link"))
|
||||
//line views/readers.qtpl:141
|
||||
//line views/readers.qtpl:146
|
||||
qw422016.N().S(`</a></p>
|
||||
`)
|
||||
//line views/readers.qtpl:142
|
||||
//line views/readers.qtpl:147
|
||||
qw422016.N().S(NaviTitleHTML(h))
|
||||
//line views/readers.qtpl:142
|
||||
//line views/readers.qtpl:147
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:143
|
||||
//line views/readers.qtpl:148
|
||||
qw422016.N().S(contents)
|
||||
//line views/readers.qtpl:143
|
||||
//line views/readers.qtpl:148
|
||||
qw422016.N().S(`
|
||||
</section>
|
||||
`)
|
||||
//line views/readers.qtpl:145
|
||||
//line views/readers.qtpl:150
|
||||
StreamSubhyphaeHTML(qw422016, subhyphae, lc)
|
||||
//line views/readers.qtpl:145
|
||||
//line views/readers.qtpl:150
|
||||
qw422016.N().S(`
|
||||
</main>
|
||||
`)
|
||||
//line views/readers.qtpl:147
|
||||
//line views/readers.qtpl:152
|
||||
streamsiblingHyphaeHTML(qw422016, siblings, lc)
|
||||
//line views/readers.qtpl:147
|
||||
//line views/readers.qtpl:152
|
||||
qw422016.N().S(`
|
||||
</div>
|
||||
`)
|
||||
//line views/readers.qtpl:149
|
||||
//line views/readers.qtpl:154
|
||||
streamviewScripts(qw422016)
|
||||
//line views/readers.qtpl:149
|
||||
//line views/readers.qtpl:154
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:150
|
||||
func WriteRevisionHTML(qq422016 qtio422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypher, contents, revHash string) {
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
func WriteRevisionHTML(qq422016 qtio422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents, revHash string) {
|
||||
//line views/readers.qtpl:155
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
StreamRevisionHTML(qw422016, rq, lc, h, contents, revHash)
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:150
|
||||
func RevisionHTML(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypher, contents, revHash string) string {
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
func RevisionHTML(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents, revHash string) string {
|
||||
//line views/readers.qtpl:155
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
WriteRevisionHTML(qb422016, rq, lc, h, contents, revHash)
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
qs422016 := string(qb422016.B)
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
return qs422016
|
||||
//line views/readers.qtpl:150
|
||||
//line views/readers.qtpl:155
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:152
|
||||
//line views/readers.qtpl:157
|
||||
func streamviewScripts(qw422016 *qt422016.Writer) {
|
||||
//line views/readers.qtpl:152
|
||||
//line views/readers.qtpl:157
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:153
|
||||
//line views/readers.qtpl:158
|
||||
for _, scriptPath := range cfg.ViewScripts {
|
||||
//line views/readers.qtpl:153
|
||||
//line views/readers.qtpl:158
|
||||
qw422016.N().S(`
|
||||
<script src="`)
|
||||
//line views/readers.qtpl:154
|
||||
//line views/readers.qtpl:159
|
||||
qw422016.E().S(scriptPath)
|
||||
//line views/readers.qtpl:154
|
||||
//line views/readers.qtpl:159
|
||||
qw422016.N().S(`"></script>
|
||||
`)
|
||||
//line views/readers.qtpl:155
|
||||
//line views/readers.qtpl:160
|
||||
}
|
||||
//line views/readers.qtpl:155
|
||||
//line views/readers.qtpl:160
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
func writeviewScripts(qq422016 qtio422016.Writer) {
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
streamviewScripts(qw422016)
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
}
|
||||
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
func viewScripts() string {
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
writeviewScripts(qb422016)
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
qs422016 := string(qb422016.B)
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
return qs422016
|
||||
//line views/readers.qtpl:156
|
||||
//line views/readers.qtpl:161
|
||||
}
|
||||
|
@ -262,16 +262,17 @@ sort.Strings(editors)
|
||||
close(hyphaNames)
|
||||
%}
|
||||
{% for hyphaName := range sortedHypha %}
|
||||
{% code hypha := hyphae.ByName(hyphaName).(*hyphae.NonEmptyHypha) %}
|
||||
{% code h := hyphae.ByName(hyphaName) %}
|
||||
<li class="hypha-list__entry">
|
||||
<a class="hypha-list__link" href="/hypha/{%s hypha.CanonicalName() %}">
|
||||
{%s util.BeautifulName(hypha.CanonicalName()) %}
|
||||
<a class="hypha-list__link" href="/hypha/{%s h.CanonicalName() %}">
|
||||
{%s util.BeautifulName(h.CanonicalName()) %}
|
||||
</a>
|
||||
{% if hypha.Kind() == hyphae.HyphaMedia %}
|
||||
{% switch h := h.(type) %}
|
||||
{% case *hyphae.MediaHypha %}
|
||||
<span class="hypha-list__amnt-type">
|
||||
{%s filepath.Ext(hypha.BinaryPath())[1:] %}
|
||||
{%s filepath.Ext(h.MediaFilePath())[1:] %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endswitch %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
@ -1020,247 +1020,249 @@ func StreamHyphaListHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) {
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/stuff.qtpl:265
|
||||
hypha := hyphae.ByName(hyphaName).(*hyphae.NonEmptyHypha)
|
||||
h := hyphae.ByName(hyphaName)
|
||||
|
||||
//line views/stuff.qtpl:265
|
||||
qw422016.N().S(`
|
||||
<li class="hypha-list__entry">
|
||||
<a class="hypha-list__link" href="/hypha/`)
|
||||
//line views/stuff.qtpl:267
|
||||
qw422016.E().S(hypha.CanonicalName())
|
||||
qw422016.E().S(h.CanonicalName())
|
||||
//line views/stuff.qtpl:267
|
||||
qw422016.N().S(`">
|
||||
`)
|
||||
//line views/stuff.qtpl:268
|
||||
qw422016.E().S(util.BeautifulName(hypha.CanonicalName()))
|
||||
qw422016.E().S(util.BeautifulName(h.CanonicalName()))
|
||||
//line views/stuff.qtpl:268
|
||||
qw422016.N().S(`
|
||||
</a>
|
||||
`)
|
||||
//line views/stuff.qtpl:270
|
||||
if hypha.Kind() == hyphae.HyphaMedia {
|
||||
//line views/stuff.qtpl:270
|
||||
switch h := h.(type) {
|
||||
//line views/stuff.qtpl:271
|
||||
case *hyphae.MediaHypha:
|
||||
//line views/stuff.qtpl:271
|
||||
qw422016.N().S(`
|
||||
<span class="hypha-list__amnt-type">
|
||||
`)
|
||||
//line views/stuff.qtpl:272
|
||||
qw422016.E().S(filepath.Ext(hypha.BinaryPath())[1:])
|
||||
//line views/stuff.qtpl:272
|
||||
//line views/stuff.qtpl:273
|
||||
qw422016.E().S(filepath.Ext(h.MediaFilePath())[1:])
|
||||
//line views/stuff.qtpl:273
|
||||
qw422016.N().S(`
|
||||
</span>
|
||||
`)
|
||||
//line views/stuff.qtpl:274
|
||||
//line views/stuff.qtpl:275
|
||||
}
|
||||
//line views/stuff.qtpl:274
|
||||
//line views/stuff.qtpl:275
|
||||
qw422016.N().S(`
|
||||
</li>
|
||||
`)
|
||||
//line views/stuff.qtpl:276
|
||||
//line views/stuff.qtpl:277
|
||||
}
|
||||
//line views/stuff.qtpl:276
|
||||
//line views/stuff.qtpl:277
|
||||
qw422016.N().S(`
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
`)
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
}
|
||||
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
func WriteHyphaListHTML(qq422016 qtio422016.Writer, lc *l18n.Localizer) {
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
StreamHyphaListHTML(qw422016, lc)
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
}
|
||||
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
func HyphaListHTML(lc *l18n.Localizer) string {
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
WriteHyphaListHTML(qb422016, lc)
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
qs422016 := string(qb422016.B)
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
return qs422016
|
||||
//line views/stuff.qtpl:280
|
||||
//line views/stuff.qtpl:281
|
||||
}
|
||||
|
||||
//line views/stuff.qtpl:282
|
||||
//line views/stuff.qtpl:283
|
||||
func StreamAboutHTML(qw422016 *qt422016.Writer, lc *l18n.Localizer) {
|
||||
//line views/stuff.qtpl:282
|
||||
//line views/stuff.qtpl:283
|
||||
qw422016.N().S(`
|
||||
<div class="layout">
|
||||
<main class="main-width">
|
||||
<section>
|
||||
<h1>`)
|
||||
//line views/stuff.qtpl:286
|
||||
//line views/stuff.qtpl:287
|
||||
qw422016.E().S(lc.Get("ui.about_title", &l18n.Replacements{"name": cfg.WikiName}))
|
||||
//line views/stuff.qtpl:286
|
||||
//line views/stuff.qtpl:287
|
||||
qw422016.N().S(`</h1>
|
||||
<ul>
|
||||
<li><b>`)
|
||||
//line views/stuff.qtpl:288
|
||||
//line views/stuff.qtpl:289
|
||||
qw422016.N().S(lc.Get("ui.about_version", &l18n.Replacements{"pre": "<a href=\"https://mycorrhiza.wiki\">", "post": "</a>"}))
|
||||
//line views/stuff.qtpl:288
|
||||
//line views/stuff.qtpl:289
|
||||
qw422016.N().S(`</b> 1.8.0</li>
|
||||
`)
|
||||
//line views/stuff.qtpl:289
|
||||
//line views/stuff.qtpl:290
|
||||
if cfg.UseAuth {
|
||||
//line views/stuff.qtpl:289
|
||||
//line views/stuff.qtpl:290
|
||||
qw422016.N().S(` <li><b>`)
|
||||
//line views/stuff.qtpl:290
|
||||
//line views/stuff.qtpl:291
|
||||
qw422016.E().S(lc.Get("ui.about_usercount"))
|
||||
//line views/stuff.qtpl:290
|
||||
//line views/stuff.qtpl:291
|
||||
qw422016.N().S(`</b> `)
|
||||
//line views/stuff.qtpl:290
|
||||
//line views/stuff.qtpl:291
|
||||
qw422016.N().DUL(user.Count())
|
||||
//line views/stuff.qtpl:290
|
||||
//line views/stuff.qtpl:291
|
||||
qw422016.N().S(`</li>
|
||||
<li><b>`)
|
||||
//line views/stuff.qtpl:291
|
||||
//line views/stuff.qtpl:292
|
||||
qw422016.E().S(lc.Get("ui.about_homepage"))
|
||||
//line views/stuff.qtpl:291
|
||||
//line views/stuff.qtpl:292
|
||||
qw422016.N().S(`</b> <a href="/">`)
|
||||
//line views/stuff.qtpl:291
|
||||
//line views/stuff.qtpl:292
|
||||
qw422016.E().S(cfg.HomeHypha)
|
||||
//line views/stuff.qtpl:291
|
||||
//line views/stuff.qtpl:292
|
||||
qw422016.N().S(`</a></li>
|
||||
<li><b>`)
|
||||
//line views/stuff.qtpl:292
|
||||
//line views/stuff.qtpl:293
|
||||
qw422016.E().S(lc.Get("ui.about_admins"))
|
||||
//line views/stuff.qtpl:292
|
||||
//line views/stuff.qtpl:293
|
||||
qw422016.N().S(`</b>`)
|
||||
//line views/stuff.qtpl:292
|
||||
//line views/stuff.qtpl:293
|
||||
for i, username := range user.ListUsersWithGroup("admin") {
|
||||
//line views/stuff.qtpl:293
|
||||
//line views/stuff.qtpl:294
|
||||
if i > 0 {
|
||||
//line views/stuff.qtpl:293
|
||||
//line views/stuff.qtpl:294
|
||||
qw422016.N().S(`<span aria-hidden="true">, </span>
|
||||
`)
|
||||
//line views/stuff.qtpl:294
|
||||
//line views/stuff.qtpl:295
|
||||
}
|
||||
//line views/stuff.qtpl:294
|
||||
//line views/stuff.qtpl:295
|
||||
qw422016.N().S(` <a href="/hypha/`)
|
||||
//line views/stuff.qtpl:295
|
||||
//line views/stuff.qtpl:296
|
||||
qw422016.E().S(cfg.UserHypha)
|
||||
//line views/stuff.qtpl:295
|
||||
//line views/stuff.qtpl:296
|
||||
qw422016.N().S(`/`)
|
||||
//line views/stuff.qtpl:295
|
||||
//line views/stuff.qtpl:296
|
||||
qw422016.E().S(username)
|
||||
//line views/stuff.qtpl:295
|
||||
//line views/stuff.qtpl:296
|
||||
qw422016.N().S(`">`)
|
||||
//line views/stuff.qtpl:295
|
||||
//line views/stuff.qtpl:296
|
||||
qw422016.E().S(username)
|
||||
//line views/stuff.qtpl:295
|
||||
//line views/stuff.qtpl:296
|
||||
qw422016.N().S(`</a>`)
|
||||
//line views/stuff.qtpl:295
|
||||
//line views/stuff.qtpl:296
|
||||
}
|
||||
//line views/stuff.qtpl:295
|
||||
//line views/stuff.qtpl:296
|
||||
qw422016.N().S(`</li>
|
||||
`)
|
||||
//line views/stuff.qtpl:296
|
||||
//line views/stuff.qtpl:297
|
||||
} else {
|
||||
//line views/stuff.qtpl:296
|
||||
//line views/stuff.qtpl:297
|
||||
qw422016.N().S(` <li>`)
|
||||
//line views/stuff.qtpl:297
|
||||
//line views/stuff.qtpl:298
|
||||
qw422016.E().S(lc.Get("ui.about_noauth"))
|
||||
//line views/stuff.qtpl:297
|
||||
//line views/stuff.qtpl:298
|
||||
qw422016.N().S(`</li>
|
||||
`)
|
||||
//line views/stuff.qtpl:298
|
||||
//line views/stuff.qtpl:299
|
||||
}
|
||||
//line views/stuff.qtpl:298
|
||||
//line views/stuff.qtpl:299
|
||||
qw422016.N().S(` </ul>
|
||||
<p>`)
|
||||
//line views/stuff.qtpl:300
|
||||
//line views/stuff.qtpl:301
|
||||
qw422016.N().S(lc.Get("ui.about_hyphae", &l18n.Replacements{"link": "<a href=\"/list\">/list</a>"}))
|
||||
//line views/stuff.qtpl:300
|
||||
//line views/stuff.qtpl:301
|
||||
qw422016.N().S(`</p>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
`)
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
}
|
||||
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
func WriteAboutHTML(qq422016 qtio422016.Writer, lc *l18n.Localizer) {
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
StreamAboutHTML(qw422016, lc)
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
}
|
||||
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
func AboutHTML(lc *l18n.Localizer) string {
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
WriteAboutHTML(qb422016, lc)
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
qs422016 := string(qb422016.B)
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
return qs422016
|
||||
//line views/stuff.qtpl:304
|
||||
//line views/stuff.qtpl:305
|
||||
}
|
||||
|
||||
//line views/stuff.qtpl:306
|
||||
//line views/stuff.qtpl:307
|
||||
func StreamCommonScripts(qw422016 *qt422016.Writer) {
|
||||
//line views/stuff.qtpl:306
|
||||
//line views/stuff.qtpl:307
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/stuff.qtpl:307
|
||||
//line views/stuff.qtpl:308
|
||||
for _, scriptPath := range cfg.CommonScripts {
|
||||
//line views/stuff.qtpl:307
|
||||
//line views/stuff.qtpl:308
|
||||
qw422016.N().S(`
|
||||
<script src="`)
|
||||
//line views/stuff.qtpl:308
|
||||
//line views/stuff.qtpl:309
|
||||
qw422016.E().S(scriptPath)
|
||||
//line views/stuff.qtpl:308
|
||||
//line views/stuff.qtpl:309
|
||||
qw422016.N().S(`"></script>
|
||||
`)
|
||||
//line views/stuff.qtpl:309
|
||||
//line views/stuff.qtpl:310
|
||||
}
|
||||
//line views/stuff.qtpl:309
|
||||
//line views/stuff.qtpl:310
|
||||
qw422016.N().S(`
|
||||
`)
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
}
|
||||
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
func WriteCommonScripts(qq422016 qtio422016.Writer) {
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
StreamCommonScripts(qw422016)
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
}
|
||||
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
func CommonScripts() string {
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
WriteCommonScripts(qb422016)
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
qs422016 := string(qb422016.B)
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
return qs422016
|
||||
//line views/stuff.qtpl:310
|
||||
//line views/stuff.qtpl:311
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ func initMutators(r *mux.Router) {
|
||||
|
||||
func factoryHandlerAsker(
|
||||
actionPath string,
|
||||
asker func(*user.User, hyphae.Hypher, *l18n.Localizer) (string, error),
|
||||
asker func(*user.User, hyphae.Hypha, *l18n.Localizer) (string, error),
|
||||
succTitleKey string,
|
||||
succPageTemplate func(*http.Request, string, bool) string,
|
||||
) func(http.ResponseWriter, *http.Request) {
|
||||
@ -63,7 +63,7 @@ func factoryHandlerAsker(
|
||||
w,
|
||||
views.BaseHTML(
|
||||
fmt.Sprintf(lc.Get(succTitleKey), util.BeautifulName(hyphaName)),
|
||||
succPageTemplate(rq, hyphaName, func(h hyphae.Hypher) bool {
|
||||
succPageTemplate(rq, hyphaName, func(h hyphae.Hypha) bool {
|
||||
switch h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
return false
|
||||
@ -99,7 +99,7 @@ var handlerRenameAsk = factoryHandlerAsker(
|
||||
|
||||
func factoryHandlerConfirmer(
|
||||
actionPath string,
|
||||
confirmer func(hyphae.Hypher, *user.User, *http.Request) (*history.Op, string),
|
||||
confirmer func(hyphae.Hypha, *user.User, *http.Request) (*history.Op, string),
|
||||
) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, rq *http.Request) {
|
||||
util.PrepareRq(rq)
|
||||
@ -121,14 +121,14 @@ func factoryHandlerConfirmer(
|
||||
|
||||
var handlerUnattachConfirm = factoryHandlerConfirmer(
|
||||
"unattach-confirm",
|
||||
func(h hyphae.Hypher, u *user.User, rq *http.Request) (*history.Op, string) {
|
||||
func(h hyphae.Hypha, u *user.User, rq *http.Request) (*history.Op, string) {
|
||||
return shroom.UnattachHypha(u, h, l18n.FromRequest(rq))
|
||||
},
|
||||
)
|
||||
|
||||
var handlerDeleteConfirm = factoryHandlerConfirmer(
|
||||
"delete-confirm",
|
||||
func(h hyphae.Hypher, u *user.User, rq *http.Request) (*history.Op, string) {
|
||||
func(h hyphae.Hypha, u *user.User, rq *http.Request) (*history.Op, string) {
|
||||
return shroom.DeleteHypha(u, h, l18n.FromRequest(rq))
|
||||
},
|
||||
)
|
||||
@ -177,7 +177,7 @@ func handlerEdit(w http.ResponseWriter, rq *http.Request) {
|
||||
case *hyphae.EmptyHypha:
|
||||
warning = fmt.Sprintf(`<p class="warning warning_new-hypha">%s</p>`, lc.Get("edit.new_hypha"))
|
||||
default:
|
||||
textAreaFill, err = shroom.FetchTextPart(h)
|
||||
textAreaFill, err = shroom.FetchTextFile(h)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
httpErr(w, lc, http.StatusInternalServerError, hyphaName,
|
||||
|
@ -47,7 +47,7 @@ func handlerAttachment(w http.ResponseWriter, rq *http.Request) {
|
||||
util.HTTP200Page(w,
|
||||
views.BaseHTML(
|
||||
lc.Get("ui.attach_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName)}),
|
||||
views.AttachmentMenuHTML(rq, h.(*hyphae.NonEmptyHypha), u),
|
||||
views.AttachmentMenuHTML(rq, h, u),
|
||||
lc,
|
||||
u))
|
||||
}
|
||||
@ -63,12 +63,18 @@ func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) {
|
||||
u = user.FromRequest(rq)
|
||||
lc = l18n.FromRequest(rq)
|
||||
)
|
||||
switch h := h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
_, _ = io.WriteString(w, "404 not found")
|
||||
case hyphae.ExistingHypha:
|
||||
util.HTTP200Page(w,
|
||||
views.BaseHTML(
|
||||
lc.Get("ui.diff_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName), "rev": revHash}),
|
||||
views.PrimitiveDiffHTML(rq, h, u, revHash),
|
||||
lc,
|
||||
u))
|
||||
}
|
||||
}
|
||||
|
||||
// handlerRevisionText sends Mycomarkup text of the hypha at the given revision. See also: handlerRevision, handlerText.
|
||||
@ -82,18 +88,29 @@ func handlerRevisionText(w http.ResponseWriter, rq *http.Request) {
|
||||
revHash = shorterURL[:firstSlashIndex]
|
||||
hyphaName = util.CanonicalName(shorterURL[firstSlashIndex+1:])
|
||||
h = hyphae.ByName(hyphaName)
|
||||
textContents, err = history.FileAtRevision(h.TextPartPath(), revHash)
|
||||
)
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
switch h := h.(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
log.Printf(`Hypha ‘%s’ does not exist`)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case hyphae.ExistingHypha:
|
||||
if !h.HasTextFile() {
|
||||
log.Printf(`Media hypha ‘%s’ has no text`)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
var textContents, err = history.FileAtRevision(h.TextFilePath(), revHash)
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
log.Printf("While serving text of ‘%s’ at revision ‘%s’: %s\n", hyphaName, revHash, err.Error())
|
||||
_, _ = io.WriteString(w, "Error: "+err.Error())
|
||||
return
|
||||
}
|
||||
log.Printf("Serving text of ‘%s’ from ‘%s’ at revision ‘%s’\n", hyphaName, h.TextPartPath(), revHash)
|
||||
log.Printf("Serving text of ‘%s’ from ‘%s’ at revision ‘%s’\n", hyphaName, h.TextFilePath(), revHash)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = io.WriteString(w, textContents)
|
||||
}
|
||||
}
|
||||
|
||||
// handlerRevision displays a specific revision of the text part the hypha
|
||||
@ -107,13 +124,17 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
|
||||
hyphaName = util.CanonicalName(shorterURL[firstSlashIndex+1:])
|
||||
h = hyphae.ByName(hyphaName)
|
||||
contents = fmt.Sprintf(`<p>%s</p>`, lc.Get("ui.revision_no_text"))
|
||||
textContents, err = history.FileAtRevision(h.TextPartPath(), revHash)
|
||||
u = user.FromRequest(rq)
|
||||
)
|
||||
switch h := h.(type) {
|
||||
case *hyphae.TextualHypha:
|
||||
var textContents, err = history.FileAtRevision(h.TextFilePath(), revHash)
|
||||
|
||||
if err == nil {
|
||||
ctx, _ := mycocontext.ContextFromStringInput(hyphaName, textContents)
|
||||
contents = mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx))
|
||||
}
|
||||
}
|
||||
page := views.RevisionHTML(
|
||||
rq,
|
||||
lc,
|
||||
@ -139,13 +160,10 @@ func handlerText(w http.ResponseWriter, rq *http.Request) {
|
||||
util.PrepareRq(rq)
|
||||
hyphaName := util.HyphaNameFromRq(rq, "text")
|
||||
switch h := hyphae.ByName(hyphaName).(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
case *hyphae.NonEmptyHypha:
|
||||
if h.Kind() == hyphae.HyphaText {
|
||||
log.Println("Serving", h.TextPartPath())
|
||||
case *hyphae.TextualHypha:
|
||||
log.Println("Serving", h.TextFilePath())
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
http.ServeFile(w, rq, h.TextPartPath())
|
||||
}
|
||||
http.ServeFile(w, rq, h.TextFilePath())
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,16 +173,13 @@ func handlerBinary(w http.ResponseWriter, rq *http.Request) {
|
||||
hyphaName := util.HyphaNameFromRq(rq, "binary")
|
||||
switch h := hyphae.ByName(hyphaName).(type) {
|
||||
case *hyphae.EmptyHypha:
|
||||
default: // TODO: deindent
|
||||
switch h := h.(*hyphae.NonEmptyHypha); h.Kind() {
|
||||
case hyphae.HyphaText:
|
||||
case *hyphae.TextualHypha:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
log.Printf("Textual hypha ‘%s’ has no media, cannot serve\n", h.CanonicalName())
|
||||
default:
|
||||
log.Println("Serving", h.BinaryPath())
|
||||
w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(h.BinaryPath())))
|
||||
http.ServeFile(w, rq, h.BinaryPath())
|
||||
}
|
||||
case *hyphae.MediaHypha:
|
||||
log.Println("Serving", h.MediaFilePath())
|
||||
w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(h.MediaFilePath())))
|
||||
http.ServeFile(w, rq, h.MediaFilePath())
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,8 +204,8 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
|
||||
lc,
|
||||
u,
|
||||
openGraph))
|
||||
case *hyphae.NonEmptyHypha:
|
||||
fileContentsT, errT := os.ReadFile(h.TextPartPath())
|
||||
case hyphae.ExistingHypha:
|
||||
fileContentsT, errT := os.ReadFile(h.TextFilePath())
|
||||
if errT == nil {
|
||||
ctx, _ := mycocontext.ContextFromStringInput(hyphaName, string(fileContentsT))
|
||||
ctx = mycocontext.WithWebSiteURL(ctx, cfg.URL)
|
||||
@ -199,7 +214,8 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
|
||||
contents = mycomarkup.BlocksToHTML(ctx, ast)
|
||||
openGraph = getOpenGraph()
|
||||
}
|
||||
if h.Kind() == hyphae.HyphaMedia {
|
||||
switch h := h.(type) {
|
||||
case *hyphae.MediaHypha:
|
||||
contents = views.AttachmentHTML(h, lc) + contents
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user