Skip to content

Instantly share code, notes, and snippets.

@thetooth
Created February 21, 2013 18:28
Show Gist options
  • Save thetooth/5006923 to your computer and use it in GitHub Desktop.
Save thetooth/5006923 to your computer and use it in GitHub Desktop.
package pages
import (
"crypto/sha1"
"fmt"
"github.com/gorilla/sessions"
"github.com/nfnt/resize"
"image"
"image/gif"
"image/jpeg"
"image/png"
"io/ioutil"
"log"
"math"
"math/rand"
"net/http"
"os"
"path"
"sort"
"strconv"
"text/template"
)
type GalleryT struct {
Image string
ImageSrc string
Valid bool
}
type GalleryInfoT struct {
Size int
Index int
IndexMax int
Pages []bool
}
type Page struct {
Title string
Debug string
Gallery []GalleryT
GalleryInfo GalleryInfoT
}
type byModTime []os.FileInfo
func (f byModTime) Len() int { return len(f) }
func (f byModTime) Less(i, j int) bool { return f[i].ModTime().Unix() > f[j].ModTime().Unix() }
func (f byModTime) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
func (g GalleryInfoT) ListPages() string {
buff := ""
for i := 0; i < g.IndexMax; i++ {
buff = fmt.Sprintf("%s<a href=\"?offset=%d\">%d</a>", buff, i, i+1)
}
return buff
}
func min(x, y int) int {
if x > y {
return y
}
return x
}
func max(x, y int) int {
if x < y {
return y
}
return x
}
var secret = []byte("46139b0b16d7696468a818ef81ab82a93691f7d5")
var itemsPerPage = 21
// Default Request Handler
func DefaultHandler(w http.ResponseWriter, r *http.Request) {
sessionDataStore := sessions.NewFilesystemStore("./session/", secret)
sessionData, err := sessionDataStore.Get(r, "clientID")
var p *Page = new(Page)
p.Title = "thetooth.name"
// Setup a session ID for storing client profile
if sessionData.Values["id"] == nil {
hash := sha1.New()
hash.Write([]byte(string(secret) + fmt.Sprintf("%d", rand.Int())))
sessionData.Values["id"] = fmt.Sprintf("%x", hash.Sum(nil))
hash.Write([]byte(r.RemoteAddr))
sessionData.Values["test"] = fmt.Sprintf("% x", hash.Sum(nil))
}
var ID string = sessionData.Values["id"].(string)
if err != nil {
log.Println(err)
}
p.Debug = fmt.Sprintf("Your session ID is: <strong>0x%s</strong><br />Which accesses this data on the server: <br /><strong>%s</strong>", ID, sessionData.Values["test"])
log.Printf("[%s] REQUEST", ID)
d, err := os.Open("images/")
if err != nil {
log.Println(err)
os.Exit(1)
}
fi, err := d.Readdir(-1)
if err != nil {
log.Println(err)
os.Exit(1)
}
sort.Sort(byModTime(fi))
var filteredFileList []os.FileInfo
for _, v := range fi {
if !v.IsDir() {
switch path.Ext(v.Name()) {
case ".jpg", ".jpeg", ".png", ".gif":
filteredFileList = append(filteredFileList, v)
p.GalleryInfo.Size++
break
}
}
}
rawIndex, _ := strconv.Atoi(r.URL.Query().Get("offset"))
maxIndex := int(math.Ceil((float64(len(filteredFileList)) / float64(itemsPerPage))))
absIndex := min(rawIndex, maxIndex-1) * itemsPerPage
pageList := filteredFileList[absIndex:(absIndex + min(itemsPerPage, len(filteredFileList[absIndex:])))]
p.GalleryInfo.Index = rawIndex + 1
p.GalleryInfo.IndexMax = maxIndex
p.GalleryInfo.Pages = make([]bool, maxIndex)
p.Gallery = make([]GalleryT, len(pageList))
sem := make(chan string, len(pageList))
for i, v := range pageList {
go CreateThumbnail(sem, p, i, v)
}
for i, _ := range pageList {
status := <-sem
if status != "" {
log.Printf("Channel %d exited with status \"%s\".", i, status)
}
}
sessions.Save(r, w)
tmpl, _ := ioutil.ReadFile("template.html")
t, err := template.New("test").Parse(string(tmpl))
if err != nil {
log.Printf("[%s] ERROR", err)
}
t.Execute(w, p)
log.Printf("[%s] FINAL", ID)
}
func CreateThumbnail(ch chan<- string, p *Page, i int, v os.FileInfo) {
resizeName := v.Name()[0:(len(v.Name())-len(path.Ext(v.Name())))] + ".png"
_, err := os.Stat("images/thumbs/" + resizeName)
if os.IsNotExist(err) {
log.Println("Generating thumbnail: " + resizeName)
file, err := os.Open("images/" + v.Name())
defer file.Close()
if err != nil {
log.Println(err)
ch <- "Cannot open image file"
return
}
var source image.Image = nil
var thumb image.Image = nil
switch path.Ext(v.Name()) {
case ".jpg", ".jpeg":
source, err = jpeg.Decode(file)
break
case ".png":
source, err = png.Decode(file)
break
case ".gif":
source, err = gif.Decode(file)
break
default:
ch <- "Image decode missmatch"
return
}
if err != nil {
log.Println(err)
thumb = image.NewRGBA(image.Rect(0, 0, 96, 96))
} else {
x := 0
y := 96
if bool(source.Bounds().Max.X > source.Bounds().Max.Y) {
x = 96
y = 0
}
thumb = resize.Resize(uint(x), uint(y), source, resize.Lanczos3)
}
out, err := os.Create("images/thumbs/" + resizeName)
defer out.Close()
if err != nil {
log.Println(err)
ch <- "Cannot open destination thumbnail file"
return
}
png.Encode(out, thumb)
}
p.Gallery[i] = GalleryT{resizeName, v.Name(), true}
ch <- ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment