<commit_before>package main

import (
	"github.com/MarvinMenzerath/UpAndRunning2/lib"
	"github.com/MarvinMenzerath/UpAndRunning2/routes"
	"github.com/MarvinMenzerath/UpAndRunning2/routes/APIv1"
	"github.com/MarvinMenzerath/UpAndRunning2/routes/APIv2"
	"github.com/franela/goreq"
	"github.com/julienschmidt/httprouter"
	"github.com/op/go-logging"
	"net/http"
	"runtime"
	"strconv"
	"time"
)

const VERSION = "2.2.0"

var goVersion = runtime.Version()
var goArch = runtime.GOOS + "_" + runtime.GOARCH

// UpAndRunning2 Main - The application's entrance-point
func main() {
	// Logger
	lib.SetupLogger()

	// Welcome
	logging.MustGetLogger("").Info("Welcome to UpAndRunning2 v" + VERSION + " [" + goVersion + "@" + goArch + "]!")

	// Config
	lib.ReadConfigurationFromFile("config/local.json")
	lib.SetStaticConfiguration(lib.StaticConfiguration{VERSION, goVersion, goArch})

	// Database
	lib.OpenDatabase(lib.GetConfiguration().Database)

	// Config (again)
	lib.ReadConfigurationFromDatabase(lib.GetDatabase())

	// Admin-User
	admin := lib.Admin{}
	admin.Init()

	// Session-Management
	lib.InitSessionManagement()

	// Additional Libraries
	goreq.SetConnectTimeout(5 * time.Second)
	lib.InitHttpStatusCodeMap()
	go lib.RunTelegramBot()

	// Start Checking and Serving
	checkAllSites()
	startCheckTimer()
	startCleaningTimer()
	serveRequests()

	lib.GetDatabase().Close()
}

// Create all routes and start the HTTP-server
func serveRequests() {
	router := httprouter.New()

	// Default API-message
	router.GET("/api", routes.ApiIndex)

	// API
	setupApi1(router)
	setupApi2(router)

	// Web-Frontend
	if lib.GetConfiguration().Application.UseWebFrontend {
		setupWebFrontend(router)
	} else {
		router.GET("/", routes.NoWebFrontendIndex)
	}

	// 404 Handler
	router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "Error 404: Not Found", 404)
	})

	logging.MustGetLogger("").Debug("Listening on " + lib.GetConfiguration().Address + ":" + strconv.Itoa(lib.GetConfiguration().Port) + "...")
	logging.MustGetLogger("").Fatal(http.ListenAndServe(lib.GetConfiguration().Address+":"+strconv.Itoa(lib.GetConfiguration().Port), router))
}

// Setup all routes for API v1
func setupApi1(router *httprouter.Router) {
	router.GET("/api/v1/*all", APIv1.ApiIndexVersion)
	router.POST("/api/v1/*all", APIv1.ApiIndexVersion)
	router.PUT("/api/v1/*all", APIv1.ApiIndexVersion)
	router.DELETE("/api/v1/*all", APIv1.ApiIndexVersion)
}

// Setup all routes for API v2
func setupApi2(router *httprouter.Router) {
	router.GET("/api/v2", APIv2.ApiIndexVersion)

	// Public Statistics
	router.GET("/api/v2/websites", APIv2.ApiWebsites)
	router.GET("/api/v2/websites/:url/status", APIv2.ApiWebsitesStatus)
	router.GET("/api/v2/websites/:url/results", APIv2.ApiWebsitesResults)

	// Authentication
	router.POST("/api/v2/auth/login", APIv2.ApiAuthLogin)
	router.GET("/api/v2/auth/logout", APIv2.ApiAuthLogout)

	// Settings
	router.PUT("/api/v2/settings/password", APIv2.ApiSettingsPassword)
	router.PUT("/api/v2/settings/interval", APIv2.ApiSettingsInterval)

	// Website Management
	router.POST("/api/v2/websites/:url", APIv2.ApiWebsitesAdd)
	router.PUT("/api/v2/websites/:url", APIv2.ApiWebsitesEdit)
	router.DELETE("/api/v2/websites/:url", APIv2.ApiWebsitesDelete)
	router.PUT("/api/v2/websites/:url/enabled", APIv2.ApiWebsitesEnabled)
	router.PUT("/api/v2/websites/:url/visibility", APIv2.ApiWebsitesVisibility)
	router.GET("/api/v2/websites/:url/notifications", APIv2.ApiWebsitesGetNotifications)
	router.PUT("/api/v2/websites/:url/notifications", APIv2.ApiWebsitePutNotifications)
	router.GET("/api/v2/websites/:url/check", APIv2.ApiWebsiteCheck)
}

// Setup all routes for Web-Frontend
func setupWebFrontend(router *httprouter.Router) {
	// Index
	router.GET("/", routes.ViewIndex)
	router.GET("/status/:url", routes.ViewIndex)
	router.GET("/results/:url", routes.ViewIndex)

	// Admin
	router.GET("/admin", routes.ViewAdmin)
	router.GET("/admin/login", routes.ViewLogin)

	// Static Files
	router.ServeFiles("/public/*filepath", http.Dir("public"))
}

// Creates a timer to regularly check all Websites
func startCheckTimer() {
	timer := time.NewTimer(time.Second * time.Duration(lib.GetConfiguration().Dynamic.Interval))
	go func() {
		<-timer.C
		checkAllSites()
		startCheckTimer()
	}()
}

// Creates a timer to remove old check-results from the Database
func startCleaningTimer() {
	timer := time.NewTimer(time.Hour * 24)
	go func() {
		<-timer.C
		lib.CleanDatabase()
		startCleaningTimer()
	}()
}

// Checks all enabled Websites
func checkAllSites() {
	// Check for internet-connection
	if !lib.GetConfiguration().Application.RunCheckIfOffline {
		res, err := goreq.Request{Uri: "https://google.com", Method: "HEAD", UserAgent: "UpAndRunning2 (https://github.com/MarvinMenzerath/UpAndRunning2)", MaxRedirects: 1, Timeout: 5 * time.Second}.Do()
		if err != nil {
			logging.MustGetLogger("").Warning("Did not check Websites because of missing internet-connection: ", err)
			return
		} else {
			if res.StatusCode != 200 {
				logging.MustGetLogger("").Warning("Did not check Websites because of missing internet-connection.")
				res.Body.Close()
				return
			}
		}
	}

	// Query the Database
	db := lib.GetDatabase()
	rows, err := db.Query("SELECT id, protocol, url, checkMethod FROM websites WHERE enabled = 1;")
	if err != nil {
		logging.MustGetLogger("").Error("Unable to fetch Websites: ", err)
		return
	}
	defer rows.Close()

	// Check every Website
	count := 0
	for rows.Next() {
		var website lib.Website
		err = rows.Scan(&website.Id, &website.Protocol, &website.Url, &website.CheckMethod)
		if err != nil {
			logging.MustGetLogger("").Error("Unable to read Website-Row: ", err)
			return
		}
		go website.RunCheck(false)
		count++
		time.Sleep(time.Millisecond * 200)
	}

	// Check for Errors
	err = rows.Err()
	if err != nil {
		logging.MustGetLogger("").Error("Unable to read Website-Rows: ", err)
		return
	}

	logging.MustGetLogger("").Info("Checked " + strconv.Itoa(count) + " active Websites.")
}
<commit_msg>Bump to v2.2.1<commit_after>package main

import (
	"github.com/MarvinMenzerath/UpAndRunning2/lib"
	"github.com/MarvinMenzerath/UpAndRunning2/routes"
	"github.com/MarvinMenzerath/UpAndRunning2/routes/APIv1"
	"github.com/MarvinMenzerath/UpAndRunning2/routes/APIv2"
	"github.com/franela/goreq"
	"github.com/julienschmidt/httprouter"
	"github.com/op/go-logging"
	"net/http"
	"runtime"
	"strconv"
	"time"
)

const VERSION = "2.2.1"

var goVersion = runtime.Version()
var goArch = runtime.GOOS + "_" + runtime.GOARCH

// UpAndRunning2 Main - The application's entrance-point
func main() {
	// Logger
	lib.SetupLogger()

	// Welcome
	logging.MustGetLogger("").Info("Welcome to UpAndRunning2 v" + VERSION + " [" + goVersion + "@" + goArch + "]!")

	// Config
	lib.ReadConfigurationFromFile("config/local.json")
	lib.SetStaticConfiguration(lib.StaticConfiguration{VERSION, goVersion, goArch})

	// Database
	lib.OpenDatabase(lib.GetConfiguration().Database)

	// Config (again)
	lib.ReadConfigurationFromDatabase(lib.GetDatabase())

	// Admin-User
	admin := lib.Admin{}
	admin.Init()

	// Session-Management
	lib.InitSessionManagement()

	// Additional Libraries
	goreq.SetConnectTimeout(5 * time.Second)
	lib.InitHttpStatusCodeMap()
	go lib.RunTelegramBot()

	// Start Checking and Serving
	checkAllSites()
	startCheckTimer()
	startCleaningTimer()
	serveRequests()

	lib.GetDatabase().Close()
}

// Create all routes and start the HTTP-server
func serveRequests() {
	router := httprouter.New()

	// Default API-message
	router.GET("/api", routes.ApiIndex)

	// API
	setupApi1(router)
	setupApi2(router)

	// Web-Frontend
	if lib.GetConfiguration().Application.UseWebFrontend {
		setupWebFrontend(router)
	} else {
		router.GET("/", routes.NoWebFrontendIndex)
	}

	// 404 Handler
	router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "Error 404: Not Found", 404)
	})

	logging.MustGetLogger("").Debug("Listening on " + lib.GetConfiguration().Address + ":" + strconv.Itoa(lib.GetConfiguration().Port) + "...")
	logging.MustGetLogger("").Fatal(http.ListenAndServe(lib.GetConfiguration().Address+":"+strconv.Itoa(lib.GetConfiguration().Port), router))
}

// Setup all routes for API v1
func setupApi1(router *httprouter.Router) {
	router.GET("/api/v1/*all", APIv1.ApiIndexVersion)
	router.POST("/api/v1/*all", APIv1.ApiIndexVersion)
	router.PUT("/api/v1/*all", APIv1.ApiIndexVersion)
	router.DELETE("/api/v1/*all", APIv1.ApiIndexVersion)
}

// Setup all routes for API v2
func setupApi2(router *httprouter.Router) {
	router.GET("/api/v2", APIv2.ApiIndexVersion)

	// Public Statistics
	router.GET("/api/v2/websites", APIv2.ApiWebsites)
	router.GET("/api/v2/websites/:url/status", APIv2.ApiWebsitesStatus)
	router.GET("/api/v2/websites/:url/results", APIv2.ApiWebsitesResults)

	// Authentication
	router.POST("/api/v2/auth/login", APIv2.ApiAuthLogin)
	router.GET("/api/v2/auth/logout", APIv2.ApiAuthLogout)

	// Settings
	router.PUT("/api/v2/settings/password", APIv2.ApiSettingsPassword)
	router.PUT("/api/v2/settings/interval", APIv2.ApiSettingsInterval)

	// Website Management
	router.POST("/api/v2/websites/:url", APIv2.ApiWebsitesAdd)
	router.PUT("/api/v2/websites/:url", APIv2.ApiWebsitesEdit)
	router.DELETE("/api/v2/websites/:url", APIv2.ApiWebsitesDelete)
	router.PUT("/api/v2/websites/:url/enabled", APIv2.ApiWebsitesEnabled)
	router.PUT("/api/v2/websites/:url/visibility", APIv2.ApiWebsitesVisibility)
	router.GET("/api/v2/websites/:url/notifications", APIv2.ApiWebsitesGetNotifications)
	router.PUT("/api/v2/websites/:url/notifications", APIv2.ApiWebsitePutNotifications)
	router.GET("/api/v2/websites/:url/check", APIv2.ApiWebsiteCheck)
}

// Setup all routes for Web-Frontend
func setupWebFrontend(router *httprouter.Router) {
	// Index
	router.GET("/", routes.ViewIndex)
	router.GET("/status/:url", routes.ViewIndex)
	router.GET("/results/:url", routes.ViewIndex)

	// Admin
	router.GET("/admin", routes.ViewAdmin)
	router.GET("/admin/login", routes.ViewLogin)

	// Static Files
	router.ServeFiles("/public/*filepath", http.Dir("public"))
}

// Creates a timer to regularly check all Websites
func startCheckTimer() {
	timer := time.NewTimer(time.Second * time.Duration(lib.GetConfiguration().Dynamic.Interval))
	go func() {
		<-timer.C
		checkAllSites()
		startCheckTimer()
	}()
}

