Example #1
0
func getIndex(w http.ResponseWriter, r *http.Request, ctx routes.Context) error {
	tpl, err := routes.LoadTemplates("base.tpl", "index.tpl")
	if err != nil {
		return tracederror.New(err)
	}

	recent, err := models.GetRecentBlogPosts(ctx.DB, 4, 0)
	if err != nil {
		return tracederror.New(err)
	}

	featured, err := models.GetRecentPostsInCategory(ctx.DB, "featured", 1, 0)
	if err != nil {
		return tracederror.New(err)
	}

	if len(featured) == 0 {
		return tracederror.New(fmt.Errorf("No featured posts?"))
	}

	data := indexPage{
		Posts:    recent,
		Featured: featured[0],
	}

	return routes.RenderTemplateWithData(w, r, tpl, &data)
}
Example #2
0
func LoadTemplates(str ...string) (*template.Template, error) {
	pathed := []string{}
	for _, v := range str {
		pathed = append(pathed, fmt.Sprintf("assets/templates/%s", v))
	}

	res := template.New(str[0])
	// Load default functions.
	mapping := template.FuncMap{
		"blackfriday": templateBlackfriday,
		"s3img":       s3img,
		"add":         add,
		"slug":        slug,
		"timef":       timef,
		"darkenimg":   linearGradient,
	}

	res = res.Funcs(mapping)

	res, err := res.ParseFiles(pathed...)
	if err != nil {
		log.Print(tracederror.New(err))
		return nil, tracederror.New(err)
	}

	return res, tracederror.New(err)
}
Example #3
0
func getGenericArchive(w http.ResponseWriter, r *http.Request, ctx routes.Context) error {
	vars := mux.Vars(r)

	page, err := strconv.ParseInt(vars["page"], 10, 32)
	if err != nil {
		return tracederror.New(err)
	}

	if page <= 0 {
		return routes.MakeHttpError(fmt.Errorf("Page must be larger than 0"), http.StatusBadRequest, r)
	}

	tpl, err := routes.LoadTemplates("base.tpl", "archive.tpl")
	if err != nil {
		return routes.MakeHttpError(err, http.StatusNotFound, r)
	}

	posts, err := models.GetRecentBlogPosts(ctx.DB, 100, int32((page-1)*100))
	if err != nil {
		return tracederror.New(err)
	}

	data := archivePage{
		Page:     int32(page),
		Posts:    posts,
		Category: "All",
	}

	return routes.RenderTemplateWithData(w, r, tpl, data)
}
Example #4
0
func postEdit(w http.ResponseWriter, r *http.Request, ctx routes.Context) error {
	err := routes.CheckAuth(r, ctx)
	if err != nil {
		return err
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return routes.MakeHttpError(err, http.StatusBadRequest, r)
	}

	res := editBody{}
	err = json.Unmarshal(body, &res)
	if err != nil {
		return routes.MakeHttpError(err, http.StatusBadRequest, r)
	}

	post := &models.BlogPost{
		ID:         res.ID,
		CategoryID: 1,
	}

	if res.ID != 0 {
		post, err = models.GetBlogPostByID(ctx.DB, res.ID)
		if err != nil {
			return tracederror.New(err)
		}
	}

	post.Content = res.Content
	post.Title = res.Title
	post.CategoryID = res.Category
	post.Hero = res.Hero

	t := time.Unix(int64(res.Publish), 0)
	post.Publish = &t

	if res.Publish == 0 {
		post.Publish = nil
	}

	err = post.Save(ctx.DB)
	if err != nil {
		return tracederror.New(err)
	}

	result := editResponse{
		ID: post.ID,
	}

	bytes, err := json.Marshal(result)
	if err != nil {
		return tracederror.New(err)
	}

	w.Write(bytes)
	return nil
}
Example #5
0
func LoadConfigurationFromFileAndEnvironment(file string, cfg interface{}) error {
	bytes, err := ioutil.ReadFile(file)
	if err != nil {
		return tracederror.New(err)
	}

	err = json.Unmarshal(bytes, cfg)

	if err != nil {
		return tracederror.New(err)
	}

	err = LoadConfigurationFromEnvironmentVariables(cfg)
	return tracederror.New(err)
}
Example #6
0
func GetImagesInGallery(bucket *s3.Bucket, g *Gallery) ([]Image, error) {
	pre := fmt.Sprintf("%s%s", g.S3Prefix, "orig-")
	res, err := bucket.List(pre, "/", "", 1000)
	if err != nil {
		return nil, tracederror.New(err)
	}

	paths := []Image{}
	for _, v := range res.Contents {
		if v.Key[len(v.Key)-1] != '/' {
			raw := strings.TrimPrefix(v.Key, pre)

			t, err := time.Parse("2006-01-02T15:04:05.000Z", v.LastModified)
			if err != nil {
				log.Print("Couldn't parse time from amazon, assuming 'now' for upload date.")
				log.Print(err)

				t = time.Now()
			}

			paths = append(paths, Image{
				Thumb: fmt.Sprintf("%sthumb-%s", g.S3Prefix, raw),
				Orig:  fmt.Sprintf("%sorig-%s", g.S3Prefix, raw),
				Hero:  fmt.Sprintf("%shero-%s", g.S3Prefix, raw),

				ETag:         v.ETag,
				LastModified: t,
			})
		}
	}

	sort.Sort(ByDate(paths))
	return paths, nil
}
Example #7
0
func GetHiddenGalleries(db sqlx.Ext) ([]Gallery, error) {
	q := `SELECT * FROM galleries`

	res := []Gallery{}
	err := sqlx.Select(db, &res, q)
	return res, tracederror.New(err)
}
Example #8
0
func GetGalleries(db sqlx.Ext) ([]Gallery, error) {
	q := `SELECT * FROM galleries WHERE displayed`

	res := []Gallery{}
	err := sqlx.Select(db, &res, q)
	return res, tracederror.New(err)
}
Example #9
0
func GetGalleryByID(db sqlx.Ext, id int32) (*Gallery, error) {
	q := `SELECT * FROM galleries WHERE id=$1`

	res := Gallery{}
	err := sqlx.Get(db, &res, q, id)

	return &res, tracederror.New(err)
}
Example #10
0
func GetCategories(db sqlx.Ext) ([]BlogCategory, error) {
	q := `
		SELECT * FROM blog_categories ORDER BY id;
	`

	res := []BlogCategory{}
	err := sqlx.Select(db, &res, q)
	return res, tracederror.New(err)
}
Example #11
0
func GetBlogPostByID(db sqlx.Ext, id int32) (*BlogPost, error) {
	q := `
		SELECT p.*, c.category AS category_value 
		FROM blog_posts p JOIN blog_categories c ON c.id = p.category
		WHERE p.id = $1
	`

	res := BlogPost{}
	err := sqlx.Get(db, &res, q, id)
	return &res, tracederror.New(err)
}
Example #12
0
func getCategoryArchive(w http.ResponseWriter, r *http.Request, ctx routes.Context) error {
	vars := mux.Vars(r)

	page, err := strconv.ParseInt(vars["page"], 10, 32)
	if err != nil {
		return tracederror.New(err)
	}

	if page <= 0 {
		return routes.MakeHttpError(fmt.Errorf("Page must be larger than 0"), http.StatusBadRequest, r)
	}

	category := vars["category"]
	valid, err := models.IsValidCategory(ctx.DB, category)

	if err != nil {
		return tracederror.New(err)
	}

	if !valid {
		return routes.MakeHttpError(fmt.Errorf("Invalid category %s", category), http.StatusBadRequest, r)
	}

	tpl, err := routes.LoadTemplates("base.tpl", "archive.tpl")
	if err != nil {
		return routes.MakeHttpError(err, http.StatusNotFound, r)
	}

	posts, err := models.GetRecentPostsInCategory(ctx.DB, category, 100, int32((page-1)*100))
	if err != nil {
		return tracederror.New(err)
	}

	data := archivePage{
		Page:     int32(page),
		Posts:    posts,
		Category: strings.Title(category),
	}

	return routes.RenderTemplateWithData(w, r, tpl, data)
}
Example #13
0
func getEdit(w http.ResponseWriter, r *http.Request, ctx routes.Context) error {
	err := routes.CheckAuth(r, ctx)
	if err != nil {
		return err
	}

	vars := mux.Vars(r)
	id := int64(0)
	if vars["id"] != "new" {
		id, err = strconv.ParseInt(vars["id"], 10, 64)
		if err != nil {
			return tracederror.New(err)
		}
	}

	post := &models.BlogPost{}

	if id != 0 {
		post, err = models.GetBlogPostByID(ctx.DB, int32(id))
		if err != nil {
			return routes.MakeHttpError(err, http.StatusNotFound, r)
		}
	}

	categories, err := models.GetCategories(ctx.DB)
	if err != nil {
		return tracederror.New(err)
	}

	tpl, err := routes.LoadTemplates("base.tpl", "edit.tpl")
	if err != nil {
		return tracederror.New(err)
	}

	data := editPage{
		Post:       post,
		Categories: categories,
	}

	return routes.RenderTemplateWithData(w, r, tpl, &data)
}
Example #14
0
func IsValidCategory(db sqlx.Ext, category string) (bool, error) {
	q := `SELECT * FROM blog_categories WHERE category = $1`

	res := []BlogCategory{}
	err := sqlx.Select(db, &res, q, category)

	if err != nil {
		return false, tracederror.New(err)
	}

	return len(res) == 1, nil
}
Example #15
0
func getPost(w http.ResponseWriter, r *http.Request, ctx routes.Context) error {
	vars := mux.Vars(r)

	tpl, err := routes.LoadTemplates("base.tpl", "post.tpl")
	if err != nil {
		return tracederror.New(err)
	}

	recent, err := models.GetRecentBlogPosts(ctx.DB, 4, 0)
	if err != nil {
		return tracederror.New(err)
	}

	id, err := strconv.ParseInt(vars["id"], 10, 32)
	if err != nil {
		return tracederror.New(err)
	}

	self, err := models.GetBlogPostByID(ctx.DB, int32(id))
	if err != nil {
		return tracederror.New(err)
	}

	authErr := routes.CheckAuth(r, ctx)
	if self.Publish == nil && authErr != nil {
		return routes.MakeHttpError(nil, http.StatusNotFound, r)
	}

	if self.Publish != nil && self.Publish.After(time.Now().UTC()) && authErr != nil {
		return routes.MakeHttpError(nil, http.StatusNotFound, r)
	}

	data := postPage{
		Post:   self,
		Recent: recent,
	}

	return routes.RenderTemplateWithData(w, r, tpl, &data)
}
Example #16
0
func postRender(w http.ResponseWriter, r *http.Request, ctx routes.Context) error {
	err := routes.CheckAuth(r, ctx)
	if err != nil {
		return err
	}

	tpl, err := routes.LoadTemplates("render.tpl")
	if err != nil {
		return tracederror.New(err)
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return tracederror.New(err)
	}

	bodyStr := string(body)
	bodyStr = strings.Replace(bodyStr, "{:truncate}", "", 1)
	bodyStr = strings.Replace(bodyStr, "{:longtruncate}", "", 1)

	return routes.RenderTemplateWithData(w, r, tpl, bodyStr)
}
Example #17
0
func GetRecentBlogPosts(db sqlx.Ext, count int32, offset int32) ([]BlogPost, error) {
	q := `
		SELECT p.*, c.category AS category_value 
		FROM blog_posts p JOIN blog_categories c ON c.id = p.category
		WHERE publish IS NOT NULL AND NOT c.hidden
		ORDER BY publish DESC
		LIMIT $1
		OFFSET $2
	`

	res := []BlogPost{}
	err := sqlx.Select(db, &res, q, count, offset)
	return res, tracederror.New(err)
}
Example #18
0
func importImage(args []string, context *routes.Context) error {
	//Args in the format
	// gallery <image>
	if len(args) < 2 {
		return fmt.Errorf("usage: <gallery> <image>")
	}

	args[0] = strings.TrimSpace(args[0])
	log.Print(args)

	// Step 1: create a sha-256 hash of the file contents.
	f, err := ioutil.ReadFile(args[1])
	if err != nil {
		return tracederror.New(err)
	}

	sum := sha256.Sum256(f)
	key := base64.URLEncoding.EncodeToString(sum[:])

	ext := filepath.Ext(args[1])
	m := mime.TypeByExtension(ext)

	// Step 2: Upload the original file to orig-<sha256>.jpg
	log.Printf("Uploading %s to %s/%s", args[1], args[0], key)
	err = context.Bucket.Put(fmt.Sprintf("%s/orig-%s", args[0], key), f, m, s3.PublicRead)
	if err != nil {
		return tracederror.New(err)
	}

	convbinary := "convert"
	if runtime.GOOS == "windows" {
		convbinary = "imgconvert"
	}

	// Step 3: Generate thumbnails/hero by cutting it through the center.
	os.Mkdir("temp", 0777)
	target := fmt.Sprintf("temp/%s%s", key, ext)
	cmd := exec.Command(convbinary, args[1],
		"-gravity", "center",
		"-resize", "25%",
		target)

	_, err = cmd.CombinedOutput()
	if err != nil {
		return tracederror.New(err)
	}

	f, err = ioutil.ReadFile(target)
	if err != nil {
		return tracederror.New(err)
	}

	log.Printf("Uploading thumbnail...")
	err = context.Bucket.Put(fmt.Sprintf("%s/thumb-%s", args[0], key), f, m, s3.PublicRead)
	if err != nil {
		return tracederror.New(err)
	}

	cmd = exec.Command(convbinary, args[1],
		"-gravity", "center",
		"-crop", "1200x400+0+0",
		target)

	_, err = cmd.CombinedOutput()
	if err != nil {
		return tracederror.New(err)
	}

	f, err = ioutil.ReadFile(target)
	if err != nil {
		return tracederror.New(err)
	}

	log.Printf("Uploading hero...")
	err = context.Bucket.Put(fmt.Sprintf("%s/hero-%s", args[0], key), f, m, s3.PublicRead)
	if err != nil {
		return tracederror.New(err)
	}

	os.Remove(target)

	log.Printf("Cleaning cache")
	clearCache(args, context)

	log.Printf("Saving Original Image URL to Clipboard...")

	url := context.Bucket.URL(fmt.Sprintf("/%s/orig-%s", args[0], key))
	clipboard.WriteAll(url)

	return nil
}