<commit_before>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"html/template"
	"io"
	"log"
	"net/http"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

type Page struct {
	Title string
	Body  []byte
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste string) string {
	hasher := sha1.New()

	hasher.Write([]byte(paste))
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw string, lang string) []string {
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	sha := hash(raw)
	query, err := db.Query("select id, hash, data, delkey from pastebin")
	for query.Next() {
		var id, hash, paste, delkey string
		err := query.Scan(&id, &hash, &paste, &delkey)
		check(err)
		if hash == sha {
			url := ADDRESS + "/p/" + id
			return []string{id, hash, url, paste, delkey}
		}
	}
	id := generateName()
	var url string
	if lang == "" {
		url = ADDRESS + "/p/" + id
	} else {
		url = ADDRESS + "/p/" + id + "/" + lang
	}
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(raw)

	stmt, err := db.Prepare("INSERT INTO pastebin(id, hash, data, delkey) values(?,?,?,?)")
	check(err)
	_, err = stmt.Exec(id, sha, paste, delKey)
	check(err)
	db.Close()
	return []string{id, sha, url, paste, delKey}
}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	delkey := vars["delKey"]

	db, err := sql.Open("mysql", DATABASE)
	check(err)

	stmt, err := db.Prepare("delete from pastebin where delkey=?")
	check(err)

	res, err := stmt.Exec(html.EscapeString(delkey))
	check(err)

	_, err = res.RowsAffected()
	if err == sql.ErrNoRows {
		io.WriteString(w, "Error invalid paste")
	} else {
		io.WriteString(w, paste+" deleted")
	}
	db.Close()

}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		paste := r.FormValue("p")
		lang := r.FormValue("lang")
		if paste == "" {
			http.Error(w, "Empty paste", 500)
			return
		}
		values := save(paste, lang)
		b := &Response{
			ID:     values[0],
			HASH:   values[1],
			URL:    values[2],
			SIZE:   len(values[3]),
			DELKEY: values[4],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		case "html":
			w.Header().Set("Content-Type", "text/html")
			io.WriteString(w, "
URL: "+b.URL+"
")
			io.WriteString(w, "
Delete Key: "+b.DELKEY+"
")

		default:
			w.Header().Set("Content-Type", "plain/text")
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func langHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s := getPaste(paste)
	highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "full, style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,", "utf-8")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	io.WriteString(w, highlight)

}

func getPaste(paste string) string {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("mysql", DATABASE)
	var s string
	err = db.QueryRow("select data from pastebin where id=?", param1).Scan(&s)
	db.Close()
	check(err)

	if err == sql.ErrNoRows {
		return "Error invalid paste"
	} else {
		return html.UnescapeString(s)
	}

}

var templates = template.Must(template.ParseFiles("assets/paste.html"))

func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s := getPaste(paste)
	p := &Page{
		Title: paste,
		Body:  []byte(s),
	}
	err := templates.ExecuteTemplate(w, "assets/paste.html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func rawHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s := getPaste(paste)
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/raw/{pasteId}", rawHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", langHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("assets/"))))
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<commit_msg>Template bug fix<commit_after>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"html/template"
	"io"
	"log"
	"net/http"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

type Page struct {
	Title string
	Body  []byte
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste string) string {
	hasher := sha1.New()

	hasher.Write([]byte(paste))
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw string, lang string) []string {
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	sha := hash(raw)
	query, err := db.Query("select id, hash, data, delkey from pastebin")
	for query.Next() {
		var id, hash, paste, delkey string
		err := query.Scan(&id, &hash, &paste, &delkey)
		check(err)
		if hash == sha {
			url := ADDRESS + "/p/" + id
			return []string{id, hash, url, paste, delkey}
		}
	}
	id := generateName()
	var url string
	if lang == "" {
		url = ADDRESS + "/p/" + id
	} else {
		url = ADDRESS + "/p/" + id + "/" + lang
	}
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(raw)

	stmt, err := db.Prepare("INSERT INTO pastebin(id, hash, data, delkey) values(?,?,?,?)")
	check(err)
	_, err = stmt.Exec(id, sha, paste, delKey)
	check(err)
	db.Close()
	return []string{id, sha, url, paste, delKey}
}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	delkey := vars["delKey"]

	db, err := sql.Open("mysql", DATABASE)
	check(err)

	stmt, err := db.Prepare("delete from pastebin where delkey=?")
	check(err)

	res, err := stmt.Exec(html.EscapeString(delkey))
	check(err)

	_, err = res.RowsAffected()
	if err == sql.ErrNoRows {
		io.WriteString(w, "Error invalid paste")
	} else {
		io.WriteString(w, paste+" deleted")
	}
	db.Close()

}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		paste := r.FormValue("p")
		lang := r.FormValue("lang")
		if paste == "" {
			http.Error(w, "Empty paste", 500)
			return
		}
		values := save(paste, lang)
		b := &Response{
			ID:     values[0],
			HASH:   values[1],
			URL:    values[2],
			SIZE:   len(values[3]),
			DELKEY: values[4],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		case "html":
			w.Header().Set("Content-Type", "text/html")
			io.WriteString(w, "
URL: "+b.URL+"
")
			io.WriteString(w, "
Delete Key: "+b.DELKEY+"
")

		default:
			w.Header().Set("Content-Type", "plain/text")
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func langHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s := getPaste(paste)
	highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "full, style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,", "utf-8")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	io.WriteString(w, highlight)

}

func getPaste(paste string) string {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("mysql", DATABASE)
	var s string
	err = db.QueryRow("select data from pastebin where id=?", param1).Scan(&s)
	db.Close()
	check(err)

	if err == sql.ErrNoRows {
		return "Error invalid paste"
	} else {
		return html.UnescapeString(s)
	}

}

func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s := getPaste(paste)
	p := &Page{
		Title: paste,
		Body:  []byte(s),
	}
	t, err := template.ParseFiles("assets/edit.html")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	t.Execute(w, p)
}

func rawHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s := getPaste(paste)
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/raw/{pasteId}", rawHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", langHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("assets/"))))
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>package main

import (
	gohst "github.com/warreq/gohstd/service"
	"log"
	"net/http"
	"os"
)

func main() {

	conn := os.Getenv("DATABASE_URL")

	if conn == "" {
		log.Fatal("DATABASE_URL environment variable not set!")
	}
	dao := *gohst.NewPsqlDao(conn)
	cmd := *gohst.NewPsqlCommandRepo(dao)
	user := *gohst.NewPsqlUserRepo(dao)
	post := *gohst.NewPsqlPostRepo(dao)

	port := os.Getenv("PORT") // Get Heroku assigned PORT
	httpOnlyPort := os.Getenv("HTTP_ONLY_PORT")
	cert := os.Getenv("GOHST_CERT")
	key := os.Getenv("GOHST_KEY")

	if port == "" {
		port = "8080" // if not on Heroku or not defined, use 8080
	}

	router := gohst.NewRouter(cmd, user, post)

	if cert != "" && key != "" {
		if httpOnlyPort != "" {
			go log.Fatal(http.ListenAndServe(":"+httpOnlyPort, nil))
		}
		log.Fatal(http.ListenAndServeTLS(":"+port, cert, key, router))
	} else {
		log.Fatal(http.ListenAndServe(":"+port, router))
	}

}
<commit_msg>redirect http to https<commit_after>package main

import (
	gohst "github.com/warreq/gohstd/service"
	"log"
	"net/http"
	"os"
)

func main() {

	conn := os.Getenv("DATABASE_URL")

	if conn == "" {
		log.Fatal("DATABASE_URL environment variable not set!")
	}
	dao := *gohst.NewPsqlDao(conn)
	cmd := *gohst.NewPsqlCommandRepo(dao)
	user := *gohst.NewPsqlUserRepo(dao)
	post := *gohst.NewPsqlPostRepo(dao)

	port := os.Getenv("PORT") // Get Heroku assigned PORT
	httpOnlyPort := os.Getenv("HTTP_ONLY_PORT")
	cert := os.Getenv("GOHST_CERT")
	key := os.Getenv("GOHST_KEY")

	if port == "" {
		port = "8080" // if not on Heroku or not defined, use 8080
	}

	router := gohst.NewRouter(cmd, user, post)

	if cert != "" && key != "" {
		// Set up a listener for HTTP requests that redirect to HTTPS
		if httpOnlyPort != "" {
			redir := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				http.Redirect(w, r, "https://"+r.Host, http.StatusMovedPermanently)
			})
			go log.Fatal(http.ListenAndServe(":"+httpOnlyPort, redir))
		}
		log.Fatal(http.ListenAndServeTLS(":"+port, cert, key, router))
	} else {
		log.Fatal(http.ListenAndServe(":"+port, router))
	}

}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"github.com/TakatoshiMaeda/kinu/engine"
	"github.com/TakatoshiMaeda/kinu/logger"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"net/http/pprof"
	"os"
	"path/filepath"
	"runtime"
)

var (
	ErrInvalidImageExt = errors.New("supported image type is only jpg/jpeg")
	listenPort         = "80"
)

type ErrInvalidRequest struct {
	error
	Message string
}

type ErrInvalidGeometryOrderRequest struct {
	error
	Message string
}

func (e *ErrInvalidRequest) Error() string { return e.Message }

func init() {
	if len(os.Getenv("KINU_PORT")) != 0 {
		listenPort = os.Getenv("KINU_PORT")
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	engine.Initialize()
	defer engine.Finalize()

	router := httprouter.New()

	if os.Getenv("KINU_DEBUG") == "1" {
		router.GET("/debug/pprof/*pprof", HandlePprof)
	}

	router.GET("/images/:type/:geometry/:filename", GetImageHandler)

	router.POST("/upload", UploadImageHandler)
	router.POST("/sandbox", UploadImageToSandboxHandler)
	router.POST("/sandbox/attach", ApplyFromSandboxHandler)

	logger.Info("kinu started")

	logger.Fatal(http.ListenAndServe(":"+listenPort, router))
}

func HandlePprof(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	switch p.ByName("pprof") {
	case "/cmdline":
		pprof.Cmdline(w, r)
	case "/profile":
		pprof.Profile(w, r)
	case "/symbol":
		pprof.Symbol(w, r)
	default:
		pprof.Index(w, r)
	}
}

func SetContentType(w http.ResponseWriter, filename string) error {
	ext := ExtractExtension(filepath.Ext(filename))
	if IsValidImageExt(ext) {
		w.Header().Set("Content-Type", "image/"+ext)
		return nil
	} else {
		return ErrInvalidImageExt
	}
}

func RespondBadRequest(w http.ResponseWriter, reason string) {
	w.Header().Set("X-Kinu-BadRequest-Reason", reason)
	w.WriteHeader(http.StatusBadRequest)
}

func RespondNotFound(w http.ResponseWriter) {
	w.WriteHeader(http.StatusNotFound)
}

func RespondInternalServerError(w http.ResponseWriter, err error) {
	logger.ErrorDebug(err)
	w.WriteHeader(http.StatusInternalServerError)
}

func RespondServiceUnavailable(w http.ResponseWriter, err error) {
	logger.ErrorDebug(err)
	w.WriteHeader(http.StatusServiceUnavailable)
}

type UploadResult struct {
	ImageType string `json:"name"`
	ImageId   string `json:"id"`
}

func RespondImageUploadSuccessJson(w http.ResponseWriter, imageType string, imageId string) {
	json, err := json.Marshal(&UploadResult{ImageType: imageType, ImageId: imageId})
	if err != nil {
		RespondInternalServerError(w, err)
	}
	RespondJson(w, json)
}

func RespondJson(w http.ResponseWriter, json []byte) {
	w.Write(json)
}

func RespondImage(w http.ResponseWriter, bytes []byte) {
	w.Write(bytes)
}
<commit_msg>Graceful shutdown<commit_after>package main

import (
	"encoding/json"
	"errors"
	"github.com/TakatoshiMaeda/kinu/engine"
	"github.com/TakatoshiMaeda/kinu/logger"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"net/http/pprof"
	"os"
	"path/filepath"
	"runtime"
	"fmt"
	"github.com/zenazn/goji/graceful"
	"github.com/zenazn/goji/bind"
)

const (
	DEFAULT_BIND = "127.0.0.1:8080"
)

var (
	ErrInvalidImageExt = errors.New("supported image type is only jpg/jpeg")
)

type ErrInvalidRequest struct {
	error
	Message string
}

type ErrInvalidGeometryOrderRequest struct {
	error
	Message string
}

func (e *ErrInvalidRequest) Error() string { return e.Message }

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	engine.Initialize()
	defer engine.Finalize()

	router := httprouter.New()

	if os.Getenv("KINU_DEBUG") == "1" {
		router.GET("/debug/pprof/*pprof", HandlePprof)
	}

	router.GET("/images/:type/:geometry/:filename", GetImageHandler)

	router.POST("/upload", UploadImageHandler)
	router.POST("/sandbox", UploadImageToSandboxHandler)
	router.POST("/sandbox/attach", ApplyFromSandboxHandler)

	addr := os.Getenv("KINU_BIND")
	if len(addr) == 0 {
		addr = DEFAULT_BIND
	}

	graceful.HandleSignals()
	graceful.PreHook(func() {
		logger.Info("kinu received graceful shutdown signal.")
	})
	graceful.PostHook(func() {
		logger.Info("kinu stopped.")
	})

	logger.Info(fmt.Sprintf("starting kinu on %s", addr))

	err := graceful.Serve(bind.Socket(addr), router)
	if err != nil {
		logger.Panic(err)
	}

	graceful.Wait()
}