// Creates a timer to remove old check-results from the Database
func startCleaningTimer() {
	timer := time.NewTimer(time.Hour * 24)
	go func() {
		<-timer.C
		lib.CleanDatabase()
		startCleaningTimer()
	}()
}

// Checks all enabled Websites
func checkAllSites() {
	// Check for internet-connection
	if !lib.GetConfiguration().Application.RunCheckIfOffline {
		res, err := goreq.Request{Uri: "https://google.com", Method: "HEAD", UserAgent: "UpAndRunning2 (https://github.com/MarvinMenzerath/UpAndRunning2)", MaxRedirects: 1, Timeout: 5 * time.Second}.Do()
		if err != nil {
			logging.MustGetLogger("").Warning("Did not check Websites because of missing internet-connection: ", err)
			return
		} else {
			if res.StatusCode != 200 {
				logging.MustGetLogger("").Warning("Did not check Websites because of missing internet-connection.")
				res.Body.Close()
				return
			}
		}
	}

	// Query the Database
	db := lib.GetDatabase()
	rows, err := db.Query("SELECT id, protocol, url, checkMethod FROM websites WHERE enabled = 1;")
	if err != nil {
		logging.MustGetLogger("").Error("Unable to fetch Websites: ", err)
		return
	}
	defer rows.Close()

	// Check every Website
	count := 0
	for rows.Next() {
		var website lib.Website
		err = rows.Scan(&website.Id, &website.Protocol, &website.Url, &website.CheckMethod)
		if err != nil {
			logging.MustGetLogger("").Error("Unable to read Website-Row: ", err)
			return
		}
		go website.RunCheck(false)
		count++
		time.Sleep(time.Millisecond * 200)
	}

	// Check for Errors
	err = rows.Err()
	if err != nil {
		logging.MustGetLogger("").Error("Unable to read Website-Rows: ", err)
		return
	}

	logging.MustGetLogger("").Info("Checked " + strconv.Itoa(count) + " active Websites.")
}
<|endoftext|>


<commit_before>package main

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"

	"github.com/blakesmith/ar"
)

type semaphore chan int

type Conf struct {
	ListenPort   string   `json:"listenPort"`
	RootRepoPath string   `json:"rootRepoPath"`
	SupportArch  []string `json:"supportedArch"`
}

var sem = make(semaphore, 1)
var configFile = flag.String("c", "conf.json", "config file location")
var config = &Conf{}

func main() {
	flag.Parse()
	file, err := ioutil.ReadFile(*configFile)
	if err != nil {
		log.Panic("unable to read config file, exiting...")
	}
	config = &Conf{}
	if err := json.Unmarshal(file, &config); err != nil {
		log.Panic("unable to marshal config file, exiting...")
	}

	http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(config.RootRepoPath))))
	http.HandleFunc("/upload", uploadHandler)
	http.ListenAndServe(":"+config.ListenPort, nil)
}

func inspectPackage(filename string) string {
	f, err := os.Open(filename)
	if err != nil {
		log.Printf("error opening package file %s: %s\n", filename, err)
		return ""
	}
	defer f.Close()

	arReader := ar.NewReader(f)
	var controlBuf bytes.Buffer

	for {
		header, err := arReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Println("error in inspectPackage loop: ", err)
			return ""
		}

		if header.Name == "control.tar.gz" {
			io.Copy(&controlBuf, arReader)
			return inspectPackageControl(controlBuf)

		}

	}
	return ""
}

func inspectPackageControl(filename bytes.Buffer) string {
	gzf, err := gzip.NewReader(bytes.NewReader(filename.Bytes()))
	if err != nil {
		log.Println("error creating gzip reader: ", err)
		return ""
	}

	tarReader := tar.NewReader(gzf)
	var controlBuf bytes.Buffer
	for {
		header, err := tarReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Println("error in inspectPackage loop: ", err)
			return ""
		}

		name := header.Name

		switch header.Typeflag {
		case tar.TypeDir:
			continue
		case tar.TypeReg:
			if name == "./control" {
				io.Copy(&controlBuf, tarReader)
				log.Printf("control file: %s\n", controlBuf.String())
				return controlBuf.String()
			}
		default:
			log.Printf("%s : %c %s %s\n",
				"Yikes! Unable to figure out type",
				header.Typeflag,
				"in file",
				name,
			)
		}
	}
	return ""
}

func createPackagesTar(arch string) bool {
	var packBuf bytes.Buffer
	// loop through each directory
	// run inspectPackage
	dirList, err := ioutil.ReadDir(config.RootRepoPath + "/dists/stable/main/binary-" + arch)
	if err != nil {
		log.Printf("error scanning %s: %s\n", config.RootRepoPath+"/dists/stable/main/binary-"+arch, err)
		return false
	}
	for _, debFile := range dirList {
		if strings.HasSuffix(debFile.Name(), "deb") {
			tempCtlData := inspectPackage(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name())
			packBuf.WriteString(tempCtlData)
			packBuf.WriteString("Filename: " + config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name() + "\n")
			packBuf.WriteString("Size: " + strconv.FormatInt(debFile.Size(), 10) + "\n")
			f, _ := ioutil.ReadFile(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name())
			md5hash := md5.New()
			io.WriteString(md5hash, string(f[:]))
			md5sum := hex.EncodeToString(md5hash.Sum(nil))
			packBuf.WriteString("MD5sum: " + md5sum + "\n")
			sha1hash := sha1.New()
			io.WriteString(sha1hash, string(f[:]))
			sha1sum := hex.EncodeToString(sha1hash.Sum(nil))
			packBuf.WriteString("SHA1: " + sha1sum + "\n")
			sha256hash := sha256.New()
			io.WriteString(sha256hash, string(f[:]))
			sha256sum := hex.EncodeToString(sha256hash.Sum(nil))
			packBuf.WriteString("SHA256: " + sha256sum + "\n")
			packBuf.WriteString("\n\n")
		}
	}

	outfile, err := os.Create(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/Packages.gz")
	if err != nil {
		log.Println("error creating packages.gz file")
		return false
	}
	defer outfile.Close()
	gzOut := gzip.NewWriter(outfile)
	defer gzOut.Close()
	gzOut.Write(packBuf.Bytes())
	gzOut.Flush()
	return true
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		file, header, err := r.FormFile("file")
		if err != nil {
			log.Println("error parsing file: ", err)
		}
		log.Println("filename is: ", header.Filename)
		out, err := os.Create(config.RootRepoPath + "/dists/stable/main/binary-amd64/" + header.Filename)
		if err != nil {
			log.Println("error creating file: ", err)
		}
		hash := md5.New()
		_, err = io.Copy(out, io.TeeReader(file, hash))
		defer file.Close()
		if err != nil {
			log.Println("error saving file: ", err)
		}
		md5sum := hex.EncodeToString(hash.Sum(nil))
		log.Println("md5sum = ", md5sum)
		log.Println("grabbing lock...")
		sem.Lock()
		log.Println("got lock, updating package list...")
		if !createPackagesTar("amd64") {
			log.Println("unable to create Packages.gz")
		}
		sem.Unlock()
		log.Println("lock returned")
	} else {
		log.Println("not a POST")
	}
}

func (s semaphore) Lock() {
	s <- 1
}

func (s semaphore) Unlock() {
	<-s
}
<commit_msg>create directory structure on startup<commit_after>package main

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"

	"github.com/blakesmith/ar"
)

type semaphore chan int

type Conf struct {
	ListenPort   string   `json:"listenPort"`
	RootRepoPath string   `json:"rootRepoPath"`
	SupportArch  []string `json:"supportedArch"`
}

var sem = make(semaphore, 1)
var configFile = flag.String("c", "conf.json", "config file location")
var config = &Conf{}

func main() {
	flag.Parse()
	file, err := ioutil.ReadFile(*configFile)
	if err != nil {
		log.Panic("unable to read config file, exiting...")
	}
	config = &Conf{}
	if err := json.Unmarshal(file, &config); err != nil {
		log.Panic("unable to marshal config file, exiting...")
	}

	if !createDirs() {
		log.Println("error creating directory structure, exiting")
		os.Exit(1)
	}
	http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(config.RootRepoPath))))
	http.HandleFunc("/upload", uploadHandler)
	http.ListenAndServe(":"+config.ListenPort, nil)
}

func createDirs() bool {
	for _, archDir := range config.SupportArch {
		if _, err := os.Stat(config.RootRepoPath + "/dists/stable/main/" + archDir); err != nil {
			if os.IsNotExist(err) {
				log.Printf("Directory for %s does not exist, creating", archDir)
				dirErr := os.MkdirAll(config.RootRepoPath+"/dists/stable/main/"+archDir, 0755)
				if dirErr != nil {
					log.Printf("error creating directory for %s: %s\n", archDir, dirErr)
					return false
				}
			} else {
				log.Printf("error inspecting %s: %s\n", archDir, err)
				return false
			}
		}
	}
	return true
}

func inspectPackage(filename string) string {
	f, err := os.Open(filename)
	if err != nil {
		log.Printf("error opening package file %s: %s\n", filename, err)
		return ""
	}
	defer f.Close()

	arReader := ar.NewReader(f)
	var controlBuf bytes.Buffer

	for {
		header, err := arReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Println("error in inspectPackage loop: ", err)
			return ""
		}

		if header.Name == "control.tar.gz" {
			io.Copy(&controlBuf, arReader)
			return inspectPackageControl(controlBuf)

		}

	}
	return ""
}

func inspectPackageControl(filename bytes.Buffer) string {
	gzf, err := gzip.NewReader(bytes.NewReader(filename.Bytes()))
	if err != nil {
		log.Println("error creating gzip reader: ", err)
		return ""
	}

	tarReader := tar.NewReader(gzf)
	var controlBuf bytes.Buffer
	for {
		header, err := tarReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Println("error in inspectPackage loop: ", err)
			return ""
		}

		name := header.Name

		switch header.Typeflag {
		case tar.TypeDir:
			continue
		case tar.TypeReg:
			if name == "./control" {
				io.Copy(&controlBuf, tarReader)
				log.Printf("control file: %s\n", controlBuf.String())
				return controlBuf.String()
			}
		default:
			log.Printf("%s : %c %s %s\n",
				"Yikes! Unable to figure out type",
				header.Typeflag,
				"in file",
				name,
			)
		}
	}
	return ""
}

func createPackagesTar(arch string) bool {
	var packBuf bytes.Buffer
	// loop through each directory
	// run inspectPackage
	dirList, err := ioutil.ReadDir(config.RootRepoPath + "/dists/stable/main/binary-" + arch)
	if err != nil {
		log.Printf("error scanning %s: %s\n", config.RootRepoPath+"/dists/stable/main/binary-"+arch, err)
		return false
	}
	for _, debFile := range dirList {
		if strings.HasSuffix(debFile.Name(), "deb") {
			tempCtlData := inspectPackage(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name())
			packBuf.WriteString(tempCtlData)
			packBuf.WriteString("Filename: " + config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name() + "\n")
			packBuf.WriteString("Size: " + strconv.FormatInt(debFile.Size(), 10) + "\n")
			f, _ := ioutil.ReadFile(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name())
			md5hash := md5.New()
			io.WriteString(md5hash, string(f[:]))
			md5sum := hex.EncodeToString(md5hash.Sum(nil))
			packBuf.WriteString("MD5sum: " + md5sum + "\n")
			sha1hash := sha1.New()
			io.WriteString(sha1hash, string(f[:]))
			sha1sum := hex.EncodeToString(sha1hash.Sum(nil))
			packBuf.WriteString("SHA1: " + sha1sum + "\n")
			sha256hash := sha256.New()
			io.WriteString(sha256hash, string(f[:]))
			sha256sum := hex.EncodeToString(sha256hash.Sum(nil))
			packBuf.WriteString("SHA256: " + sha256sum + "\n")
			packBuf.WriteString("\n\n")
		}
	}

	outfile, err := os.Create(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/Packages.gz")
	if err != nil {
		log.Println("error creating packages.gz file")
		return false
	}
	defer outfile.Close()
	gzOut := gzip.NewWriter(outfile)
	defer gzOut.Close()
	gzOut.Write(packBuf.Bytes())
	gzOut.Flush()
	return true
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		file, header, err := r.FormFile("file")
		if err != nil {
			log.Println("error parsing file: ", err)
		}
		log.Println("filename is: ", header.Filename)
		out, err := os.Create(config.RootRepoPath + "/dists/stable/main/binary-amd64/" + header.Filename)
		if err != nil {
			log.Println("error creating file: ", err)
		}
		hash := md5.New()
		_, err = io.Copy(out, io.TeeReader(file, hash))
		defer file.Close()
		if err != nil {
			log.Println("error saving file: ", err)
		}
		md5sum := hex.EncodeToString(hash.Sum(nil))
		log.Println("md5sum = ", md5sum)
		log.Println("grabbing lock...")
		sem.Lock()
		log.Println("got lock, updating package list...")
		if !createPackagesTar("amd64") {
			log.Println("unable to create Packages.gz")
		}
		sem.Unlock()
		log.Println("lock returned")
	} else {
		log.Println("not a POST")
	}
}

