mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-04 18:19:54 +00:00
Move mimetype stuff to a separate module
This commit is contained in:
parent
d25c953409
commit
ae1c5db3b3
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
mycorrhiza
|
||||
hyphae/*.gog
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/history"
|
||||
"github.com/bouncepaw/mycorrhiza/markup"
|
||||
"github.com/bouncepaw/mycorrhiza/mimetype"
|
||||
"github.com/bouncepaw/mycorrhiza/templates"
|
||||
"github.com/bouncepaw/mycorrhiza/tree"
|
||||
"github.com/bouncepaw/mycorrhiza/user"
|
||||
@ -71,7 +72,7 @@ func handlerBinary(w http.ResponseWriter, rq *http.Request) {
|
||||
hyphaName := HyphaNameFromRq(rq, "binary")
|
||||
if data, ok := HyphaStorage[hyphaName]; ok {
|
||||
log.Println("Serving", data.binaryPath)
|
||||
w.Header().Set("Content-Type", ExtensionToMime(filepath.Ext(data.binaryPath)))
|
||||
w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(data.binaryPath)))
|
||||
http.ServeFile(w, rq, data.binaryPath)
|
||||
}
|
||||
}
|
||||
|
87
hypha.go
87
hypha.go
@ -13,6 +13,7 @@ import (
|
||||
"github.com/bouncepaw/mycorrhiza/history"
|
||||
"github.com/bouncepaw/mycorrhiza/hyphae"
|
||||
"github.com/bouncepaw/mycorrhiza/markup"
|
||||
"github.com/bouncepaw/mycorrhiza/mimetype"
|
||||
"github.com/bouncepaw/mycorrhiza/user"
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
)
|
||||
@ -114,7 +115,7 @@ func UploadBinary(hyphaName, mime string, file multipart.File, u *user.User) *hi
|
||||
if err != nil {
|
||||
return hop.WithError(err).Apply()
|
||||
}
|
||||
return uploadHelp(hop, hyphaName, MimeToExtension(mime), data, u)
|
||||
return uploadHelp(hop, hyphaName, mimetype.ToExtension(mime), data, u)
|
||||
}
|
||||
|
||||
// DeleteHypha deletes hypha and makes a history record about that.
|
||||
@ -254,48 +255,6 @@ func binaryHtmlBlock(hyphaName string, hd *HyphaData) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Index finds all hypha files in the full `path` and saves them to HyphaStorage. This function is recursive.
|
||||
func Index(path string) {
|
||||
nodes, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
// If this hypha looks like it can be a hypha path, go deeper. Do not touch the .git and static folders for they have an admnistrative importance!
|
||||
if node.IsDir() && isCanonicalName(node.Name()) && node.Name() != ".git" && node.Name() != "static" {
|
||||
Index(filepath.Join(path, node.Name()))
|
||||
continue
|
||||
}
|
||||
|
||||
var (
|
||||
hyphaPartPath = filepath.Join(path, node.Name())
|
||||
hyphaName, isText, skip = DataFromFilename(hyphaPartPath)
|
||||
hyphaData *HyphaData
|
||||
)
|
||||
if !skip {
|
||||
// Reuse the entry for existing hyphae, create a new one for those that do not exist yet.
|
||||
if hd, ok := HyphaStorage[hyphaName]; ok {
|
||||
hyphaData = hd
|
||||
} else {
|
||||
hyphaData = &HyphaData{}
|
||||
HyphaStorage[hyphaName] = hyphaData
|
||||
hyphae.IncrementCount()
|
||||
}
|
||||
if isText {
|
||||
hyphaData.textPath = hyphaPartPath
|
||||
} else {
|
||||
// Notify the user about binary part collisions. It's a design decision to just use any of them, it's the user's fault that they have screwed up the folder structure, but the engine should at least let them know, right?
|
||||
if hyphaData.binaryPath != "" {
|
||||
log.Println("There is a file collision for binary part of a hypha:", hyphaData.binaryPath, "and", hyphaPartPath, "-- going on with the latter")
|
||||
}
|
||||
hyphaData.binaryPath = hyphaPartPath
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// FetchTextPart tries to read text file in the `d`. If there is no file, empty string is returned.
|
||||
func FetchTextPart(d *HyphaData) (string, error) {
|
||||
if d.textPath == "" {
|
||||
@ -327,3 +286,45 @@ func setHeaderLinks() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Index finds all hypha files in the full `path` and saves them to HyphaStorage. This function is recursive.
|
||||
func Index(path string) {
|
||||
nodes, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
// If this hypha looks like it can be a hypha path, go deeper. Do not touch the .git and static folders for they have an admnistrative importance!
|
||||
if node.IsDir() && isCanonicalName(node.Name()) && node.Name() != ".git" && node.Name() != "static" {
|
||||
Index(filepath.Join(path, node.Name()))
|
||||
continue
|
||||
}
|
||||
|
||||
var (
|
||||
hyphaPartPath = filepath.Join(path, node.Name())
|
||||
hyphaName, isText, skip = mimetype.DataFromFilename(hyphaPartPath)
|
||||
hyphaData *HyphaData
|
||||
)
|
||||
if !skip {
|
||||
// Reuse the entry for existing hyphae, create a new one for those that do not exist yet.
|
||||
if hd, ok := HyphaStorage[hyphaName]; ok {
|
||||
hyphaData = hd
|
||||
} else {
|
||||
hyphaData = &HyphaData{}
|
||||
HyphaStorage[hyphaName] = hyphaData
|
||||
hyphae.IncrementCount()
|
||||
}
|
||||
if isText {
|
||||
hyphaData.textPath = hyphaPartPath
|
||||
} else {
|
||||
// Notify the user about binary part collisions. It's a design decision to just use any of them, it's the user's fault that they have screwed up the folder structure, but the engine should at least let them know, right?
|
||||
if hyphaData.binaryPath != "" {
|
||||
log.Println("There is a file collision for binary part of a hypha:", hyphaData.binaryPath, "and", hyphaPartPath, "-- going on with the latter")
|
||||
}
|
||||
hyphaData.binaryPath = hyphaPartPath
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
package hyphae
|
||||
|
||||
// TODO: do
|
||||
import ()
|
||||
|
||||
type Hypha struct {
|
||||
Name string
|
||||
Exists bool
|
||||
TextPath string
|
||||
BinaryPath string
|
||||
OutLinks []string
|
||||
BackLinks []string
|
||||
}
|
||||
|
||||
// AddHypha adds a hypha named `name` with such `textPath` and `binaryPath`. Both paths can be empty. Does //not// check for hypha's existence beforehand. Count is handled.
|
||||
func AddHypha(name, textPath, binaryPath string) {
|
||||
}
|
||||
|
||||
// DeleteHypha clears both paths and all out-links from the named hypha and marks it as non-existent. It does not actually delete it from the memdb. Count is handled.
|
||||
func DeleteHypha(name string) {
|
||||
}
|
3
main.go
3
main.go
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/history"
|
||||
"github.com/bouncepaw/mycorrhiza/hyphae"
|
||||
"github.com/bouncepaw/mycorrhiza/mimetype"
|
||||
"github.com/bouncepaw/mycorrhiza/templates"
|
||||
"github.com/bouncepaw/mycorrhiza/user"
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
@ -64,7 +65,7 @@ func handlerList(w http.ResponseWriter, rq *http.Request) {
|
||||
u = user.FromRequest(rq)
|
||||
)
|
||||
for hyphaName, data := range HyphaStorage {
|
||||
tbody += templates.HyphaListRowHTML(hyphaName, ExtensionToMime(filepath.Ext(data.binaryPath)), data.binaryPath != "")
|
||||
tbody += templates.HyphaListRowHTML(hyphaName, mimetype.FromExtension(filepath.Ext(data.binaryPath)), data.binaryPath != "")
|
||||
}
|
||||
util.HTTP200Page(w, base("List of pages", templates.HyphaListHTML(tbody, pageCount), u))
|
||||
}
|
||||
|
62
mime.go
62
mime.go
@ -1,62 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func MimeToExtension(mime string) string {
|
||||
mm := map[string]string{
|
||||
"application/octet-stream": "bin",
|
||||
"image/jpeg": "jpg",
|
||||
"image/gif": "gif",
|
||||
"image/png": "png",
|
||||
"image/webp": "webp",
|
||||
"image/svg+xml": "svg",
|
||||
"image/x-icon": "ico",
|
||||
"application/ogg": "ogg",
|
||||
"video/webm": "webm",
|
||||
"audio/mp3": "mp3",
|
||||
"video/mp4": "mp4",
|
||||
}
|
||||
if ext, ok := mm[mime]; ok {
|
||||
return "." + ext
|
||||
}
|
||||
return ".bin"
|
||||
}
|
||||
|
||||
func ExtensionToMime(ext string) string {
|
||||
mm := map[string]string{
|
||||
".bin": "application/octet-stream",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".gif": "image/gif",
|
||||
".png": "image/png",
|
||||
".webp": "image/webp",
|
||||
".svg": "image/svg+xml",
|
||||
".ico": "image/x-icon",
|
||||
".ogg": "application/ogg",
|
||||
".webm": "video/webm",
|
||||
".mp3": "audio/mp3",
|
||||
".mp4": "video/mp4",
|
||||
}
|
||||
if mime, ok := mm[ext]; ok {
|
||||
return mime
|
||||
}
|
||||
return "application/octet-stream"
|
||||
}
|
||||
|
||||
// DataFromFilename fetches all meta information from hypha content file with path `fullPath`. If it is not a content file, `skip` is true, and you are expected to ignore this file when indexing hyphae. `name` is name of the hypha to which this file relates. `isText` is true when the content file is text, false when is binary. `mimeId` is an integer representation of content type. Cast it to TextType if `isText == true`, cast it to BinaryType if `isText == false`.
|
||||
func DataFromFilename(fullPath string) (name string, isText bool, skip bool) {
|
||||
shortPath := strings.TrimPrefix(fullPath, WikiDir)[1:]
|
||||
ext := filepath.Ext(shortPath)
|
||||
name = CanonicalName(strings.TrimSuffix(shortPath, ext))
|
||||
switch ext {
|
||||
case ".myco":
|
||||
isText = true
|
||||
case "", shortPath:
|
||||
skip = true
|
||||
}
|
||||
|
||||
return
|
||||
}
|
68
mimetype/mime.go
Normal file
68
mimetype/mime.go
Normal file
@ -0,0 +1,68 @@
|
||||
package mimetype
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/bouncepaw/mycorrhiza/util"
|
||||
)
|
||||
|
||||
// ToExtension returns dotted extension for given mime-type.
|
||||
func ToExtension(mime string) string {
|
||||
if ext, ok := mapMime2Ext[mime]; ok {
|
||||
return "." + ext
|
||||
}
|
||||
return ".bin"
|
||||
}
|
||||
|
||||
// FromExtension returns mime-type for given extension. The extension must start with a dot.
|
||||
func FromExtension(ext string) string {
|
||||
if mime, ok := mapExt2Mime[ext]; ok {
|
||||
return mime
|
||||
}
|
||||
return "application/octet-stream"
|
||||
}
|
||||
|
||||
// DataFromFilename fetches all meta information from hypha content file with path `fullPath`. If it is not a content file, `skip` is true, and you are expected to ignore this file when indexing hyphae. `name` is name of the hypha to which this file relates. `isText` is true when the content file is text, false when is binary.
|
||||
func DataFromFilename(fullPath string) (name string, isText bool, skip bool) {
|
||||
shortPath := util.ShorterPath(fullPath)
|
||||
ext := filepath.Ext(shortPath)
|
||||
name = util.CanonicalName(strings.TrimSuffix(shortPath, ext))
|
||||
switch ext {
|
||||
case ".myco":
|
||||
isText = true
|
||||
case "", shortPath:
|
||||
skip = true
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var mapMime2Ext = map[string]string{
|
||||
"application/octet-stream": "bin",
|
||||
"image/jpeg": "jpg",
|
||||
"image/gif": "gif",
|
||||
"image/png": "png",
|
||||
"image/webp": "webp",
|
||||
"image/svg+xml": "svg",
|
||||
"image/x-icon": "ico",
|
||||
"application/ogg": "ogg",
|
||||
"video/webm": "webm",
|
||||
"audio/mp3": "mp3",
|
||||
"video/mp4": "mp4",
|
||||
}
|
||||
|
||||
var mapExt2Mime = map[string]string{
|
||||
".bin": "application/octet-stream",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".gif": "image/gif",
|
||||
".png": "image/png",
|
||||
".webp": "image/webp",
|
||||
".svg": "image/svg+xml",
|
||||
".ico": "image/x-icon",
|
||||
".ogg": "application/ogg",
|
||||
".webm": "video/webm",
|
||||
".mp3": "audio/mp3",
|
||||
".mp4": "video/mp4",
|
||||
}
|
14
util/util.go
14
util/util.go
@ -4,6 +4,7 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -65,3 +66,16 @@ func BeautifulName(uglyName string) string {
|
||||
}
|
||||
return strings.Title(strings.ReplaceAll(uglyName, "_", " "))
|
||||
}
|
||||
|
||||
// CanonicalName makes sure the `name` is canonical. A name is canonical if it is lowercase and all spaces are replaced with underscores.
|
||||
func CanonicalName(name string) string {
|
||||
return strings.ToLower(strings.ReplaceAll(name, " ", "_"))
|
||||
}
|
||||
|
||||
// HyphaPattern is a pattern which all hyphae must match.
|
||||
var HyphaPattern = regexp.MustCompile(`[^?!:#@><*|"\'&%{}]+`)
|
||||
|
||||
// IsCanonicalName checks if the `name` is canonical.
|
||||
func IsCanonicalName(name string) bool {
|
||||
return HyphaPattern.MatchString(name)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user