func HandlePprof(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	switch p.ByName("pprof") {
	case "/cmdline":
		pprof.Cmdline(w, r)
	case "/profile":
		pprof.Profile(w, r)
	case "/symbol":
		pprof.Symbol(w, r)
	default:
		pprof.Index(w, r)
	}
}

func SetContentType(w http.ResponseWriter, filename string) error {
	ext := ExtractExtension(filepath.Ext(filename))
	if IsValidImageExt(ext) {
		w.Header().Set("Content-Type", "image/"+ext)
		return nil
	} else {
		return ErrInvalidImageExt
	}
}

func RespondBadRequest(w http.ResponseWriter, reason string) {
	w.Header().Set("X-Kinu-BadRequest-Reason", reason)
	w.WriteHeader(http.StatusBadRequest)
}

func RespondNotFound(w http.ResponseWriter) {
	w.WriteHeader(http.StatusNotFound)
}

func RespondInternalServerError(w http.ResponseWriter, err error) {
	logger.ErrorDebug(err)
	w.WriteHeader(http.StatusInternalServerError)
}

func RespondServiceUnavailable(w http.ResponseWriter, err error) {
	logger.ErrorDebug(err)
	w.WriteHeader(http.StatusServiceUnavailable)
}

type UploadResult struct {
	ImageType string `json:"name"`
	ImageId   string `json:"id"`
}

func RespondImageUploadSuccessJson(w http.ResponseWriter, imageType string, imageId string) {
	json, err := json.Marshal(&UploadResult{ImageType: imageType, ImageId: imageId})
	if err != nil {
		RespondInternalServerError(w, err)
	}
	RespondJson(w, json)
}

func RespondJson(w http.ResponseWriter, json []byte) {
	w.Write(json)
}

func RespondImage(w http.ResponseWriter, bytes []byte) {
	w.Write(bytes)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/gbbr/gopherblog/controllers"
	"github.com/gbbr/gopherblog/models"
	"log"
	"net/http"
)

// Command line flags, HTTP hostname, port and
// database connection string. DB String format is
// user:pass@tcp(hostname:port)/database_name
var (
	host     = flag.String("host", "localhost", "Hostname for HTTP server")
	port     = flag.String("port", "8080", "Port for HTTP server")
	dbString = flag.String("db", "root:root@tcp(localhost:3306)/gopherblog", "Database connection string")
)

func main() {
	flag.Parse()

	models.ConnectDb(*dbString)
	defer models.CloseDb()

	mux := http.NewServeMux()

	mux.HandleFunc("/", controller.Home)
	mux.HandleFunc("/post/", controller.Post)
	mux.HandleFunc("/login", controller.Login)
	mux.HandleFunc("/new", authenticate(controller.NewPost))
	mux.HandleFunc("/manage", authenticate(controller.Manage))
	mux.HandleFunc("/edit/", authenticate(controller.EditPost))

	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

	err := http.ListenAndServe(*host+":"+*port, mux)

	log.Fatal(err)
}
<commit_msg>Added more logging<commit_after>package main

import (
	"flag"
	"github.com/gbbr/gopherblog/controllers"
	"github.com/gbbr/gopherblog/models"
	"log"
	"net/http"
)

// Command line flags, HTTP hostname, port and
// database connection string. DB String format is
// user:pass@tcp(hostname:port)/database_name
var (
	host     = flag.String("host", "localhost", "Hostname for HTTP server")
	port     = flag.String("port", "8080", "Port for HTTP server")
	dbString = flag.String("db", "root:root@tcp(localhost:3306)/gopherblog", "Database connection string")
)

func main() {
	flag.Parse()

	models.ConnectDb(*dbString)
	defer models.CloseDb()

	mux := http.NewServeMux()

	mux.HandleFunc("/", controller.Home)
	mux.HandleFunc("/post/", controller.Post)
	mux.HandleFunc("/login", controller.Login)
	mux.HandleFunc("/new", authenticate(controller.NewPost))
	mux.HandleFunc("/manage", authenticate(controller.Manage))
	mux.HandleFunc("/edit/", authenticate(controller.EditPost))

	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

	log.Printf("Starting on %s:%s\n", *host, *port)
	err := http.ListenAndServe(*host+":"+*port, mux)

	log.Fatal(err)
}
<|endoftext|>


<commit_before>/*
   Multihost
   Multiple ports
*/

package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"github.com/skynetservices/skydns/client"
	"github.com/skynetservices/skydns/msg"
	"io"
	"log"
	"net/http"
	"os"
	"time"
)

var (
	pathToSocket string
	domain       string
	environment  string
	skydnsUrl    string
	secret       string
	ttl          int
	beat         int

	skydns       *client.Client
	dockerClient *docker
	running      = make(map[string]struct{})
	errNotTagged = errors.New("image not tagged")
)

func init() {
	flag.StringVar(&pathToSocket, "s", "/var/run/docker.sock", "path to the docker unix socket")
	flag.StringVar(&skydnsUrl, "skydns", "", "url to the skydns url")
	flag.StringVar(&secret, "secret", "", "skydns secret")
	flag.StringVar(&domain, "domain", "", "same domain passed to skydns")
	flag.StringVar(&environment, "environment", "dev", "environment name where service is running")
	flag.IntVar(&ttl, "ttl", 60, "default ttl to use when registering a service")
	flag.IntVar(&beat, "beat", 0, "heartbeat interval")

	flag.Parse()

	if beat < 1 {
		beat = ttl - (ttl / 4)
	}

	if skydnsUrl == "" {
		skydnsUrl = "http://" + os.Getenv("SKYDNS_PORT_8080_TCP_ADDR") + ":8080"
	}

	if domain == "" {
		log.Fatal("Must specify your skydns domain")
	}
}

func heartbeat(uuid string) {
	if _, exists := running[uuid]; exists {
		return
	}
	// TODO: not safe for concurrent access
	running[uuid] = struct{}{}
	defer delete(running, uuid)

	var (
		errorCount int
		err        error
		container  *Container
	)

	for _ = range time.Tick(time.Duration(beat) * time.Second) {
		if errorCount > 10 {
			// if we encountered more than 10 errors just quit
			log.Printf("Aborting heartbeat for %s after 10 errors\n", uuid)
			return
		}

		if container, err = dockerClient.fetchContainer(uuid, ""); err != nil {
			errorCount++
			log.Println(err)
			break
		}

		if !container.State.Running {
			if err := removeService(uuid); err != nil {
				log.Println(err)
			}
			return
		}

		// don't fill logs if we have a low beat
		// may need to do something better here
		if beat >= 30 {
			log.Printf("Updating ttl for %s\n", container.Name)
		}

		if err := skydns.Update(uuid, uint32(ttl)); err != nil {
			errorCount++
			log.Println(err)
			break
		}
	}
}

// restoreContainers loads all running containers and inserts
// them into skydns when skydock starts
func restoreContainers() error {
	req, err := http.NewRequest("GET", fmt.Sprintf("/containers/json"), nil)
	if err != nil {
		return err
	}

	resp, err := dockerClient.c.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		var (
			containers []*Container
			container  *Container
		)

		if err = json.NewDecoder(resp.Body).Decode(&containers); err != nil {
			return err
		}

		for _, cnt := range containers {
			uuid := truncate(cnt.Id)
			if container, err = dockerClient.fetchContainer(uuid, cnt.Image); err != nil {
				if err != errNotTagged {
					log.Printf("Failed to fetch %s for restore - %s\n", cnt.Id, err)
				}
				continue
			}

			if err := sendService(uuid, createService(container)); err != nil {
				log.Printf("Failed to send %s to skydns for restore - %s\n", uuid, err)
			}
		}
	}
	return nil
}

// <uuid>.<host>.<region>.<version>.<service>.<environment>.skydns.local
func createService(container *Container) *msg.Service {
	return &msg.Service{
		Name:        cleanImageImage(container.Image), // Service name
		Version:     removeSlash(container.Name),      // Instance of the service
		Host:        container.NetworkSettings.IpAddress,
		Environment: environment, // testing, prod, dev
		TTL:         uint32(ttl), // 60 seconds
		Port:        80,          // TODO: How to handle multiple ports
	}
}

// sendService sends the uuid and service data to skydns
func sendService(uuid string, service *msg.Service) error {
	log.Printf("Adding %s (%s)\n", uuid, service.Name)

	if err := skydns.Add(uuid, service); err != nil {
		return err
	}
	go heartbeat(uuid)

	return nil
}

func removeService(uuid string) error {
	log.Printf("Removing %s from skydns\n", uuid)
	return skydns.Delete(uuid)
}

func addService(uuid, image string) error {
	log.Printf("Adding %s for %s\n", uuid, image)
	container, err := dockerClient.fetchContainer(uuid, image)
	if err != nil {
		if err != errNotTagged {
			return err
		}
		return nil
	}

	if err := sendService(uuid, createService(container)); err != nil {
		return err
	}
	return nil
}

func main() {
	var err error
	if dockerClient, err = newClient(pathToSocket); err != nil {
		log.Fatal(err)
	}

	if skydns, err = client.NewClient(skydnsUrl, secret, domain, 53); err != nil {
		log.Fatal(err)
	}

	log.Println("Starting restore of running containers...")
	if err := restoreContainers(); err != nil {
		log.Fatal(err)
	}

	eventStream, err := dockerClient.getEventStream()
	if err != nil {
		log.Fatal(err)
	}
	defer eventStream.Close()

	log.Println("Starting run loop...")
	d := json.NewDecoder(eventStream)
	for {
		var event *Event
		if err := d.Decode(&event); err != nil {
			if err == io.EOF {
				log.Println("Stopping cleanly via EOF")
				break
			}
			log.Printf("Error decoding json %s\n", err)
		}
		uuid := truncate(event.ContainerId)

		switch event.Status {
		case "die", "stop", "kill":
			if err := removeService(uuid); err != nil {
				log.Printf("Error deleting %s - %s\n", uuid, err)
			}
		case "start", "restart":
			if err := addService(uuid, event.Image); err != nil {
				log.Printf("Error adding %s - %s\n", uuid, err)
			}
		}
	}
}
<commit_msg>Continue after decoding error<commit_after>/*
   Multihost
   Multiple ports
*/

package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"github.com/skynetservices/skydns/client"
	"github.com/skynetservices/skydns/msg"
	"io"
	"log"
	"net/http"
	"os"
	"time"
)

var (
	pathToSocket string
	domain       string
	environment  string
	skydnsUrl    string
	secret       string
	ttl          int
	beat         int

	skydns       *client.Client
	dockerClient *docker
	running      = make(map[string]struct{})
	errNotTagged = errors.New("image not tagged")
)

