Various tweaks

pull/5/head
Noah 2018-04-11 18:59:30 -07:00
parent 709e1f9577
commit b7d1661fcd
7 changed files with 216 additions and 169 deletions

View File

@ -50,7 +50,7 @@ def main(tumblr, root, scheme):
} }
log.info("Blog title: %s", SiteSettings["site"]["title"]) log.info("Blog title: %s", SiteSettings["site"]["title"])
log.info("Description: %s", SiteSettings["site"]["description"]) log.info("Description: %s", SiteSettings["site"]["description"])
write_db(root, "app/settings", SiteSettings) # write_db(root, "app/settings", SiteSettings)
posts_total = r["posts-total"] # n posts_total = r["posts-total"] # n
log.info("Total Posts: %d", posts_total) log.info("Total Posts: %d", posts_total)
@ -63,6 +63,9 @@ def main(tumblr, root, scheme):
POST_ID = 0 POST_ID = 0
# Unique Tumblr post IDs so no duplicates.
tumblr_posts = set()
while posts_start >= 0: while posts_start >= 0:
log.info("GET PAGE start=%d num=%d\n", posts_start, per_page) log.info("GET PAGE start=%d num=%d\n", posts_start, per_page)
r = api_get(API_ROOT, start=posts_start, num=per_page) r = api_get(API_ROOT, start=posts_start, num=per_page)
@ -80,6 +83,10 @@ def main(tumblr, root, scheme):
timestamp = datetime.fromtimestamp(post["unix-timestamp"]) timestamp = datetime.fromtimestamp(post["unix-timestamp"])
timestamp = timestamp.strftime("%Y-%m-%dT%H:%M:%SZ") timestamp = timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
if post["id"] in tumblr_posts:
continue
tumblr_posts.add(post["id"])
slug = post.get("slug") slug = post.get("slug")
if not slug: if not slug:
slug = re.sub(r'.*{}/'.format(tumblr), '', post.get("url-with-slug")) slug = re.sub(r'.*{}/'.format(tumblr), '', post.get("url-with-slug"))
@ -209,12 +216,15 @@ def _download_images(root, images):
for i, url in enumerate(images): for i, url in enumerate(images):
log.info("DOWNLOAD: %s", url) log.info("DOWNLOAD: %s", url)
filename = url.rsplit("/", 1)[-1] filename = url.rsplit("/", 1)[-1]
r = requests.get(url)
if r.ok:
filename = "static/photos/"+filename filename = "static/photos/"+filename
if os.path.isfile(os.path.join(root, filename)): if os.path.isfile(os.path.join(root, filename)):
result.append("/"+filename)
continue continue
r = requests.get(url)
if r.ok:
with open(os.path.join(root, filename), "wb") as fh: with open(os.path.join(root, filename), "wb") as fh:
fh.write(r.content) fh.write(r.content)
result.append("/"+filename) result.append("/"+filename)

View File

@ -10,16 +10,24 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/kirsle/blog/internal/forms" "github.com/kirsle/blog/internal/forms"
"github.com/kirsle/blog/internal/log"
"github.com/kirsle/blog/internal/mail" "github.com/kirsle/blog/internal/mail"
"github.com/kirsle/blog/internal/markdown" "github.com/kirsle/blog/internal/markdown"
"github.com/kirsle/blog/models/settings"
"github.com/kirsle/blog/internal/render" "github.com/kirsle/blog/internal/render"
"github.com/kirsle/blog/internal/responses" "github.com/kirsle/blog/internal/responses"
"github.com/kirsle/blog/models/settings"
) )
// Register attaches the contact URL to the app. // Register attaches the contact URL to the app.
func Register(r *mux.Router) { func Register(r *mux.Router) {
r.HandleFunc("/contact", func(w http.ResponseWriter, r *http.Request) { r.HandleFunc("/contact", func(w http.ResponseWriter, r *http.Request) {
// Allow ?next= to redirect to other local pages.
nextURL := r.FormValue("next")
if nextURL != "" && nextURL[0] != '/' {
log.Error("/contact?next=: URL must be a local page beginning with /")
nextURL = ""
}
form := &forms.Contact{} form := &forms.Contact{}
v := map[string]interface{}{ v := map[string]interface{}{
"Form": form, "Form": form,
@ -42,6 +50,15 @@ func Register(r *mux.Router) {
if r.Method == http.MethodPost { if r.Method == http.MethodPost {
form.ParseForm(r) form.ParseForm(r)
if err = form.Validate(); err != nil { if err = form.Validate(); err != nil {
// If they're not from the /contact front-end, redirect them
// with the flash.
if len(nextURL) > 0 {
responses.FlashAndRedirect(w, r, nextURL, err.Error())
return
}
// Otherwise flash and let the /contact page render to retain
// their form fields so far.
responses.Flash(w, r, err.Error()) responses.Flash(w, r, err.Error())
} else { } else {
go mail.SendEmail(mail.Email{ go mail.SendEmail(mail.Email{
@ -72,8 +89,14 @@ func Register(r *mux.Router) {
)) ))
fh.Close() fh.Close()
} }
if len(nextURL) > 0 {
responses.FlashAndRedirect(w, r, nextURL, "Your message has been sent.")
} else {
responses.FlashAndRedirect(w, r, "/contact", "Your message has been sent.") responses.FlashAndRedirect(w, r, "/contact", "Your message has been sent.")
} }
return
}
} }
render.Template(w, r, "contact", v) render.Template(w, r, "contact", v)

View File

@ -6,10 +6,10 @@ import (
"time" "time"
"github.com/gorilla/feeds" "github.com/gorilla/feeds"
"github.com/kirsle/blog/internal/responses"
"github.com/kirsle/blog/models/posts" "github.com/kirsle/blog/models/posts"
"github.com/kirsle/blog/models/settings" "github.com/kirsle/blog/models/settings"
"github.com/kirsle/blog/models/users" "github.com/kirsle/blog/models/users"
"github.com/kirsle/blog/internal/responses"
) )
func feedHandler(w http.ResponseWriter, r *http.Request) { func feedHandler(w http.ResponseWriter, r *http.Request) {
@ -46,7 +46,7 @@ func feedHandler(w http.ResponseWriter, r *http.Request) {
Description: post.Body + suffix, Description: post.Body + suffix,
Created: p.Created, Created: p.Created,
}) })
if i >= 5 { if i == 9 { // 10 -1
break break
} }
} }

View File

@ -8,11 +8,11 @@ import (
"strconv" "strconv"
"github.com/kirsle/blog/internal/log" "github.com/kirsle/blog/internal/log"
"github.com/kirsle/blog/internal/render"
"github.com/kirsle/blog/internal/types"
"github.com/kirsle/blog/models/comments" "github.com/kirsle/blog/models/comments"
"github.com/kirsle/blog/models/posts" "github.com/kirsle/blog/models/posts"
"github.com/kirsle/blog/models/users" "github.com/kirsle/blog/models/users"
"github.com/kirsle/blog/internal/render"
"github.com/kirsle/blog/internal/types"
) )
// partialIndex renders and returns the blog index partial. // partialIndex renders and returns the blog index partial.
@ -28,10 +28,16 @@ func partialIndex(r *http.Request, tag, privacy string) template.HTML {
if page <= 0 { if page <= 0 {
page = 1 page = 1
} }
perPage := 5 // TODO: configurable perPage := 10 // TODO: configurable
offset := (page - 1) * perPage offset := (page - 1) * perPage
stop := offset + perPage stop := offset + perPage
// Calculate page total.
var pages = int(len(pool) / perPage)
if pages == 0 {
pages = 1
}
// Handle pagination. // Handle pagination.
var previousPage, nextPage int var previousPage, nextPage int
if page > 1 { if page > 1 {
@ -48,7 +54,7 @@ func partialIndex(r *http.Request, tag, privacy string) template.HTML {
var view []PostMeta var view []PostMeta
for i := offset; i < stop; i++ { for i := offset; i < stop; i++ {
if i >= len(pool) { if i >= len(pool) {
continue break
} }
post, err := posts.Load(pool[i].ID) post, err := posts.Load(pool[i].ID)
if err != nil { if err != nil {
@ -81,6 +87,8 @@ func partialIndex(r *http.Request, tag, privacy string) template.HTML {
v := map[string]interface{}{ v := map[string]interface{}{
"PreviousPage": previousPage, "PreviousPage": previousPage,
"NextPage": nextPage, "NextPage": nextPage,
"Page": page,
"Pages": pages,
"View": view, "View": view,
} }
render.Template(&output, r, "blog/index.partial", v) render.Template(&output, r, "blog/index.partial", v)

View File

@ -10,10 +10,10 @@ import (
"github.com/kirsle/blog/internal/log" "github.com/kirsle/blog/internal/log"
"github.com/kirsle/blog/internal/middleware" "github.com/kirsle/blog/internal/middleware"
"github.com/kirsle/blog/internal/middleware/auth" "github.com/kirsle/blog/internal/middleware/auth"
"github.com/kirsle/blog/models/settings"
"github.com/kirsle/blog/models/users"
"github.com/kirsle/blog/internal/sessions" "github.com/kirsle/blog/internal/sessions"
"github.com/kirsle/blog/internal/types" "github.com/kirsle/blog/internal/types"
"github.com/kirsle/blog/models/settings"
"github.com/kirsle/blog/models/users"
) )
// Vars is an interface to implement by the templates to pass their own custom // Vars is an interface to implement by the templates to pass their own custom
@ -23,6 +23,7 @@ type vars struct {
// Global, "constant" template variables. // Global, "constant" template variables.
SetupNeeded bool SetupNeeded bool
Title string Title string
Description string
Path string Path string
TemplatePath string // actual template file on disk TemplatePath string // actual template file on disk
LoggedIn bool LoggedIn bool
@ -62,6 +63,7 @@ func Template(w io.Writer, r *http.Request, path string, data interface{}) error
Request: r, Request: r,
RequestTime: r.Context().Value(types.StartTimeKey).(time.Time), RequestTime: r.Context().Value(types.StartTimeKey).(time.Time),
Title: s.Site.Title, Title: s.Site.Title,
Description: s.Site.Description,
Path: r.URL.Path, Path: r.URL.Path,
Data: data, Data: data,

View File

@ -50,7 +50,7 @@
<div class="bluez-header"> <div class="bluez-header">
<div class="container"> <div class="container">
<h1 class="bluez-title">{{ .Title }}</h1> <h1 class="bluez-title">{{ .Title }}</h1>
<p class="lead bluez-description">Just another web blog.</p> <p class="lead bluez-description">{{ .Description }}</p>
</div> </div>
</div> </div>

View File

@ -1,9 +1,11 @@
{{ define "title" }}Website Settings{{ end }} {{ define "title" }}Website Settings{{ end }}
{{ define "content" }} {{ define "content" }}
<form action="/admin/settings" method="POST"> <div class="card">
<input type="hidden" name="_csrf" value="{{ .CSRF }}"> <div class="card-body">
<form action="/admin/settings" method="POST">
<input type="hidden" name="_csrf" value="{{ .CSRF }}">
{{ with .Data.s }} {{ with .Data.s }}
<h3>The Basics</h3> <h3>The Basics</h3>
<div class="form-group"> <div class="form-group">
@ -163,7 +165,9 @@
<button type="submit" class="btn btn-primary">Save Settings</button> <button type="submit" class="btn btn-primary">Save Settings</button>
<a href="/admin" class="btn btn-secondary">Cancel</a> <a href="/admin" class="btn btn-secondary">Cancel</a>
</div> </div>
{{ end }} {{ end }}
</form> </form>
</div>
</div>
{{ end }} {{ end }}