mirror of
https://github.com/schollz/cowyo.git
synced 2023-08-10 21:13:00 +03:00
commit
8b3e7b0605
5
Makefile
5
Makefile
@ -9,6 +9,11 @@ build:
|
|||||||
go-bindata static/... templates/...
|
go-bindata static/... templates/...
|
||||||
go build ${LDFLAGS}
|
go build ${LDFLAGS}
|
||||||
|
|
||||||
|
.PHONY: quick
|
||||||
|
quick:
|
||||||
|
go-bindata static/... templates/...
|
||||||
|
go build
|
||||||
|
|
||||||
.PHONY: linuxarm
|
.PHONY: linuxarm
|
||||||
linuxarm:
|
linuxarm:
|
||||||
env GOOS=linux GOARCH=arm go build ${LDFLAGS} -o dist/cowyo_linux_arm
|
env GOOS=linux GOARCH=arm go build ${LDFLAGS} -o dist/cowyo_linux_arm
|
||||||
|
68
handlers.go
68
handlers.go
@ -17,7 +17,10 @@ import (
|
|||||||
"github.com/schollz/cowyo/encrypt"
|
"github.com/schollz/cowyo/encrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func serve(host, port, crt_path, key_path string, TLS bool) {
|
var customCSS []byte
|
||||||
|
var defaultLock string
|
||||||
|
|
||||||
|
func serve(host, port, crt_path, key_path string, TLS bool, cssFile string, defaultPage string, defaultPassword string) {
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
store := sessions.NewCookieStore([]byte("secret"))
|
store := sessions.NewCookieStore([]byte("secret"))
|
||||||
@ -25,7 +28,11 @@ func serve(host, port, crt_path, key_path string, TLS bool) {
|
|||||||
router.HTMLRender = loadTemplates("index.tmpl")
|
router.HTMLRender = loadTemplates("index.tmpl")
|
||||||
// router.Use(static.Serve("/static/", static.LocalFile("./static", true)))
|
// router.Use(static.Serve("/static/", static.LocalFile("./static", true)))
|
||||||
router.GET("/", func(c *gin.Context) {
|
router.GET("/", func(c *gin.Context) {
|
||||||
|
if defaultPage != "" {
|
||||||
|
c.Redirect(302, "/"+defaultPage+"/read")
|
||||||
|
} else {
|
||||||
c.Redirect(302, "/"+randomAlliterateCombo())
|
c.Redirect(302, "/"+randomAlliterateCombo())
|
||||||
|
}
|
||||||
})
|
})
|
||||||
router.GET("/:page", func(c *gin.Context) {
|
router.GET("/:page", func(c *gin.Context) {
|
||||||
page := c.Param("page")
|
page := c.Param("page")
|
||||||
@ -45,6 +52,22 @@ func serve(host, port, crt_path, key_path string, TLS bool) {
|
|||||||
// start long-processes as threads
|
// start long-processes as threads
|
||||||
go thread_SiteMap()
|
go thread_SiteMap()
|
||||||
|
|
||||||
|
// collect custom CSS
|
||||||
|
if len(cssFile) > 0 {
|
||||||
|
var errRead error
|
||||||
|
customCSS, errRead = ioutil.ReadFile(cssFile)
|
||||||
|
if errRead != nil {
|
||||||
|
fmt.Println(errRead.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("Loaded CSS file, %d bytes\n", len(customCSS))
|
||||||
|
}
|
||||||
|
|
||||||
|
if defaultPassword != "" {
|
||||||
|
fmt.Println("running with locked pages")
|
||||||
|
defaultLock = HashPassword(defaultPassword)
|
||||||
|
}
|
||||||
|
|
||||||
if TLS {
|
if TLS {
|
||||||
http.ListenAndServeTLS(host+":"+port, crt_path, key_path, router)
|
http.ListenAndServeTLS(host+":"+port, crt_path, key_path, router)
|
||||||
} else {
|
} else {
|
||||||
@ -149,6 +172,7 @@ func generateSiteMap() (sitemap string) {
|
|||||||
sitemap += "</urlset>"
|
sitemap += "</urlset>"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePageRequest(c *gin.Context) {
|
func handlePageRequest(c *gin.Context) {
|
||||||
page := c.Param("page")
|
page := c.Param("page")
|
||||||
command := c.Param("command")
|
command := c.Param("command")
|
||||||
@ -165,26 +189,49 @@ func handlePageRequest(c *gin.Context) {
|
|||||||
data, _ := Asset("/static/img/cowyo/favicon.ico")
|
data, _ := Asset("/static/img/cowyo/favicon.ico")
|
||||||
c.Data(http.StatusOK, contentType("/static/img/cowyo/favicon.ico"), data)
|
c.Data(http.StatusOK, contentType("/static/img/cowyo/favicon.ico"), data)
|
||||||
return
|
return
|
||||||
|
} else if page == "/static/css/custom.css" {
|
||||||
|
c.Data(http.StatusOK, contentType("custom.css"), customCSS)
|
||||||
|
return
|
||||||
} else if page == "static" {
|
} else if page == "static" {
|
||||||
filename := page + command
|
filename := page + command
|
||||||
data, err := Asset(filename)
|
var data []byte
|
||||||
if err != nil {
|
fmt.Println(filename)
|
||||||
|
if filename == "static/css/custom.css" {
|
||||||
|
data = customCSS
|
||||||
|
} else {
|
||||||
|
var errAssset error
|
||||||
|
data, errAssset = Asset(filename)
|
||||||
|
if errAssset != nil {
|
||||||
c.String(http.StatusInternalServerError, "Could not find data")
|
c.String(http.StatusInternalServerError, "Could not find data")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
c.Data(http.StatusOK, contentType(filename), data)
|
c.Data(http.StatusOK, contentType(filename), data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
p := Open(page)
|
||||||
|
fmt.Println(command)
|
||||||
if len(command) < 2 {
|
if len(command) < 2 {
|
||||||
|
fmt.Println(p.IsPublished)
|
||||||
|
if p.IsPublished {
|
||||||
|
c.Redirect(302, "/"+page+"/read")
|
||||||
|
} else {
|
||||||
c.Redirect(302, "/"+page+"/edit")
|
c.Redirect(302, "/"+page+"/edit")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
version := c.DefaultQuery("version", "ajksldfjl")
|
version := c.DefaultQuery("version", "ajksldfjl")
|
||||||
p := Open(page)
|
|
||||||
|
// use the default lock
|
||||||
|
if defaultLock != "" && p.IsNew() {
|
||||||
|
p.IsLocked = true
|
||||||
|
p.PassphraseToUnlock = defaultLock
|
||||||
|
}
|
||||||
|
|
||||||
// Disallow anything but viewing locked/encrypted pages
|
// Disallow anything but viewing locked/encrypted pages
|
||||||
if (p.IsEncrypted || p.IsLocked) &&
|
if (p.IsEncrypted || p.IsLocked) &&
|
||||||
(command[0:2] != "/v" && command[0:2] != "/r") {
|
(command[0:2] != "/v" && command[0:2] != "/r") {
|
||||||
|
fmt.Println("IS LOCKED")
|
||||||
c.Redirect(302, "/"+page+"/view")
|
c.Redirect(302, "/"+page+"/view")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -232,7 +279,7 @@ func handlePageRequest(c *gin.Context) {
|
|||||||
versionsChangeSums = reverseSliceInt(versionsChangeSums)
|
versionsChangeSums = reverseSliceInt(versionsChangeSums)
|
||||||
}
|
}
|
||||||
|
|
||||||
if command[0:2] == "/r" {
|
if command[0:3] == "/ra" {
|
||||||
c.Writer.Header().Set("Content-Type", contentType(p.Name))
|
c.Writer.Header().Set("Content-Type", contentType(p.Name))
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
c.Writer.Header().Set("Access-Control-Max-Age", "86400")
|
c.Writer.Header().Set("Access-Control-Max-Age", "86400")
|
||||||
@ -246,7 +293,8 @@ func handlePageRequest(c *gin.Context) {
|
|||||||
log.Debug("%v", command[0:2] != "/e" &&
|
log.Debug("%v", command[0:2] != "/e" &&
|
||||||
command[0:2] != "/v" &&
|
command[0:2] != "/v" &&
|
||||||
command[0:2] != "/l" &&
|
command[0:2] != "/l" &&
|
||||||
command[0:2] != "/h")
|
command[0:2] != "/h" &&
|
||||||
|
command[0:2] != "/r")
|
||||||
|
|
||||||
var FileNames, FileLastEdited []string
|
var FileNames, FileLastEdited []string
|
||||||
var FileSizes, FileNumChanges []int
|
var FileSizes, FileNumChanges []int
|
||||||
@ -260,6 +308,7 @@ func handlePageRequest(c *gin.Context) {
|
|||||||
"ViewPage": command[0:2] == "/v", // /view
|
"ViewPage": command[0:2] == "/v", // /view
|
||||||
"ListPage": command[0:2] == "/l", // /list
|
"ListPage": command[0:2] == "/l", // /list
|
||||||
"HistoryPage": command[0:2] == "/h", // /history
|
"HistoryPage": command[0:2] == "/h", // /history
|
||||||
|
"ReadPage": command[0:2] == "/r", // /history
|
||||||
"DontKnowPage": command[0:2] != "/e" &&
|
"DontKnowPage": command[0:2] != "/e" &&
|
||||||
command[0:2] != "/v" &&
|
command[0:2] != "/v" &&
|
||||||
command[0:2] != "/l" &&
|
command[0:2] != "/l" &&
|
||||||
@ -282,6 +331,7 @@ func handlePageRequest(c *gin.Context) {
|
|||||||
"HasDotInName": strings.Contains(page, "."),
|
"HasDotInName": strings.Contains(page, "."),
|
||||||
"RecentlyEdited": getRecentlyEdited(page, c),
|
"RecentlyEdited": getRecentlyEdited(page, c),
|
||||||
"IsPublished": p.IsPublished,
|
"IsPublished": p.IsPublished,
|
||||||
|
"CustomCSS": len(customCSS) > 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,6 +469,11 @@ func handleLock(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
p := Open(json.Page)
|
p := Open(json.Page)
|
||||||
|
if defaultLock != "" && p.IsNew() {
|
||||||
|
p.IsLocked = true
|
||||||
|
p.PassphraseToUnlock = defaultLock
|
||||||
|
}
|
||||||
|
|
||||||
if p.IsEncrypted {
|
if p.IsEncrypted {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": "Encrypted"})
|
c.JSON(http.StatusOK, gin.H{"success": false, "message": "Encrypted"})
|
||||||
return
|
return
|
||||||
@ -437,6 +492,7 @@ func handleLock(c *gin.Context) {
|
|||||||
p.PassphraseToUnlock = HashPassword(json.Passphrase)
|
p.PassphraseToUnlock = HashPassword(json.Passphrase)
|
||||||
message = "Locked"
|
message = "Locked"
|
||||||
}
|
}
|
||||||
|
fmt.Println(p)
|
||||||
p.Save()
|
p.Save()
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": message})
|
c.JSON(http.StatusOK, gin.H{"success": true, "message": message})
|
||||||
}
|
}
|
||||||
|
17
main.go
17
main.go
@ -38,7 +38,7 @@ func main() {
|
|||||||
} else {
|
} else {
|
||||||
fmt.Printf("\nRunning cowyo server (version %s) at http://%s:%s\n\n", version, host, c.GlobalString("port"))
|
fmt.Printf("\nRunning cowyo server (version %s) at http://%s:%s\n\n", version, host, c.GlobalString("port"))
|
||||||
}
|
}
|
||||||
serve(c.GlobalString("host"), c.GlobalString("port"), c.GlobalString("cert"), c.GlobalString("key"), TLS)
|
serve(c.GlobalString("host"), c.GlobalString("port"), c.GlobalString("cert"), c.GlobalString("key"), TLS, c.GlobalString("css"), c.GlobalString("default-page"), c.GlobalString("lock"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
@ -72,6 +72,21 @@ func main() {
|
|||||||
Value: "",
|
Value: "",
|
||||||
Usage: "absolute path to SSL private key",
|
Usage: "absolute path to SSL private key",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "css",
|
||||||
|
Value: "",
|
||||||
|
Usage: "use a custom CSS file",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "default-page",
|
||||||
|
Value: "",
|
||||||
|
Usage: "show default-page/read instead of editing (default: show random editing)",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "lock",
|
||||||
|
Value: "",
|
||||||
|
Usage: "password to lock editing all files (default: all pages unlocked)",
|
||||||
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "debug, d",
|
Name: "debug, d",
|
||||||
Usage: "turn on debugging",
|
Usage: "turn on debugging",
|
||||||
|
4
page.go
4
page.go
@ -102,6 +102,10 @@ func (p *Page) Save() error {
|
|||||||
return ioutil.WriteFile(path.Join(pathToData, encodeToBase32(strings.ToLower(p.Name))+".json"), bJSON, 0644)
|
return ioutil.WriteFile(path.Join(pathToData, encodeToBase32(strings.ToLower(p.Name))+".json"), bJSON, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Page) IsNew() bool {
|
||||||
|
return !exists(path.Join(pathToData, encodeToBase32(strings.ToLower(p.Name))+".json"))
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Page) Erase() error {
|
func (p *Page) Erase() error {
|
||||||
log.Trace("Erasing " + p.Name)
|
log.Trace("Erasing " + p.Name)
|
||||||
return os.Remove(path.Join(pathToData, encodeToBase32(strings.ToLower(p.Name))+".json"))
|
return os.Remove(path.Join(pathToData, encodeToBase32(strings.ToLower(p.Name))+".json"))
|
||||||
|
@ -22,15 +22,18 @@
|
|||||||
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
|
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
|
||||||
<meta name="theme-color" content="#fff">
|
<meta name="theme-color" content="#fff">
|
||||||
|
|
||||||
<script type="text/javascript" src="/static/js/jquery-1.8.3.js"></script>
|
{{ if and .CustomCSS .ReadPage }}
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/github-markdown.css">
|
<link rel="stylesheet" type="text/css" href="/static/css/custom.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/menus-min.css">
|
{{ else }}
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/base-min.css">
|
<script type="text/javascript" src="/static/js/jquery-1.8.3.js"></script>
|
||||||
<link rel="stylesheet" href="/static/css/highlight.css">
|
<link rel="stylesheet" type="text/css" href="/static/css/github-markdown.css">
|
||||||
<script src="/static/js/highlight.min.js"></script>
|
<link rel="stylesheet" type="text/css" href="/static/css/menus-min.css">
|
||||||
<script type="text/javascript" src="/static/js/highlight.pack.js"></script>
|
<link rel="stylesheet" type="text/css" href="/static/css/base-min.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/highlight.css">
|
||||||
|
<script src="/static/js/highlight.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/static/js/highlight.pack.js"></script>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
{{ if .ListPage }}
|
{{ if .ListPage }}
|
||||||
/* Required for lists */
|
/* Required for lists */
|
||||||
span { cursor: pointer; }
|
span { cursor: pointer; }
|
||||||
@ -129,9 +132,8 @@ body#pad textarea {
|
|||||||
padding-right: 20%;
|
padding-right: 20%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
</style>
|
{{ end }}
|
||||||
|
|
||||||
<title>{{ .Page }}</title>
|
<title>{{ .Page }}</title>
|
||||||
|
|
||||||
|
|
||||||
@ -478,9 +480,18 @@ body#pad textarea {
|
|||||||
<script>hljs.initHighlightingOnLoad();</script>
|
<script>hljs.initHighlightingOnLoad();</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body id="pad">
|
<body id="pad">
|
||||||
<article class="markdown-body">
|
<article class="markdown-body">
|
||||||
|
|
||||||
|
{{ if .ReadPage }}
|
||||||
|
<div id="wrap">
|
||||||
|
<div id="rendered">
|
||||||
|
{{ .RenderedPage }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ else }}
|
||||||
|
|
||||||
|
|
||||||
<div class="pure-menu pure-menu-horizontal" id="menu">
|
<div class="pure-menu pure-menu-horizontal" id="menu">
|
||||||
<ul class="pure-menu-list">
|
<ul class="pure-menu-list">
|
||||||
<li></li>
|
<li></li>
|
||||||
@ -594,8 +605,9 @@ body#pad textarea {
|
|||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
{{ end }}
|
||||||
|
|
||||||
|
</article>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user