func init() {
	flag.StringVar(&pathToSocket, "s", "/var/run/docker.sock", "path to the docker unix socket")
	flag.StringVar(&skydnsUrl, "skydns", "", "url to the skydns url")
	flag.StringVar(&secret, "secret", "", "skydns secret")
	flag.StringVar(&domain, "domain", "", "same domain passed to skydns")
	flag.StringVar(&environment, "environment", "dev", "environment name where service is running")
	flag.IntVar(&ttl, "ttl", 60, "default ttl to use when registering a service")
	flag.IntVar(&beat, "beat", 0, "heartbeat interval")

	flag.Parse()

	if beat < 1 {
		beat = ttl - (ttl / 4)
	}

	if skydnsUrl == "" {
		skydnsUrl = "http://" + os.Getenv("SKYDNS_PORT_8080_TCP_ADDR") + ":8080"
	}

	if domain == "" {
		log.Fatal("Must specify your skydns domain")
	}
}

func heartbeat(uuid string) {
	if _, exists := running[uuid]; exists {
		return
	}
	// TODO: not safe for concurrent access
	running[uuid] = struct{}{}
	defer delete(running, uuid)

	var (
		errorCount int
		err        error
		container  *Container
	)

	for _ = range time.Tick(time.Duration(beat) * time.Second) {
		if errorCount > 10 {
			// if we encountered more than 10 errors just quit
			log.Printf("Aborting heartbeat for %s after 10 errors\n", uuid)
			return
		}

		if container, err = dockerClient.fetchContainer(uuid, ""); err != nil {
			errorCount++
			log.Println(err)
			break
		}

		if !container.State.Running {
			if err := removeService(uuid); err != nil {
				log.Println(err)
			}
			return
		}

		// don't fill logs if we have a low beat
		// may need to do something better here
		if beat >= 30 {
			log.Printf("Updating ttl for %s\n", container.Name)
		}

		if err := skydns.Update(uuid, uint32(ttl)); err != nil {
			errorCount++
			log.Println(err)
			break
		}
	}
}

// restoreContainers loads all running containers and inserts
// them into skydns when skydock starts
func restoreContainers() error {
	req, err := http.NewRequest("GET", fmt.Sprintf("/containers/json"), nil)
	if err != nil {
		return err
	}

	resp, err := dockerClient.c.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		var (
			containers []*Container
			container  *Container
		)

		if err = json.NewDecoder(resp.Body).Decode(&containers); err != nil {
			return err
		}

		for _, cnt := range containers {
			uuid := truncate(cnt.Id)
			if container, err = dockerClient.fetchContainer(uuid, cnt.Image); err != nil {
				if err != errNotTagged {
					log.Printf("Failed to fetch %s for restore - %s\n", cnt.Id, err)
				}
				continue
			}

			if err := sendService(uuid, createService(container)); err != nil {
				log.Printf("Failed to send %s to skydns for restore - %s\n", uuid, err)
			}
		}
	}
	return nil
}

// <uuid>.<host>.<region>.<version>.<service>.<environment>.skydns.local
func createService(container *Container) *msg.Service {
	return &msg.Service{
		Name:        cleanImageImage(container.Image), // Service name
		Version:     removeSlash(container.Name),      // Instance of the service
		Host:        container.NetworkSettings.IpAddress,
		Environment: environment, // testing, prod, dev
		TTL:         uint32(ttl), // 60 seconds
		Port:        80,          // TODO: How to handle multiple ports
	}
}

// sendService sends the uuid and service data to skydns
func sendService(uuid string, service *msg.Service) error {
	log.Printf("Adding %s (%s)\n", uuid, service.Name)

	if err := skydns.Add(uuid, service); err != nil {
		return err
	}
	go heartbeat(uuid)

	return nil
}

func removeService(uuid string) error {
	log.Printf("Removing %s from skydns\n", uuid)
	return skydns.Delete(uuid)
}

func addService(uuid, image string) error {
	log.Printf("Adding %s for %s\n", uuid, image)
	container, err := dockerClient.fetchContainer(uuid, image)
	if err != nil {
		if err != errNotTagged {
			return err
		}
		return nil
	}

	if err := sendService(uuid, createService(container)); err != nil {
		return err
	}
	return nil
}

