2020-06-13 11:18:11 +00:00
package main
import (
"fmt"
"io/ioutil"
2020-06-16 18:35:52 +00:00
"log"
"net/http"
2020-06-19 14:30:19 +00:00
2020-06-19 13:03:31 +00:00
"strconv"
2020-06-19 15:17:00 +00:00
2020-06-19 14:30:19 +00:00
"github.com/gomarkdown/markdown"
2020-06-13 11:18:11 +00:00
)
2020-06-19 13:03:31 +00:00
// In different places, revision variable is called `r`. But when there is an http.Request as well, the revision becomes `rev`. TODO: name them consistently.
2020-06-13 11:18:11 +00:00
type Revision struct {
2020-06-19 13:03:31 +00:00
Id int ` json:"-" `
FullName string ` json:"-" `
2020-06-16 18:35:52 +00:00
Tags [ ] string ` json:"tags" `
2020-06-17 09:40:51 +00:00
ShortName string ` json:"name" `
2020-06-16 18:35:52 +00:00
Comment string ` json:"comment" `
Author string ` json:"author" `
Time int ` json:"time" `
TextMime string ` json:"text_mime" `
BinaryMime string ` json:"binary_mime" `
2020-06-19 13:03:31 +00:00
TextPath string ` json:"-" `
BinaryPath string ` json:"-" `
}
func ( r * Revision ) IdAsStr ( ) string {
return strconv . Itoa ( r . Id )
2020-06-13 11:18:11 +00:00
}
2020-06-16 18:35:52 +00:00
// During initialisation, it is guaranteed that r.BinaryMime is set to "" if the revision has no binary data.
func ( r * Revision ) hasBinaryData ( ) bool {
return r . BinaryMime != ""
2020-06-13 11:18:11 +00:00
}
2020-06-16 18:35:52 +00:00
func ( r * Revision ) urlOfBinary ( ) string {
return fmt . Sprintf ( "/%s?action=getBinary&rev=%d" , r . FullName , r . Id )
}
// TODO: use templates https://github.com/bouncepaw/mycorrhiza/issues/2
func ( r * Revision ) AsHtml ( hyphae map [ string ] * Hypha ) ( ret string , err error ) {
2020-06-13 11:18:11 +00:00
ret += ` < article class = "page" >
2020-06-17 09:40:51 +00:00
< h1 class = "page__title" > ` + r.FullName + ` < / h1 >
2020-06-13 11:18:11 +00:00
`
2020-06-16 18:35:52 +00:00
// TODO: support things other than images
if r . hasBinaryData ( ) {
2020-06-17 09:40:51 +00:00
ret += fmt . Sprintf ( ` <img src="%s" class="page__amnt"/> ` , r . urlOfBinary ( ) )
2020-06-13 11:18:11 +00:00
}
contents , err := ioutil . ReadFile ( r . TextPath )
if err != nil {
return "" , err
}
// TODO: support more markups.
// TODO: support mycorrhiza extensions like transclusion.
2020-06-16 18:35:52 +00:00
switch r . TextMime {
case "text/markdown" :
2020-06-13 11:18:11 +00:00
html := markdown . ToHTML ( contents , nil , nil )
ret += string ( html )
default :
2020-06-17 09:40:51 +00:00
ret += fmt . Sprintf ( ` <pre>%s</pre> ` , contents )
2020-06-13 11:18:11 +00:00
}
ret += `
< / article > `
return ret , nil
}
2020-06-16 18:35:52 +00:00
func ( r * Revision ) ActionGetBinary ( w http . ResponseWriter ) {
2020-06-18 10:23:44 +00:00
fileContents , err := ioutil . ReadFile ( r . BinaryPath )
2020-06-16 18:35:52 +00:00
if err != nil {
log . Println ( "Failed to load binary data of" , r . FullName , r . Id )
w . WriteHeader ( http . StatusNotFound )
return
}
w . Header ( ) . Set ( "Content-Type" , r . BinaryMime )
w . WriteHeader ( http . StatusOK )
w . Write ( fileContents )
log . Println ( "Serving binary data of" , r . FullName , r . Id )
}
func ( r * Revision ) ActionRaw ( w http . ResponseWriter ) {
fileContents , err := ioutil . ReadFile ( r . TextPath )
if err != nil {
log . Println ( "Failed to load text data of" , r . FullName , r . Id )
w . WriteHeader ( http . StatusNotFound )
return
}
w . Header ( ) . Set ( "Content-Type" , r . TextMime )
w . WriteHeader ( http . StatusOK )
w . Write ( fileContents )
log . Println ( "Serving text data of" , r . FullName , r . Id )
}
2020-06-18 10:23:44 +00:00
func ( r * Revision ) ActionZen ( w http . ResponseWriter ) {
2020-06-16 18:35:52 +00:00
html , err := r . AsHtml ( hyphae )
if err != nil {
log . Println ( "Failed to render" , r . FullName )
w . WriteHeader ( http . StatusInternalServerError )
return
}
w . Header ( ) . Set ( "Content-Type" , "text/html; charset=utf-8" )
w . WriteHeader ( http . StatusOK )
fmt . Fprint ( w , html )
}
2020-06-18 10:23:44 +00:00
func ( r * Revision ) ActionView ( w http . ResponseWriter , layoutFun func ( map [ string ] * Hypha , Revision , string ) string ) {
2020-06-16 18:35:52 +00:00
html , err := r . AsHtml ( hyphae )
if err != nil {
log . Println ( "Failed to render" , r . FullName )
w . WriteHeader ( http . StatusInternalServerError )
return
}
2020-06-19 14:30:19 +00:00
2020-06-16 18:35:52 +00:00
w . Header ( ) . Set ( "Content-Type" , "text/html; charset=utf-8" )
w . WriteHeader ( http . StatusOK )
2020-06-19 14:30:19 +00:00
2020-06-16 18:35:52 +00:00
fmt . Fprint ( w , layoutFun ( hyphae , * r , html ) )
log . Println ( "Rendering" , r . FullName )
}