diff --git a/archetype/adapter.go b/archetype/adapter.go index a8caf13..e2b493e 100644 --- a/archetype/adapter.go +++ b/archetype/adapter.go @@ -1,5 +1,10 @@ package archetype +type BuildStatus struct { + Success bool + Message string +} + type Adapter interface { Init(cfg *Config) Name() string @@ -14,5 +19,5 @@ type Adapter interface { CreatePage(slug, title, content string) error SavePage(oldSlug, newSlug, title, content string) error DeletePage(slug string) error - Build(buildOptions map[string]string) (bool, string) + Build(buildOptions map[string][]string) BuildStatus } diff --git a/archetype/eureka.go b/archetype/eureka.go index 99e613b..47f5255 100644 --- a/archetype/eureka.go +++ b/archetype/eureka.go @@ -4,6 +4,7 @@ import ( "errors" "io/ioutil" "os" + "os/exec" "path/filepath" "strings" ) @@ -141,7 +142,20 @@ func (self *EurekaAdapter) DeletePage(slug string) error { return os.Remove(filepath.Join(self.Root, "inc", slug)) } -func (self *EurekaAdapter) Build(buildOptions map[string]string) (bool, string) { - // TODO: shell out to build.sh with buildOptions, record exit status and output - return true, "Build successful" +func (self *EurekaAdapter) Build(buildOptions map[string][]string) BuildStatus { + + twtxt := buildOptions["twtxt"][0] + cmdArgs := "" + if twtxt != "" { + cmdArgs += " -t " + twtxt + } + + cmd := exec.Command("./build.sh", cmdArgs) + cmd.Dir = self.Root + out, err := cmd.CombinedOutput() + + return BuildStatus{ + Success: err == nil, + Message: string(out), + } } diff --git a/nirvash.go b/nirvash.go index 50142ea..14023f8 100644 --- a/nirvash.go +++ b/nirvash.go @@ -117,5 +117,50 @@ func main() { udb, "/")) + rtr.Get( + `/build`, + middleware.Fortify( + middleware.Protected( + shell.WithAdapter( + renderer.Template( + "templates/build.html", + "templates/header.html", + "templates/footer.html"), + cfg.Adapter), + http.MethodGet, + udb, + "/login"))) + + rtr.Post( + `/build-run`, + middleware.Defend( + middleware.Protected( + shell.WithAdapter( + renderer.Template( + "templates/build_run.html", + "templates/header.html", + "templates/footer.html"), + cfg.Adapter), + http.MethodGet, + udb, + "/login"), + udb, + "/")) + + rtr.Post( + `/delete/(?P\S+)`, + middleware.Defend( + middleware.Protected( + shell.WithAdapter( + renderer.Template( + "templates/delete.html", + "templates/header.html", + "templates/footer.html"), + cfg.Adapter), + http.MethodGet, + udb, + "/login"), + udb, + "/")) http.ListenAndServe(":8080", rtr) } diff --git a/static/bg2.png b/static/bg2.png new file mode 100644 index 0000000..cb711d6 Binary files /dev/null and b/static/bg2.png differ diff --git a/static/style.css b/static/style.css index 076f56c..6d02248 100644 --- a/static/style.css +++ b/static/style.css @@ -2,13 +2,20 @@ body { padding: 0; margin: 0; font-family: sans; + font-size: 16px; + height: 100vh; + background: black; + color: white; + background: url('/static/bg2.png'); + background-size: cover; + background-position: top left; + background-attachment: fixed; } .login-body { background: url('/static/bg.png'); background-size: cover; background-position: center center; - height: 100vh; } .login { @@ -71,4 +78,160 @@ body { color: lightgray; border-bottom: 2px solid crimson; width: auto; +} + +h1 { + text-align: center; + font-size: 225%; + text-transform: uppercase; + background: rgba(0,0,0,0.8); + margin: 0; + padding-top: 0.5em; + padding-bottom: 0.5em; +} + +.login h1 { + background: transparent; +} + +nav { + text-align: center; + background: rgba(0,0,0,0.8); + padding-top: 0.5em; + padding-bottom: 0.5em; + position: sticky; + top: 0px; +} + +nav ul { + list-style: none; +} + +nav ul li { + display: inline; + margin-left: 0.5em; + margin-right: 0.5em; +} + +a { + color: white; + font-weight: normal; + text-decoration: underline; +} + +a:hover { + color: cyan; +} + +a.new-page-button { + position: sticky; + top: 0; + text-decoration: none; + background: transparent; + border: solid 2px lightgray; + font-size: 150%; + color: lightgray; + padding: 0.2em; + text-transform: uppercase; + transition: background 1s, color 1s; + float: right; + z-index: 2; +} + +a.new-page-button:hover { + background: lightgray; + color: black; +} + +h2 { + margin: 1em; + font-size: 200%; + text-transform: uppercase; + background: rgba(0,0,0,0.8); + display: block; + border-left: 8px solid cyan; + padding-left: 8px; + position: sticky; + top: 3em; +} + +.page-list, form.editor, form.build, span.adapter-error, span.adapter-success, .danger-zone { + width: 80%; + max-width: 500px; + background: rgba(0,0,0,0.8); + padding: 2em; + margin-left: auto; + margin-right: auto; + max-height: calc(100vh - 20em); + overflow-y: auto; +} + +form.editor label, form.build label { + font-size: 80%; + color: lightgray; + text-transform: uppercase; +} + +form.editor input, form.build input, form.editor textarea { + display: block; + margin: 0; + margin-top: 0.2em; + margin-bottom: 0.2em; + background: transparent; + border: solid 2px lightgray; + color: lightgray; + padding: 0.2em; + transition: border 1s; + outline: none; +} + +form.editor input.title-input { + margin: 0; + width: 100%; + font-size: 150%; +} + +form.editor, .danger-zone { + max-width: 80em; +} + +form.editor textarea { + margin: 0; + width: 80em; + font-size: 16px; + height: 25em; +} + +form.editor input[type="submit"], form.build input[type="submit"] { + margin-left: auto; + margin-right: 0; + font-size: 150%; + text-transform: uppercase; + transition: background 1s, color 1s; +} + +form.editor input[type="submit"]:hover { + background: lightgray; + color: black; +} + +.edited-time { + font-size: 75%; + color: lightgray; + float: right; +} + +.page-list ul { + margin: 0; + position: relative; + list-style: none; + z-index: 1; +} + +.page-list ul li a { + line-height: 2em; +} + +form input[hidden] { + display: none; } \ No newline at end of file diff --git a/templates/build.html b/templates/build.html new file mode 100644 index 0000000..364b68c --- /dev/null +++ b/templates/build.html @@ -0,0 +1,23 @@ +{{ $buildOpts := ((.Context).Value "adapter").BuildOptions }} +{{ $csrfToken := (.Context).Value "csrfToken" }} + +{{ template "header" . }} + +

Build

+ +
+ +
Build Options +{{ if $buildOpts }} + {{ range $optName := $buildOpts }} + + {{ end }} +{{ else }} +There are no build options for this adapter. +{{ end }} +
+ + +
+ +{{ template "footer" . }} \ No newline at end of file diff --git a/templates/build_run.html b/templates/build_run.html new file mode 100644 index 0000000..e0c7e61 --- /dev/null +++ b/templates/build_run.html @@ -0,0 +1,14 @@ +{{ $buildOpts := .PostForm }} +{{ $status := ((.Context).Value "adapter").Build $buildOpts }} + +{{ template "header" . }} + +{{ if ne ($status).Success true }} +

Build Error

+
{{($status).Message}}
+{{ else }} +

Build Successful

+
{{($status).Message}}
+{{ end }} + +{{ template "footer" . }} \ No newline at end of file diff --git a/templates/cms_create.html b/templates/cms_create.html index c5b919d..bcb668c 100644 --- a/templates/cms_create.html +++ b/templates/cms_create.html @@ -6,8 +6,10 @@ {{ template "header" . }} {{ if $createErr }} +

Page Creation Error

There was an error creating the page: {{ ($createErr).Error }} {{ else }} +

Page Created

Page '{{ $title }}' created successfully {{ end }} diff --git a/templates/cms_edit.html b/templates/cms_edit.html index 35e4f0f..c265d7b 100644 --- a/templates/cms_edit.html +++ b/templates/cms_edit.html @@ -5,7 +5,9 @@ {{ $noEmpty := .FormValue "no-empty" }} {{ template "header" . }} -« + +

Edit Page

+
{{ if $noEmpty }} Empty fields are not allowed - please try again
@@ -13,12 +15,27 @@ {{ if $editableSlugs }} -
+
+
{{ end }} -
- last edited {{($page).Edited}}
-
+
+
+ last edited {{($page).Edited.Format "2006-01-02 15:04"}}
+
+
-{{ template "footer" . }} \ No newline at end of file +
Danger Zone +
+ +
+
+ +
+
+{{ template "footer" . }} diff --git a/templates/cms_list.html b/templates/cms_list.html index b2a2c4d..69a80b3 100644 --- a/templates/cms_list.html +++ b/templates/cms_list.html @@ -1,8 +1,11 @@ {{ $pages := ((.Context).Value "adapter").ListPages }} {{ template "header" .}} + +

Pages

+
- New Page + New Page