func main() {
	var err error
	if dockerClient, err = newClient(pathToSocket); err != nil {
		log.Fatal(err)
	}

	if skydns, err = client.NewClient(skydnsUrl, secret, domain, 53); err != nil {
		log.Fatal(err)
	}

	log.Println("Starting restore of running containers...")
	if err := restoreContainers(); err != nil {
		log.Fatal(err)
	}

	eventStream, err := dockerClient.getEventStream()
	if err != nil {
		log.Fatal(err)
	}
	defer eventStream.Close()

	log.Println("Starting run loop...")
	d := json.NewDecoder(eventStream)
	for {
		var event *Event
		if err := d.Decode(&event); err != nil {
			if err == io.EOF {
				log.Println("Stopping cleanly via EOF")
				break
			}
			log.Printf("Error decoding json %s\n", err)
			continue
		}
		uuid := truncate(event.ContainerId)

		switch event.Status {
		case "die", "stop", "kill":
			if err := removeService(uuid); err != nil {
				log.Printf("Error deleting %s - %s\n", uuid, err)
			}
		case "start", "restart":
			if err := addService(uuid, event.Image); err != nil {
				log.Printf("Error adding %s - %s\n", uuid, err)
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/pressly/prefixer"

	"gopkg.in/yaml.v2"
)

type Command struct {
	Name   string `yaml:-`
	Desc   string `yaml:"desc"`
	Exec   string `yaml:"exec`
	Script string `yaml:"script"`
	//Env map[string]string `yaml:"env"`
}

// Config represents the configuration data that are
// loaded from the Supfile YAML file.
type Config struct {
	Hosts    map[string][]string `yaml:"hosts"`
	Env      map[string]string   `yaml:"env"`
	Commands map[string]Command  `yaml:"commands"`
	Targets  map[string][]string `yaml:"targets"`
}

func usage(conf *Config) {
	switch len(os.Args) {
	case 2:
		log.Println("Usage: sup <hosts> <target/command>\n")
		fallthrough
	case 3:
		log.Println("Available targets (from Supfile):")
		for target, _ := range conf.Targets {
			log.Printf("- %v\n", target)
		}
		log.Println("Available commands (from Supfile):")
		for cmd, _ := range conf.Commands {
			log.Printf("- %v\n", cmd)
		}
	case 1:
		log.Println("Usage: sup <hosts> <target/command>")
		log.Println("Available hosts (from Supfile):")
		for group, hosts := range conf.Hosts {
			log.Printf("- %v\n", group)
			for _, host := range hosts {
				log.Printf("   - %v\n", host)
			}
		}
	}
	os.Exit(1)
}

func main() {
	var (
		conf           Config
		commands       []Command
		longestHostLen int
	)

	data, _ := ioutil.ReadFile("./Supfile")
	if err := yaml.Unmarshal(data, &conf); err != nil {
		log.Fatal(err)
	}

	if len(os.Args) != 3 {
		usage(&conf)
	}

	hosts, ok := conf.Hosts[os.Args[1]]
	if !ok || len(hosts) == 0 {
		usage(&conf)
	}

	target, isTarget := conf.Targets[os.Args[2]]
	if isTarget {
		for _, cmd := range target {
			command, isCommand := conf.Commands[cmd]
			if !isCommand {
				log.Printf("Unknown command \"%v\" (from target \"%v\": %v)\n\n", cmd, os.Args[2], target)
				usage(&conf)
			}
			command.Name = cmd
			commands = append(commands, command)
		}
	} else {
		command, isCommand := conf.Commands[os.Args[2]]
		if !isCommand {
			// Not a target, nor command
			log.Printf("Unknown target/command \"%v\"\n\n", os.Args[2])
			usage(&conf)
		}
		command.Name = os.Args[2]
		commands = append(commands, command)
	}

	clients := make([]*SSHClient, len(hosts))
	for i, host := range hosts {
		c := &SSHClient{
			Env: map[string]string{"FOO": "sup"},
		}
		if err := c.Connect(host); err != nil {
			log.Fatal(err)
		}
		defer c.Close()

		if len(c.Host) > longestHostLen {
			longestHostLen = len(c.Host)
		}

		clients[i] = c
	}

	for _, cmd := range commands {
		if cmd.Exec != "" {
			log.Printf("Run command \"%v\": Exec \"%v\"", cmd.Name, cmd.Exec)
		} else if cmd.Script != "" {
			log.Printf("Run command \"%v\": Exec script \"%v\"", cmd.Name, cmd.Script)
			f, err := os.Open(cmd.Script)
			if err != nil {
				log.Fatal(err)
			}
			data, err = ioutil.ReadAll(f)
			if err != nil {
				log.Fatal(err)
			}
			cmd.Exec = string(data)
		} else {
			log.Fatalf("Run command \"%v\": Nothing to run", cmd.Name)
		}

		for _, c := range clients {
			padding := strings.Repeat(" ", longestHostLen-len(c.Host))
			c.Prefix = padding + c.Host + " | "
			c.Run(cmd)

			go func(c *SSHClient) {
				if _, err := io.Copy(os.Stdout, prefixer.New(c.RemoteStdout, c.Prefix)); err != nil {
					log.Printf("STDOUT(%v): %v", c.Host, err)
				}
			}(c)
			go func(c *SSHClient) {
				if _, err := io.Copy(os.Stderr, prefixer.New(c.RemoteStderr, c.Prefix)); err != nil {
					log.Printf("STERR(%v): %v", c.Host, err)
				}
			}(c)
		}

		for _, c := range clients {
			_ = c.Wait()
			// TODO: check for exit err:
			// err = session.Wait()
			// if err == nil {
			// 	t.Fatalf("expected command to fail but it didn't")
			// }
			// e, ok := err.(*ExitError)
			// if !ok {
			// 	t.Fatalf("expected *ExitError but got %T", err)
			// }
			// if e.ExitStatus() != 15 {
			// 	t.Fatalf("expected command to exit with 15 but got %v", e.ExitStatus())
			// }
		}
	}
}
<commit_msg>Handle remote command non-zero exit status<commit_after>package main

import (
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/pressly/prefixer"

	"golang.org/x/crypto/ssh"
	"gopkg.in/yaml.v2"
)

type Command struct {
	Name   string `yaml:-`
	Desc   string `yaml:"desc"`
	Exec   string `yaml:"exec`
	Script string `yaml:"script"`
	//Env map[string]string `yaml:"env"`
}

// Config represents the configuration data that are
// loaded from the Supfile YAML file.
type Config struct {
	Hosts    map[string][]string `yaml:"hosts"`
	Env      map[string]string   `yaml:"env"`
	Commands map[string]Command  `yaml:"commands"`
	Targets  map[string][]string `yaml:"targets"`
}

func usage(conf *Config) {
	switch len(os.Args) {
	case 2:
		log.Println("Usage: sup <hosts> <target/command>\n")
		fallthrough
	case 3:
		log.Println("Available targets (from Supfile):")
		for target, _ := range conf.Targets {
			log.Printf("- %v\n", target)
		}
		log.Println("Available commands (from Supfile):")
		for cmd, _ := range conf.Commands {
			log.Printf("- %v\n", cmd)
		}
	case 1:
		log.Println("Usage: sup <hosts> <target/command>")
		log.Println("Available hosts (from Supfile):")
		for group, hosts := range conf.Hosts {
			log.Printf("- %v\n", group)
			for _, host := range hosts {
				log.Printf("   - %v\n", host)
			}
		}
	}
	os.Exit(1)
}

func main() {
	var (
		conf           Config
		commands       []Command
		longestHostLen int
	)

	data, _ := ioutil.ReadFile("./Supfile")
	if err := yaml.Unmarshal(data, &conf); err != nil {
		log.Fatal(err)
	}

	if len(os.Args) != 3 {
		usage(&conf)
	}

	hosts, ok := conf.Hosts[os.Args[1]]
	if !ok || len(hosts) == 0 {
		usage(&conf)
	}

	target, isTarget := conf.Targets[os.Args[2]]
	if isTarget {
		for _, cmd := range target {
			command, isCommand := conf.Commands[cmd]
			if !isCommand {
				log.Printf("Unknown command \"%v\" (from target \"%v\": %v)\n\n", cmd, os.Args[2], target)
				usage(&conf)
			}
			command.Name = cmd
			commands = append(commands, command)
		}
	} else {
		command, isCommand := conf.Commands[os.Args[2]]
		if !isCommand {
			// Not a target, nor command
			log.Printf("Unknown target/command \"%v\"\n\n", os.Args[2])
			usage(&conf)
		}
		command.Name = os.Args[2]
		commands = append(commands, command)
	}

	clients := make([]*SSHClient, len(hosts))
	for i, host := range hosts {
		c := &SSHClient{
			Env: map[string]string{"FOO": "sup"},
		}
		if err := c.Connect(host); err != nil {
			log.Fatal(err)
		}
		defer c.Close()

		if len(c.Host) > longestHostLen {
			longestHostLen = len(c.Host)
		}

		clients[i] = c
	}

	for _, cmd := range commands {
		if cmd.Exec != "" {
			log.Printf("Run command \"%v\": Exec \"%v\"", cmd.Name, cmd.Exec)
		} else if cmd.Script != "" {
			log.Printf("Run command \"%v\": Exec script \"%v\"", cmd.Name, cmd.Script)
			f, err := os.Open(cmd.Script)
			if err != nil {
				log.Fatal(err)
			}
			data, err = ioutil.ReadAll(f)
			if err != nil {
				log.Fatal(err)
			}
			cmd.Exec = string(data)
		} else {
			log.Fatalf("Run command \"%v\": Nothing to run", cmd.Name)
		}

		for _, c := range clients {
			padding := strings.Repeat(" ", longestHostLen-len(c.Host))
			c.Prefix = padding + c.Host + " | "
			c.Run(cmd)

			go func(c *SSHClient) {
				if _, err := io.Copy(os.Stdout, prefixer.New(c.RemoteStdout, c.Prefix)); err != nil {
					log.Printf("%sSTDOUT error: %v", c.Prefix, c.Host, err)
				}
			}(c)
			go func(c *SSHClient) {
				if _, err := io.Copy(os.Stderr, prefixer.New(c.RemoteStderr, c.Prefix)); err != nil {
					log.Printf("%sSTDERR error: %v", c.Prefix, c.Host, err)
				}
			}(c)
		}

		for _, c := range clients {
			if err := c.Wait(); err != nil {
				//TODO: Handle the SSH ExitError in ssh.go
				e, ok := err.(*ssh.ExitError)
				if !ok {
					log.Fatalf("%sexpected *ExitError but got %T", c.Prefix, err)
				}
				if e.ExitStatus() != 15 {
					log.Fatalf("%sexit %v", c.Prefix, e.ExitStatus())
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
)

const Version = "5.0.0"

var options struct {
	http            string
	pinNumber       int
	statusPinNumber int
	sleepTimeout    int
	cert            string
	key             string
	version         bool
}

var SharedSecret = os.Getenv("GARAGE_SECRET")

func main() {
	if os.Args[1] == "update" {
		CheckForUpdates()
		os.Exit(0)
	}

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage:  %s [options]\n", os.Args[0])
		flag.PrintDefaults()
	}

	flag.IntVar(&options.pinNumber, "pin", 25, "GPIO pin of relay")
	flag.IntVar(&options.statusPinNumber, "status-pin", 10, "GPIO pin of reed switch")
	flag.IntVar(&options.sleepTimeout, "sleep", 100, "Time in milliseconds to keep switch closed")
	flag.StringVar(&options.http, "http", "", "HTTP listen address (e.g. 127.0.0.1:8225)")
	flag.StringVar(&options.cert, "cert", "", "SSL certificate path (e.g. /ssl/example.com.cert)")
	flag.StringVar(&options.key, "key", "", "SSL certificate key (e.g. /ssl/example.com.key)")
	flag.BoolVar(&options.version, "version", false, "print version and exit")
	flag.Parse()

	if options.version {
		fmt.Printf("garage-server v%v\n", Version)
		os.Exit(0)
	}

	if SharedSecret == "" {
		println("You did not set GARAGE_SECRET env var")
		os.Exit(1)
	}

	serveAddress := "127.0.0.1:8225"
	if options.http != "" {
		serveAddress = options.http
	}

	Relay := CreateRelayHandler(ToggleSwitch, apiLogHandler, options.pinNumber, options.sleepTimeout)
	Status := CreateDoorStatusHandler(CheckDoorStatus, apiLogHandler, options.statusPinNumber)
	AppVersion := CreateVersionHandler(apiLogHandler)

	http.HandleFunc("/", Relay)
	http.HandleFunc("/status", Status)
	http.HandleFunc("/version", AppVersion)

	fmt.Fprintln(os.Stderr, "=> Booting Garage Server ", Version)
	fmt.Fprintln(os.Stderr, "=> Run `garage-server -h` for more startup options")
	fmt.Fprintln(os.Stderr, "=> Ctrl-C to shutdown server")

	var err error
	if options.key != "" && options.cert != "" {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("* Listening on https://%s", serveAddress))
		err = http.ListenAndServeTLS(serveAddress, options.cert, options.key, nil)
	} else {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("* Listening on http://%s", serveAddress))
		err = http.ListenAndServe(serveAddress, nil)
	}

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
<commit_msg>Prevent crashes when no arguments are passed<commit_after>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
)

const Version = "5.0.0"

var options struct {
	http            string
	pinNumber       int
	statusPinNumber int
	sleepTimeout    int
	cert            string
	key             string
	version         bool
}

var SharedSecret = os.Getenv("GARAGE_SECRET")

func main() {
	if len(os.Args) > 1 && os.Args[1] == "update" {
		CheckForUpdates()
		os.Exit(0)
	}

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage:  %s [options]\n", os.Args[0])
		flag.PrintDefaults()
	}

	flag.IntVar(&options.pinNumber, "pin", 25, "GPIO pin of relay")
	flag.IntVar(&options.statusPinNumber, "status-pin", 10, "GPIO pin of reed switch")
	flag.IntVar(&options.sleepTimeout, "sleep", 100, "Time in milliseconds to keep switch closed")
	flag.StringVar(&options.http, "http", "", "HTTP listen address (e.g. 127.0.0.1:8225)")
	flag.StringVar(&options.cert, "cert", "", "SSL certificate path (e.g. /ssl/example.com.cert)")
	flag.StringVar(&options.key, "key", "", "SSL certificate key (e.g. /ssl/example.com.key)")
	flag.BoolVar(&options.version, "version", false, "print version and exit")
	flag.Parse()

	if options.version {
		fmt.Printf("garage-server v%v\n", Version)
		os.Exit(0)
	}

	if SharedSecret == "" {
		println("You did not set GARAGE_SECRET env var")
		os.Exit(1)
	}

	serveAddress := "127.0.0.1:8225"
	if options.http != "" {
		serveAddress = options.http
	}

	Relay := CreateRelayHandler(ToggleSwitch, apiLogHandler, options.pinNumber, options.sleepTimeout)
	Status := CreateDoorStatusHandler(CheckDoorStatus, apiLogHandler, options.statusPinNumber)
	AppVersion := CreateVersionHandler(apiLogHandler)

	http.HandleFunc("/", Relay)
	http.HandleFunc("/status", Status)
	http.HandleFunc("/version", AppVersion)

	fmt.Fprintln(os.Stderr, "=> Booting Garage Server ", Version)
	fmt.Fprintln(os.Stderr, "=> Run `garage-server -h` for more startup options")
	fmt.Fprintln(os.Stderr, "=> Ctrl-C to shutdown server")

	var err error
	if options.key != "" && options.cert != "" {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("* Listening on https://%s", serveAddress))
		err = http.ListenAndServeTLS(serveAddress, options.cert, options.key, nil)
	} else {
		fmt.Fprintln(os.Stderr, fmt.Sprintf("* Listening on http://%s", serveAddress))
		err = http.ListenAndServe(serveAddress, nil)
	}

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"

	"github.com/codegangsta/negroni"
	"github.com/gorilla/mux"
)

// Returns the "Not found" response.
func notFound(w http.ResponseWriter, req *http.Request) {
	http.Error(w, "Error 404: Not Found", http.StatusNotFound)
}

func main() {
	var configFile string
	const defaultConfigFile = "obs2vagrant.json"
	flag.StringVar(&configFile, "c", defaultConfigFile, "configuration file")
	flag.Parse()

	err := readConfig(configFile)
	if err != nil {
		log.Fatalf("Error while parsing configuration file: %s", err)
	}

	n := negroni.New(negroni.NewRecovery(), negroni.NewLogger())
	r := mux.NewRouter()
	r.NotFoundHandler = http.HandlerFunc(notFound)
	r.HandleFunc("/{server}/{project}/{repo}/{box}.json", boxHandler).
		Methods("GET")
	n.UseHandler(r)

	listenOn := fmt.Sprintf("%v:%v", config.Address, config.Port)
	n.Run(listenOn)
}
<commit_msg>Added package documentation<commit_after>// This is a simple web application that makes possible to use Open Build
// Service as a simple Vagrant image catalog.
package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"

	"github.com/codegangsta/negroni"
	"github.com/gorilla/mux"
)

// Returns the "Not found" response.
func notFound(w http.ResponseWriter, req *http.Request) {
	http.Error(w, "Error 404: Not Found", http.StatusNotFound)
}

func main() {
	var configFile string
	const defaultConfigFile = "obs2vagrant.json"
	flag.StringVar(&configFile, "c", defaultConfigFile, "configuration file")
	flag.Parse()

	err := readConfig(configFile)
	if err != nil {
		log.Fatalf("Error while parsing configuration file: %s", err)
	}

	n := negroni.New(negroni.NewRecovery(), negroni.NewLogger())
	r := mux.NewRouter()
	r.NotFoundHandler = http.HandlerFunc(notFound)
	r.HandleFunc("/{server}/{project}/{repo}/{box}.json", boxHandler).
		Methods("GET")
	n.UseHandler(r)

	listenOn := fmt.Sprintf("%v:%v", config.Address, config.Port)
	n.Run(listenOn)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
)

func exitWithUsage() {
	fmt.Fprintln(
		os.Stderr,
		`$ dot-github [flags] [{dir}]

  A CLI tool to generate GitHub files such as CONTRIBUTING.md,
  ISSUE_TEMPLATE.md and PULLfrom template file.

  GitHub Blog: https://github.com/blog/2111-issue-and-pull-request-templates
  More usage:  https://github.com/rhysd/dot-github#readme

Flags:`)
	flag.PrintDefaults()
	os.Exit(0)
}

func exitWithVersion() {
	fmt.Println("0.0.0")
	os.Exit(0)
}

type Flags struct {
	Help    bool
	Version bool
}

func parseCmdArgs() *Flags {
	var (
		help    bool
		version bool
	)

	flag.BoolVar(&help, "help", false, "Show this help")
	flag.BoolVar(&version, "version", false, "Show version")
	flag.Parse()

	return &Flags{
		help,
		version,
	}
}

func main() {
	flags := parseCmdArgs()
	if flags.Help {
		exitWithUsage()
	} else if flags.Version {
		exitWithVersion()
	}
}
<commit_msg>get user and name of current repository<commit_after>package main

import (
	"flag"
	"fmt"
	"net/url"
	"os"
	"os/exec"
	"strings"
)

func exitWithUsage() {
	fmt.Fprintln(
		os.Stderr,
		`$ dot-github [flags] [{dir}]

  A CLI tool to generate GitHub files such as CONTRIBUTING.md,
  ISSUE_TEMPLATE.md and PULLfrom template file.

  GitHub Blog: https://github.com/blog/2111-issue-and-pull-request-templates
  More usage:  https://github.com/rhysd/dot-github#readme

Flags:`)
	flag.PrintDefaults()
	os.Exit(0)
}

func exitWithVersion() {
	fmt.Println("0.0.0")
	os.Exit(0)
}

type Flags struct {
	Help    bool
	Version bool
}

func parseCmdArgs() *Flags {
	var (
		help    bool
		version bool
	)

	flag.BoolVar(&help, "help", false, "Show this help")
	flag.BoolVar(&version, "version", false, "Show version")
	flag.Parse()

	return &Flags{
		help,
		version,
	}
}

func gitCmdPath() string {
	specified := os.Getenv("DOT_GITHUB_GIT_CMD")
	if len(specified) != 0 {
		return specified
	}

	path, err := exec.LookPath("git")
	if err != nil {
		panic("'git' command not found.  Consider to specify $DOT_GITHUB_GIT_CMD manually.")
	}
	return path
}

func originURL() *url.URL {
	cmd := exec.Command(gitCmdPath(), "ls-remote", "--get-url", "origin")
	out, err := cmd.Output()
	if err != nil {
		panic("'git ls-remote --git-url origin' failed: " + err.Error())
	}
	url, err := url.Parse(strings.TrimSpace(string(out[:])))
	if err != nil {
		panic(err.Error())
	}

	return url
}

type Repository struct {
	user string
	name string
}

func NewRepositoryFromHttpsURL(u *url.URL) *Repository {
	// TODO Check valid GitHub or GHE url
	if u.Path == "" {
		panic("Invalid https URL for GitHub: " + u.String())
	}
	split := strings.SplitN(u.Path[1:], "/", 2)
	return &Repository{
		split[0],
		strings.TrimSuffix(split[1], ".git"),
	}
}

func NewRepositoryFromGitURL(u *url.URL) *Repository {
	if !strings.HasPrefix(u.Path, "git@") || !strings.Contains(u.Path, ":") {
		panic("Invalid git@ URL for GitHub: " + u.String())
	}
	// TODO Check valid GitHub or GHE url
	split := strings.SplitN(
		strings.SplitN(u.Path, ":", 2)[1],
		"/",
		2,
	)
	return &Repository{
		split[0],
		strings.TrimSuffix(split[1], ".git"),
	}
}

func NewRepositoryFromURL(u *url.URL) *Repository {
	if u.Scheme == "https" {
		return NewRepositoryFromHttpsURL(u)
	} else if u.Scheme == "" {
		return NewRepositoryFromGitURL(u)
	}
	return nil
}

func main() {
	flags := parseCmdArgs()
	if flags.Help {
		exitWithUsage()
	} else if flags.Version {
		exitWithVersion()
	}

	// TODO
	fmt.Println(NewRepositoryFromURL(originURL()))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"time"

	"github.com/freeusd/solebtc/Godeps/_workspace/src/github.com/gin-gonic/gin"
	"github.com/freeusd/solebtc/controllers/v1"
	"github.com/freeusd/solebtc/errors"
	"github.com/freeusd/solebtc/middlewares"
	"github.com/freeusd/solebtc/models"
	"github.com/freeusd/solebtc/services/cache"
	"github.com/freeusd/solebtc/services/cache/memory"
	"github.com/freeusd/solebtc/services/mail"
	"github.com/freeusd/solebtc/services/mail/mandrill"
	"github.com/freeusd/solebtc/services/storage"
	"github.com/freeusd/solebtc/services/storage/mysql"
	"github.com/freeusd/solebtc/utils"
)

var (
	logWriter   io.Writer = os.Stdout
	panicWriter io.Writer = os.Stderr
	mailer      mail.Mailer
	store       storage.Storage
	memoryCache cache.Cache
	err         error
)

func init() {
	initConfig()
	initMailer()
	initStorage()
	initCache()
}

func main() {
	gin.SetMode(ginEnvMode())
	router := gin.New()

	// middlewares
	recovery := gin.RecoveryWithWriter(panicWriter)
	logger := middlewares.LoggerWithWriter(logWriter)
	cors := middlewares.CORS()
	errorWriter := middlewares.ErrorWriter()
	authRequired := middlewares.AuthRequired(store.GetAuthToken, config.AuthToken.Lifetime)

	// globally use middlewares
	router.Use(recovery).Use(logger).Use(cors).Use(errorWriter)

	// version 1 api endpoints
	v1Endpoints := router.Group("/v1")

	// user endpoints
	v1UserEndpoints := v1Endpoints.Group("/users")
	v1UserEndpoints.POST("", v1.Signup(store.CreateUser, store.GetUserByID))
	v1UserEndpoints.PUT("/:id/status", v1.VerifyEmail(store.GetSessionByToken, store.GetUserByID, store.UpdateUser))

	// auth token endpoints
	v1AuthTokenEndpoints := v1Endpoints.Group("/auth_tokens")
	v1AuthTokenEndpoints.POST("", v1.Login(store.GetUserByEmail, store.CreateAuthToken))
	v1AuthTokenEndpoints.Use(authRequired).DELETE("", v1.Logout(store.DeleteAuthToken))

	// session endpoints
	v1SessionEndpoints := v1Endpoints.Group("/sessions")
	v1SessionEndpoints.Use(authRequired).POST("", v1.RequestVerifyEmail(store.GetUserByID, store.UpsertSession, mailer.SendEmail))

	// income endpoints
	v1IncomeEndpoints := v1Endpoints.Group("/incomes")
	v1IncomeEndpoints.Use(authRequired).POST("/rewards", v1.GetReward(store.GetUserByID, memoryCache.GetLatestTotalReward, memoryCache.GetLatestConfig, memoryCache.GetRewardRatesByType, memoryCache.GetBitcoinPrice, createRewardIncome()))

	fmt.Fprintf(logWriter, "SoleBTC is running on %s\n", config.HTTP.Port)
	if err := router.Run(config.HTTP.Port); err != nil {
		fmt.Fprintf(panicWriter, "HTTP listen and serve error: %v\n", err)
		os.Exit(1)
	}
}

func createRewardIncome() func(userID, refererID, reward, rewardReferer int64, now time.Time) *errors.Error {
	return func(userID, refererID, reward, rewardReferer int64, now time.Time) *errors.Error {
		if err := store.CreateRewardIncome(userID, refererID, reward, rewardReferer, now); err != nil {
			return err
		}

		totalReward := reward
		if refererID > 0 {
			totalReward += rewardReferer
		}
		memoryCache.IncrementTotalReward(now, totalReward)

		return nil
	}
}

func initMailer() {
	// mailer
	mailer = mandrill.New(config.Mandrill.Key, config.Mandrill.FromEmail, config.Mandrill.FromName)
}

func initStorage() {
	// storage service
	store, err = mysql.New(config.DB.DataSourceName)
	if err != nil {
		log.Fatalf("Cannot create mysql storage: %v", err)
	}
}

func initCache() {
	memoryCache = memory.New(utils.BitcoinPrice, logWriter, time.Minute*5)

	// init config in cache
	config, err := store.GetLatestConfig()
	if err != nil {
		log.Fatalf("Cannot get latest config: %v", err)
	}
	memoryCache.SetLatestConfig(config)

	// init rates in cache
	lessRates, err := store.GetRewardRatesByType(models.RewardRateTypeLess)
	if err != nil {
		log.Fatalf("Cannot get reward rates with type less: %v", err)
	}
	moreRates, err := store.GetRewardRatesByType(models.RewardRateTypeMore)
	if err != nil {
		log.Fatalf("Cannot get reward rates with type more: %v", err)
	}
	memoryCache.SetRewardRates(models.RewardRateTypeLess, lessRates)
	memoryCache.SetRewardRates(models.RewardRateTypeMore, moreRates)
}
<commit_msg>Refactor getReward endpoint<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"time"

	"github.com/freeusd/solebtc/Godeps/_workspace/src/github.com/gin-gonic/gin"
	"github.com/freeusd/solebtc/controllers/v1"
	"github.com/freeusd/solebtc/errors"
	"github.com/freeusd/solebtc/middlewares"
	"github.com/freeusd/solebtc/models"
	"github.com/freeusd/solebtc/services/cache"
	"github.com/freeusd/solebtc/services/cache/memory"
	"github.com/freeusd/solebtc/services/mail"
	"github.com/freeusd/solebtc/services/mail/mandrill"
	"github.com/freeusd/solebtc/services/storage"
	"github.com/freeusd/solebtc/services/storage/mysql"
	"github.com/freeusd/solebtc/utils"
)

var (
	logWriter   io.Writer = os.Stdout
	panicWriter io.Writer = os.Stderr
	mailer      mail.Mailer
	store       storage.Storage
	memoryCache cache.Cache
	err         error
)

func init() {
	initConfig()
	initMailer()
	initStorage()
	initCache()
}

func main() {
	gin.SetMode(ginEnvMode())
	router := gin.New()

	// middlewares
	recovery := gin.RecoveryWithWriter(panicWriter)
	logger := middlewares.LoggerWithWriter(logWriter)
	cors := middlewares.CORS()
	errorWriter := middlewares.ErrorWriter()
	authRequired := middlewares.AuthRequired(store.GetAuthToken, config.AuthToken.Lifetime)

	// globally use middlewares
	router.Use(recovery).Use(logger).Use(cors).Use(errorWriter)

	// version 1 api endpoints
	v1Endpoints := router.Group("/v1")

	// user endpoints
	v1UserEndpoints := v1Endpoints.Group("/users")
	v1UserEndpoints.POST("", v1.Signup(store.CreateUser, store.GetUserByID))
	v1UserEndpoints.PUT("/:id/status", v1.VerifyEmail(store.GetSessionByToken, store.GetUserByID, store.UpdateUser))

	// auth token endpoints
	v1AuthTokenEndpoints := v1Endpoints.Group("/auth_tokens")
	v1AuthTokenEndpoints.POST("", v1.Login(store.GetUserByEmail, store.CreateAuthToken))
	v1AuthTokenEndpoints.Use(authRequired).DELETE("", v1.Logout(store.DeleteAuthToken))

	// session endpoints
	v1SessionEndpoints := v1Endpoints.Group("/sessions")
	v1SessionEndpoints.Use(authRequired).POST("", v1.RequestVerifyEmail(store.GetUserByID, store.UpsertSession, mailer.SendEmail))

	// income endpoints
	v1IncomeEndpoints := v1Endpoints.Group("/incomes")
	v1IncomeEndpoints.Use(authRequired).POST("/rewards", v1.GetReward(store.GetUserByID, memoryCache.GetLatestTotalReward, memoryCache.GetLatestConfig, memoryCache.GetRewardRatesByType, memoryCache.GetBitcoinPrice, createRewardIncome))

	fmt.Fprintf(logWriter, "SoleBTC is running on %s\n", config.HTTP.Port)
	if err := router.Run(config.HTTP.Port); err != nil {
		fmt.Fprintf(panicWriter, "HTTP listen and serve error: %v\n", err)
		os.Exit(1)
	}
}

func createRewardIncome(userID, refererID, reward, rewardReferer int64, now time.Time) *errors.Error {
	if err := store.CreateRewardIncome(userID, refererID, reward, rewardReferer, now); err != nil {
		return err
	}

	totalReward := reward
	if refererID > 0 {
		totalReward += rewardReferer
	}
	memoryCache.IncrementTotalReward(now, totalReward)

	return nil
}

func initMailer() {
	// mailer
	mailer = mandrill.New(config.Mandrill.Key, config.Mandrill.FromEmail, config.Mandrill.FromName)
}

func initStorage() {
	// storage service
	store, err = mysql.New(config.DB.DataSourceName)
	if err != nil {
		log.Fatalf("Cannot create mysql storage: %v", err)
	}
}