func (s semaphore) Lock() {
	s <- 1
}

func (s semaphore) Unlock() {
	<-s
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/opencontainers/runc/libcontainer/logs"

	"github.com/opencontainers/runtime-spec/specs-go"

	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
)

// version will be populated by the Makefile, read from
// VERSION file of the source code.
var version = ""

// gitCommit will be the hash that the binary was built from
// and will be populated by the Makefile
var gitCommit = ""

const (
	specConfig = "config.json"
	usage      = `Open Container Initiative runtime

runc is a command line client for running applications packaged according to
the Open Container Initiative (OCI) format and is a compliant implementation of the
Open Container Initiative specification.

runc integrates well with existing process supervisors to provide a production
container runtime environment for applications. It can be used with your
existing process monitoring tools and the container will be spawned as a
direct child of the process supervisor.

Containers are configured using bundles. A bundle for a container is a directory
that includes a specification file named "` + specConfig + `" and a root filesystem.
The root filesystem contains the contents of the container.

To start a new instance of a container:

    # runc run [ -b bundle ] <container-id>

Where "<container-id>" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on
your host. Providing the bundle directory using "-b" is optional. The default
value for "bundle" is the current directory.`
)

func main() {
	app := cli.NewApp()
	app.Name = "runc"
	app.Usage = usage

	var v []string
	if version != "" {
		v = append(v, version)
	}
	if gitCommit != "" {
		v = append(v, fmt.Sprintf("commit: %s", gitCommit))
	}
	v = append(v, fmt.Sprintf("spec: %s", specs.Version))
	app.Version = strings.Join(v, "\n")

	root := "/run/runc"
	if shouldHonorXDGRuntimeDir() {
		if runtimeDir := os.Getenv("XDG_RUNTIME_DIR"); runtimeDir != "" {
			root = runtimeDir + "/runc"
			// According to the XDG specification, we need to set anything in
			// XDG_RUNTIME_DIR to have a sticky bit if we don't want it to get
			// auto-pruned.
			if err := os.MkdirAll(root, 0700); err != nil {
				fatal(err)
			}
			if err := os.Chmod(root, 0700|os.ModeSticky); err != nil {
				fatal(err)
			}
		}
	}

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output for logging",
		},
		cli.StringFlag{
			Name:  "log",
			Value: "",
			Usage: "set the log file path where internal debug information is written",
		},
		cli.StringFlag{
			Name:  "log-format",
			Value: "text",
			Usage: "set the format used by logs ('text' (default), or 'json')",
		},
		cli.StringFlag{
			Name:  "root",
			Value: root,
			Usage: "root directory for storage of container state (this should be located in tmpfs)",
		},
		cli.StringFlag{
			Name:  "criu",
			Value: "criu",
			Usage: "path to the criu binary used for checkpoint and restore",
		},
		cli.BoolFlag{
			Name:  "systemd-cgroup",
			Usage: "enable systemd cgroup support, expects cgroupsPath to be of form \"slice:prefix:name\" for e.g. \"system.slice:runc:434234\"",
		},
		cli.StringFlag{
			Name:  "rootless",
			Value: "auto",
			Usage: "ignore cgroup permission errors ('true', 'false', or 'auto')",
		},
	}
	app.Commands = []cli.Command{
		checkpointCommand,
		createCommand,
		deleteCommand,
		eventsCommand,
		execCommand,
		initCommand,
		killCommand,
		listCommand,
		pauseCommand,
		psCommand,
		restoreCommand,
		resumeCommand,
		runCommand,
		specCommand,
		startCommand,
		stateCommand,
		updateCommand,
	}
	app.Before = func(context *cli.Context) error {
		return logs.ConfigureLogging(createLogConfig(context))
	}

	// If the command returns an error, cli takes upon itself to print
	// the error on cli.ErrWriter and exit.
	// Use our own writer here to ensure the log gets sent to the right location.
	cli.ErrWriter = &FatalWriter{cli.ErrWriter}
	if err := app.Run(os.Args); err != nil {
		fatal(err)
	}
}

type FatalWriter struct {
	cliErrWriter io.Writer
}

func (f *FatalWriter) Write(p []byte) (n int, err error) {
	logrus.Error(string(p))
	return f.cliErrWriter.Write(p)
}

func createLogConfig(context *cli.Context) logs.Config {
	logFilePath := context.GlobalString("log")
	logPipeFd := ""
	if logFilePath == "" {
		logPipeFd = "2"
	}
	config := logs.Config{
		LogPipeFd:   logPipeFd,
		LogLevel:    logrus.InfoLevel,
		LogFilePath: logFilePath,
		LogFormat:   context.GlobalString("log-format"),
	}
	if context.GlobalBool("debug") {
		config.LogLevel = logrus.DebugLevel
	}

	return config
}
<commit_msg>fix error when there is --root and XDG_RUNTIME_DIR env<commit_after>package main

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/opencontainers/runc/libcontainer/logs"

	"github.com/opencontainers/runtime-spec/specs-go"

	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
)

// version will be populated by the Makefile, read from
// VERSION file of the source code.
var version = ""

// gitCommit will be the hash that the binary was built from
// and will be populated by the Makefile
var gitCommit = ""

const (
	specConfig = "config.json"
	usage      = `Open Container Initiative runtime

runc is a command line client for running applications packaged according to
the Open Container Initiative (OCI) format and is a compliant implementation of the
Open Container Initiative specification.

runc integrates well with existing process supervisors to provide a production
container runtime environment for applications. It can be used with your
existing process monitoring tools and the container will be spawned as a
direct child of the process supervisor.

Containers are configured using bundles. A bundle for a container is a directory
that includes a specification file named "` + specConfig + `" and a root filesystem.
The root filesystem contains the contents of the container.

To start a new instance of a container:

    # runc run [ -b bundle ] <container-id>

Where "<container-id>" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on
your host. Providing the bundle directory using "-b" is optional. The default
value for "bundle" is the current directory.`
)

func main() {
	app := cli.NewApp()
	app.Name = "runc"
	app.Usage = usage

	var v []string
	if version != "" {
		v = append(v, version)
	}
	if gitCommit != "" {
		v = append(v, fmt.Sprintf("commit: %s", gitCommit))
	}
	v = append(v, fmt.Sprintf("spec: %s", specs.Version))
	app.Version = strings.Join(v, "\n")

	xdgRuntimeDir := ""
	root := "/run/runc"
	if shouldHonorXDGRuntimeDir() {
		if runtimeDir := os.Getenv("XDG_RUNTIME_DIR"); runtimeDir != "" {
			root = runtimeDir + "/runc"
			xdgRuntimeDir = root
		}
	}

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output for logging",
		},
		cli.StringFlag{
			Name:  "log",
			Value: "",
			Usage: "set the log file path where internal debug information is written",
		},
		cli.StringFlag{
			Name:  "log-format",
			Value: "text",
			Usage: "set the format used by logs ('text' (default), or 'json')",
		},
		cli.StringFlag{
			Name:  "root",
			Value: root,
			Usage: "root directory for storage of container state (this should be located in tmpfs)",
		},
		cli.StringFlag{
			Name:  "criu",
			Value: "criu",
			Usage: "path to the criu binary used for checkpoint and restore",
		},
		cli.BoolFlag{
			Name:  "systemd-cgroup",
			Usage: "enable systemd cgroup support, expects cgroupsPath to be of form \"slice:prefix:name\" for e.g. \"system.slice:runc:434234\"",
		},
		cli.StringFlag{
			Name:  "rootless",
			Value: "auto",
			Usage: "ignore cgroup permission errors ('true', 'false', or 'auto')",
		},
	}
	app.Commands = []cli.Command{
		checkpointCommand,
		createCommand,
		deleteCommand,
		eventsCommand,
		execCommand,
		initCommand,
		killCommand,
		listCommand,
		pauseCommand,
		psCommand,
		restoreCommand,
		resumeCommand,
		runCommand,
		specCommand,
		startCommand,
		stateCommand,
		updateCommand,
	}
	app.Before = func(context *cli.Context) error {
		if !context.IsSet("root") && xdgRuntimeDir != "" {
			// According to the XDG specification, we need to set anything in
			// XDG_RUNTIME_DIR to have a sticky bit if we don't want it to get
			// auto-pruned.
			if err := os.MkdirAll(root, 0700); err != nil {
				fmt.Fprintln(os.Stderr, "the path in $XDG_RUNTIME_DIR must be writable by the user")
				fatal(err)
			}
			if err := os.Chmod(root, 0700|os.ModeSticky); err != nil {
				fmt.Fprintln(os.Stderr, "you should check permission of the path in $XDG_RUNTIME_DIR")
				fatal(err)
			}
		}
		return logs.ConfigureLogging(createLogConfig(context))
	}

	// If the command returns an error, cli takes upon itself to print
	// the error on cli.ErrWriter and exit.
	// Use our own writer here to ensure the log gets sent to the right location.
	cli.ErrWriter = &FatalWriter{cli.ErrWriter}
	if err := app.Run(os.Args); err != nil {
		fatal(err)
	}
}

type FatalWriter struct {
	cliErrWriter io.Writer
}

func (f *FatalWriter) Write(p []byte) (n int, err error) {
	logrus.Error(string(p))
	return f.cliErrWriter.Write(p)
}

func createLogConfig(context *cli.Context) logs.Config {
	logFilePath := context.GlobalString("log")
	logPipeFd := ""
	if logFilePath == "" {
		logPipeFd = "2"
	}
	config := logs.Config{
		LogPipeFd:   logPipeFd,
		LogLevel:    logrus.InfoLevel,
		LogFilePath: logFilePath,
		LogFormat:   context.GlobalString("log-format"),
	}
	if context.GlobalBool("debug") {
		config.LogLevel = logrus.DebugLevel
	}

	return config
}
<|endoftext|>


<commit_before>package main

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

	"github.com/julienschmidt/httprouter"
	"github.com/rlayte/dive"
)

type Toystore struct {
	dive *dive.Node
	port int
	data map[string]string
}

func (t *Toystore) Get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	key := params.ByName("key")
	value, ok := t.data[key]

	log.Printf("GET - %s : %s", key, value, t.dive.Members)

	if !ok {
		w.Header().Set("Status", "404")
		fmt.Fprint(w, "Not found")
		return
	} else {
		fmt.Fprint(w, value)
	}
}

func (t *Toystore) Put(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	key := params.ByName("key")
	value := r.FormValue("data")
	t.data[key] = value
}

func main() {
	var seed string
	port, err := strconv.Atoi(os.Args[1])

	if port != 3000 {
		seed = ":3010"
	}

	if err != nil {
		panic(err)
	}

	t := Toystore{
		dive: dive.NewNode(port+10, seed),
		port: port,
		data: map[string]string{},
	}

	router := httprouter.New()

	router.GET("/:key", t.Get)
	router.POST("/:key", t.Put)

	log.Println("Running server on port", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), router))
}
<commit_msg>Abstract data into Store interface<commit_after>package main

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

	"github.com/julienschmidt/httprouter"
	"github.com/rlayte/dive"
)

type Toystore struct {
	dive *dive.Node
	port int
	data Store
}

type Store interface {
	Get(string) (string, bool)
	Put(string, string)
}

type MemoryStore struct {
	data map[string]string
}

func (m MemoryStore) Get(key string) (string, bool) {
	value, ok := m.data[key]
	return value, ok
}

func (m MemoryStore) Put(key string, value string) {
	m.data[key] = value
}

func (t *Toystore) Get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	key := params.ByName("key")
	value, ok := t.data.Get(key)

	log.Printf("GET - %s : %s", key, value)

	if !ok {
		w.Header().Set("Status", "404")
		fmt.Fprint(w, "Not found")
		return
	} else {
		fmt.Fprint(w, value)
	}
}

func (t *Toystore) Put(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	key := params.ByName("key")
	value := r.FormValue("data")
	t.data.Put(key, value)
}

func main() {
	var seed string
	port, err := strconv.Atoi(os.Args[1])

	if port != 3000 {
		seed = ":3010"
	}

	if err != nil {
		panic(err)
	}

	t := Toystore{
		dive: dive.NewNode(port+10, seed),
		port: port,
		data: MemoryStore{map[string]string{}},
	}

	router := httprouter.New()

	router.GET("/:key", t.Get)
	router.POST("/:key", t.Put)

	log.Println("Running server on port", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), router))
}
<|endoftext|>


<commit_before>package image

import (
	"encoding/json"
	"errors"
	"github.com/dotcloud/docker/future"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strings"
	"time"
)

type Store struct {
	*Index
	Root   string
	Layers *LayerStore
}

func New(root string) (*Store, error) {
	abspath, err := filepath.Abs(root)
	if err != nil {
		return nil, err
	}
	if err := os.MkdirAll(abspath, 0700); err != nil && !os.IsExist(err) {
		return nil, err
	}
	layers, err := NewLayerStore(path.Join(root, "layers"))
	if err != nil {
		return nil, err
	}
	if err := layers.Init(); err != nil {
		return nil, err
	}
	return &Store{
		Root:   abspath,
		Index:  NewIndex(path.Join(root, "index.json")),
		Layers: layers,
	}, nil
}

type Compression uint32

const (
	Uncompressed Compression = iota
	Bzip2
	Gzip
)

func (store *Store) Import(name string, archive io.Reader, stderr io.Writer, parent *Image, compression Compression) (*Image, error) {
	layer, err := store.Layers.AddLayer(archive, stderr, compression)
	if err != nil {
		return nil, err
	}
	layers := []string{layer}
	if parent != nil {
		layers = append(layers, parent.Layers...)
	}
	var parentId string
	if parent != nil {
		parentId = parent.Id
	}
	return store.Create(name, parentId, layers...)
}

func (store *Store) Create(name string, source string, layers ...string) (*Image, error) {
	image, err := NewImage(name, layers, source)
	if err != nil {
		return nil, err
	}
	if err := store.Index.Add(name, image); err != nil {
		return nil, err
	}
	return image, nil
}

// Index

type Index struct {
	Path   string
	ByName map[string]*History
	ById   map[string]*Image
}

func NewIndex(path string) *Index {
	return &Index{
		Path:   path,
		ByName: make(map[string]*History),
		ById:   make(map[string]*Image),
	}
}

func (index *Index) Exists(id string) bool {
	_, exists := index.ById[id]
	return exists
}

func (index *Index) Find(idOrName string) *Image {
	// Load
	if err := index.load(); err != nil {
		return nil
	}
	// Lookup by ID
	if image, exists := index.ById[idOrName]; exists {
		return image
	}
	// Lookup by name
	if history, exists := index.ByName[idOrName]; exists && history.Len() > 0 {
		return (*history)[0]
	}
	return nil
}

func (index *Index) Add(name string, image *Image) error {
	// Load
	if err := index.load(); err != nil {
		return err
	}
	if _, exists := index.ByName[name]; !exists {
		index.ByName[name] = new(History)
	} else {
		// If this image is already the latest version, don't add it.
		if (*index.ByName[name])[0].Id == image.Id {
			return nil
		}
	}
	index.ByName[name].Add(image)
	index.ById[image.Id] = image
	// Save
	if err := index.save(); err != nil {
		return err
	}
	return nil
}

func (index *Index) Copy(srcNameOrId, dstName string) (*Image, error) {
	if srcNameOrId == "" || dstName == "" {
		return nil, errors.New("Illegal image name")
	}
	// Load
	if err := index.load(); err != nil {
		return nil, err
	}
	src := index.Find(srcNameOrId)
	if src == nil {
		return nil, errors.New("No such image: " + srcNameOrId)
	}
	dst, err := NewImage(dstName, src.Layers, src.Id)
	if err != nil {
		return nil, err
	}
	if err := index.Add(dstName, dst); err != nil {
		return nil, err
	}
	// Save
	if err := index.save(); err != nil {
		return nil, err
	}
	return dst, nil
}

func (index *Index) Rename(oldName, newName string) error {
	// Load
	if err := index.load(); err != nil {
		return err
	}
	if _, exists := index.ByName[oldName]; !exists {
		return errors.New("Can't rename " + oldName + ": no such image.")
	}
	if _, exists := index.ByName[newName]; exists {
		return errors.New("Can't rename to " + newName + ": name is already in use.")
	}
	index.ByName[newName] = index.ByName[oldName]
	delete(index.ByName, oldName)
	// Change the ID of all images, since they include the name
	for _, image := range *index.ByName[newName] {
		if id, err := generateImageId(newName, image.Layers); err != nil {
			return err
		} else {
			oldId := image.Id
			image.Id = id
			index.ById[id] = image
			delete(index.ById, oldId)
		}
	}
	// Save
	if err := index.save(); err != nil {
		return err
	}
	return nil
}

// Delete deletes all images with the name `name`
func (index *Index) Delete(name string) error {
	// Load
	if err := index.load(); err != nil {
		return err
	}
	if _, exists := index.ByName[name]; !exists {
		return errors.New("No such image: " + name)
	}
	// Remove from index lookup
	for _, image := range *index.ByName[name] {
		delete(index.ById, image.Id)
	}
	// Remove from name lookup
	delete(index.ByName, name)
	// Save
	if err := index.save(); err != nil {
		return err
	}
	return nil
}

func (index *Index) Names() []string {
	if err := index.load(); err != nil {
		return []string{}
	}
	var names []string
	for name := range index.ByName {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}

func (index *Index) load() error {
	jsonData, err := ioutil.ReadFile(index.Path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return err
	}
	path := index.Path
	if err := json.Unmarshal(jsonData, index); err != nil {
		return err
	}
	index.Path = path
	return nil
}

func (index *Index) save() error {
	jsonData, err := json.Marshal(index)
	if err != nil {
		return err
	}
	if err := ioutil.WriteFile(index.Path, jsonData, 0600); err != nil {
		return err
	}
	return nil
}

// History wraps an array of images so they can be sorted by date (most recent first)

type History []*Image

func (history *History) Len() int {
	return len(*history)
}

func (history *History) Less(i, j int) bool {
	images := *history
	return images[j].Created.Before(images[i].Created)
}

func (history *History) Swap(i, j int) {
	images := *history
	tmp := images[i]
	images[i] = images[j]
	images[j] = tmp
}

func (history *History) Add(image *Image) {
	*history = append(*history, image)
	sort.Sort(history)
}

func (history *History) Del(id string) {
	for idx, image := range *history {
		if image.Id == id {
			*history = append((*history)[:idx], (*history)[idx+1:]...)
		}
	}
}

type Image struct {
	Id      string   // Globally unique identifier
	Layers  []string // Absolute paths
	Created time.Time
	Parent  string
}

func (image *Image) IdParts() (string, string) {
	if len(image.Id) < 8 {
		return "", image.Id
	}
	hash := image.Id[len(image.Id)-8 : len(image.Id)]
	name := image.Id[:len(image.Id)-9]
	return name, hash
}

func (image *Image) IdIsFinal() bool {
	return len(image.Layers) == 1
}

func generateImageId(name string, layers []string) (string, error) {
	if len(layers) == 0 {
		return "", errors.New("No layers provided.")
	}
	var hash string
	if len(layers) == 1 {
		hash = path.Base(layers[0])
	} else {
		var ids string
		for _, layer := range layers {
			ids += path.Base(layer)
		}
		if h, err := future.ComputeId(strings.NewReader(ids)); err != nil {
			return "", err
		} else {
			hash = h
		}
	}
	return name + ":" + hash, nil
}

func NewImage(name string, layers []string, parent string) (*Image, error) {
	id, err := generateImageId(name, layers)
	if err != nil {
		return nil, err
	}
	return &Image{
		Id:      id,
		Layers:  layers,
		Created: time.Now(),
		Parent:  parent,
	}, nil
}
<commit_msg>Removed deprecated docker/image package<commit_after><|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"gopkg.in/alecthomas/kingpin.v2"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
)

var (
	version    = "0.3.1"
	user_agent = fmt.Sprint("github-markdown-toc.go v", version)
)

//
// Internal
//

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func do_http_req(req *http.Request) string {
	req.Header.Set("User-Agent", user_agent)
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return ""
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return ""
	}

	return string(body)
}

// Executes HTTP GET request
func http_get(url_path string) string {
	req, err := http.NewRequest("GET", url_path, nil)
	if err != nil {
		return ""
	}
	return do_http_req(req)
}

// Executes HTTP POST with file content
func http_post(url_path string, file_path string) string {
	file, err := os.Open(file_path)
	if err != nil {
		return ""
	}
	defer file.Close()

	body := &bytes.Buffer{}
	io.Copy(body, file)

	req, err := http.NewRequest("POST", url_path, body)
	req.Header.Set("Content-Type", "text/plain")

	return do_http_req(req)
}

func removeStuf(s string) string {
	res := strings.Replace(s, "\n", "", -1)
	res = strings.Replace(res, "", "", -1)
	res = strings.Replace(res, "", "", -1)
	res = strings.TrimSpace(res)

	return res
}

// Public

// If path is url then just executes HTTP GET and
// Returns html for this url.
//
// If path is a local path then sends file to the GitHub's
// Markdown -> Html converter and returns html.
func GetHmtlBody(path string) string {
	if IsUrl(path) {
		return http_get(path)
	} else {
		return ConvertMd2Html(path)
	}
}

// Check if string is url
func IsUrl(candidate string) bool {
	u, err := url.Parse(candidate)
	if err != nil || u.Scheme == "" {
		return false
	}
	return true
}

// Sends Markdown to the github converter
// and returns html.
func ConvertMd2Html(localpath string) string {
	return http_post("https://api.github.com/markdown/raw", localpath)
}

// Create TOC by html from github
func GrabToc(html string) []string {
	re := `(?si)<h(?P<num>[1-6])>\s*` +
		`<a\s*id="user-content-[^"]*"\s*class="anchor"\s*` +
		`href="(?P<href>[^"]*)"[^>]*>\s*` +
		`<span[^<*]*</span>\s*</a>(?P<name>.*?)</h`
	r := regexp.MustCompile(re)

	toc := []string{}
	groups := make(map[string]string)
	for _, match := range r.FindAllStringSubmatch(html, -1) {
		// fill map for groups
		for i, name := range r.SubexpNames() {
			if i == 0 || name == "" {
				continue
			}
			groups[name] = removeStuf(match[i])
		}
		// format result
		n, _ := strconv.Atoi(groups["num"])
		toc_item := strings.Repeat("  ", n) + "* " +
			"[" + removeStuf(groups["name"]) + "]" +
			"(" + groups["href"] + ")"
		//fmt.Println(toc_item)
		toc = append(toc, toc_item)
	}

	return toc
}

// Generate TOC for document (path in filesystem or url)
func GenerateToc(path string) []string {
	return GrabToc(GetHmtlBody(path))
}

func PrintToc(toc []string) {
	for _, toc_item := range toc {
		fmt.Println(toc_item)
	}
	fmt.Println()
}

// Entry point
func main() {
	paths_desc := "Local path or URL of the document to grab TOC. " +
		"If not entered, then read Markdown from stdin."
	paths := kingpin.Arg("path", paths_desc).Strings()
	kingpin.Version(version)
	kingpin.Parse()

	if len(*paths) == 1 {
		fmt.Println()
		fmt.Println("Table of Contents")
		fmt.Println("=================")
		fmt.Println()
	}

	// read file paths | urls from args
	for _, p := range *paths {
		PrintToc(GenerateToc(p))
	}

	// read md from stdin
	if len(*paths) == 0 {
		file, err := ioutil.TempFile(os.TempDir(), "ghtoc")
		check(err)
		defer os.Remove(file.Name())
		file_path, err := filepath.Abs(file.Name())
		check(err)
		bytes, err := ioutil.ReadAll(os.Stdin)
		check(err)
		check(ioutil.WriteFile(file.Name(), bytes, 0644))
		PrintToc(GenerateToc(file_path))
	}

	fmt.Println("Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc.go)")
}
<commit_msg>improved names internals funcs<commit_after>package main

import (
	"bytes"
	"fmt"
	"gopkg.in/alecthomas/kingpin.v2"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
)

var (
	version    = "0.3.1"
	user_agent = fmt.Sprint("github-markdown-toc.go v", version)
)

//
// Internal
//

// check checks if there whas an error and do panic if it was
func check(e error) {
	if e != nil {
		panic(e)
	}
}

// doHttpReq executes a particullar http request
func doHttpReq(req *http.Request) string {
	req.Header.Set("User-Agent", user_agent)
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return ""
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return ""
	}

	return string(body)
}

// Executes HTTP GET request
func httpGet(url_path string) string {
	req, err := http.NewRequest("GET", url_path, nil)
	if err != nil {
		return ""
	}
	return doHttpReq(req)
}

// httpPost executes HTTP POST with file content
func httpPost(url_path string, file_path string) string {
	file, err := os.Open(file_path)
	if err != nil {
		return ""
	}
	defer file.Close()

	body := &bytes.Buffer{}
	io.Copy(body, file)

	req, err := http.NewRequest("POST", url_path, body)
	req.Header.Set("Content-Type", "text/plain")

	return doHttpReq(req)
}

// removeStuf trims spaces, removes new lines and code tag from a string
func removeStuf(s string) string {
	res := strings.Replace(s, "\n", "", -1)
	res = strings.Replace(res, "", "", -1)
	res = strings.Replace(res, "", "", -1)
	res = strings.TrimSpace(res)

	return res
}

// Public

// If path is url then just executes HTTP GET and
// Returns html for this url.
//
// If path is a local path then sends file to the GitHub's
// Markdown -> Html converter and returns html.
func GetHmtlBody(path string) string {
	if IsUrl(path) {
		return httpGet(path)
	} else {
		return ConvertMd2Html(path)
	}
}

// Check if string is url
func IsUrl(candidate string) bool {
	u, err := url.Parse(candidate)
	if err != nil || u.Scheme == "" {
		return false
	}
	return true
}

// Sends Markdown to the github converter
// and returns html.
func ConvertMd2Html(localpath string) string {
	return httpPost("https://api.github.com/markdown/raw", localpath)
}

// Create TOC by html from github
func GrabToc(html string) []string {
	re := `(?si)<h(?P<num>[1-6])>\s*` +
		`<a\s*id="user-content-[^"]*"\s*class="anchor"\s*` +
		`href="(?P<href>[^"]*)"[^>]*>\s*` +
		`<span[^<*]*</span>\s*</a>(?P<name>.*?)</h`
	r := regexp.MustCompile(re)

	toc := []string{}
	groups := make(map[string]string)
	for _, match := range r.FindAllStringSubmatch(html, -1) {
		// fill map for groups
		for i, name := range r.SubexpNames() {
			if i == 0 || name == "" {
				continue
			}
			groups[name] = removeStuf(match[i])
		}
		// format result
		n, _ := strconv.Atoi(groups["num"])
		toc_item := strings.Repeat("  ", n) + "* " +
			"[" + removeStuf(groups["name"]) + "]" +
			"(" + groups["href"] + ")"
		//fmt.Println(toc_item)
		toc = append(toc, toc_item)
	}

	return toc
}

// Generate TOC for document (path in filesystem or url)
func GenerateToc(path string) []string {
	return GrabToc(GetHmtlBody(path))
}

// PrintToc print on console string array
func PrintToc(toc []string) {
	for _, toc_item := range toc {
		fmt.Println(toc_item)
	}
	fmt.Println()
}

// Entry point
func main() {
	paths_desc := "Local path or URL of the document to grab TOC. " +
		"If not entered, then read Markdown from stdin."
	paths := kingpin.Arg("path", paths_desc).Strings()
	kingpin.Version(version)
	kingpin.Parse()

	if len(*paths) == 1 {
		fmt.Println()
		fmt.Println("Table of Contents")
		fmt.Println("=================")
		fmt.Println()
	}

	// read file paths | urls from args
	for _, p := range *paths {
		PrintToc(GenerateToc(p))
	}

	// read md from stdin
	if len(*paths) == 0 {
		file, err := ioutil.TempFile(os.TempDir(), "ghtoc")
		check(err)
		defer os.Remove(file.Name())
		file_path, err := filepath.Abs(file.Name())
		check(err)
		bytes, err := ioutil.ReadAll(os.Stdin)
		check(err)
		check(ioutil.WriteFile(file.Name(), bytes, 0644))
		PrintToc(GenerateToc(file_path))
	}

	fmt.Println("Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc.go)")
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"io/ioutil"
	"os"

	"github.com/mithrandie/csvq/lib/action"
	"github.com/mithrandie/csvq/lib/cmd"

	"github.com/urfave/cli"
)

var version = "v0.4.6"

func main() {
	cli.AppHelpTemplate = appHHelpTemplate
	cli.CommandHelpTemplate = commandHelpTemplate

	app := cli.NewApp()

	app.Name = "csvq"
	app.Usage = "SQL like query language for csv"
	app.ArgsUsage = "[\"query\"|\"statements\"]"
	app.Version = version

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "delimiter, d",
			Usage: "field delimiter. Default is \",\" for csv files, \"\\t\" for tsv files.",
		},
		cli.StringFlag{
			Name:  "encoding, e",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "line-break, l",
			Value: "LF",
			Usage: "line break. one of: CRLF|LF|CR",
		},
		cli.StringFlag{
			Name:  "timezone, z",
			Value: "Local",
			Usage: "default timezone. \"Local\", \"UTC\" or a timezone name(e.g. \"America/Los_Angeles\")",
		},
		cli.StringFlag{
			Name:  "repository, r",
			Usage: "directory path where files are located",
		},
		cli.StringFlag{
			Name:  "source, s",
			Usage: "load query from `FILE`",
		},
		cli.StringFlag{
			Name:  "datetime-format, t",
			Usage: "set datetime format to parse strings",
		},
		cli.BoolFlag{
			Name:  "no-header, n",
			Usage: "import the first line as a record",
		},
		cli.BoolFlag{
			Name:  "without-null, a",
			Usage: "parse empty fields as empty strings",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "write",
			Usage:     "Write output to a file",
			ArgsUsage: "[\"query\"|\"statements\"]",

			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "write-encoding, E",
					Value: "UTF8",
					Usage: "file encoding. one of: UTF8|SJIS",
				},
				cli.StringFlag{
					Name:  "out, o",
					Usage: "write output to `FILE`",
				},
				cli.StringFlag{
					Name:  "format, f",
					Usage: "output format. one of: CSV|TSV|JSON|TEXT",
				},
				cli.StringFlag{
					Name:  "write-delimiter, D",
					Usage: "field delimiter for CSV",
				},
				cli.BoolFlag{
					Name:  "without-header, N",
					Usage: "when the file format is specified as CSV or TSV, write without the header line",
				},
			},
			Before: func(c *cli.Context) error {
				return setWriteFlags(c)
			},
			Action: func(c *cli.Context) error {
				query, err := readQuery(c)
				if err != nil {
					cli.ShowCommandHelp(c, "write")
					return cli.NewExitError(err.Error(), 1)
				}

				err = action.Write(query, cmd.GetFlags().Source)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
		{
			Name:      "fields",
			Usage:     "Show fields in a file",
			ArgsUsage: "CSV_FILE_PATH",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "fields")
					return cli.NewExitError("table is not specified", 1)
				}

				table := c.Args().First()

				err := action.ShowFields(table)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
		{
			Name:      "calc",
			Usage:     "Calculate a value from stdin",
			ArgsUsage: "\"expression\"",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "calc")
					return cli.NewExitError("expression is empty", 1)
				}

				expr := c.Args().First()
				err := action.Calc(expr)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
	}

	app.Before = func(c *cli.Context) error {
		return setGlobalFlags(c)
	}

	app.Action = func(c *cli.Context) error {
		query, err := readQuery(c)
		if err != nil {
			cli.ShowAppHelp(c)
			return cli.NewExitError(err.Error(), 1)
		}

		err = action.Write(query, cmd.GetFlags().Source)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}

		return nil
	}

	app.Run(os.Args)
}

func readQuery(c *cli.Context) (string, error) {
	var query string

	flags := cmd.GetFlags()
	if 0 < len(flags.Source) {
		fp, err := os.Open(flags.Source)
		if err != nil {
			return query, err
		}
		defer fp.Close()

		buf, err := ioutil.ReadAll(fp)
		if err != nil {
			return query, err
		}
		query = string(buf)

	} else {
		if c.NArg() != 1 {
			return query, errors.New("query is empty")
		}
		query = c.Args().First()
	}

	return query, nil
}

func setGlobalFlags(c *cli.Context) error {
	if err := cmd.SetDelimiter(c.GlobalString("delimiter")); err != nil {
		return err
	}
	if err := cmd.SetEncoding(c.GlobalString("encoding")); err != nil {
		return err
	}
	if err := cmd.SetLineBreak(c.String("line-break")); err != nil {
		return err
	}
	if err := cmd.SetLocation(c.String("timezone")); err != nil {
		return err
	}
	if err := cmd.SetRepository(c.GlobalString("repository")); err != nil {
		return err
	}
	if err := cmd.SetSource(c.GlobalString("source")); err != nil {
		return err
	}
	cmd.SetDatetimeFormat(c.GlobalString("datetime-format"))
	cmd.SetNoHeader(c.GlobalBool("no-header"))
	cmd.SetWithoutNull(c.GlobalBool("without-null"))
	return nil
}

func setWriteFlags(c *cli.Context) error {
	if err := cmd.SetWriteEncoding(c.String("write-encoding")); err != nil {
		return err
	}
	if err := cmd.SetOut(c.String("out")); err != nil {
		return err
	}
	if err := cmd.SetFormat(c.String("format")); err != nil {
		return err
	}
	if err := cmd.SetWriteDelimiter(c.String("write-delimiter")); err != nil {
		return err
	}
	cmd.SetWithoutHeader(c.Bool("without-header"))
	return nil
}
<commit_msg>Update version for Release v0.4.7<commit_after>package main

import (
	"errors"
	"io/ioutil"
	"os"

	"github.com/mithrandie/csvq/lib/action"
	"github.com/mithrandie/csvq/lib/cmd"

	"github.com/urfave/cli"
)

var version = "v0.4.7"

func main() {
	cli.AppHelpTemplate = appHHelpTemplate
	cli.CommandHelpTemplate = commandHelpTemplate

	app := cli.NewApp()

	app.Name = "csvq"
	app.Usage = "SQL like query language for csv"
	app.ArgsUsage = "[\"query\"|\"statements\"]"
	app.Version = version

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "delimiter, d",
			Usage: "field delimiter. Default is \",\" for csv files, \"\\t\" for tsv files.",
		},
		cli.StringFlag{
			Name:  "encoding, e",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "line-break, l",
			Value: "LF",
			Usage: "line break. one of: CRLF|LF|CR",
		},
		cli.StringFlag{
			Name:  "timezone, z",
			Value: "Local",
			Usage: "default timezone. \"Local\", \"UTC\" or a timezone name(e.g. \"America/Los_Angeles\")",
		},
		cli.StringFlag{
			Name:  "repository, r",
			Usage: "directory path where files are located",
		},
		cli.StringFlag{
			Name:  "source, s",
			Usage: "load query from `FILE`",
		},
		cli.StringFlag{
			Name:  "datetime-format, t",
			Usage: "set datetime format to parse strings",
		},
		cli.BoolFlag{
			Name:  "no-header, n",
			Usage: "import the first line as a record",
		},
		cli.BoolFlag{
			Name:  "without-null, a",
			Usage: "parse empty fields as empty strings",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "write",
			Usage:     "Write output to a file",
			ArgsUsage: "[\"query\"|\"statements\"]",

			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "write-encoding, E",
					Value: "UTF8",
					Usage: "file encoding. one of: UTF8|SJIS",
				},
				cli.StringFlag{
					Name:  "out, o",
					Usage: "write output to `FILE`",
				},
				cli.StringFlag{
					Name:  "format, f",
					Usage: "output format. one of: CSV|TSV|JSON|TEXT",
				},
				cli.StringFlag{
					Name:  "write-delimiter, D",
					Usage: "field delimiter for CSV",
				},
				cli.BoolFlag{
					Name:  "without-header, N",
					Usage: "when the file format is specified as CSV or TSV, write without the header line",
				},
			},
			Before: func(c *cli.Context) error {
				return setWriteFlags(c)
			},
			Action: func(c *cli.Context) error {
				query, err := readQuery(c)
				if err != nil {
					cli.ShowCommandHelp(c, "write")
					return cli.NewExitError(err.Error(), 1)
				}

				err = action.Write(query, cmd.GetFlags().Source)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
		{
			Name:      "fields",
			Usage:     "Show fields in a file",
			ArgsUsage: "CSV_FILE_PATH",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "fields")
					return cli.NewExitError("table is not specified", 1)
				}

				table := c.Args().First()

				err := action.ShowFields(table)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
		{
			Name:      "calc",
			Usage:     "Calculate a value from stdin",
			ArgsUsage: "\"expression\"",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "calc")
					return cli.NewExitError("expression is empty", 1)
				}

				expr := c.Args().First()
				err := action.Calc(expr)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}

				return nil
			},
		},
	}

	app.Before = func(c *cli.Context) error {
		return setGlobalFlags(c)
	}

	app.Action = func(c *cli.Context) error {
		query, err := readQuery(c)
		if err != nil {
			cli.ShowAppHelp(c)
			return cli.NewExitError(err.Error(), 1)
		}

		err = action.Write(query, cmd.GetFlags().Source)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}

		return nil
	}

	app.Run(os.Args)
}