func initCache() {
	memoryCache = memory.New(utils.BitcoinPrice, logWriter, time.Minute*5)

	// init config in cache
	config, err := store.GetLatestConfig()
	if err != nil {
		log.Fatalf("Cannot get latest config: %v", err)
	}
	memoryCache.SetLatestConfig(config)

	// init rates in cache
	lessRates, err := store.GetRewardRatesByType(models.RewardRateTypeLess)
	if err != nil {
		log.Fatalf("Cannot get reward rates with type less: %v", err)
	}
	moreRates, err := store.GetRewardRatesByType(models.RewardRateTypeMore)
	if err != nil {
		log.Fatalf("Cannot get reward rates with type more: %v", err)
	}
	memoryCache.SetRewardRates(models.RewardRateTypeLess, lessRates)
	memoryCache.SetRewardRates(models.RewardRateTypeMore, moreRates)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/BurntSushi/toml"
	"github.com/bitly/go-nsq"
	"github.com/braintree/manners"
	"github.com/garyburd/redigo/redis"
	"github.com/gorilla/mux"
)

var (
	configPath = flag.String("config-file", "./config.toml", "path to qmd config file")
	config     Config

	producer *nsq.Producer
	consumer *nsq.Consumer
	redisDB  *redis.Pool
)

func main() {
	flag.Parse()
	fmt.Printf("Using config file from: %s\n", *configPath)

	var err error
	_, err = toml.DecodeFile(*configPath, &config)
	if err != nil {
		log.Println(err)
		return
	}

	fmt.Println("Setting up producer")
	producer = nsq.NewProducer(config.QueueAddr, nsq.NewConfig())

	fmt.Println("Creating Redis connection pool")
	redisDB = newPool(config.RedisAddr)

	// Setup and start worker.
	fmt.Println("Creating worker")
	worker, err := NewWorker(config)
	if err != nil {
		log.Println(err)
		return
	}
	go worker.Run()

	// Register endpoints
	rtr := mux.NewRouter()
	rtr.HandleFunc("/", ServiceRoot).Methods("GET")
	rtr.HandleFunc("/", ServiceRoot).Methods("POST") // callback echo
	rtr.HandleFunc("/scripts", GetAllScripts).Methods("GET")
	rtr.HandleFunc("/scripts", ReloadScripts).Methods("PUT")
	rtr.HandleFunc("/scripts/{name}", RunScript).Methods("POST")
	rtr.HandleFunc("/scripts/{name}/logs", GetAllLogs).Methods("GET")
	rtr.HandleFunc("/scripts/{name}/logs/{id}", GetLog).Methods("GET")

	// Create and start server
	server := manners.NewServer()
	fmt.Printf("Listening on %s\n", config.ListenOnAddr)
	go server.ListenAndServe(config.ListenOnAddr, rtr)

	termChan := make(chan os.Signal, 1)
	signal.Notify(termChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

	// Gracefully shutdown all the connections
	for {
		select {
		case <-termChan:
			fmt.Println("Shutting down producer")
			producer.Stop()

			fmt.Println("Shutting down worker consumers")
			worker.Stop()

			fmt.Println("Closing Redis connections")
			redisDB.Close()

			fmt.Println("Shutting down server")
			server.Shutdown <- true

			fmt.Println("Goodbye!\n")
			return
		}
	}
}
<commit_msg>Fixed issue with trailing slash not routing.<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/BurntSushi/toml"
	"github.com/bitly/go-nsq"
	"github.com/braintree/manners"
	"github.com/garyburd/redigo/redis"
	"github.com/gorilla/mux"
)

var (
	configPath = flag.String("config-file", "./config.toml", "path to qmd config file")
	config     Config

	producer *nsq.Producer
	consumer *nsq.Consumer
	redisDB  *redis.Pool
)

func main() {
	flag.Parse()
	fmt.Printf("Using config file from: %s\n", *configPath)

	var err error
	_, err = toml.DecodeFile(*configPath, &config)
	if err != nil {
		log.Println(err)
		return
	}

	fmt.Println("Setting up producer")
	producer = nsq.NewProducer(config.QueueAddr, nsq.NewConfig())

	fmt.Println("Creating Redis connection pool")
	redisDB = newPool(config.RedisAddr)

	// Setup and start worker.
	fmt.Println("Creating worker")
	worker, err := NewWorker(config)
	if err != nil {
		log.Println(err)
		return
	}
	go worker.Run()

	// Register endpoints
	rtr := mux.NewRouter().StrictSlash(true)
	rtr.HandleFunc("/", ServiceRoot).Methods("GET")
	rtr.HandleFunc("/", ServiceRoot).Methods("POST") // callback echo
	rtr.HandleFunc("/scripts", GetAllScripts).Methods("GET")
	rtr.HandleFunc("/scripts", ReloadScripts).Methods("PUT")
	rtr.HandleFunc("/scripts/{name}", RunScript).Methods("POST")
	rtr.HandleFunc("/scripts/{name}/logs", GetAllLogs).Methods("GET")
	rtr.HandleFunc("/scripts/{name}/logs/{id}", GetLog).Methods("GET")

	// Create and start server
	server := manners.NewServer()
	fmt.Printf("Listening on %s\n", config.ListenOnAddr)
	go server.ListenAndServe(config.ListenOnAddr, rtr)

	termChan := make(chan os.Signal, 1)
	signal.Notify(termChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

	// Gracefully shutdown all the connections
	for {
		select {
		case <-termChan:
			fmt.Println("Shutting down producer")
			producer.Stop()

			fmt.Println("Shutting down worker consumers")
			worker.Stop()

			fmt.Println("Closing Redis connections")
			redisDB.Close()

			fmt.Println("Shutting down server")
			server.Shutdown <- true

			fmt.Println("Goodbye!\n")
			return
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"
	"os"

	"github.com/declantraynor/go-events-service/interfaces/datastore"
	"github.com/declantraynor/go-events-service/interfaces/web"
	"github.com/declantraynor/go-events-service/usecases"
)

func main() {

	redisAddr := os.Getenv("REDIS_PORT_6379_TCP_ADDR")
	redisPort := os.Getenv("REDIS_PORT_6379_TCP_PORT")
	eventStore, err := datastore.NewRedisEventStore(redisAddr, redisPort)
	if err != nil {
		log.Fatal(err.Error())
	}

	eventInteractor := usecases.EventInteractor{Store: &eventStore}
	webservice := web.WebService{EventInteractor: &eventInteractor}

	http.HandleFunc("/events", webservice.Create)
	http.HandleFunc("/events/count", webservice.Count)
	http.ListenAndServe(":5000", nil)
}
<commit_msg>refactor main for easier testing<commit_after>package main

import (
	"log"
	"net/http"
	"os"

	"github.com/declantraynor/go-events-service/interfaces/datastore"
	"github.com/declantraynor/go-events-service/interfaces/web"
	"github.com/declantraynor/go-events-service/usecases"
)

func run(serve func(webservice *web.WebService)) {
	redisAddr := os.Getenv("REDIS_PORT_6379_TCP_ADDR")
	redisPort := os.Getenv("REDIS_PORT_6379_TCP_PORT")
	eventStore, err := datastore.NewRedisEventStore(redisAddr, redisPort)
	if err != nil {
		log.Fatal(err.Error())
	}

	eventInteractor := usecases.EventInteractor{Store: &eventStore}
	webservice := web.WebService{EventInteractor: &eventInteractor}

	serve(&webservice)
}

func serve(webservice *web.WebService) {
	http.HandleFunc("/events", webservice.Create)
	http.HandleFunc("/events/count", webservice.Count)
	http.ListenAndServe(":5000", nil)
}

func main() {
	run(serve)
}
<|endoftext|>


<commit_before>// main.go
package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello World!")
	shs := allShips()
	for val, i := range *shs {
		fmt.Println(val, i) //test of all things shipy. Will change soon
	}
}
<commit_msg>First attempt at drawing things. Error<commit_after>// main.go
package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello World!")
	shs := allShips()
	for val, i := range *shs {
		fmt.Println(val, i) //test of all things shipy. Will change soon
	}

	rule, _ := getRules()
	leftField := newField(rule.fLen, rule.fWid)
	rightField := newField(rule.fLen, rule.fWid)
	rfc := make(chan Field)
	rfc <- *rightField
	lfc := make(chan Field)
	lfc <- *leftField

	drawfield(lfc, rfc)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"html/template"
	"net"
	"net/http"
	"net/http/fcgi"
	"os"
	"os/exec"
	"strings"
	"math/rand"
)

var (
	headertpl = `
<!DOCTYPE html>

<title>alpha status</title>

`
	footertpl = `

`

	statustpl = `

{{.Hostname}}

{{.Quote}}

{{ range .Outputs }}

# {{.Cmd}}
{{ range .Output }} {{ . }}
{{ end }}

{{ end }}

#^D

`

	cmds = []string{
		"cat /etc/motd",
		`who | awk '{ printf "%-10s    %s  %s %2s %s\n", $1, $2, $3, $4, $5 }'`,
		"uptime",
		"downtimes",
		"df -h",
	}

	quotes = []string{
		"i need something stronger.",
		"for more enjoyment and greater efficiency, consumption is being standardized. we are sorry ...",
		"everything will be all right. you are in my hands. i am here to protect you. you have nowhere to go. you have nowhere to go.",
		"you have nowhere to go. i am here to protect you.",
		"how shall the new environment be programmed? it all happened so slowly that most men failed to realize that anything had happened at all.",
		"take four red capsules. in 10 minutes take two more. help is on the way.",
		"control center 626 holds no responsibility... for error in mindlock.",
	}
)

type CommandOutput struct {
	Cmd    string
	Output []string
}

func RunSh(cmd string) CommandOutput {
	c := exec.Command("/bin/sh", "-c", cmd)

	output, err := c.CombinedOutput()
	if err != nil {
		return CommandOutput{cmd, []string{err.Error()}}
	}

	buf := bytes.NewBuffer(output)

	sc := bufio.NewScanner(buf)

	var out []string
	for sc.Scan() {
		out = append(out, strings.TrimSpace(sc.Text()))
	}

	return CommandOutput{cmd, out}
}

type Status struct {
	Hostname string
	Quote string
	Outputs []CommandOutput
}

func status(w http.ResponseWriter, r *http.Request) {
	var err error
	var statdat Status
	var outputs []CommandOutput
	var hdr, stat, footer *template.Template

	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered in status", r)
		}
	}()

	wr := bufio.NewWriter(w)

	statdat.Hostname = r.Host
	if statdat.Hostname == "" {
		statdat.Hostname, _ = os.Hostname()
	}

	statdat.Quote = quotes[rand.Intn(len(quotes))]

	if hdr, err = template.New("header").Parse(headertpl); err != nil {
		goto error
	} else if err = hdr.Execute(wr, nil); err != nil {
		goto error
	}

	for _, c := range cmds {
		outputs = append(outputs, RunSh(c))
	}

	statdat.Outputs = outputs

	if stat, err = template.New("status").Parse(statustpl); err != nil {
		goto error
	} else if err = stat.Execute(wr, statdat); err != nil {
		goto error
	}

	if footer, err = template.New("footer").Parse(footertpl); err != nil {
		goto error
	} else if err = footer.Execute(wr, nil); err != nil {
		goto error
	}

error:
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %s\n", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	wr.Flush()

}

func main() {
	listener, _ := net.Listen("tcp", "127.0.0.1:9001")
	http.HandleFunc("/", status)
	fcgi.Serve(listener, nil)
}
<commit_msg>add hostname in title<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"html/template"
	"net"
	"net/http"
	"net/http/fcgi"
	"os"
	"os/exec"
	"strings"
	"math/rand"
)

var (
	headertpl = `
<!DOCTYPE html>

<title>{{ .Hostname }}</title>

`
	footertpl = `

`

	statustpl = `

{{.Hostname}}

{{.Quote}}

{{ range .Outputs }}

# {{.Cmd}}
{{ range .Output }} {{ . }}
{{ end }}

{{ end }}

#^D

`

	cmds = []string{
		"cat /etc/motd",
		`who | awk '{ printf "%-10s    %s  %s %2s %s\n", $1, $2, $3, $4, $5 }'`,
		"uptime",
		"downtimes",
		"df -h",
	}

	quotes = []string{
		"i need something stronger.",
		"for more enjoyment and greater efficiency, consumption is being standardized. we are sorry ...",
		"everything will be all right. you are in my hands. i am here to protect you. you have nowhere to go. you have nowhere to go.",
		"you have nowhere to go. i am here to protect you.",
		"how shall the new environment be programmed? it all happened so slowly that most men failed to realize that anything had happened at all.",
		"take four red capsules. in 10 minutes take two more. help is on the way.",
		"control center 626 holds no responsibility... for error in mindlock.",
	}
)

type CommandOutput struct {
	Cmd    string
	Output []string
}

func RunSh(cmd string) CommandOutput {
	c := exec.Command("/bin/sh", "-c", cmd)

	output, err := c.CombinedOutput()
	if err != nil {
		return CommandOutput{cmd, []string{err.Error()}}
	}

	buf := bytes.NewBuffer(output)

	sc := bufio.NewScanner(buf)

	var out []string
	for sc.Scan() {
		out = append(out, strings.TrimSpace(sc.Text()))
	}

	return CommandOutput{cmd, out}
}

type Header struct {
	Hostname string
}

type Status struct {
	Hostname string
	Quote string
	Outputs []CommandOutput
}

func status(w http.ResponseWriter, r *http.Request) {
	var err error
	var headdat Header
	var statdat Status
	var outputs []CommandOutput
	var hdr, stat, footer *template.Template

	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered in status", r)
		}
	}()

	wr := bufio.NewWriter(w)

	statdat.Hostname = r.Host
	if statdat.Hostname == "" {
		statdat.Hostname, _ = os.Hostname()
	}

	headdat.Hostname = statdat.Hostname

	statdat.Quote = quotes[rand.Intn(len(quotes))]

	if hdr, err = template.New("header").Parse(headertpl); err != nil {
		goto error
	} else if err = hdr.Execute(wr, headdat); err != nil {
		goto error
	}

	for _, c := range cmds {
		outputs = append(outputs, RunSh(c))
	}

	statdat.Outputs = outputs

	if stat, err = template.New("status").Parse(statustpl); err != nil {
		goto error
	} else if err = stat.Execute(wr, statdat); err != nil {
		goto error
	}

	if footer, err = template.New("footer").Parse(footertpl); err != nil {
		goto error
	} else if err = footer.Execute(wr, nil); err != nil {
		goto error
	}

error:
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %s\n", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	wr.Flush()

}

func main() {
	listener, _ := net.Listen("tcp", "127.0.0.1:9001")
	http.HandleFunc("/", status)
	fcgi.Serve(listener, nil)
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	TITLE  string `json:"title"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

type Page struct {
	Title    string
	Body     []byte
	Raw      string
	Home     string
	Download string
	Clone    string
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste string) string {
	hasher := sha1.New()

	hasher.Write([]byte(paste))
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw string, lang string, title string) []string {
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	sha := hash(raw)
	query, err := db.Query("select id, hash, data, delkey from pastebin")
	for query.Next() {
		var id, hash, paste, delkey string
		err := query.Scan(&id, &hash, &paste, &delkey)
		check(err)
		if hash == sha {
			url := ADDRESS + "/p/" + id
			return []string{id, hash, url, paste, delkey}
		}
	}
	id := generateName()
	var url string
	if lang == "" {
		url = ADDRESS + "/p/" + id
	} else {
		url = ADDRESS + "/p/" + id + "/" + lang
	}
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(raw)

	stmt, err := db.Prepare("INSERT INTO pastebin(id, title, hash, data, delkey) values(?,?,?,?,?)")
	check(err)
	if title == "" {
		_, err = stmt.Exec(id, id, sha, paste, delKey)
		check(err)
	} else {
		_, err = stmt.Exec(id, html.EscapeString(title), sha, paste, delKey)
		check(err)
	}
	db.Close()
	return []string{id, title, sha, url, paste, delKey}
}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	delkey := vars["delKey"]

	db, err := sql.Open("mysql", DATABASE)
	check(err)

	stmt, err := db.Prepare("delete from pastebin where delkey=?")
	check(err)

	res, err := stmt.Exec(html.EscapeString(delkey))
	check(err)

	_, err = res.RowsAffected()
	if err == sql.ErrNoRows {
		io.WriteString(w, "Error invalid paste")
	} else {
		io.WriteString(w, paste+" deleted")
	}
	db.Close()

}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		paste := r.FormValue("p")
		lang := r.FormValue("lang")
		title := r.FormValue("title")
		if paste == "" {
			http.Error(w, "Empty paste", 500)
			return
		}
		values := save(paste, lang, title)
		b := &Response{
			ID:     values[0],
			TITLE:  values[1],
			HASH:   values[2],
			URL:    values[3],
			SIZE:   len(values[4]),
			DELKEY: values[5],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		case "html":
			w.Header().Set("Content-Type", "text/html")
			io.WriteString(w, "
URL: "+b.URL+"
")
			io.WriteString(w, "
Delete Key: "+b.DELKEY+"
")

		case "redirect":
			http.Redirect(w, r, b.URL, 301)

		default:
			w.Header().Set("Content-Type", "plain/text")
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func highlight(s string, lang string) (string, error) {

	highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,noclasses=True,", "utf-8")
	if err != nil {
		return "", err
	}
	return highlight, nil

}

func getPaste(paste string, lang string) (string, string) {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("mysql", DATABASE)
	var title, s string
	err = db.QueryRow("select title, data from pastebin where id=?", param1).Scan(&title, &s)
	db.Close()
	check(err)

	if err == sql.ErrNoRows {
		return "Error invalid paste", ""
	} else {
		if lang == "" {
			return html.UnescapeString(s), html.UnescapeString(title)
		} else {
			high, err := highlight(s, lang)
			check(err)
			return high, html.UnescapeString(title)

		}
	}

}

var templates = template.Must(template.ParseFiles("assets/paste.html", "assets/index.html", "assets/clone.html"))
var syntax, _ = ioutil.ReadFile("assets/syntax.html")

func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s, title := getPaste(paste, lang)
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	if lang == "" {
		p := &Page{
			Title:    title,
			Body:     []byte(s),
			Raw:      link,
			Home:     ADDRESS,
			Download: download,
			Clone:    clone,
		}
		err := templates.ExecuteTemplate(w, "paste.html", p)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}

	} else {
		fmt.Fprintf(w, string(syntax), paste, paste, s, ADDRESS, download, link, clone)

	}
}

func cloneHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, title := getPaste(paste, "")
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	p := &Page{
		Title:    title,
		Body:     []byte(s),
		Raw:      link,
		Home:     ADDRESS,
		Download: download,
		Clone:    clone,
	}
	err := templates.ExecuteTemplate(w, "clone.html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	w.Header().Set("Content-Disposition", "attachment; filename="+paste)
	w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
	io.WriteString(w, s)

}
func rawHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/raw/{pasteId}", rawHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", pasteHandler)
	router.HandleFunc("/clone/{pasteId}", cloneHandler)
	router.HandleFunc("/download/{pasteId}", downloadHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("assets/"))))
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<commit_msg>Fix up array error<commit_after>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	TITLE  string `json:"title"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

type Page struct {
	Title    string
	Body     []byte
	Raw      string
	Home     string
	Download string
	Clone    string
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste string) string {
	hasher := sha1.New()

	hasher.Write([]byte(paste))
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw string, lang string, title string) []string {
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	sha := hash(raw)
	query, err := db.Query("select id, title hash, data, delkey from pastebin")
	for query.Next() {
		var id, title, hash, paste, delkey string
		err := query.Scan(&id, &title, &hash, &paste, &delkey)
		check(err)
		if hash == sha {
			url := ADDRESS + "/p/" + id
			if title == "" {
				return []string{id, title, hash, url, paste, delkey}
			}
		}
	}
	id := generateName()
	var url string
	if lang == "" {
		url = ADDRESS + "/p/" + id
	} else {
		url = ADDRESS + "/p/" + id + "/" + lang
	}
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(raw)

	stmt, err := db.Prepare("INSERT INTO pastebin(id, title, hash, data, delkey) values(?,?,?,?,?)")
	check(err)
	if title == "" {
		_, err = stmt.Exec(id, id, sha, paste, delKey)
		check(err)
	} else {
		_, err = stmt.Exec(id, html.EscapeString(title), sha, paste, delKey)
		check(err)
	}
	db.Close()
	return []string{id, title, sha, url, paste, delKey}
}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	delkey := vars["delKey"]

	db, err := sql.Open("mysql", DATABASE)
	check(err)

	stmt, err := db.Prepare("delete from pastebin where delkey=?")
	check(err)

	res, err := stmt.Exec(html.EscapeString(delkey))
	check(err)

	_, err = res.RowsAffected()
	if err == sql.ErrNoRows {
		io.WriteString(w, "Error invalid paste")
	} else {
		io.WriteString(w, paste+" deleted")
	}
	db.Close()

}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		paste := r.FormValue("p")
		lang := r.FormValue("lang")
		title := r.FormValue("title")
		if paste == "" {
			http.Error(w, "Empty paste", 500)
			return
		}
		values := save(paste, lang, title)
		b := &Response{
			ID:     values[0],
			TITLE:  values[1],
			HASH:   values[2],
			URL:    values[3],
			SIZE:   len(values[4]),
			DELKEY: values[5],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		case "html":
			w.Header().Set("Content-Type", "text/html")
			io.WriteString(w, "
URL: "+b.URL+"
")
			io.WriteString(w, "
Delete Key: "+b.DELKEY+"
")

		case "redirect":
			http.Redirect(w, r, b.URL, 301)

		default:
			w.Header().Set("Content-Type", "plain/text")
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func highlight(s string, lang string) (string, error) {

	highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,noclasses=True,", "utf-8")
	if err != nil {
		return "", err
	}
	return highlight, nil

}

func getPaste(paste string, lang string) (string, string) {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("mysql", DATABASE)
	var title, s string
	err = db.QueryRow("select title, data from pastebin where id=?", param1).Scan(&title, &s)
	db.Close()
	check(err)

	if err == sql.ErrNoRows {
		return "Error invalid paste", ""
	} else {
		if lang == "" {
			return html.UnescapeString(s), html.UnescapeString(title)
		} else {
			high, err := highlight(s, lang)
			check(err)
			return high, html.UnescapeString(title)

		}
	}

}

var templates = template.Must(template.ParseFiles("assets/paste.html", "assets/index.html", "assets/clone.html"))
var syntax, _ = ioutil.ReadFile("assets/syntax.html")

func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s, title := getPaste(paste, lang)
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	if lang == "" {
		p := &Page{
			Title:    title,
			Body:     []byte(s),
			Raw:      link,
			Home:     ADDRESS,
			Download: download,
			Clone:    clone,
		}
		err := templates.ExecuteTemplate(w, "paste.html", p)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}

	} else {
		fmt.Fprintf(w, string(syntax), paste, paste, s, ADDRESS, download, link, clone)

	}
}

func cloneHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, title := getPaste(paste, "")
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	p := &Page{
		Title:    title,
		Body:     []byte(s),
		Raw:      link,
		Home:     ADDRESS,
		Download: download,
		Clone:    clone,
	}
	err := templates.ExecuteTemplate(w, "clone.html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	w.Header().Set("Content-Disposition", "attachment; filename="+paste)
	w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
	io.WriteString(w, s)

}
func rawHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/raw/{pasteId}", rawHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", pasteHandler)
	router.HandleFunc("/clone/{pasteId}", cloneHandler)
	router.HandleFunc("/download/{pasteId}", downloadHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("assets/"))))
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/cheggaaa/pb"
	"github.com/codegangsta/cli"
	"os"
	"time"
)

var r rutil

func main() {
	app := cli.NewApp()
	app.Usage = "redis multitool utility"
	app.Version = "0.1.0"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "host, s",
			Value: "127.0.0.1",
			Usage: "redis host",
		},
		cli.StringFlag{
			Name:  "auth, a",
			Usage: "authentication password",
		},
		cli.IntFlag{
			Name:  "port, p",
			Value: 6379,
			Usage: "redis port",
		},
	}

	app.Before = func(c *cli.Context) error {
		r.Host = c.GlobalString("host")
		r.Port = c.GlobalInt("port")
		r.Auth = c.GlobalString("auth")
		return nil
	}

	app.Commands = []cli.Command{
		{
			Name:  "dump",
			Usage: "dump redis database to a file",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "keys, k",
					Value: "*",
					Usage: "keys pattern (passed to redis 'keys' command)",
				},
				cli.BoolFlag{
					Name:  "auto, a",
					Usage: "make up a file name for the dump - redisYYYYMMDDHHMMSS.rdmp",
				},
				cli.StringFlag{
					Name:  "match, m",
					Usage: "regexp filter for key names",
				},
				cli.BoolFlag{
					Name:  "invert, v",
					Usage: "invert match regexp",
				},
			},
			Action: func(c *cli.Context) {
				args := c.Args()
				auto := c.Bool("auto")
				regex := c.String("match")
				inv := c.Bool("invert")

				var fileName string

				if len(args) == 0 && auto == false {
					checkErr("provide a file name for the dump or use rutil dump --auto to make one up")
				} else if len(args) > 0 && auto == true {
					checkErr("you can't provide a name and use --auto at the same time")
				} else if len(args) == 1 && auto == false {
					fileName = args[0]
				} else if auto == true {
					fileName = fmt.Sprintf("redis%s.rdmp", time.Now().Format("20060102150405"))
				} else if len(args) > 1 {
					checkErr("to many file names")
				} else if fileName == "" {
					checkErr("brain damage. panic")
				}

				keys, keys_c := r.getKeys(c.String("keys"), regex, inv)

				file, err := os.Create(fileName)
				checkErr(err)

				bar := pb.StartNew(keys_c)

				totalBytes := r.writeHeader(file, keys_c)

				for _, k := range keys {
					bar.Increment()
					b := r.writeDump(file, r.dumpKey(k))
					totalBytes = totalBytes + b
				}
				bar.FinishPrint(fmt.Sprintf("file: %s, keys: %d, bytes: %d", fileName, keys_c, totalBytes))
			},
		},
		{
			Name:  "restore",
			Usage: "restore redis database from file",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "dry-run, r",
					Usage: "pretend to restore",
				},
				cli.BoolFlag{
					Name:  "flushdb, f",
					Usage: "flush the database before restoring",
				},
				cli.BoolFlag{
					Name:  "delete, d",
					Usage: "delete key before restoring",
				},
				cli.BoolFlag{
					Name:  "ignore, g",
					Usage: "ignore BUSYKEY restore errors",
				},
			},
			Action: func(c *cli.Context) {
				args := c.Args()
				dry := c.Bool("dry-run")
				flush := c.Bool("flushdb")
				del := c.Bool("delete")
				ignor := c.Bool("ignore")

				if flush && del {
					checkErr("flush or delete?")
				}

				if len(args) == 0 {
					checkErr("no file name provided")
				} else if len(args) > 1 {
					checkErr("to many file names")
				}

				file, err := os.Open(args[0])
				checkErr(err)
				hd := r.readHeader(file)

				if dry == false && flush == true {
					res := r.Client().Cmd("FLUSHDB")
					checkErr(res.Err)
				}

				bar := pb.StartNew(int(hd.Keys))
				keys_c := 0
				for i := uint64(0); i < hd.Keys; i++ {
					bar.Increment()
					d := r.readDump(file)
					if dry == false {
						if dry == false {
							keys_c = keys_c + r.restoreKey(d, del, ignor)
						}
					}
				}
				bar.FinishPrint(fmt.Sprintf("file: %s, keys: %d", args[0], keys_c))
			},
		},
		{
			Name:    "delete",
			Aliases: []string{"del"},
			Usage:   "delete keys matching the pattern provided by --keys",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "keys, k",
					Usage: "keys pattern (passed to redis 'keys' command)",
				},
				cli.BoolFlag{
					Name:  "yes",
					Usage: "really delete keys, default is pretend to delete",
				},
				cli.StringFlag{
					Name:  "match, m",
					Usage: "regexp filter for key names",
				},
				cli.BoolFlag{
					Name:  "invert, v",
					Usage: "invert match regexp",
				},
			},
			Action: func(c *cli.Context) {
				yes := c.Bool("yes")
				pat := c.String("keys")
				regex := c.String("match")
				inv := c.Bool("invert")
				if pat == "" {
					checkErr("missing --keys pattern")
				}

				keys, _ := r.getKeys(pat, regex, inv)

				for i, k := range keys {
					fmt.Printf("%3d: %s\n", i+1, k)
					if yes == true {
						res := r.Client().Cmd("DEL", k)
						checkErr(res.Err)
					}
				}
			},
		},
		{
			Name:    "print",
			Aliases: []string{"pp"},
			Usage:   "print keys matching the pattern provided by --keys",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "keys, k",
					Usage: "keys pattern (passed to redis 'keys' command)",
				},
				cli.StringFlag{
					Name:  "match, m",
					Usage: "regexp filter for key names",
				},
				cli.BoolFlag{
					Name:  "invert, v",
					Usage: "invert match regexp",
				},
				cli.StringSliceFlag{
					Name:  "field, f",
					Usage: "hash fields to print (default all)",
				},
				cli.BoolFlag{
					Name:  "json, j",
					Usage: "attempt to parse and pretty print strings as json",
				},
			},
			Action: func(c *cli.Context) {
				pat := c.String("keys")
				regex := c.String("match")
				inv := c.Bool("invert")

				if pat == "" {
					checkErr("missing --keys pattern")
				}

				keys, _ := r.getKeys(pat, regex, inv)

				for _, k := range keys {
					r.printKey(k, c.StringSlice("field"), c.Bool("json"))
				}
			},
		},
	}

	app.Run(os.Args)
}
<commit_msg>fix typo<commit_after>package main

import (
	"fmt"
	"github.com/cheggaaa/pb"
	"github.com/codegangsta/cli"
	"os"
	"time"
)

var r rutil

func main() {
	app := cli.NewApp()
	app.Usage = "redis multitool utility"
	app.Version = "0.1.0"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "host, s",
			Value: "127.0.0.1",
			Usage: "redis host",
		},
		cli.StringFlag{
			Name:  "auth, a",
			Usage: "authentication password",
		},
		cli.IntFlag{
			Name:  "port, p",
			Value: 6379,
			Usage: "redis port",
		},
	}

	app.Before = func(c *cli.Context) error {
		r.Host = c.GlobalString("host")
		r.Port = c.GlobalInt("port")
		r.Auth = c.GlobalString("auth")
		return nil
	}

	app.Commands = []cli.Command{
		{
			Name:  "dump",
			Usage: "dump redis database to a file",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "keys, k",
					Value: "*",
					Usage: "keys pattern (passed to redis 'keys' command)",
				},
				cli.BoolFlag{
					Name:  "auto, a",
					Usage: "make up a file name for the dump - redisYYYYMMDDHHMMSS.rdmp",
				},
				cli.StringFlag{
					Name:  "match, m",
					Usage: "regexp filter for key names",
				},
				cli.BoolFlag{
					Name:  "invert, v",
					Usage: "invert match regexp",
				},
			},
			Action: func(c *cli.Context) {
				args := c.Args()
				auto := c.Bool("auto")
				regex := c.String("match")
				inv := c.Bool("invert")

				var fileName string

				if len(args) == 0 && auto == false {
					checkErr("provide a file name for the dump or use rutil dump --auto to make one up")
				} else if len(args) > 0 && auto == true {
					checkErr("you can't provide a name and use --auto at the same time")
				} else if len(args) == 1 && auto == false {
					fileName = args[0]
				} else if auto == true {
					fileName = fmt.Sprintf("redis%s.rdmp", time.Now().Format("20060102150405"))
				} else if len(args) > 1 {
					checkErr("to many file names")
				} else if fileName == "" {
					checkErr("brain damage. panic")
				}

				keys, keys_c := r.getKeys(c.String("keys"), regex, inv)

				file, err := os.Create(fileName)
				checkErr(err)

				bar := pb.StartNew(keys_c)

				totalBytes := r.writeHeader(file, keys_c)

				for _, k := range keys {
					bar.Increment()
					b := r.writeDump(file, r.dumpKey(k))
					totalBytes = totalBytes + b
				}
				bar.FinishPrint(fmt.Sprintf("file: %s, keys: %d, bytes: %d", fileName, keys_c, totalBytes))
			},
		},
		{
			Name:  "restore",
			Usage: "restore redis database from a file",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "dry-run, r",
					Usage: "pretend to restore",
				},
				cli.BoolFlag{
					Name:  "flushdb, f",
					Usage: "flush the database before restoring",
				},
				cli.BoolFlag{
					Name:  "delete, d",
					Usage: "delete key before restoring",
				},
				cli.BoolFlag{
					Name:  "ignore, g",
					Usage: "ignore BUSYKEY restore errors",
				},
			},
			Action: func(c *cli.Context) {
				args := c.Args()
				dry := c.Bool("dry-run")
				flush := c.Bool("flushdb")
				del := c.Bool("delete")
				ignor := c.Bool("ignore")

				if flush && del {
					checkErr("flush or delete?")
				}

				if len(args) == 0 {
					checkErr("no file name provided")
				} else if len(args) > 1 {
					checkErr("to many file names")
				}

				file, err := os.Open(args[0])
				checkErr(err)
				hd := r.readHeader(file)

				if dry == false && flush == true {
					res := r.Client().Cmd("FLUSHDB")
					checkErr(res.Err)
				}

				bar := pb.StartNew(int(hd.Keys))
				keys_c := 0
				for i := uint64(0); i < hd.Keys; i++ {
					bar.Increment()
					d := r.readDump(file)
					if dry == false {
						if dry == false {
							keys_c = keys_c + r.restoreKey(d, del, ignor)
						}
					}
				}
				bar.FinishPrint(fmt.Sprintf("file: %s, keys: %d", args[0], keys_c))
			},
		},
		{
			Name:    "delete",
			Aliases: []string{"del"},
			Usage:   "delete keys matching the pattern provided by --keys",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "keys, k",
					Usage: "keys pattern (passed to redis 'keys' command)",
				},
				cli.BoolFlag{
					Name:  "yes",
					Usage: "really delete keys, default is pretend to delete",
				},
				cli.StringFlag{
					Name:  "match, m",
					Usage: "regexp filter for key names",
				},
				cli.BoolFlag{
					Name:  "invert, v",
					Usage: "invert match regexp",
				},
			},
			Action: func(c *cli.Context) {
				yes := c.Bool("yes")
				pat := c.String("keys")
				regex := c.String("match")
				inv := c.Bool("invert")
				if pat == "" {
					checkErr("missing --keys pattern")
				}

				keys, _ := r.getKeys(pat, regex, inv)

				for i, k := range keys {
					fmt.Printf("%3d: %s\n", i+1, k)
					if yes == true {
						res := r.Client().Cmd("DEL", k)
						checkErr(res.Err)
					}
				}
			},
		},
		{
			Name:    "print",
			Aliases: []string{"pp"},
			Usage:   "print keys matching the pattern provided by --keys",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "keys, k",
					Usage: "keys pattern (passed to redis 'keys' command)",
				},
				cli.StringFlag{
					Name:  "match, m",
					Usage: "regexp filter for key names",
				},
				cli.BoolFlag{
					Name:  "invert, v",
					Usage: "invert match regexp",
				},
				cli.StringSliceFlag{
					Name:  "field, f",
					Usage: "hash fields to print (default all)",
				},
				cli.BoolFlag{
					Name:  "json, j",
					Usage: "attempt to parse and pretty print strings as json",
				},
			},
			Action: func(c *cli.Context) {
				pat := c.String("keys")
				regex := c.String("match")
				inv := c.Bool("invert")

				if pat == "" {
					checkErr("missing --keys pattern")
				}

				keys, _ := r.getKeys(pat, regex, inv)

				for _, k := range keys {
					r.printKey(k, c.StringSlice("field"), c.Bool("json"))
				}
			},
		},
	}

	app.Run(os.Args)
}
<|endoftext|>