func readQuery(c *cli.Context) (string, error) {
	var query string

	flags := cmd.GetFlags()
	if 0 < len(flags.Source) {
		fp, err := os.Open(flags.Source)
		if err != nil {
			return query, err
		}
		defer fp.Close()

		buf, err := ioutil.ReadAll(fp)
		if err != nil {
			return query, err
		}
		query = string(buf)

	} else {
		if c.NArg() != 1 {
			return query, errors.New("query is empty")
		}
		query = c.Args().First()
	}

	return query, nil
}

func setGlobalFlags(c *cli.Context) error {
	if err := cmd.SetDelimiter(c.GlobalString("delimiter")); err != nil {
		return err
	}
	if err := cmd.SetEncoding(c.GlobalString("encoding")); err != nil {
		return err
	}
	if err := cmd.SetLineBreak(c.String("line-break")); err != nil {
		return err
	}
	if err := cmd.SetLocation(c.String("timezone")); err != nil {
		return err
	}
	if err := cmd.SetRepository(c.GlobalString("repository")); err != nil {
		return err
	}
	if err := cmd.SetSource(c.GlobalString("source")); err != nil {
		return err
	}
	cmd.SetDatetimeFormat(c.GlobalString("datetime-format"))
	cmd.SetNoHeader(c.GlobalBool("no-header"))
	cmd.SetWithoutNull(c.GlobalBool("without-null"))
	return nil
}

func setWriteFlags(c *cli.Context) error {
	if err := cmd.SetWriteEncoding(c.String("write-encoding")); err != nil {
		return err
	}
	if err := cmd.SetOut(c.String("out")); err != nil {
		return err
	}
	if err := cmd.SetFormat(c.String("format")); err != nil {
		return err
	}
	if err := cmd.SetWriteDelimiter(c.String("write-delimiter")); err != nil {
		return err
	}
	cmd.SetWithoutHeader(c.Bool("without-header"))
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

var maxAge string

func abortTLS(conn net.Conn) {
	// This sends a TLS v1.2 alert packet regardless of query.
	// We respond the certificate authority (CA) that issued
	// the requesters certificate is unknown to us. This is possibly
	// the shortest response to a TLS (HTTPS) connection which
	// initiates a graceful shutdown on both ends.
	//
	// Note: This isn't TLS 1.3 compatible. Once browsers start
	//       deprecating 1.2 this will need to be overhauled. The
	//       1.3 specification is nothing like 1.2.
	//
	// The original idea came from h0tw1r3. Relevant projects:
	//  https://github.com/kvic-z/pixelserv-tls/wiki/Command-Line-Options
	//  https://github.com/h0tw1r3/pixelserv/blob/master/pixelserv.c
	_, _ = conn.Write([]byte{
		'\x15',         // Alert protocol header (21)
		'\x03', '\x03', // TLS v1.2 (RFC 5246)
		'\x00', '\x02', // Message length (2)
		'\x02',         // Alert level fatal (2)
		'\x30'})        // Unknown Certificate Authority (48)
	conn.Close()
}

func nullHandler(w http.ResponseWriter, r *http.Request) {
	u, _ := url.QueryUnescape(r.URL.String())

	for _, value := range []string{"?", ";", "#"} {
		if strings.Contains(u, value) {
			u = strings.Split(u, value)[0]
		}
	}

	suffix := ""
	if strings.Contains(u, ".") {
		tmp := strings.Split(u, ".")
		suffix = strings.ToLower(tmp[len(tmp)-1])
	}

	// Locate alternate suffix spellings or related file types
	if realSuffix, ok := AltSuffix[suffix]; ok == true {
		suffix = realSuffix
	}

	if _, ok := NotFoundFiles[suffix]; ok == true {
		http.NotFound(w, r)
		return
	}

	w.Header().Set("Cache-Control", "public, max-age=" + maxAge)
	if f, ok := nullFiles[suffix]; ok == true {
		w.Header().Set("Content-Type", f.content)
		if f.data != nil {
			w.Write(f.data)
		}
	} else {
		f = nullFiles["html"] // unknown suffixes become HTML
		w.Header().Set("Content-Type", f.content)
		w.Write(f.data)
	}
}

func main() {
	// Parse command line arguments
	httpAddr := flag.String("a", "", "http address (default '' = all)")
	httpPort := flag.Int("p", 80, "http port")
	httpsAddr := flag.String("A", "", "https address (default '' = all)")
	httpsPort := flag.Int("P", 443, "https port")
	tmpMaxAge := flag.Int("m", 31536000, "content cache age in secs")
	flag.Parse()
	maxAge = strconv.Itoa(*tmpMaxAge)

	// Starting HTTP server
	addr := *httpAddr + ":" + strconv.Itoa(*httpPort)
	http.HandleFunc("/", nullHandler)
	go func() {
		if err := http.ListenAndServe(addr, nil); err != nil {
			log.Fatal("HTTP service error: " + err.Error())
		}
	}()

	// Starting the abort TLS (HTTPS) server
	sslAddr := *httpsAddr + ":" + strconv.Itoa(*httpsPort)
	l, err := net.Listen("tcp", sslAddr)
	if err != nil {
		log.Fatal("Abort TLS listen error: " + err.Error())
	}
	defer l.Close()
	for {
		conn, err := l.Accept()
		if err != nil {
			log.Println("Abort TLS accept error: " + err.Error())
		}
		go abortTLS(conn)
	}
}
<commit_msg>main: simplify and cleanup the nullHandler<commit_after>package main

import (
	"flag"
	"log"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

var maxAge string

func abortTLS(conn net.Conn) {
	// This sends a TLS v1.2 alert packet regardless of query.
	// We respond the certificate authority (CA) that issued
	// the requesters certificate is unknown to us. This is possibly
	// the shortest response to a TLS (HTTPS) connection which
	// initiates a graceful shutdown on both ends.
	//
	// Note: This isn't TLS 1.3 compatible. Once browsers start
	//       deprecating 1.2 this will need to be overhauled. The
	//       1.3 specification is nothing like 1.2.
	//
	// The original idea came from h0tw1r3. Relevant projects:
	//  https://github.com/kvic-z/pixelserv-tls/wiki/Command-Line-Options
	//  https://github.com/h0tw1r3/pixelserv/blob/master/pixelserv.c
	_, _ = conn.Write([]byte{
		'\x15',         // Alert protocol header (21)
		'\x03', '\x03', // TLS v1.2 (RFC 5246)
		'\x00', '\x02', // Message length (2)
		'\x02',         // Alert level fatal (2)
		'\x30'})        // Unknown Certificate Authority (48)
	conn.Close()
}

func nullHandler(w http.ResponseWriter, r *http.Request) {
	u, _ := url.QueryUnescape(r.URL.String())

	// RFC 3986, Section 3 lists '?' as a query delimiter,
	// '#' as a fragment delimiter, and ';' as a sub-delimiter.
	// All three cannot be part of the path. Remove them.
	for _, value := range []string{"?", ";", "#"} {
		if strings.Contains(u, value) {
			u = strings.Split(u, value)[0]
		}
	}

	// Obtain the file suffix in the URI, if any.
	suffix := ""
	idx := strings.LastIndex(u, ".")
	if idx != -1 {
		suffix = u[idx+1:len(u)]
	}

	// If this is an alternate suffix, replace with the real one.
	if realSuffix, ok := AltSuffix[suffix]; ok == true {
		suffix = realSuffix
	}

	// These are suffixes where we return 404, not found.
	if _, ok := NotFoundFiles[suffix]; ok == true {
		http.NotFound(w, r)
		return
	}

	// Fetch the null file for this suffix. Use HTML as the default case.
	f, ok := nullFiles[suffix]
	if ok != true {
		f = nullFiles["html"]
	}
	w.Header().Set("Cache-Control", "public, max-age=" + maxAge)
	w.Header().Set("Content-Type", f.content)
	if f.data != nil {
		w.Write(f.data)
	}
}

func main() {
	// Parse command line arguments
	httpAddr := flag.String("a", "", "http address (default '' = all)")
	httpPort := flag.Int("p", 80, "http port")
	httpsAddr := flag.String("A", "", "https address (default '' = all)")
	httpsPort := flag.Int("P", 443, "https port")
	tmpMaxAge := flag.Int("m", 31536000, "content cache age in secs")
	flag.Parse()
	maxAge = strconv.Itoa(*tmpMaxAge)

	// Starting HTTP server
	addr := *httpAddr + ":" + strconv.Itoa(*httpPort)
	http.HandleFunc("/", nullHandler)
	go func() {
		if err := http.ListenAndServe(addr, nil); err != nil {
			log.Fatal("HTTP service error: " + err.Error())
		}
	}()

	// Starting the abort TLS (HTTPS) server
	sslAddr := *httpsAddr + ":" + strconv.Itoa(*httpsPort)
	l, err := net.Listen("tcp", sslAddr)
	if err != nil {
		log.Fatal("Abort TLS listen error: " + err.Error())
	}
	defer l.Close()
	for {
		conn, err := l.Accept()
		if err != nil {
			log.Println("Abort TLS accept error: " + err.Error())
		}
		go abortTLS(conn)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"flag"
	"os"
	"path"
	"strings"
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"github.com/Knorkebrot/ansirgb"
	"github.com/olekukonko/ts"
)

type Block struct {
	top	*ansirgb.Color
	bottom	*ansirgb.Color
}

func (b *Block) String() string {
	ret := fmt.Sprintf("\033[48;5;%dm", b.bottom.Code)
	if b.top != nil {
		ret += fmt.Sprintf("\033[38;5;%dm", b.top.Code)
		// If it's not a UTF-8 terminal, fall back to '#'
		if strings.Contains(os.Getenv("LC_ALL"), "UTF-8") ||
		   strings.Contains(os.Getenv("LANG"), "UTF-8") {
			ret += "\u2580"
		} else {
			ret += "#"
		}
	} else {
		ret += " "
	}
	return ret
}

func reset() {
	// add a space to prevent artifacts after resizing
	fmt.Printf("\033[0m ")
}

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

func main() {
	var width int
	flag.IntVar(&width, "w", 0, "Output width, use 0 for terminal width")
	flag.Usage = usage
	flag.Parse()

	if len(flag.Args()) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	if width == 0 {
		size, err := ts.GetSize()
		if err != nil {
			fmt.Fprintln(os.Stderr, err, "\nYou may need to "+
				"set width manually using -w num")
			os.Exit(2)
		}
		width = size.Col() - 1	// -1 for the reset column
	}

	for _, fpath := range flag.Args() {
		fh, err := os.Open(fpath)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(10)
		}

		img, _, err := image.Decode(fh)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			fh.Close()
			os.Exit(20)
		}

		imgWidth := img.Bounds().Dx()
		imgHeight := img.Bounds().Dy()

		if imgWidth < width {
			width = imgWidth
		}

		ratio := float64(imgWidth) / float64(width)
		rows := int(float64(imgHeight) / ratio)

		for i := 1; i < rows; i += 2 {
			for j := 0; j < width; j++ {
				// TODO: get average color of the area instead
				// of one pixel?
				x := int(ratio * float64(j))
				yTop := int(ratio * float64(i - 1))
				yBottom := int(ratio * float64(i))

				top := ansirgb.Convert(img.At(x, yTop))
				bottom := ansirgb.Convert(img.At(x, yBottom))

				b := &Block{}
				b.bottom = bottom

				// Foreground colors are lighter in some terminals.
				// Ignore top (FG) if it's the same color anyway
				if top.Code != bottom.Code {
					b.top = top
				}

				fmt.Printf("%s", b)
			}
			reset()
			fmt.Printf("\n")
		}
		fh.Close()

		fmt.Println("File:", path.Base(fpath), "size:", imgWidth, "x", imgHeight)
	}
}
<commit_msg>use filepath, not path (path is for slash seperated stuff)<commit_after>package main

import (
	"fmt"
	"flag"
	"os"
	"path/filepath"
	"strings"
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"github.com/Knorkebrot/ansirgb"
	"github.com/olekukonko/ts"
)

type Block struct {
	top	*ansirgb.Color
	bottom	*ansirgb.Color
}

func (b *Block) String() string {
	ret := fmt.Sprintf("\033[48;5;%dm", b.bottom.Code)
	if b.top != nil {
		ret += fmt.Sprintf("\033[38;5;%dm", b.top.Code)
		// If it's not a UTF-8 terminal, fall back to '#'
		if strings.Contains(os.Getenv("LC_ALL"), "UTF-8") ||
		   strings.Contains(os.Getenv("LANG"), "UTF-8") {
			ret += "\u2580"
		} else {
			ret += "#"
		}
	} else {
		ret += " "
	}
	return ret
}

func reset() {
	// add a space to prevent artifacts after resizing
	fmt.Printf("\033[0m ")
}

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

func main() {
	var width int
	flag.IntVar(&width, "w", 0, "Output width, use 0 for terminal width")
	flag.Usage = usage
	flag.Parse()

	if len(flag.Args()) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	if width == 0 {
		size, err := ts.GetSize()
		if err != nil {
			fmt.Fprintln(os.Stderr, err, "\nYou may need to "+
				"set width manually using -w num")
			os.Exit(2)
		}
		width = size.Col() - 1	// -1 for the reset column
	}

	for _, fpath := range flag.Args() {
		fh, err := os.Open(fpath)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(10)
		}

		img, _, err := image.Decode(fh)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			fh.Close()
			os.Exit(20)
		}

		imgWidth := img.Bounds().Dx()
		imgHeight := img.Bounds().Dy()

		if imgWidth < width {
			width = imgWidth
		}

		ratio := float64(imgWidth) / float64(width)
		rows := int(float64(imgHeight) / ratio)

		for i := 1; i < rows; i += 2 {
			for j := 0; j < width; j++ {
				// TODO: get average color of the area instead
				// of one pixel?
				x := int(ratio * float64(j))
				yTop := int(ratio * float64(i - 1))
				yBottom := int(ratio * float64(i))

				top := ansirgb.Convert(img.At(x, yTop))
				bottom := ansirgb.Convert(img.At(x, yBottom))

				b := &Block{}
				b.bottom = bottom

				// Foreground colors are lighter in some terminals.
				// Ignore top (FG) if it's the same color anyway
				if top.Code != bottom.Code {
					b.top = top
				}

				fmt.Printf("%s", b)
			}
			reset()
			fmt.Printf("\n")
		}
		fh.Close()

		fmt.Println("File:", filepath.Base(fpath), "size:", imgWidth, "x", imgHeight)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"time"
	"encoding/json"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"log"
	"os"
	//"io"
	"fmt"
	"database/sql"
	_ "github.com/lib/pq"
	"gopkg.in/antage/eventsource.v1"
)

var conn *sql.DB
var es eventsource.EventSource

func SetHeaders(w *http.ResponseWriter) {
	(*w).Header().Set("Access-Control-Allow-Origin", "*")
	(*w).Header().Set("Content-Type", "application/json")
}

func GetBlog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM blog")
	data := []BlogPost{}
	for rows.Next() {
		post := BlogPost{}
		rows.Scan(&post.Id, &post.Titel, &post.Text, &post.Auteur, &post.Img_url, &post.Ctime, &post.Image)
		data = append(data, post)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT * FROM blog WHERE id = $1 LIMIT 1", ps.ByName("id"))
	data := BlogPost{}
	row.Scan(&data.Id, &data.Titel, &data.Text, &data.Auteur, &data.Img_url, &data.Ctime, &data.Image)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM spindata ORDER BY tijd DESC LIMIT 1")
	spin := SpinData{}
	rows.Next()
	rows.Scan(&spin.Id, &spin.Tijd, &spin.Mode, &spin.Hellingsgraad, &spin.Snelheid, &spin.Batterij, &spin.BallonCount)
	buf,_ := json.Marshal(spin)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinBatterij(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT batterij FROM spindata ORDER BY tijd DESC LIMIT 1")
	var data int
	row.Scan(&data)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinMode(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT mode FROM spindata ORDER BY tijd DESC LIMIT 1")
	var data string
	row.Scan(&data)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM spindata")
	data := []SpinData{}
	for rows.Next() {
		spin := SpinData{}
		rows.Scan(&spin.Id, &spin.Tijd, &spin.Mode, &spin.Hellingsgraad, &spin.Snelheid, &spin.Batterij, &spin.BallonCount)
		data = append(data, spin)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinBatterij(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT batterij FROM spindata")
	data := make([]int, 0)
	var scanInt int
	for rows.Next() {
		rows.Scan(&scanInt)
		data = append(data, scanInt)
	}
	buf,_ := json.Marshal(data)
	fmt.Printf(string(buf))
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinMode(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT mode FROM spindata")
	data := make([]string, 0)
	var scanStr string
	for rows.Next() {
		rows.Scan(&scanStr)
		data = append(data, scanStr)
	}
	buf,_ := json.Marshal(data)
	fmt.Printf(string(buf))
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT * FROM servodata ORDER BY tijd DESC LIMIT 1")
	servo := ServoData{}
	row.Scan(&servo.Id, &servo.ServoId, &servo.Tijd, &servo.Voltage, &servo.Positie, &servo.Load, &servo.Temperatuur)
	buf,_ := json.Marshal(servo)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM servodata")
	data := []ServoData{}
	for rows.Next() {
		servo := ServoData{}
		rows.Scan(&servo.Id, &servo.ServoId, &servo.Tijd, &servo.Voltage, &servo.Positie, &servo.Load, &servo.Temperatuur)
		data = append(data, servo)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLogs(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM logs")
	data := []LogData{}
	for rows.Next() {
		log := LogData{}
		rows.Scan(&log.Id, &log.Log)
		data = append(data, log)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func Test(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	buf,_ := json.Marshal("test")
	SetHeaders(&w)
	w.Write(buf)
}

func PostBlog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	//r.ParseMultipartForm(32 << 20)
	/*file, handler, err := r.FormFile("uploadfile")
	defer file.Close()
	if err == nil {
		fmt.Fprintf(w, "%v", handler.Header)
		f, err := os.OpenFile("./img/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			w.WriteHeader(500)
			return
		}
		defer f.Close()
		io.Copy(f, file)
	}

	err = nil*/

	//_,err := conn.Query("INSERT INTO blog (titel, text, auteur, ctime, image) VALUES ($1, $2, $3, $4, $5)", r.FormValue("titel"), r.FormValue("text"), r.FormValue("auteur"), time.Now(), "http://idp-api.herokuapp.com/img/"+handler.Filename)
	_,err := conn.Query("INSERT INTO blog (titel, text, auteur, ctime) VALUES ($1, $2, $3, $4)", r.FormValue("onderwerp"), r.FormValue("bericht"), r.FormValue("naam"), time.Now())
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	w.Header().Set("Content-Type", "text/html")
	w.WriteHeader(201)
	w.Write([]byte("<meta http-equiv=\"refresh\" content=\"1; url=http://knightspider.herokuapp.com/#/blog\">successful"))
}

func PostSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	//reqStr, _ := httputil.DumpRequest(r, true)
	w.Write([]byte(r.FormValue("mode")))
	//r.ParseForm()
	/*mode := r.FormValue("mode")
	hellingsgraad := r.FormValue("hellingsgraad")
	snelheid := r.FormValue("snelheid")
	batterij := r.FormValue("batterij")
	balloncount := r.FormValue("ballonCount")*/
	/*_,err := conn.Query("INSERT INTO spindata (tijd, mode, hellingsgraad, snelheid, batterij, balloncount) VALUES ($1, $2, $3, $4, $5, $6)", time.Now(),
		mode, hellingsgraad, snelheid, batterij, balloncount)
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(fmt.Sprintf("mode = %s, hellingsgraad = %s, batterij = %s, balloncount = %s", mode, hellingsgraad, batterij, balloncount)))
		w.Write([]byte(err.Error()))
		return
	}*/
	/*w.WriteHeader(201)
	w.Write([]byte(fmt.Sprintf("mode = %s, hellingsgraad = %s, snelheid = %s, batterij = %s, balloncount = %s", mode, hellingsgraad, snelheid, batterij, balloncount)))*/
	//w.Write([]byte("successful"))
}

func PostServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	_,err := conn.Query("INSERT INTO servodata (servo_id, tijd, voltage, positie, load, temperatuur) VALUES ($1, $2, $3, $4, $5, $6)",
		r.FormValue("servo_id"), time.Now(), r.FormValue("voltage"), r.FormValue("positie"), r.FormValue("load"), r.FormValue("Temperatuur"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	w.WriteHeader(201)
	w.Write([]byte("successful"))
}

func PostLog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	_,err := conn.Query("INSERT INTO logs (log) VALUES ($1)",
		r.FormValue("log"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	es.SendEventMessage(r.FormValue("log"), "log", "")
	w.WriteHeader(201)
	w.Write([]byte(r.FormValue("log")))
}

func Head(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	SetHeaders(&w)
	w.WriteHeader(204)
}

func main() {
	conn,_ = sql.Open("postgres", os.Getenv("DATABASE_URL"))
	defer conn.Close()

	es = eventsource.New(
		&eventsource.Settings{
			Timeout: 5 * time.Second,
			CloseOnTimeout: false,
			IdleTimeout: 30 * time.Minute,
		},
		func(req *http.Request) [][]byte {
			return [][]byte{
				[]byte("X-Accel-Buffering: no"),
				[]byte("Access-Control-Allow-Origin: *"),
			}
		},
	)
	defer es.Close()

	router := httprouter.New()
	router.HEAD("/*path", Head)
	router.GET("/test", Test)
	router.GET("/blog", GetBlog)
	router.GET("/blog/:id", GetPost)
	router.GET("/spin/latest", GetLatestSpinData)
	router.GET("/spin/latest/batterij", GetLatestSpinBatterij)
	router.GET("/spin/latest/mode", GetLatestSpinMode)
	router.GET("/spin/archive", GetArchivedSpinData)
	router.GET("/spin/archive/batterij", GetArchivedSpinBatterij)
	router.GET("/spin/archive/mode", GetArchivedSpinMode)
	router.GET("/servo/latest", GetLatestServoData)
	router.GET("/servo/archive", GetArchivedServoData)
	router.GET("/log", GetLogs)
	router.POST("/blog", PostBlog)
	router.POST("/spin", PostSpinData)
	router.POST("/servo", PostServoData)
	router.POST("/log", PostLog)

	http.Handle("/subscribe", es)
	http.Handle("/", router)

	port := os.Getenv("PORT")
	if port == "" {
		port = "3000"
	}
	fmt.Printf("Starting server at localhost:%s...", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}<commit_msg>postformvalue<commit_after>package main

import (
	"time"
	"encoding/json"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"net/http/httputil"
	"log"
	"os"
	//"io"
	"fmt"
	"database/sql"
	_ "github.com/lib/pq"
	"gopkg.in/antage/eventsource.v1"
)

var conn *sql.DB
var es eventsource.EventSource

func SetHeaders(w *http.ResponseWriter) {
	(*w).Header().Set("Access-Control-Allow-Origin", "*")
	(*w).Header().Set("Content-Type", "application/json")
}

func GetBlog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM blog")
	data := []BlogPost{}
	for rows.Next() {
		post := BlogPost{}
		rows.Scan(&post.Id, &post.Titel, &post.Text, &post.Auteur, &post.Img_url, &post.Ctime, &post.Image)
		data = append(data, post)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT * FROM blog WHERE id = $1 LIMIT 1", ps.ByName("id"))
	data := BlogPost{}
	row.Scan(&data.Id, &data.Titel, &data.Text, &data.Auteur, &data.Img_url, &data.Ctime, &data.Image)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM spindata ORDER BY tijd DESC LIMIT 1")
	spin := SpinData{}
	rows.Next()
	rows.Scan(&spin.Id, &spin.Tijd, &spin.Mode, &spin.Hellingsgraad, &spin.Snelheid, &spin.Batterij, &spin.BallonCount)
	buf,_ := json.Marshal(spin)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinBatterij(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT batterij FROM spindata ORDER BY tijd DESC LIMIT 1")
	var data int
	row.Scan(&data)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinMode(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT mode FROM spindata ORDER BY tijd DESC LIMIT 1")
	var data string
	row.Scan(&data)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM spindata")
	data := []SpinData{}
	for rows.Next() {
		spin := SpinData{}
		rows.Scan(&spin.Id, &spin.Tijd, &spin.Mode, &spin.Hellingsgraad, &spin.Snelheid, &spin.Batterij, &spin.BallonCount)
		data = append(data, spin)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinBatterij(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT batterij FROM spindata")
	data := make([]int, 0)
	var scanInt int
	for rows.Next() {
		rows.Scan(&scanInt)
		data = append(data, scanInt)
	}
	buf,_ := json.Marshal(data)
	fmt.Printf(string(buf))
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinMode(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT mode FROM spindata")
	data := make([]string, 0)
	var scanStr string
	for rows.Next() {
		rows.Scan(&scanStr)
		data = append(data, scanStr)
	}
	buf,_ := json.Marshal(data)
	fmt.Printf(string(buf))
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT * FROM servodata ORDER BY tijd DESC LIMIT 1")
	servo := ServoData{}
	row.Scan(&servo.Id, &servo.ServoId, &servo.Tijd, &servo.Voltage, &servo.Positie, &servo.Load, &servo.Temperatuur)
	buf,_ := json.Marshal(servo)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM servodata")
	data := []ServoData{}
	for rows.Next() {
		servo := ServoData{}
		rows.Scan(&servo.Id, &servo.ServoId, &servo.Tijd, &servo.Voltage, &servo.Positie, &servo.Load, &servo.Temperatuur)
		data = append(data, servo)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLogs(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM logs")
	data := []LogData{}
	for rows.Next() {
		log := LogData{}
		rows.Scan(&log.Id, &log.Log)
		data = append(data, log)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func Test(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	buf,_ := json.Marshal("test")
	SetHeaders(&w)
	w.Write(buf)
}

func PostBlog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	//r.ParseMultipartForm(32 << 20)
	/*file, handler, err := r.FormFile("uploadfile")
	defer file.Close()
	if err == nil {
		fmt.Fprintf(w, "%v", handler.Header)
		f, err := os.OpenFile("./img/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			w.WriteHeader(500)
			return
		}
		defer f.Close()
		io.Copy(f, file)
	}

	err = nil*/

	//_,err := conn.Query("INSERT INTO blog (titel, text, auteur, ctime, image) VALUES ($1, $2, $3, $4, $5)", r.FormValue("titel"), r.FormValue("text"), r.FormValue("auteur"), time.Now(), "http://idp-api.herokuapp.com/img/"+handler.Filename)
	_,err := conn.Query("INSERT INTO blog (titel, text, auteur, ctime) VALUES ($1, $2, $3, $4)", r.FormValue("onderwerp"), r.FormValue("bericht"), r.FormValue("naam"), time.Now())
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	w.Header().Set("Content-Type", "text/html")
	w.WriteHeader(201)
	reqStr, _ := httputil.DumpRequest(r,true)
	w.Write(reqStr)
	//w.Write([]byte("<meta http-equiv=\"refresh\" content=\"1; url=http://knightspider.herokuapp.com/#/blog\">successful"))
}

func PostSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	//reqStr, _ := httputil.DumpRequest(r, true)
	w.Write([]byte(r.FormValue("mode")))
	//r.ParseForm()
	/*mode := r.FormValue("mode")
	hellingsgraad := r.FormValue("hellingsgraad")
	snelheid := r.FormValue("snelheid")
	batterij := r.FormValue("batterij")
	balloncount := r.FormValue("ballonCount")*/
	/*_,err := conn.Query("INSERT INTO spindata (tijd, mode, hellingsgraad, snelheid, batterij, balloncount) VALUES ($1, $2, $3, $4, $5, $6)", time.Now(),
		mode, hellingsgraad, snelheid, batterij, balloncount)
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(fmt.Sprintf("mode = %s, hellingsgraad = %s, batterij = %s, balloncount = %s", mode, hellingsgraad, batterij, balloncount)))
		w.Write([]byte(err.Error()))
		return
	}*/
	/*w.WriteHeader(201)
	w.Write([]byte(fmt.Sprintf("mode = %s, hellingsgraad = %s, snelheid = %s, batterij = %s, balloncount = %s", mode, hellingsgraad, snelheid, batterij, balloncount)))*/
	//w.Write([]byte("successful"))
}

func PostServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	_,err := conn.Query("INSERT INTO servodata (servo_id, tijd, voltage, positie, load, temperatuur) VALUES ($1, $2, $3, $4, $5, $6)",
		r.FormValue("servo_id"), time.Now(), r.FormValue("voltage"), r.FormValue("positie"), r.FormValue("load"), r.FormValue("Temperatuur"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	w.WriteHeader(201)
	w.Write([]byte("successful"))
}

func PostLog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	_,err := conn.Query("INSERT INTO logs (log) VALUES ($1)",
		r.FormValue("log"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	es.SendEventMessage(r.FormValue("log"), "log", "")
	w.WriteHeader(201)
	w.Write([]byte(r.FormValue("log")))
}

func Head(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	SetHeaders(&w)
	w.WriteHeader(204)
}

func main() {
	conn,_ = sql.Open("postgres", os.Getenv("DATABASE_URL"))
	defer conn.Close()

	es = eventsource.New(
		&eventsource.Settings{
			Timeout: 5 * time.Second,
			CloseOnTimeout: false,
			IdleTimeout: 30 * time.Minute,
		},
		func(req *http.Request) [][]byte {
			return [][]byte{
				[]byte("X-Accel-Buffering: no"),
				[]byte("Access-Control-Allow-Origin: *"),
			}
		},
	)
	defer es.Close()

	router := httprouter.New()
	router.HEAD("/*path", Head)
	router.GET("/test", Test)
	router.GET("/blog", GetBlog)
	router.GET("/blog/:id", GetPost)
	router.GET("/spin/latest", GetLatestSpinData)
	router.GET("/spin/latest/batterij", GetLatestSpinBatterij)
	router.GET("/spin/latest/mode", GetLatestSpinMode)
	router.GET("/spin/archive", GetArchivedSpinData)
	router.GET("/spin/archive/batterij", GetArchivedSpinBatterij)
	router.GET("/spin/archive/mode", GetArchivedSpinMode)
	router.GET("/servo/latest", GetLatestServoData)
	router.GET("/servo/archive", GetArchivedServoData)
	router.GET("/log", GetLogs)
	router.POST("/blog", PostBlog)
	router.POST("/spin", PostSpinData)
	router.POST("/servo", PostServoData)
	router.POST("/log", PostLog)

	http.Handle("/subscribe", es)
	http.Handle("/", router)

	port := os.Getenv("PORT")
	if port == "" {
		port = "3000"
	}
	fmt.Printf("Starting server at localhost:%s...", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/asdine/storm"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"

	_ "github.com/joho/godotenv/autoload"

	"github.com/auth0-community/go-auth0"
	"gopkg.in/square/go-jose.v2"
)

func createMux() (*storm.DB, *echo.Echo) {
	// Setup Storm
	dbPath := os.Getenv("DB_PATH")

	db, err := storm.Open(fmt.Sprintf("%s/imascg.db", dbPath))

	if err != nil {
		fmt.Println(err)
		panic("Storm DB could not be opened")
	}

	// Setup Echo
	e := echo.New()

	e.Use(middleware.CORS())
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())
	e.Use(middleware.Gzip())

	/// Setup Auth0 middleware
	/// Whitelist filtering will only be active if these values are provided
	domain := os.Getenv("AUTH0_DOMAIN")
	client := os.Getenv("AUTH0_CLIENT")
	secret := os.Getenv("AUTH0_SECRET")

	if len(domain) > 0 && len(client) > 0 && len(secret) > 0 {
		url := fmt.Sprintf("https://%s/", domain)
		provider := auth0.NewKeyProvider([]byte(secret))
		config := auth0.NewConfiguration(provider, []string{client}, url, jose.HS256)
		validator := auth0.NewValidator(config)

		/// Setup Whitelist middleware
		allowed := func() []string {
			editors := make([]Editor, 0)
			if err := db.All(&editors); err != nil {
				fmt.Println(err)
			}
			allowed := make([]string, len(editors))
			for index, value := range editors {
				allowed[index] = value.ID
			}
			return allowed
		}

		e.Use(Auth0(validator))
		e.Use(Whitelist(allowed))
	}

	return db, e
}

func main() {
	defer db.Close()

	/// Setup target and serve
	host := os.Getenv("HOST")
	port := os.Getenv("PORT")

	target := fmt.Sprintf("%s:%s", host, port)

	e.Logger.Fatal(e.Start(target))
}
<commit_msg>Add full database download<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/asdine/storm"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"

	_ "github.com/joho/godotenv/autoload"

	"github.com/auth0-community/go-auth0"
	"gopkg.in/square/go-jose.v2"
)

func createMux() (*storm.DB, *echo.Echo) {
	// Setup Storm
	dbPath := os.Getenv("DB_PATH")
	dbFile := fmt.Sprintf("%s/imascg.db", dbPath)

	db, err := storm.Open(dbFile)

	if err != nil {
		fmt.Println(err)
		panic("Storm DB could not be opened")
	}

	// Setup Echo
	e := echo.New()

	e.Use(middleware.CORS())
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())
	e.Use(middleware.Gzip())

	e.GET("/download", func(c echo.Context) error {
		return c.Attachment(dbFile, "imascg.db")
	})

	/// Setup Auth0 middleware
	/// Whitelist filtering will only be active if these values are provided
	domain := os.Getenv("AUTH0_DOMAIN")
	client := os.Getenv("AUTH0_CLIENT")
	secret := os.Getenv("AUTH0_SECRET")

	if len(domain) > 0 && len(client) > 0 && len(secret) > 0 {
		url := fmt.Sprintf("https://%s/", domain)
		provider := auth0.NewKeyProvider([]byte(secret))
		config := auth0.NewConfiguration(provider, []string{client}, url, jose.HS256)
		validator := auth0.NewValidator(config)

		/// Setup Whitelist middleware
		allowed := func() []string {
			editors := make([]Editor, 0)
			if err := db.All(&editors); err != nil {
				fmt.Println(err)
			}
			allowed := make([]string, len(editors))
			for index, value := range editors {
				allowed[index] = value.ID
			}
			return allowed
		}

		e.Use(Auth0(validator))
		e.Use(Whitelist(allowed))
	}

	return db, e
}

func main() {
	defer db.Close()

	/// Setup target and serve
	host := os.Getenv("HOST")
	port := os.Getenv("PORT")

	target := fmt.Sprintf("%s:%s", host, port)

	e.Logger.Fatal(e.Start(target))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	bserrors "github.com/bugsnag/bugsnag-go/errors"
	"github.com/dynport/dgtk/cli"
	"github.com/phrase/phraseapp-go/phraseapp"
)

func main() {
	Run()
}

const phraseAppSupport = "support@phraseapp.com"

func Run() {
	var cfg *phraseapp.Config
	defer func() {
		if recovered := recover(); recovered != nil {
			if recovered, ok := recovered.(error); ok && PHRASEAPP_CLIENT_VERSION != "DEV" {
				reportError(bserrors.New(recovered, 3), cfg)
			}
			printError(fmt.Errorf("This should not have happened: %s - Contact support: %s", recovered, phraseAppSupport))
			os.Exit(1)
		}
	}()

	phraseapp.ClientVersion = PHRASEAPP_CLIENT_VERSION
	CheckForUpdate(os.Stderr)

	cfg, err := phraseapp.ReadConfig()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %s\n", err)
		os.Exit(2)
	}

	r, err := router(cfg)
	if err != nil {
		printError(err)
		os.Exit(3)
	}

	switch err := r.RunWithArgs(); err {
	case cli.ErrorHelpRequested, cli.ErrorNoRoute:
		os.Exit(1)
	case nil:
		os.Exit(0)
	default:
		printError(err)
		os.Exit(1)
	}
}
<commit_msg>don't check for error type; print stack in debug mode (#78)<commit_after>package main

import (
	"fmt"
	"os"
	"runtime/debug"

	bserrors "github.com/bugsnag/bugsnag-go/errors"
	"github.com/dynport/dgtk/cli"
	"github.com/phrase/phraseapp-go/phraseapp"
)

func main() {
	Run()
}

const phraseAppSupport = "support@phraseapp.com"

func Run() {
	var cfg *phraseapp.Config
	defer func() {
		if recovered := recover(); recovered != nil {
			if PHRASEAPP_CLIENT_VERSION != "DEV" {
				reportError(bserrors.New(recovered, 1), cfg)
			}
			if Debug {
				fmt.Fprintf(os.Stderr, "%v\n%s", recovered, debug.Stack())
			}
			printError(fmt.Errorf("This should not have happened: %s - Contact support: %s", recovered, phraseAppSupport))
			os.Exit(1)
		}
	}()

	phraseapp.ClientVersion = PHRASEAPP_CLIENT_VERSION
	CheckForUpdate(os.Stderr)

	cfg, err := phraseapp.ReadConfig()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %s\n", err)
		os.Exit(2)
	}

	r, err := router(cfg)
	if err != nil {
		printError(err)
		os.Exit(3)
	}

	switch err := r.RunWithArgs(); err {
	case cli.ErrorHelpRequested, cli.ErrorNoRoute:
		os.Exit(1)
	case nil:
		os.Exit(0)
	default:
		printError(err)
		os.Exit(1)
	}
}
<|endoftext|>