<commit_before>package main

import (
	"gopkg.in/alecthomas/kingpin.v2"
	"os"
	masterServer "github.com/030io/whalefs/master"
	"github.com/030io/whalefs/volume/manager"
	"fmt"
	"net"
	"net/http"
)

const version = "1.1 beta"

var (
	app = kingpin.New("whalefs", "A simple filesystem for small file.  Version: " + version)

	verbose = app.Flag("verbose", "verbose level").Short('v').Default("0").Int()

	master = app.Command("master", "master server")
	masterPort = master.Flag("port", "master port").Short('p').Default("8888").Int()
	masterReplication = master.Flag("replication", "replication setting").Short('r').Default("000").String()
	masterRedisServer = master.Flag("redisIP", "ip of redis server").Default("localhost").String()
	masterRedisPort = master.Flag("redisPort", "ip of redis server").Default("6379").Int()
	masterRedisPW = master.Flag("redisPW", "password of redis server").String()
	masterRedisN = master.Flag("redisN", "database of redis server").Default("0").Int()

	volumeManager = app.Command("volume", "volume manager server")
	vmDir = volumeManager.Flag("dir", "directory to store data").Required().String()
	vmAdminHost = volumeManager.Flag("adminHost", "for manage files (default: auto detect by master)").String()
	vmAdminPort = volumeManager.Flag("adminPort", "for manage files (default: 7800-7899)").Int()
	vmPublicHost = volumeManager.Flag("publicHost", "for access files (default: auto detect by master)").String()
	vmPublicPort = volumeManager.Flag("publicPort", "for access files (default: 7900-7999)").Int()
	vmMasterHost = volumeManager.Flag("masterHost", "host of master server").Default("localhost").String()
	vmMasterPort = volumeManager.Flag("masterPort", "port of master server").Default("8888").Int()
	vmMachine = volumeManager.Flag("machine", "machine tag of volume manager server (defalut: auto detect by master)").String()
	vmDataCenter = volumeManager.Flag("dataCenter", "datacenter tag of volume manager server (defalut: \"\")").String()

	benchmark = app.Command("benchmark", "benchmark")
	bmMasterHost = benchmark.Flag("masterHost", "host of master server").Default("localhost").String()
	bmMasterPort = benchmark.Flag("masterPort", "post of master server").Default("8888").Int()
	bmConcurrent = benchmark.Flag("concurrent", "concurrent").Default("16").Int()
	bmNum = benchmark.Flag("num", "number of file write/read").Default("1000").Int()
	bmSize = benchmark.Flag("size", "size of file write/read").Default("1024").Int()
)

func main() {
	http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 1024

	command := kingpin.MustParse(app.Parse(os.Args[1:]))
	switch command {
	case master.FullCommand():
		m, err := masterServer.NewMaster()
		if err != nil {
			panic(m)
		}
		m.Metadata, err = masterServer.NewMetadataRedis(*masterRedisServer, *masterRedisPort, *masterRedisPW, *masterRedisN)
		if err != nil {
			panic(err)
		}
		m.Port = *masterPort
		for i, c := range *masterReplication {
			m.Replication[i] = int(c) - int('0')
		}
		m.Start()
	case volumeManager.FullCommand():
		vm, err := manager.NewVolumeManager(*vmDir)
		if err != nil {
			panic(err)
		}

		vm.AdminHost = *vmAdminHost
		if *vmAdminPort == 0 {
			*vmAdminPort, err = getFreeTcpPort(7800, 7900)
			if err != nil {
				panic(err)
			}
		}
		vm.AdminPort = *vmAdminPort

		vm.PublicHost = *vmPublicHost
		if *vmPublicPort == 0 {
			*vmPublicPort, err = getFreeTcpPort(7900, 8000)
			if err != nil {
				panic(err)
			}
		}
		vm.PublicPort = *vmPublicPort

		vm.MasterHost = *vmMasterHost
		vm.MasterPort = *vmMasterPort
		vm.Machine = *vmMachine
		vm.DataCenter = *vmDataCenter

		vm.Start()
	case benchmark.FullCommand():
		benchmark_()
	}
}

func getFreeTcpPort(start, end int) (int, error) {
	for i := start; i < end; i++ {
		if ln, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", i)); err == nil {
			ln.Close()
			return ln.Addr().(*net.TCPAddr).Port, nil
		}
	}
	return 0, fmt.Errorf("can't get a free port between [%d, %d)", start, end)
}
<commit_msg>add signal handler<commit_after>package main

import (
	"gopkg.in/alecthomas/kingpin.v2"
	"os"
	masterServer "github.com/030io/whalefs/master"
	"github.com/030io/whalefs/volume/manager"
	"fmt"
	"net"
	"net/http"
	"os/signal"
	"syscall"
)

const version = "1.1 beta"

var (
	app = kingpin.New("whalefs", "A simple filesystem for small file.  Version: " + version)

	verbose = app.Flag("verbose", "verbose level").Short('v').Default("0").Int()

	master = app.Command("master", "master server")
	masterPort = master.Flag("port", "master port").Short('p').Default("8888").Int()
	masterReplication = master.Flag("replication", "replication setting").Short('r').Default("000").String()
	masterRedisServer = master.Flag("redisIP", "ip of redis server").Default("localhost").String()
	masterRedisPort = master.Flag("redisPort", "ip of redis server").Default("6379").Int()
	masterRedisPW = master.Flag("redisPW", "password of redis server").String()
	masterRedisN = master.Flag("redisN", "database of redis server").Default("0").Int()

	volumeManager = app.Command("volume", "volume manager server")
	vmDir = volumeManager.Flag("dir", "directory to store data").Required().String()
	vmAdminHost = volumeManager.Flag("adminHost", "for manage files (default: auto detect by master)").String()
	vmAdminPort = volumeManager.Flag("adminPort", "for manage files (default: 7800-7899)").Int()
	vmPublicHost = volumeManager.Flag("publicHost", "for access files (default: auto detect by master)").String()
	vmPublicPort = volumeManager.Flag("publicPort", "for access files (default: 7900-7999)").Int()
	vmMasterHost = volumeManager.Flag("masterHost", "host of master server").Default("localhost").String()
	vmMasterPort = volumeManager.Flag("masterPort", "port of master server").Default("8888").Int()
	vmMachine = volumeManager.Flag("machine", "machine tag of volume manager server (defalut: auto detect by master)").String()
	vmDataCenter = volumeManager.Flag("dataCenter", "datacenter tag of volume manager server (defalut: \"\")").String()

	benchmark = app.Command("benchmark", "benchmark")
	bmMasterHost = benchmark.Flag("masterHost", "host of master server").Default("localhost").String()
	bmMasterPort = benchmark.Flag("masterPort", "post of master server").Default("8888").Int()
	bmConcurrent = benchmark.Flag("concurrent", "concurrent").Default("16").Int()
	bmNum = benchmark.Flag("num", "number of file write/read").Default("1000").Int()
	bmSize = benchmark.Flag("size", "size of file write/read").Default("1024").Int()
)

func main() {
	http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 1024

	signals := make(chan os.Signal)
	signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)

	command := kingpin.MustParse(app.Parse(os.Args[1:]))
	switch command {
	case master.FullCommand():
		m, err := masterServer.NewMaster()
		if err != nil {
			panic(m)
		}
		m.Metadata, err = masterServer.NewMetadataRedis(*masterRedisServer, *masterRedisPort, *masterRedisPW, *masterRedisN)
		if err != nil {
			panic(err)
		}
		m.Port = *masterPort
		for i, c := range *masterReplication {
			m.Replication[i] = int(c) - int('0')
		}

		go func() {
			m.Stop()
			sig := <-signals
			switch sig {
			case syscall.SIGINT:
				os.Exit(int(syscall.SIGINT))
			case syscall.SIGTERM:
				os.Exit(int(syscall.SIGTERM))
			}
		}()

		m.Start()
	case volumeManager.FullCommand():
		vm, err := manager.NewVolumeManager(*vmDir)
		if err != nil {
			panic(err)
		}

		vm.AdminHost = *vmAdminHost
		if *vmAdminPort == 0 {
			*vmAdminPort, err = getFreeTcpPort(7800, 7900)
			if err != nil {
				panic(err)
			}
		}
		vm.AdminPort = *vmAdminPort

		vm.PublicHost = *vmPublicHost
		if *vmPublicPort == 0 {
			*vmPublicPort, err = getFreeTcpPort(7900, 8000)
			if err != nil {
				panic(err)
			}
		}
		vm.PublicPort = *vmPublicPort

		vm.MasterHost = *vmMasterHost
		vm.MasterPort = *vmMasterPort
		vm.Machine = *vmMachine
		vm.DataCenter = *vmDataCenter

		go func() {
			vm.Stop()
			sig := <-signals
			switch sig {
			case syscall.SIGINT:
				os.Exit(int(syscall.SIGINT))
			case syscall.SIGTERM:
				os.Exit(int(syscall.SIGTERM))
			}
		}()

		vm.Start()
	case benchmark.FullCommand():
		go func() {
			sig := <-signals
			switch sig {
			case syscall.SIGINT:
				os.Exit(int(syscall.SIGINT))
			case syscall.SIGTERM:
				os.Exit(int(syscall.SIGTERM))
			}
		}()

		benchmark_()
	}
}

func getFreeTcpPort(start, end int) (int, error) {
	for i := start; i < end; i++ {
		if ln, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", i)); err == nil {
			ln.Close()
			return ln.Addr().(*net.TCPAddr).Port, nil
		}
	}
	return 0, fmt.Errorf("can't get a free port between [%d, %d)", start, end)
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/howeyc/fsnotify"
)

const (
	watchFlags = fsnotify.FSN_CREATE |
		fsnotify.FSN_DELETE |
		fsnotify.FSN_MODIFY
)

var (
	watcher  *fsnotify.Watcher
	watched  = make(map[string]struct{})
	exitCode = make(chan int)
	rootPath string

	emptyStruct = struct{}{}
	hasSuffix   = strings.HasSuffix

	buildQueued = false
)

func fatalIf(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func build() {
	{
		log.Println("glitch: building")
		cmd := exec.Command("go", "build")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rootPath
		if err := cmd.Run(); err != nil {
			return
		}
	}

	{
		log.Println("glitch: build OK - vetting")
		cmd := exec.Command("go", "vet", "./...")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rootPath
		if err := cmd.Run(); err != nil {
			return
		}
	}

	{
		log.Println("glitch: vet OK - testing")
		cmd := exec.Command("go", "test", "./...")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rootPath
		if err := cmd.Run(); err != nil {
			return
		}
	}

	{
		log.Println("glitch: test OK - installing")
		cmd := exec.Command("go", "install")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rootPath
		if err := cmd.Run(); err != nil {
			return
		}
	}

	log.Println("glitch: install OK - wating for next build event")
}

func maybeQueueBuild(path string) {
	buildQueued = hasSuffix(path, ".go")
}

func handleCreate(path string) {
	watch(path)
	maybeQueueBuild(path)
}

func handleDelete(path string) {
	if _, watching := watched[path]; watching {
		fatalIf(watcher.RemoveWatch(path))
		delete(watched, path)
	}
	maybeQueueBuild(path)
}

func handleModify(path string) {
	maybeQueueBuild(path)
}

func handleEvent(ev *fsnotify.FileEvent) {
	if len(ev.Name) > 0 {
		switch {
		case ev.IsCreate():
			handleCreate(ev.Name)
		case ev.IsDelete():
			handleDelete(ev.Name)
		case ev.IsModify():
			handleModify(ev.Name)
		}
	}
}

func watch(dir string) {
	if _, watching := watched[dir]; watching {
		return
	}

	walker := func(path string, fileInfo os.FileInfo, err error) error {
		if err == nil && fileInfo.IsDir() {
			if err = watcher.WatchFlags(path, watchFlags); err == nil {
				watched[path] = emptyStruct
			}
		}
		return err
	}

	fatalIf(filepath.Walk(dir, walker))
}

func periodicallyLogWatchedPaths() {
	logWatchedPaths := func() {
		log.Printf("glitch: watching: %v paths", len(watched))
		for path, _ := range watched {
			log.Println("glitch: watching:", path)
		}
	}

	for _ = range time.Tick(5 * time.Second) {
		logWatchedPaths()
	}
}

func periodicallyLogBuildStatus() {
	logBuildStatus := func() {
		log.Println("glitch: buildQueued:", buildQueued)
	}

	for _ = range time.Tick(300 * time.Millisecond) {
		logBuildStatus()
	}
}

func runEventLoop() {
	for {
		select {
		case ev := <-watcher.Event:
			handleEvent(ev)
		case err := <-watcher.Error:
			fatalIf(err)
		}
	}
}

func runBuildLoop() {
	consumeBuildQueue := func() {
		if buildQueued {
			buildQueued = false
			build()
		}
	}

	for _ = range time.Tick(1 * time.Second) {
		go consumeBuildQueue()
	}
}

func main() {
	wd, err := os.Getwd()
	fatalIf(err)
	rootPath = wd

	w, err := fsnotify.NewWatcher()
	fatalIf(err)
	watcher = w
	defer watcher.Close()

	//go periodicallyLogWatchedPaths()
	//go periodicallyLogBuildStatus()
	go runEventLoop()
	go runBuildLoop()

	watch(rootPath)
	os.Exit(<-exitCode)
}
<commit_msg>fatalIf -> panicIf; finally died, need to see where<commit_after>package main

import (
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/howeyc/fsnotify"
)

const (
	watchFlags = fsnotify.FSN_CREATE |
		fsnotify.FSN_DELETE |
		fsnotify.FSN_MODIFY
)

var (
	watcher  *fsnotify.Watcher
	watched  = make(map[string]struct{})
	exitCode = make(chan int)
	rootPath string

	emptyStruct = struct{}{}
	hasSuffix   = strings.HasSuffix

	buildQueued = false
)

func panicIf(err error) {
	if err != nil {
		panic(err)
	}
}

func build() {
	{
		log.Println("glitch: building")
		cmd := exec.Command("go", "build")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rootPath
		if err := cmd.Run(); err != nil {
			return
		}
	}

	{
		log.Println("glitch: build OK - vetting")
		cmd := exec.Command("go", "vet", "./...")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rootPath
		if err := cmd.Run(); err != nil {
			return
		}
	}

	{
		log.Println("glitch: vet OK - testing")
		cmd := exec.Command("go", "test", "./...")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rootPath
		if err := cmd.Run(); err != nil {
			return
		}
	}

	{
		log.Println("glitch: test OK - installing")
		cmd := exec.Command("go", "install")
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rootPath
		if err := cmd.Run(); err != nil {
			return
		}
	}

	log.Println("glitch: install OK - wating for next build event")
}

func maybeQueueBuild(path string) {
	buildQueued = hasSuffix(path, ".go")
}

func handleCreate(path string) {
	watch(path)
	maybeQueueBuild(path)
}

func handleDelete(path string) {
	if _, watching := watched[path]; watching {
		panicIf(watcher.RemoveWatch(path))
		delete(watched, path)
	}
	maybeQueueBuild(path)
}

func handleModify(path string) {
	maybeQueueBuild(path)
}

func handleEvent(ev *fsnotify.FileEvent) {
	if len(ev.Name) > 0 {
		switch {
		case ev.IsCreate():
			handleCreate(ev.Name)
		case ev.IsDelete():
			handleDelete(ev.Name)
		case ev.IsModify():
			handleModify(ev.Name)
		}
	}
}

func watch(dir string) {
	if _, watching := watched[dir]; watching {
		return
	}

	walker := func(path string, fileInfo os.FileInfo, err error) error {
		if err == nil && fileInfo.IsDir() {
			if err = watcher.WatchFlags(path, watchFlags); err == nil {
				watched[path] = emptyStruct
			}
		}
		return err
	}

	panicIf(filepath.Walk(dir, walker))
}

func periodicallyLogWatchedPaths() {
	logWatchedPaths := func() {
		log.Printf("glitch: watching: %v paths", len(watched))
		for path, _ := range watched {
			log.Println("glitch: watching:", path)
		}
	}

	for _ = range time.Tick(5 * time.Second) {
		logWatchedPaths()
	}
}

func periodicallyLogBuildStatus() {
	logBuildStatus := func() {
		log.Println("glitch: buildQueued:", buildQueued)
	}

	for _ = range time.Tick(300 * time.Millisecond) {
		logBuildStatus()
	}
}

func runEventLoop() {
	for {
		select {
		case ev := <-watcher.Event:
			handleEvent(ev)
		case err := <-watcher.Error:
			panicIf(err)
		}
	}
}

func runBuildLoop() {
	consumeBuildQueue := func() {
		if buildQueued {
			buildQueued = false
			build()
		}
	}

	for _ = range time.Tick(1 * time.Second) {
		go consumeBuildQueue()
	}
}

func main() {
	wd, err := os.Getwd()
	panicIf(err)
	rootPath = wd

	w, err := fsnotify.NewWatcher()
	panicIf(err)
	watcher = w
	defer watcher.Close()

	//go periodicallyLogWatchedPaths()
	//go periodicallyLogBuildStatus()
	go runEventLoop()
	go runBuildLoop()

	watch(rootPath)
	os.Exit(<-exitCode)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"log"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"time"

	"github.com/tinzenite/core"
)

const name = "music"
const path = "/home/tamino/Music"
const user = "Xamino"

func main() {
	model()
	// walkTest()
	// channel()
	// tinzenite()
}

func model() {
	start := time.Now()
	m, err := core.LoadModel(path)
	if err != nil {
		log.Println(err.Error())
	}
	elapsed := time.Since(start)
	elapsed = elapsed / time.Millisecond
	log.Printf("Output:\n\n%s\n", m.String())
	log.Printf("Took %d msec\n", elapsed)
	obj, err := m.Read()
	if err != nil {
		log.Println(err.Error())
		return
	}
	bin, _ := json.MarshalIndent(obj, "", "  ")
	log.Println(string(bin))
	// register channel for updates
	updates := make(chan core.UpdateMessage, 1)
	m.Register(updates)
	go func() {
		for {
			update := <-updates
			log.Printf("Update received!\nType: %s\nContent: %+v\n", update.Operation, update.Object)
		}
	}()
	// now allow manual operations
	reader := bufio.NewReader(os.Stdin)
	for {
		input, _ := reader.ReadString('\n')
		if strings.Contains(input, "exit") {
			break
		}
		err := m.Update()
		if err != nil {
			log.Println(err.Error())
		}
		// log.Printf("Output:\n\n%s\n", m.String())
		log.Println("Updated")
	}
}

type t struct {
}

func (*t) CallbackMessage(address, message string) {
	log.Println("Incomming: " + message)
}

func (*t) CallbackNewConnection(address, message string) {
	log.Println("Accepting: " + message)
}

func channel() {
	channel, err := core.CreateChannel("test", nil, &t{})
	if err != nil {
		log.Println(err.Error())
		return
	}
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	address, _ := channel.Address()
	log.Println("ID:\n" + address)
	for {
		select {
		case <-c:
			channel.Close()
			goto exit
		case <-time.Tick(10 * time.Second):
			err := channel.Send("ed284a9fa07142cb8f6fa8c821d7f722cf63d2c7f74390566c6949bdb898b33e", "Tick!")
			if err != nil {
				log.Println(err.Error())
			}
		}
	}
exit:
}

func tinzenite() bool {
	tinzenite, err := core.CreateTinzenite(name, path, "shana", user, false)
	if err == core.ErrIsTinzenite {
		err = core.RemoveTinzenite(path)
		if err != nil {
			log.Println(err.Error())
		}
		return false
	}
	if err != nil {
		log.Println(err.Error())
		return false
	}
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	address := tinzenite.Address()
	log.Println("ID:\n" + address)
	select {
	case <-c:
		tinzenite.Close()
	}
	return false
}

func walkTest() bool {
	testpath := "/home/tamino/Programming"
	ignorepath := "/home/tamino"
	matcher, err := core.CreateMatcher(ignorepath)
	if err != nil {
		log.Println(err.Error())
		return false
	}
	var objects int
	var count int64
	filepath.Walk(testpath, func(path string, info os.FileInfo, err error) error {
		if matcher.Ignore(path) {
			objects++
			return filepath.SkipDir
		}
		count += info.Size()
		return nil
	})
	log.Printf("Kept %dkb worth of objects, ignored %d objects\n", count/1024, objects)
	return false
}
<commit_msg>adapt<commit_after>package main

import (
	"bufio"
	"log"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"time"

	"github.com/tinzenite/core"
)

const name = "music"
const path = "/home/tamino/Music"
const user = "Xamino"

func main() {
	model()
	// walkTest()
	// channel()
	// tinzenite()
}

func model() {
	start := time.Now()
	m, err := core.LoadModel(path)
	if err != nil {
		log.Println(err.Error())
	}
	elapsed := time.Since(start)
	elapsed = elapsed / time.Millisecond
	// log.Printf("Output:\n\n%s\n", m.String())
	log.Printf("Took %d msec\n", elapsed)
	/*
		obj, err := m.Read()
		if err != nil {
			log.Println(err.Error())
			return
		}
		bin, _ := json.MarshalIndent(obj, "", "  ")
		log.Println(string(bin))
	*/
	// register channel for updates
	updates := make(chan core.UpdateMessage, 1)
	m.Register(updates)
	go func() {
		for {
			update := <-updates
			log.Printf("Update received!\nType: %s\nContent: %+v\n", update.Operation, update.Object)
		}
	}()
	// now allow manual operations
	reader := bufio.NewReader(os.Stdin)
	for {
		input, _ := reader.ReadString('\n')
		if strings.Contains(input, "exit") {
			break
		}
		start := time.Now()
		err := m.Update()
		elapsed := time.Since(start)
		if err != nil {
			log.Println(err.Error())
		}
		// log.Printf("Output:\n\n%s\n", m.String())
		log.Printf("Updated in %s\n", elapsed)
	}
}

type t struct {
}

func (*t) CallbackMessage(address, message string) {
	log.Println("Incomming: " + message)
}

func (*t) CallbackNewConnection(address, message string) {
	log.Println("Accepting: " + message)
}

func channel() {
	channel, err := core.CreateChannel("test", nil, &t{})
	if err != nil {
		log.Println(err.Error())
		return
	}
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	address, _ := channel.Address()
	log.Println("ID:\n" + address)
	for {
		select {
		case <-c:
			channel.Close()
			goto exit
		case <-time.Tick(10 * time.Second):
			err := channel.Send("ed284a9fa07142cb8f6fa8c821d7f722cf63d2c7f74390566c6949bdb898b33e", "Tick!")
			if err != nil {
				log.Println(err.Error())
			}
		}
	}
exit:
}

func tinzenite() bool {
	tinzenite, err := core.CreateTinzenite(name, path, "shana", user, false)
	if err == core.ErrIsTinzenite {
		err = core.RemoveTinzenite(path)
		if err != nil {
			log.Println(err.Error())
		}
		return false
	}
	if err != nil {
		log.Println(err.Error())
		return false
	}
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	address := tinzenite.Address()
	log.Println("ID:\n" + address)
	select {
	case <-c:
		tinzenite.Close()
	}
	return false
}

func walkTest() bool {
	testpath := "/home/tamino/Programming"
	ignorepath := "/home/tamino"
	matcher, err := core.CreateMatcher(ignorepath)
	if err != nil {
		log.Println(err.Error())
		return false
	}
	var objects int
	var count int64
	filepath.Walk(testpath, func(path string, info os.FileInfo, err error) error {
		if matcher.Ignore(path) {
			objects++
			return filepath.SkipDir
		}
		count += info.Size()
		return nil
	})
	log.Printf("Kept %dkb worth of objects, ignored %d objects\n", count/1024, objects)
	return false
}
<|endoftext|>


<commit_before>package main // import "github.com/tutumcloud/weave-daemon"

import (
	"log"
	"os"
	"os/exec"
	"strings"
	"time"

	"github.com/fsouza/go-dockerclient"
	"github.com/tutumcloud/go-tutum/tutum"
	"github.com/tutumcloud/weave-daemon/nodes"
)

func AttachContainer(c *docker.Client, container_id string) error {
	inspect, err := c.InspectContainer(container_id)

	if err != nil {
		return err
	}

	cidr := ""
	env_vars := inspect.Config.Env

	for i := range env_vars {
		if strings.HasPrefix(env_vars[i], "TUTUM_IP_ADDRESS=") {
			cidr = env_vars[i][len("TUTUM_IP_ADDRESS="):]
			break
		}
	}

	if cidr != "" {
		tries := 0
		for tries < 3 {

			log.Printf("%s: adding to weave with IP %s", container_id, cidr)
			cmd := exec.Command("/weave", "--local", "attach", cidr, container_id)

			_, err := cmd.StdoutPipe()
			if err != nil {
				return err
			}

			if err := cmd.Start(); err != nil {
				return err
			}

			if err := cmd.Wait(); err != nil {
				tries++

				if tries > 3 {
					break
				}
				return err
			} else {
				break
			}
		}
	} else {
		log.Printf("%s: cannot find the IP address to add to weave", container_id)
	}
	return nil
}

func ContainerAttachThread(c *docker.Client) error {

	listener := make(chan *docker.APIEvents)

	containers, err := c.ListContainers(docker.ListContainersOptions{All: false, Size: true, Limit: 0, Since: "", Before: ""})
	if err != nil {
		return err
	}

	for _, container := range containers {
		err := AttachContainer(c, container.ID)
		if err != nil {
			return err
		}

	}
	err = c.AddEventListener(listener)
	if err != nil {
		return err
	}

	defer func() error {

		err = c.RemoveEventListener(listener)
		if err != nil {
			return err
		}
		return nil
	}()

	timeout := time.After(1 * time.Second)

	for {
		select {
		case msg := <-listener:
			if msg.Status == "start" && !strings.HasPrefix(msg.From, "weaveworks/weave") {
				err := AttachContainer(c, msg.ID)
				if err != nil {
					log.Println(err)
					break
				}
			}
		case <-timeout:
			break
		}
	}
}

func discovering() {
	c := make(chan tutum.Event)
	e := make(chan error)
	nodes.DiscoverPeers()
	go tutum.TutumEvents(c, e)
Loop:
	for {
		select {
		case event := <-c:
			if event.Type == "node" && (event.State == "Deployed" || event.State == "Terminated") {
				err := nodes.DiscoverPeers()
				if err != nil {
					log.Println(err)
				}
			}
		case err := <-e:
			log.Println(err)
			go discovering()
			break Loop
		}
	}
}

func connectToDocker() (*docker.Client, error) {
	endpoint := "unix:///var/run/docker.sock"

	client, err := docker.NewClient(endpoint)

	if err != nil {

		log.Println(err)
	}
	return client, nil
}

func main() {

	log.Println("Start running daemon")

	//Init Docker client
	client, err := connectToDocker()
	if err != nil {
		log.Println(err)
	}

	node, err := tutum.GetNode(nodes.Tutum_Node_Api_Uri)
	if err != nil {
		log.Println(err)
	}
	nodes.Tutum_Node_Public_Ip = node.Public_ip
	log.Printf("This node IP is %s", nodes.Tutum_Node_Public_Ip)
	if os.Getenv("TUTUM_AUTH") != "" {
		log.Println("Detected Tutum API access - starting peer discovery thread")
		go discovering()
	}
	err = ContainerAttachThread(client)
	if err != nil {
		log.Println("ATTACH THREAD ERR")
		log.Println(err)
	}
}
<commit_msg>add container attach thread security<commit_after>package main // import "github.com/tutumcloud/weave-daemon"

import (
	"log"
	"os"
	"os/exec"
	"strings"
	"time"

	"github.com/fsouza/go-dockerclient"
	"github.com/tutumcloud/go-tutum/tutum"
	"github.com/tutumcloud/weave-daemon/nodes"
)

func AttachContainer(c *docker.Client, container_id string) error {
	inspect, err := c.InspectContainer(container_id)

	if err != nil {
		return err
	}

	cidr := ""
	env_vars := inspect.Config.Env

	for i := range env_vars {
		if strings.HasPrefix(env_vars[i], "TUTUM_IP_ADDRESS=") {
			cidr = env_vars[i][len("TUTUM_IP_ADDRESS="):]
			break
		}
	}

	if cidr != "" {
		tries := 0
		for tries < 3 {

			log.Printf("%s: adding to weave with IP %s", container_id, cidr)
			cmd := exec.Command("/weave", "--local", "attach", cidr, container_id)

			_, err := cmd.StdoutPipe()
			if err != nil {
				return err
			}

			if err := cmd.Start(); err != nil {
				return err
			}

			if err := cmd.Wait(); err != nil {
				tries++

				if tries > 3 {
					break
				}
				return err
			} else {
				break
			}
		}
	} else {
		log.Printf("%s: cannot find the IP address to add to weave", container_id)
	}
	return nil
}

func ContainerAttachThread(c *docker.Client) error {

	listener := make(chan *docker.APIEvents)

	containers, err := c.ListContainers(docker.ListContainersOptions{All: false, Size: true, Limit: 0, Since: "", Before: ""})
	if err != nil {
		return err
	}

	for _, container := range containers {
		err := AttachContainer(c, container.ID)
		if err != nil {
			return err
		}

	}
	err = c.AddEventListener(listener)
	if err != nil {
		return err
	}

	defer func() error {

		err = c.RemoveEventListener(listener)
		if err != nil {
			return err
		}
		return nil
	}()

	timeout := time.After(1 * time.Second)

	for {
		select {
		case msg := <-listener:
			if msg.Status == "start" && !strings.HasPrefix(msg.From, "weaveworks/weave") {
				err := AttachContainer(c, msg.ID)
				if err != nil {
					log.Println(err)
					break
				}
			}
		case <-timeout:
			break
		}
	}
}

func discovering() {
	c := make(chan tutum.Event)
	e := make(chan error)
	nodes.DiscoverPeers()
	go tutum.TutumEvents(c, e)
Loop:
	for {
		select {
		case event := <-c:
			if event.Type == "node" && (event.State == "Deployed" || event.State == "Terminated") {
				err := nodes.DiscoverPeers()
				if err != nil {
					log.Println(err)
				}
			}
		case err := <-e:
			log.Println(err)
			go discovering()
			break Loop
		}
	}
}

func containerThread(client *docker.Client) {
	tries := 0
	if tries > 3 {
		time.Sleep(30 * time.Second)
	}
	err := ContainerAttachThread(client)
	if err != nil {
		log.Println("ATTACH THREAD ERR")
		log.Println(err)
		containerThread(client)
		tries++
		time.Sleep(1500 * time.Millisecond)
	}
}

func connectToDocker() (*docker.Client, error) {
	endpoint := "unix:///var/run/docker.sock"

	client, err := docker.NewClient(endpoint)

	if err != nil {

		log.Println(err)
	}
	return client, nil
}

func main() {

	log.Println("Start running daemon")

	//Init Docker client
	client, err := connectToDocker()
	if err != nil {
		log.Println(err)
	}

	node, err := tutum.GetNode(nodes.Tutum_Node_Api_Uri)
	if err != nil {
		log.Println(err)
	}
	nodes.Tutum_Node_Public_Ip = node.Public_ip
	log.Printf("This node IP is %s", nodes.Tutum_Node_Public_Ip)
	if os.Getenv("TUTUM_AUTH") != "" {
		log.Println("Detected Tutum API access - starting peer discovery thread")
		go discovering()
	}
	containerThread(client)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

// http://api.openweathermap.org/data/2.5/weather?q=Melbourne,au

func main() {

	resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?q=Melbourne,au")

	if err != nil {
		fmt.Printf("Error getting weather: %v", err)
		return
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		fmt.Printf("Error reading weather: %v", err)
		return
	}

	fmt.Printf("Response: %s", body)

}
<commit_msg>move defer below error check<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

// http://api.openweathermap.org/data/2.5/weather?q=Melbourne,au

func main() {

	resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?q=Melbourne,au")

	if err != nil {
		fmt.Printf("Error getting weather: %v", err)
		return
	}

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		fmt.Printf("Error reading weather: %v", err)
		return
	}

	defer resp.Body.Close()

	fmt.Printf("Response: %s", body)

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"gopkg.in/alecthomas/kingpin.v2"
	"gopkg.in/yaml.v2"
)

var (
	inFile = kingpin.Arg("file", "YAML file").Required().ExistingFile()
	pretty = kingpin.Flag("pretty", "Pretty print result").Short('p').Bool()
)

func main() {

	// support -h for --help
	kingpin.CommandLine.HelpFlag.Short('h')
	kingpin.Parse()

	data, _ := ioutil.ReadFile(*inFile)

	var f interface{}
	err := yaml.Unmarshal(data, &f)
	if err != nil {
		fmt.Println("ERROR:", *inFile, err)
		os.Exit(1)
	}

	if *pretty {
		b, err := yaml.Marshal(f)
		if err != nil {
			fmt.Println("ERROR:", err)
		}
		fmt.Printf(string(b))

	} else {
		fmt.Println("OK:", *inFile)
	}
}
<commit_msg>add --quiet flag<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"gopkg.in/alecthomas/kingpin.v2"
	"gopkg.in/yaml.v2"
)

var (
	inFile = kingpin.Arg("file", "YAML file.").Required().ExistingFile()
	pretty = kingpin.Flag("pretty", "Pretty print result.").Short('p').Bool()
	quiet  = kingpin.Flag("quiet", "Don't output on success.").Short('q').Bool()
)

func main() {

	// support -h for --help
	kingpin.CommandLine.HelpFlag.Short('h')
	kingpin.Parse()

	data, _ := ioutil.ReadFile(*inFile)

	var f interface{}
	err := yaml.Unmarshal(data, &f)
	if err != nil {
		fmt.Println("ERROR:", *inFile, err)
		os.Exit(1)
	}

	if *pretty {
		b, err := yaml.Marshal(f)
		if err != nil {
			fmt.Println("ERROR:", err)
		}
		fmt.Printf(string(b))

	} else {
		if !*quiet {
			fmt.Println("OK:", *inFile)
		}
	}
}
<|endoftext|>


<commit_before>package influx

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"
)

const INFLUX_MAX_BUF = 1024
const INFLUX_TIMEOUT = 5 * time.Second

type InfluxDataPoint string

type Database struct {
	http     http.Client
	c        chan InfluxDataPoint
	writeURL string
}

func (d Database) Write(name string, tags map[string]interface{}, values map[string]interface{}) (err error) {
	tags_list, err := join_kv(tags)
	if err != nil {
		return err
	}
	values_list, err := join_kv(values)
	if err != nil {
		return err
	}
	names := append([]string{name}, tags_list...)

	select {
	case d.c <- InfluxDataPoint(fmt.Sprintf("%s %s %d", strings.Join(names, ","), strings.Join(values_list, ","), time.Now().UnixNano())):
	default:
		return fmt.Errorf("Rejecting data point due to full buffer")
	}
	return nil
}

func join_kv(m map[string]interface{}) (s []string, err error) {
	var list = make([]string, 0, len(m))
	for k, v := range m {
		// TODO check for invalid characters in k, v
		key, err := json.Marshal(k)
		if err != nil {
			return nil, err
		}
		val, err := json.Marshal(v)
		if err != nil {
			return nil, err
		}
		list = append(list, fmt.Sprintf("%s=%s", key, val))
	}
	return list, nil
}

func (d Database) run() {
	tick := time.NewTicker(1 * time.Second)
	var data []string
	for {
		select {
		case x := <-d.c:
			data = append(data, string(x))
			if len(data) < INFLUX_MAX_BUF {
				continue
			}
		case _ = <-tick.C:
		}
		if len(data) == 0 {
			continue
		}
		if response, err := d.http.Post(d.writeURL, "text/line-protocol", bytes.NewBufferString(strings.Join(data, "\n"))); err != nil {
			log.Printf("Error submitting to influxdb: %s\n", err)
		} else if response.StatusCode != 204 {
			log.Printf("Unexpected return code %d: %s submitting to influxdb\n", response.StatusCode, response.Status)
		}
	}
}

func New(host string, database string) (*Database, error) {
	d := Database{
		c:        make(chan InfluxDataPoint, INFLUX_MAX_BUF),
		writeURL: fmt.Sprintf("http://%s:8086/write?db=%s", host, database),
		http:     http.Client{Timeout: INFLUX_TIMEOUT},
	}
	return &d, nil
}
<commit_msg>Shutdown logic<commit_after>package influx

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"
)

const INFLUX_MAX_BUF = 1024
const INFLUX_TIMEOUT = 5 * time.Second

type InfluxDataPoint string

type Database struct {
	http     http.Client
	c        chan InfluxDataPoint
	shutdown chan struct{}
	done     chan struct{}
	writeURL string
}

func (d Database) Write(name string, tags map[string]interface{}, values map[string]interface{}) (err error) {
	tags_list, err := join_kv(tags)
	if err != nil {
		return err
	}
	values_list, err := join_kv(values)
	if err != nil {
		return err
	}
	names := append([]string{name}, tags_list...)

	select {
	case d.c <- InfluxDataPoint(fmt.Sprintf("%s %s %d", strings.Join(names, ","), strings.Join(values_list, ","), time.Now().UnixNano())):
	default:
		return fmt.Errorf("Rejecting data point due to full buffer")
	}
	return nil
}

func join_kv(m map[string]interface{}) (s []string, err error) {
	var list = make([]string, 0, len(m))
	for k, v := range m {
		// TODO check for invalid characters in k, v
		key, err := json.Marshal(k)
		if err != nil {
			return nil, err
		}
		val, err := json.Marshal(v)
		if err != nil {
			return nil, err
		}
		list = append(list, fmt.Sprintf("%s=%s", key, val))
	}
	return list, nil
}

func (d Database) run() {
	var shutdown bool
	tick := time.NewTicker(1 * time.Second)
	var data []string
	for {
		if shutdown {
			d.done <- struct{}{}
			return
		}
		select {
		case _ = <-d.shutdown:
			close(d.c)
			for x := range d.c {
				data = append(data, string(x))
			}
			shutdown = true
		case x := <-d.c:
			data = append(data, string(x))
			if len(data) < INFLUX_MAX_BUF {
				continue
			}
		case _ = <-tick.C:
		}
		if len(data) == 0 {
			continue
		}
		if response, err := d.http.Post(d.writeURL, "text/line-protocol", bytes.NewBufferString(strings.Join(data, "\n"))); err != nil {
			log.Printf("Error submitting to influxdb: %s\n", err)
		} else if response.StatusCode != 204 {
			log.Printf("Unexpected return code %d: %s submitting to influxdb\n", response.StatusCode, response.Status)
		} else {
			data = data[0:0]
		}
	}
}

func (d Database) Finalize() {
	d.shutdown <- struct{}{}
	_ = <-d.done
}

func New(host string, database string) (*Database, error) {
	d := Database{
		c:        make(chan InfluxDataPoint, INFLUX_MAX_BUF),
		writeURL: fmt.Sprintf("http://%s:8086/write?db=%s", host, database),
		http:     http.Client{Timeout: INFLUX_TIMEOUT},
		done:     make(chan struct{}),
		shutdown: make(chan struct{}),
	}
	go d.run()
	return &d, nil
}
<|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.2.7"

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

	app := cli.NewApp()

	app.Name = "csvq"
	app.Usage = "SQL like query language for csv"
	app.Version = version

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "delimiter, d",
			Value: ",",
			Usage: "field delimiter (exam: \",\" for comma, \"\\t\" for tab)",
		},
		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:  "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",
			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",
					Value: "TEXT",
					Usage: "output format. one of: CSV|TSV|JSON|TEXT",
				},
				cli.StringFlag{
					Name:  "write-delimiter, D",
					Value: ",",
					Usage: "field delimiter for CSV or TSV (exam: \",\" for comma, \"\\t\" for tab)",
				},
				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 {
					return cli.NewExitError(err.Error(), 1)
				}

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

				return nil
			},
		},
		{
			Name:  "fields",
			Usage: "Show fields in a file",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					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",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					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 {
			return cli.NewExitError(err.Error(), 1)
		}

		err = action.Write(query)
		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.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.2.8<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.2.8"

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

	app := cli.NewApp()

	app.Name = "csvq"
	app.Usage = "SQL like query language for csv"
	app.Version = version

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "delimiter, d",
			Value: ",",
			Usage: "field delimiter (exam: \",\" for comma, \"\\t\" for tab)",
		},
		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:  "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",
			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",
					Value: "TEXT",
					Usage: "output format. one of: CSV|TSV|JSON|TEXT",
				},
				cli.StringFlag{
					Name:  "write-delimiter, D",
					Value: ",",
					Usage: "field delimiter for CSV or TSV (exam: \",\" for comma, \"\\t\" for tab)",
				},
				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 {
					return cli.NewExitError(err.Error(), 1)
				}

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

				return nil
			},
		},
		{
			Name:  "fields",
			Usage: "Show fields in a file",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					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",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					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 {
			return cli.NewExitError(err.Error(), 1)
		}

		err = action.Write(query)
		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.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 (
	"database/sql"
	"errors"
	"flag"
	"fmt"
	"github.com/gorilla/mux"
	"github.com/kylelemons/go-gypsy/yaml"
	_ "github.com/mattn/go-sqlite3"
	"github.com/shawnps/gr"
	"github.com/shawnps/rt"
	"github.com/shawnps/sp"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"sync"
	"time"
)

var (
	port       = flag.String("p", "8000", "Port number (default 8000)")
	configFile = flag.String("c", "config.yml", "Config file (default config.yml)")
)

func parseYAML() (rtKey, grKey, grSecret string, err error) {
	config, err := yaml.ReadFile(*configFile)
	if err != nil {
		return
	}
	rtKey, err = config.Get("rt")
	if err != nil {
		return
	}
	grKey, err = config.Get("gr.key")
	if err != nil {
		return
	}
	grSecret, err = config.Get("gr.secret")
	if err != nil {
		return
	}

	return rtKey, grKey, grSecret, nil
}

func createDb() error {
	db, err := sql.Open("sqlite3", "./watchreadlisten.db")
	if err != nil {
		return errors.New("Error opening or creating watchreadlisten.db: " + err.Error())
	}
	defer db.Close()
	sql := `create table if not exists entries (id integer not null primary key autoincrement, title text, link text, media_type text, timestamp datetime default current_timestamp);`
	_, err = db.Exec(sql)
	if err != nil {
		return errors.New("Error creating entries table: " + err.Error())
	}
	return nil
}

func insertEntry(db sql.DB, title, link, mediaType string) error {
	tx, err := db.Begin()
	if err != nil {
		return errors.New("Error connecting to database: " + err.Error())
	}
	stmt, err := tx.Prepare("insert into entries(title, link, media_type) values(?, ?, ?)")
	if err != nil {
		return errors.New("Error inserting to database: " + err.Error())
	}
	defer stmt.Close()
	_, err = stmt.Exec(title, link, mediaType)
	if err != nil {
		return errors.New("Error executing statement on database: " + err.Error())
	}
	tx.Commit()
	return nil
}

func truncate(s, suf string, l int) string {
	if len(s) < l {
		return s
	} else {
		return s[:l] + suf
	}
}

// Search Rotten Tomatoes, Goodreads, and Spotify.
func Search(q string, rtClient rt.RottenTomatoes, grClient gr.Goodreads, spClient sp.Spotify) (m []rt.Movie, g gr.GoodreadsResponse, s sp.SearchAlbumsResponse) {
	var wg sync.WaitGroup
	wg.Add(3)
	go func(q string) {
		defer wg.Done()
		movies, err := rtClient.SearchMovies(q)
		if err != nil {
			fmt.Println("ERROR (rt): ", err.Error())
		}
		for _, mov := range movies {
			mov.Title = truncate(mov.Title, "...", 60)
			m = append(m, mov)
		}
	}(q)
	go func(q string) {
		defer wg.Done()
		books, err := grClient.SearchBooks(q)
		if err != nil {
			fmt.Println("ERROR (gr): ", err.Error())
		}
		for i, w := range books.Search.Works {
			w.BestBook.Title = truncate(w.BestBook.Title, "...", 60)
			books.Search.Works[i] = w
		}
		g = books
	}(q)
	go func(q string) {
		defer wg.Done()
		albums, err := spClient.SearchAlbums(q)
		if err != nil {
			fmt.Println("ERROR (sp): ", err.Error())
		}
		for i, a := range albums.Albums {
			a.Name = truncate(a.Name, "...", 60)
			albums.Albums[i] = a
		}
		s = albums
	}(q)
	wg.Wait()
	return m, g, s
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
	t, err := template.New("index.html").ParseFiles("templates/index.html", "templates/base.html")
	if err != nil {
		log.Panic(err)
	}
	// Render the template
	err = t.ExecuteTemplate(w, "base", map[string]interface{}{"Page": "home"})
	if err != nil {
		log.Panic(err)
	}
}

func SearchHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	q := vars["query"]
	q, err := url.QueryUnescape(q)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	rtKey, grKey, grSecret, err := parseYAML()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	rtClient := rt.RottenTomatoes{rtKey}
	grClient := gr.Goodreads{grKey, grSecret}
	spClient := sp.Spotify{}
	m, g, s := Search(q, rtClient, grClient, spClient)
	// Since spotify: URIs are not trusted, have to pass a
	// URL function to the template to use in hrefs
	funcMap := template.FuncMap{
		"URL": func(q string) template.URL { return template.URL(q) },
	}
	t, err := template.New("search.html").Funcs(funcMap).ParseFiles("templates/search.html", "templates/base.html")
	if err != nil {
		log.Panic(err)
	}
	// Render the template
	err = t.ExecuteTemplate(w, "base", map[string]interface{}{"Movies": m, "Books": g, "Albums": s.Albums})
	if err != nil {
		log.Panic(err)
	}
}

func SaveHandler(w http.ResponseWriter, r *http.Request) {
	db, err := sql.Open("sqlite3", "./watchreadlisten.db")
	if err != nil {
		log.Println("Error opening sqlite db: " + err.Error())
		return
	}
	defer db.Close()
	t := r.FormValue("title")
	l := r.FormValue("link")
	m := r.FormValue("media_type")
	err = insertEntry(*db, t, l, m)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/list", http.StatusFound)
}

func ListHandler(w http.ResponseWriter, r *http.Request) {
	db, err := sql.Open("sqlite3", "./watchreadlisten.db")
	if err != nil {
		http.Error(w, "Error opening sqlite db: "+err.Error(), http.StatusInternalServerError)
		return
	}
	defer db.Close()
	q := "select id, title, link, media_type, timestamp from entries"
	rows, err := db.Query(q)
	if err != nil {
		http.Error(w, "Error querying sqlite db: "+err.Error(), http.StatusInternalServerError)
		return
	}
	type Entry struct {
		Id        int
		Title     string
		Link      string
		MediaType string `db:"media_type"`
		Timestamp time.Time
	}
	entries := map[string][]Entry{}
	defer rows.Close()
	for rows.Next() {
		e := Entry{}
		var id int
		var title, link, mediaType string
		var timestamp time.Time
		rows.Scan(&id, &title, &link, &mediaType, &timestamp)
		e.Id = id
		e.Title = title
		e.Link = link
		e.MediaType = mediaType
		e.Timestamp = timestamp
		entries[mediaType] = append(entries[mediaType], e)
	}
	// Create and parse Template
	t, err := template.New("list.html").ParseFiles("templates/list.html", "templates/base.html")
	if err != nil {
		log.Panic(err)
	}
	// Render the template
	t.ExecuteTemplate(w, "base", map[string]interface{}{"Entries": entries, "Page": "list"})
}

func main() {
	err := createDb()
	if err != nil {
		log.Fatal(err)
	}
	r := mux.NewRouter()
	r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/search/{query}", SearchHandler)
	r.HandleFunc("/save", SaveHandler)
	r.HandleFunc("/list", ListHandler)
	http.Handle("/", r)
	fmt.Println("Running on localhost:" + *port)

	log.Fatal(http.ListenAndServe(":"+*port, nil))
}
<commit_msg>use postgres<commit_after>package main

import (
	"database/sql"
	"errors"
	"flag"
	"fmt"
	"github.com/gorilla/mux"
	"github.com/kylelemons/go-gypsy/yaml"
	_ "github.com/lib/pq"
	"github.com/shawnps/gr"
	"github.com/shawnps/rt"
	"github.com/shawnps/sp"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"sync"
	"time"
)

var (
	port       = flag.String("p", "8000", "Port number (default 8000)")
	configFile = flag.String("c", "config.yml", "Config file (default config.yml)")
)

func parseYAML() (rtKey, grKey, grSecret string, err error) {
	config, err := yaml.ReadFile(*configFile)
	if err != nil {
		return
	}
	rtKey, err = config.Get("rt")
	if err != nil {
		return
	}
	grKey, err = config.Get("gr.key")
	if err != nil {
		return
	}
	grSecret, err = config.Get("gr.secret")
	if err != nil {
		return
	}

	return rtKey, grKey, grSecret, nil
}

func insertEntry(db sql.DB, title, link, mediaType string) error {
	tx, err := db.Begin()
	if err != nil {
		return errors.New("Error connecting to database: " + err.Error())
	}
	stmt, err := tx.Prepare("insert into entries(title, link, media_type) values(?, ?, ?)")
	if err != nil {
		return errors.New("Error inserting to database: " + err.Error())
	}
	defer stmt.Close()
	_, err = stmt.Exec(title, link, mediaType)
	if err != nil {
		return errors.New("Error executing statement on database: " + err.Error())
	}
	tx.Commit()
	return nil
}

func truncate(s, suf string, l int) string {
	if len(s) < l {
		return s
	} else {
		return s[:l] + suf
	}
}

// Search Rotten Tomatoes, Goodreads, and Spotify.
func Search(q string, rtClient rt.RottenTomatoes, grClient gr.Goodreads, spClient sp.Spotify) (m []rt.Movie, g gr.GoodreadsResponse, s sp.SearchAlbumsResponse) {
	var wg sync.WaitGroup
	wg.Add(3)
	go func(q string) {
		defer wg.Done()
		movies, err := rtClient.SearchMovies(q)
		if err != nil {
			fmt.Println("ERROR (rt): ", err.Error())
		}
		for _, mov := range movies {
			mov.Title = truncate(mov.Title, "...", 60)
			m = append(m, mov)
		}
	}(q)
	go func(q string) {
		defer wg.Done()
		books, err := grClient.SearchBooks(q)
		if err != nil {
			fmt.Println("ERROR (gr): ", err.Error())
		}
		for i, w := range books.Search.Works {
			w.BestBook.Title = truncate(w.BestBook.Title, "...", 60)
			books.Search.Works[i] = w
		}
		g = books
	}(q)
	go func(q string) {
		defer wg.Done()
		albums, err := spClient.SearchAlbums(q)
		if err != nil {
			fmt.Println("ERROR (sp): ", err.Error())
		}
		for i, a := range albums.Albums {
			a.Name = truncate(a.Name, "...", 60)
			albums.Albums[i] = a
		}
		s = albums
	}(q)
	wg.Wait()
	return m, g, s
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
	t, err := template.New("index.html").ParseFiles("templates/index.html", "templates/base.html")
	if err != nil {
		log.Panic(err)
	}
	// Render the template
	err = t.ExecuteTemplate(w, "base", map[string]interface{}{"Page": "home"})
	if err != nil {
		log.Panic(err)
	}
}

func SearchHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	q := vars["query"]
	q, err := url.QueryUnescape(q)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	rtKey, grKey, grSecret, err := parseYAML()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	rtClient := rt.RottenTomatoes{rtKey}
	grClient := gr.Goodreads{grKey, grSecret}
	spClient := sp.Spotify{}
	m, g, s := Search(q, rtClient, grClient, spClient)
	// Since spotify: URIs are not trusted, have to pass a
	// URL function to the template to use in hrefs
	funcMap := template.FuncMap{
		"URL": func(q string) template.URL { return template.URL(q) },
	}
	t, err := template.New("search.html").Funcs(funcMap).ParseFiles("templates/search.html", "templates/base.html")
	if err != nil {
		log.Panic(err)
	}
	// Render the template
	err = t.ExecuteTemplate(w, "base", map[string]interface{}{"Movies": m, "Books": g, "Albums": s.Albums})
	if err != nil {
		log.Panic(err)
	}
}

func SaveHandler(w http.ResponseWriter, r *http.Request) {
	db, err := sql.Open("postgres", "user=postgres dbname=wrl")
	if err != nil {
		log.Println("Error opening db connection: " + err.Error())
		return
	}
	defer db.Close()
	t := r.FormValue("title")
	l := r.FormValue("link")
	m := r.FormValue("media_type")
	err = insertEntry(*db, t, l, m)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/list", http.StatusFound)
}

func ListHandler(w http.ResponseWriter, r *http.Request) {
	db, err := sql.Open("postgres", "user=postgres dbname=wrl")
	if err != nil {
		http.Error(w, "Error opening db connection: "+err.Error(), http.StatusInternalServerError)
		return
	}
	defer db.Close()
	q := "select id, title, link, media_type, timestamp from entries"
	rows, err := db.Query(q)
	if err != nil {
		http.Error(w, "Error querying db: "+err.Error(), http.StatusInternalServerError)
		return
	}
	type Entry struct {
		Id        int
		Title     string
		Link      string
		MediaType string `db:"media_type"`
		Timestamp time.Time
	}
	entries := map[string][]Entry{}
	defer rows.Close()
	for rows.Next() {
		e := Entry{}
		var id int
		var title, link, mediaType string
		var timestamp time.Time
		rows.Scan(&id, &title, &link, &mediaType, &timestamp)
		e.Id = id
		e.Title = title
		e.Link = link
		e.MediaType = mediaType
		e.Timestamp = timestamp
		entries[mediaType] = append(entries[mediaType], e)
	}
	// Create and parse Template
	t, err := template.New("list.html").ParseFiles("templates/list.html", "templates/base.html")
	if err != nil {
		log.Panic(err)
	}
	// Render the template
	t.ExecuteTemplate(w, "base", map[string]interface{}{"Entries": entries, "Page": "list"})
}

func main() {
	err := createDb()
	if err != nil {
		log.Fatal(err)
	}
	r := mux.NewRouter()
	r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/search/{query}", SearchHandler)
	r.HandleFunc("/save", SaveHandler)
	r.HandleFunc("/list", ListHandler)
	http.Handle("/", r)
	fmt.Println("Running on localhost:" + *port)

	log.Fatal(http.ListenAndServe(":"+*port, nil))
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"time"

	MQTT "github.com/eclipse/paho.mqtt.golang"
	"github.com/google/uuid"
)

var (
	subTopics = []string{
		"/cooktroller/charles/smoker/set_temp",
		"/cooktroller/charles/smoker/runstate",
	}
	serverState ServerState
)

//Server state and tuning parameters
type ServerState struct {
	KP      float32
	KI      float32
	KD      float32
	Loop    int16
	Running bool
	TempSet float32
}

//Server status message
type ServerStatus struct {
	DeviceID string  `json:"device_id"`
	Running  bool    `json:"running"`
	TempCel  float32 `json:"temp_cel"`
	TempFar  float32 `json:"temp_far"`
}

//SetTemperature unmarshal json to set temp
type SetTemperature struct {
	TempFar float32 `json:"temp_far"`
	TempCel float32 `json:"temp_cel"`
}

//SetRunningState unmarshal json to set run state
type SetRunningState struct {
	Running bool `json:"on"`
}

func main() {
	log.Println("Starting up!")
	err := connect()
	if err != nil {
		log.Println("application died")
	}
}

//Connect to and setup MQTT
func connect() error {
	cid := uuid.New().String()
	connOpts := MQTT.NewClientOptions()
	connOpts.SetClientID(cid)
	connOpts.SetCleanSession(true)
	connOpts.SetAutoReconnect(true)
	connOpts.SetMaxReconnectInterval(1 * time.Second)
	connOpts.SetTLSConfig(getTLSConfig())
	log.Println("Certs loaded")
	brokerURL := fmt.Sprintf("tcps://%s:%d%s", "a10cp24047duti.iot.us-east-1.amazonaws.com", 8883, "/")
	connOpts.AddBroker(brokerURL)
	mqttClient := MQTT.NewClient(connOpts)
	token := mqttClient.Connect()
	token.WaitTimeout(30 * time.Second)
	token.Wait()

	if token.Error() != nil {
		log.Println(token.Error())
		return token.Error()
	}
	log.Println("MQTT Endpoint connected")
	for _, topic := range subTopics {
		token := mqttClient.Subscribe(topic, 1, subscriber)
		token.WaitTimeout(30 * time.Second)
		token.Wait()
		if token.Error() != nil {
			return token.Error()
		}
		log.Println("Subscribed to topic: ", topic)
	}
	//Start the PID control loop
	pidControlLoop(10*time.Second, doControl, mqttClient)
	return nil
}

//Function to subscribe to a topic
func subscriber(client MQTT.Client, msg MQTT.Message) {
	log.Println("Message", string(msg.Payload()))
	if msg.Topic() == subTopics[0] {
		var setTemp SetTemperature
		err := json.Unmarshal(msg.Payload(), setTemp)
		if err != nil {
			log.Println("Unable to unmarshal temp set")
			return
		}
		serverState.TempSet = setTemp.TempFar //set the temperature (F for now)
	} else if msg.Topic() == subTopics[1] {
		var setRunState SetRunningState
		err := json.Unmarshal(msg.Payload(), setRunState)
		if err != nil {
			log.Println("Unable to unmarshal set running state")
			return
		}
		serverState.Running = setRunState.Running //set opcode running
	} else {
		log.Println("Message from unknown topic")
	}

}

//Enter a loop to run the PID controller on a schedule
func pidControlLoop(d time.Duration, f func(time.Time), mqttClient MQTT.Client) {
	for x := range time.Tick(d) {
		log.Println("Running control loop")
		go f(x)
		var status ServerStatus
		go status.sendStatus(mqttClient)
	}
}

//TODO: Perform the PID Control
func doControl(t time.Time) {
	log.Println("running control")
}

//Set the status on the struct and send it to the MQTT backend
func (status *ServerStatus) sendStatus(mqttClient MQTT.Client) {
	status.DeviceID = "Cooktroller Smoker"
	status.Running = serverState.Running
	status.TempFar = serverState.TempSet
	data, err := json.Marshal(status)
	if err != nil {
		log.Println(err)
	}
	token := mqttClient.Publish("/cooktroller/charles/smoker/status", 1, false, data)
	token.WaitTimeout(30 * time.Second)
	token.Wait()
	if token.Error() != nil {
		log.Println("Unable to send message to MQTT", token.Error())
	}
}

//NewTlsConfig Load in the certificates and setup the TLS configurations and certs
func getTLSConfig() *tls.Config {
	// Import trusted certificates from CAfile.pem.
	// Alternatively, manually add CA certificates to
	// default openssl CA bundle.
	certpool := x509.NewCertPool()
	pemCerts, err := ioutil.ReadFile("/etc/cooktroller/ca.cert")
	if err == nil {
		certpool.AppendCertsFromPEM(pemCerts)
	}

	// Import client certificate/key pair
	cert, err := tls.LoadX509KeyPair("/etc/cooktroller/cert.pem", "/etc/cooktroller/key.pem")
	if err != nil {
		fmt.Println("Could not load X509 Key pair")
		return nil
	}

	// Just to print out the client certificate..
	cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		panic(err)
	}
	//log.Println(cert.Leaf)

	// Create tls.Config with desired tls properties
	return &tls.Config{
		// RootCAs = certs used to verify server cert.
		RootCAs: certpool,
		// ClientAuth = whether to request cert from server.
		// Since the server is set up for SSL, this happens
		// anyways.
		ClientAuth: tls.NoClientCert,
		// ClientCAs = certs used to validate client cert.
		ClientCAs: nil,
		// InsecureSkipVerify = verify that cert contents
		// match server. IP matches what is in cert etc.
		InsecureSkipVerify: true,
		// Certificates = list of certs client sends to server.
		Certificates: []tls.Certificate{cert},
	}
}
<commit_msg>fix: added logging<commit_after>package main

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"time"

	MQTT "github.com/eclipse/paho.mqtt.golang"
	"github.com/google/uuid"
)

var (
	subTopics = []string{
		"/cooktroller/charles/smoker/set_temp",
		"/cooktroller/charles/smoker/runstate",
	}
	serverState ServerState
)

//Server state and tuning parameters
type ServerState struct {
	KP      float32
	KI      float32
	KD      float32
	Loop    int16
	Running bool
	TempSet float32
}

//Server status message
type ServerStatus struct {
	DeviceID string  `json:"device_id"`
	Running  bool    `json:"running"`
	TempCel  float32 `json:"temp_cel"`
	TempFar  float32 `json:"temp_far"`
}

//SetTemperature unmarshal json to set temp
type SetTemperature struct {
	TempFar float32 `json:"temp_far"`
	TempCel float32 `json:"temp_cel"`
}

//SetRunningState unmarshal json to set run state
type SetRunningState struct {
	Running bool `json:"on"`
}

func main() {
	log.Println("Starting up!")
	err := connect()
	if err != nil {
		log.Println("application died")
	}
}

//Connect to and setup MQTT
func connect() error {
	cid := uuid.New().String()
	connOpts := MQTT.NewClientOptions()
	connOpts.SetClientID(cid)
	connOpts.SetCleanSession(true)
	connOpts.SetAutoReconnect(true)
	connOpts.SetMaxReconnectInterval(1 * time.Second)
	connOpts.SetTLSConfig(getTLSConfig())
	log.Println("Certs loaded")
	brokerURL := fmt.Sprintf("tcps://%s:%d%s", "a10cp24047duti.iot.us-east-1.amazonaws.com", 8883, "/")
	connOpts.AddBroker(brokerURL)
	mqttClient := MQTT.NewClient(connOpts)
	token := mqttClient.Connect()
	token.WaitTimeout(30 * time.Second)
	token.Wait()

	if token.Error() != nil {
		log.Println(token.Error())
		return token.Error()
	}
	log.Println("MQTT Endpoint connected")
	for _, topic := range subTopics {
		token := mqttClient.Subscribe(topic, 1, subscriber)
		token.WaitTimeout(30 * time.Second)
		token.Wait()
		if token.Error() != nil {
			return token.Error()
		}
		log.Println("Subscribed to topic: ", topic)
	}
	//Start the PID control loop
	pidControlLoop(10*time.Second, doControl, mqttClient)
	return nil
}

//Function to subscribe to a topic
func subscriber(client MQTT.Client, msg MQTT.Message) {
	log.Println("Message", string(msg.Payload()))
	if msg.Topic() == subTopics[0] {
		var setTemp SetTemperature
		err := json.Unmarshal(msg.Payload(), setTemp)
		if err != nil {
			log.Println("Unable to unmarshal temp set")
			return
		}
		serverState.TempSet = setTemp.TempFar //set the temperature (F for now)
	} else if msg.Topic() == subTopics[1] {
		var setRunState SetRunningState
		err := json.Unmarshal(msg.Payload(), setRunState)
		if err != nil {
			log.Println("Unable to unmarshal set running state")
			return
		}
		serverState.Running = setRunState.Running //set opcode running
	} else {
		log.Println("Message from unknown topic")
	}

}

//Enter a loop to run the PID controller on a schedule
func pidControlLoop(d time.Duration, f func(time.Time), mqttClient MQTT.Client) {
	for x := range time.Tick(d) {
		log.Println("Running control loop")
		go f(x)
		var status ServerStatus
		go status.sendStatus(mqttClient)
	}
}

//TODO: Perform the PID Control
func doControl(t time.Time) {
	log.Println("running control")
}

//Set the status on the struct and send it to the MQTT backend
func (status *ServerStatus) sendStatus(mqttClient MQTT.Client) {
	status.DeviceID = "Cooktroller Smoker"
	status.Running = serverState.Running
	status.TempFar = serverState.TempSet
	data, err := json.Marshal(status)
	if err != nil {
		log.Println(err)
	}
	token := mqttClient.Publish("/cooktroller/charles/smoker/status", 1, false, data)
	token.WaitTimeout(30 * time.Second)
	token.Wait()
	log.Println("Sent message: ")
	log.Println(string(data))
	if token.Error() != nil {
		log.Println("Unable to send message to MQTT", token.Error())
	}
}

//NewTlsConfig Load in the certificates and setup the TLS configurations and certs
func getTLSConfig() *tls.Config {
	// Import trusted certificates from CAfile.pem.
	// Alternatively, manually add CA certificates to
	// default openssl CA bundle.
	certpool := x509.NewCertPool()
	pemCerts, err := ioutil.ReadFile("/etc/cooktroller/ca.cert")
	if err == nil {
		certpool.AppendCertsFromPEM(pemCerts)
	}

	// Import client certificate/key pair
	cert, err := tls.LoadX509KeyPair("/etc/cooktroller/cert.pem", "/etc/cooktroller/key.pem")
	if err != nil {
		fmt.Println("Could not load X509 Key pair")
		return nil
	}

	// Just to print out the client certificate..
	cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		panic(err)
	}
	//log.Println(cert.Leaf)

	// Create tls.Config with desired tls properties
	return &tls.Config{
		// RootCAs = certs used to verify server cert.
		RootCAs: certpool,
		// ClientAuth = whether to request cert from server.
		// Since the server is set up for SSL, this happens
		// anyways.
		ClientAuth: tls.NoClientCert,
		// ClientCAs = certs used to validate client cert.
		ClientCAs: nil,
		// InsecureSkipVerify = verify that cert contents
		// match server. IP matches what is in cert etc.
		InsecureSkipVerify: true,
		// Certificates = list of certs client sends to server.
		Certificates: []tls.Certificate{cert},
	}
}
<|endoftext|>


<commit_before>// QUIC web server with built-in support for Lua, Markdown, Pongo2 and JSX.
package main

import (
	"net/http"

	log "github.com/sirupsen/logrus"
	"github.com/xyproto/algernon/engine"
)

const (
	versionString = "Algernon 1.12.12"
	description   = "Web Server"
)

func main() {
	// Create a new Algernon server. Also initialize log files etc.
	algernon, err := engine.New(versionString, description)
	if err != nil {
		if err == engine.ErrVersion {
			// Exit with error code 0 if --version was specified
			return
		} else {
			// Exit if there are problems with the fundamental setup
			log.Fatalln(err)
		}
	}

	// Set up a mux
	mux := http.NewServeMux()

	// Serve HTTP, HTTP/2 and/or HTTPS. Quit when done.
	algernon.MustServe(mux)
}
<commit_msg>Minor change<commit_after>// QUIC web server with built-in support for Lua, Markdown, Pongo2 and JSX.
package main

import (
	"net/http"

	log "github.com/sirupsen/logrus"
	"github.com/xyproto/algernon/engine"
)

const (
	versionString = "Algernon 1.12.12"
	description   = "Web Server"
)

func main() {
	// Create a new Algernon server. Also initialize log files etc.
	algernon, err := engine.New(versionString, description)
	if err != nil {
		if err == engine.ErrVersion {
			// Exit with error code 0 if --version was specified
			return
		}
		// Exit if there are problems with the fundamental setup
		log.Fatalln(err)
	}

	// Set up a mux
	mux := http.NewServeMux()

	// Serve HTTP, HTTP/2 and/or HTTPS. Quit when done.
	algernon.MustServe(mux)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"net/http"
	"os"
	"time"

	"github.com/skibish/ddns/ipprovider/ifconfig"
	"github.com/skibish/ddns/ipprovider/ipify"
	"github.com/skibish/ddns/ipprovider/wtfismyip"
	"github.com/skibish/ddns/updater"

	log "github.com/sirupsen/logrus"
	"github.com/skibish/ddns/conf"
	"github.com/skibish/ddns/ipprovider"
	"github.com/skibish/ddns/notifier"
)

var (
	reqTimeouts = flag.Duration("req-timeout", 10*time.Second, "Request timeout to external resources")
	checkPeriod = flag.Duration("check-period", 5*time.Minute, "Check if IP has been changed period")
	confFile    = flag.String("conf-file", "$HOME/.ddns.yml", "Location of the configuration file")
)

func init() {
	log.SetFormatter(&log.TextFormatter{
		DisableColors: true,
	})
	log.SetLevel(log.DebugLevel)
	log.SetOutput(os.Stdout)
}

func main() {
	flag.Parse()

	// read configuration
	var errConf error
	cf, errConf := conf.NewConfiguration(*confFile)
	if errConf != nil {
		log.Fatal(errConf.Error())
	}

	// try to register all provided hooks
	for k, v := range cf.Notify {
		hook, errGet := notifier.GetHook(k, v)
		if errGet != nil {
			log.Debugf("Notifier %q not added: %s", k, errGet.Error())
			continue
		}
		log.AddHook(hook)
	}

	// setup http client
	c := &http.Client{
		Timeout: *reqTimeouts,
	}

	// initialize new ipprovider and register IP providers
	provider := ipprovider.New()

	providerList := []ipprovider.Provider{
		ifconfig.New(c),
		ipify.New(c),
		wtfismyip.New(c),
	}

	if cf.ForceIPV6 {
		for _, p := range providerList {
			p.ForceIPV6()
		}
	}

	provider.Register(providerList...)

	// Initialize and start updater
	upd, errUpdater := updater.New(c, provider, cf, *checkPeriod)
	if errUpdater != nil {
		log.Fatal(errUpdater)
	}

	errStart := upd.Start()
	if errStart != nil {
		log.Fatal(errStart)
	}

	select {}
}
<commit_msg>Moved ifconfig as last provider, because it stopped working<commit_after>package main

import (
	"flag"
	"net/http"
	"os"
	"time"

	"github.com/skibish/ddns/ipprovider/ifconfig"
	"github.com/skibish/ddns/ipprovider/ipify"
	"github.com/skibish/ddns/ipprovider/wtfismyip"
	"github.com/skibish/ddns/updater"

	log "github.com/sirupsen/logrus"
	"github.com/skibish/ddns/conf"
	"github.com/skibish/ddns/ipprovider"
	"github.com/skibish/ddns/notifier"
)

var (
	reqTimeouts = flag.Duration("req-timeout", 10*time.Second, "Request timeout to external resources")
	checkPeriod = flag.Duration("check-period", 5*time.Minute, "Check if IP has been changed period")
	confFile    = flag.String("conf-file", "$HOME/.ddns.yml", "Location of the configuration file")
)

func init() {
	log.SetFormatter(&log.TextFormatter{
		DisableColors: true,
	})
	log.SetLevel(log.DebugLevel)
	log.SetOutput(os.Stdout)
}

func main() {
	flag.Parse()

	// read configuration
	var errConf error
	cf, errConf := conf.NewConfiguration(*confFile)
	if errConf != nil {
		log.Fatal(errConf.Error())
	}

	// try to register all provided hooks
	for k, v := range cf.Notify {
		hook, errGet := notifier.GetHook(k, v)
		if errGet != nil {
			log.Debugf("Notifier %q not added: %s", k, errGet.Error())
			continue
		}
		log.AddHook(hook)
	}

	// setup http client
	c := &http.Client{
		Timeout: *reqTimeouts,
	}

	// initialize new ipprovider and register IP providers
	provider := ipprovider.New()

	providerList := []ipprovider.Provider{
		ipify.New(c),
		wtfismyip.New(c),
		ifconfig.New(c),
	}

	if cf.ForceIPV6 {
		for _, p := range providerList {
			p.ForceIPV6()
		}
	}

	provider.Register(providerList...)

	// Initialize and start updater
	upd, errUpdater := updater.New(c, provider, cf, *checkPeriod)
	if errUpdater != nil {
		log.Fatal(errUpdater)
	}

	errStart := upd.Start()
	if errStart != nil {
		log.Fatal(errStart)
	}

	select {}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"os"

	"github.com/calebthompson/ftree/tree"
)

func main() {
	r := bufio.NewScanner(os.Stdin)
	lines := []string{}
	for r.Scan() {
		lines = append(lines, r.Text())
	}

	t := tree.Tree(lines, "/")
	t.Print(0, nil)
}
<commit_msg>Add version and help arguments<commit_after>package main

import (
	"bufio"
	"fmt"
	"os"

	"github.com/calebthompson/ftree/tree"
)

const (
	version = "v0.1.0"
	help    = `Pipe output from some command that lists a single file per line to ftree.
	find . | ftree
	git ls-files {app,spec}/models | ftree
	lsrc | cut -d : -f 1 | ftree
`
)

func main() {
	handleArguments()

	r := bufio.NewScanner(os.Stdin)
	lines := []string{}
	for r.Scan() {
		lines = append(lines, r.Text())
	}

	t := tree.Tree(lines, "/")
	t.Print(0, nil)
}

func handleArguments() {
	for _, a := range os.Args[1:] {
		switch a {
		case "--version", "-v":
			fmt.Printf("ftree %s\n", version)
			os.Exit(0)
		case "--help", "-h":
			fmt.Print(help)
			os.Exit(0)
		default:
			fmt.Fprintf(os.Stderr, "No such argument: %v\n", a)
			os.Exit(1)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"github.com/peterbourgon/mergemap"
	"github.com/russross/blackfriday"
	"html/template"
	"os"
	"path/filepath"
)

var (
	FrontSeparator = []byte("---\n")
)

var (
	debug     = flag.Bool("debug", false, "print debug information (very verbose)")
	verbose   = flag.Bool("verbose", false, "print verbose information")
	sourceDir = flag.String("source", "src", "path to site source (input)")
	targetDir = flag.String("target", "tgt", "path to site target (output)")
	globalKey = flag.String("global.key", "files", "template node name for global info")
)

func init() {
	flag.Parse()

	var err error
	for _, s := range []*string{sourceDir, targetDir} {
		if *s, err = filepath.Abs(*s); err != nil {
			Fatalf("%s", err)
		}
	}
}

func main() {
	m := map[string]interface{}{}
	s := NewStack()
	filepath.Walk(*sourceDir, gather(s, m))
	s.Add("", map[string]interface{}{*globalKey: m})

	filepath.Walk(*sourceDir, transform(s))
}

// splitMetadata splits the input buffer on FrontSeparator. It returns a byte-
// slice suitable for unmarshaling into metadata, if it exists, and the
// remainder of the input buffer.
func splitMetadata(buf []byte) ([]byte, []byte) {
	split := bytes.SplitN(buf, FrontSeparator, 2)
	if len(split) == 2 {
		return split[0], split[1]
	}
	return []byte{}, buf
}

func gather(s StackReadWriter, m map[string]interface{}) filepath.WalkFunc {
	return func(path string, info os.FileInfo, _ error) error {
		if info.IsDir() {
			return nil // descend
		}
		switch filepath.Ext(path) {
		case ".json":
			metadata := mustJSON(mustRead(path))
			s.Add(filepath.Dir(path), metadata)
			Infof("%s gathered (%d element(s))", path, len(metadata))

		case ".html":
			fullMetadata := map[string]interface{}{
				"source":  diffPath(*sourceDir, path),
				"target":  diffPath(*targetDir, targetFor(path, filepath.Ext(path))),
				"url":     "/" + diffPath(*targetDir, targetFor(path, filepath.Ext(path))),
				"sortkey": filepath.Base(path),
			}
			metadataBuf, _ := splitMetadata(mustRead(path))
			if len(metadataBuf) > 0 {
				fileMetadata := mustJSON(metadataBuf)
				s.Add(path, fileMetadata)
			}
			fullMetadata = mergemap.Merge(fullMetadata, s.Get(path))
			splatInto(m, diffPath(*sourceDir, path), fullMetadata)
			Infof("%s gathered (%d element(s))", path, len(fullMetadata))

		case ".md":
			fullMetadata := map[string]interface{}{
				"source":  diffPath(*sourceDir, path),
				"target":  diffPath(*targetDir, targetFor(path, ".html")),
				"url":     "/" + diffPath(*targetDir, targetFor(path, ".html")),
				"sortkey": filepath.Base(path),
			}
			metadataBuf, _ := splitMetadata(mustRead(path))
			if len(metadataBuf) > 0 {
				fileMetadata := mustJSON(metadataBuf)
				s.Add(path, fileMetadata)
			}
			fullMetadata = mergemap.Merge(fullMetadata, s.Get(path))
			splatInto(m, diffPath(*sourceDir, path), fullMetadata)
			Infof("%s gathered (%d element(s))", path, len(fullMetadata))

		default:
			Infof("%s ignored for gathering", path)

		}
		return nil
	}
}

func transform(s StackReader) filepath.WalkFunc {
	return func(path string, info os.FileInfo, _ error) error {
		if info.IsDir() {
			return nil // descend
		}
		switch filepath.Ext(path) {
		case ".json":
			Infof("%s ignored for transformation", path)

		case ".html":
			_, contentBuf := splitMetadata(mustRead(path))
			metadata := s.Get(path)
			outputBuf := renderTemplate(path, contentBuf, metadata)
			dst := targetFor(path, filepath.Ext(path))
			mustWrite(dst, outputBuf)
			Infof("%s transformed to %s", path, dst)

		case ".md":
			_, contentBuf := splitMetadata(mustRead(path))

			// render the markdown, and put it into the 'content' key of an
			// interstitial metadata, to be fed to the template renderer
			metadata := mergemap.Merge(s.Get(path), map[string]interface{}{
				"content": template.HTML(renderMarkdown(contentBuf)),
			})

			// render the complete html output according to the template
			outputBuf := renderTemplate(path, mustTemplate(s, path), metadata)

			// write
			dst := targetFor(path, ".html")
			mustWrite(dst, outputBuf)
			Infof("%s transformed to %s", path, dst)

		case ".source", ".template":
			Infof("%s ignored for transformation", path)

		default:
			dst := filepath.Join(*targetDir, diffPath(*sourceDir, path))
			mustCopy(targetFor(path, filepath.Ext(path)), path)
			Infof("%s transformed to %s verbatim", path, dst)
		}
		return nil
	}
}

func renderTemplate(path string, input []byte, metadata map[string]interface{}) []byte {
	funcMap := template.FuncMap{
		"importcss": func(filename string) template.CSS {
			return template.CSS(mustRead(filepath.Join(filepath.Dir(path), filename)))
		},
		"importjs": func(filename string) template.JS {
			return template.JS(mustRead(filepath.Join(filepath.Dir(path), filename)))
		},
		"importhtml": func(filename string) template.HTML {
			return template.HTML(mustRead(filepath.Join(filepath.Dir(path), filename)))
		},
		"sortkey": sortedValues,
	}
	tmpl, err := template.New(diffPath(*sourceDir, path)).Funcs(funcMap).Parse(string(input))
	if err != nil {
		Fatalf("%s", err)
	}
	output := bytes.Buffer{}
	if err := tmpl.Execute(&output, metadata); err != nil {
		Fatalf("%s", err)
	}
	return output.Bytes()
}

func renderMarkdown(input []byte) []byte {
	htmlOptions := 0
	htmlOptions = htmlOptions | blackfriday.HTML_GITHUB_BLOCKCODE
	htmlOptions = htmlOptions | blackfriday.HTML_USE_SMARTYPANTS
	title, css := "", ""
	htmlRenderer := blackfriday.HtmlRenderer(htmlOptions, title, css)

	mdOptions := 0
	mdOptions = mdOptions | blackfriday.EXTENSION_FENCED_CODE

	return blackfriday.Markdown(input, htmlRenderer, mdOptions)
}
<commit_msg>Clarity<commit_after>package main

import (
	"bytes"
	"flag"
	"github.com/peterbourgon/mergemap"
	"github.com/russross/blackfriday"
	"html/template"
	"os"
	"path/filepath"
)

var (
	FrontSeparator = []byte("---\n")
)

var (
	debug     = flag.Bool("debug", false, "print debug information (implies verbose)")
	verbose   = flag.Bool("verbose", false, "print verbose information")
	sourceDir = flag.String("source", "src", "path to site source (input)")
	targetDir = flag.String("target", "tgt", "path to site target (output)")
	globalKey = flag.String("global.key", "files", "template node name for global info")
)

func init() {
	flag.Parse()

	if *debug {
		*verbose = true
	}

	var err error
	for _, s := range []*string{sourceDir, targetDir} {
		if *s, err = filepath.Abs(*s); err != nil {
			Fatalf("%s", err)
		}
	}
}

func main() {
	m := map[string]interface{}{}
	s := NewStack()
	filepath.Walk(*sourceDir, gather(s, m))
	s.Add("", map[string]interface{}{*globalKey: m})

	filepath.Walk(*sourceDir, transform(s))
}

// splitMetadata splits the input buffer on FrontSeparator. It returns a byte-
// slice suitable for unmarshaling into metadata, if it exists, and the
// remainder of the input buffer.
func splitMetadata(buf []byte) ([]byte, []byte) {
	split := bytes.SplitN(buf, FrontSeparator, 2)
	if len(split) == 2 {
		return split[0], split[1]
	}
	return []byte{}, buf
}

func gather(s StackReadWriter, m map[string]interface{}) filepath.WalkFunc {
	return func(path string, info os.FileInfo, _ error) error {
		if info.IsDir() {
			return nil // descend
		}
		switch filepath.Ext(path) {
		case ".json":
			metadata := mustJSON(mustRead(path))
			s.Add(filepath.Dir(path), metadata)
			Infof("%s gathered (%d element(s))", path, len(metadata))

		case ".html":
			fullMetadata := map[string]interface{}{
				"source":  diffPath(*sourceDir, path),
				"target":  diffPath(*targetDir, targetFor(path, filepath.Ext(path))),
				"url":     "/" + diffPath(*targetDir, targetFor(path, filepath.Ext(path))),
				"sortkey": filepath.Base(path),
			}
			metadataBuf, _ := splitMetadata(mustRead(path))
			if len(metadataBuf) > 0 {
				fileMetadata := mustJSON(metadataBuf)
				s.Add(path, fileMetadata)
			}
			fullMetadata = mergemap.Merge(fullMetadata, s.Get(path))
			splatInto(m, diffPath(*sourceDir, path), fullMetadata)
			Infof("%s gathered (%d element(s))", path, len(fullMetadata))

		case ".md":
			fullMetadata := map[string]interface{}{
				"source":  diffPath(*sourceDir, path),
				"target":  diffPath(*targetDir, targetFor(path, ".html")),
				"url":     "/" + diffPath(*targetDir, targetFor(path, ".html")),
				"sortkey": filepath.Base(path),
			}
			metadataBuf, _ := splitMetadata(mustRead(path))
			if len(metadataBuf) > 0 {
				fileMetadata := mustJSON(metadataBuf)
				s.Add(path, fileMetadata)
			}
			fullMetadata = mergemap.Merge(fullMetadata, s.Get(path))
			splatInto(m, diffPath(*sourceDir, path), fullMetadata)
			Infof("%s gathered (%d element(s))", path, len(fullMetadata))

		default:
			Infof("%s ignored for gathering", path)

		}
		return nil
	}
}

func transform(s StackReader) filepath.WalkFunc {
	return func(path string, info os.FileInfo, _ error) error {
		if info.IsDir() {
			return nil // descend
		}
		switch filepath.Ext(path) {
		case ".json":
			Infof("%s ignored for transformation", path)

		case ".html":
			_, contentBuf := splitMetadata(mustRead(path))
			metadata := s.Get(path)
			outputBuf := renderTemplate(path, contentBuf, metadata)
			dst := targetFor(path, filepath.Ext(path))
			mustWrite(dst, outputBuf)
			Infof("%s transformed to %s", path, dst)

		case ".md":
			_, contentBuf := splitMetadata(mustRead(path))

			// render the markdown, and put it into the 'content' key of an
			// interstitial metadata, to be fed to the template renderer
			metadata := mergemap.Merge(s.Get(path), map[string]interface{}{
				"content": template.HTML(renderMarkdown(contentBuf)),
			})

			// render the complete html output according to the template
			outputBuf := renderTemplate(path, mustTemplate(s, path), metadata)

			// write
			dst := targetFor(path, ".html")
			mustWrite(dst, outputBuf)
			Infof("%s transformed to %s", path, dst)

		case ".source", ".template":
			Infof("%s ignored for transformation", path)

		default:
			dst := filepath.Join(*targetDir, diffPath(*sourceDir, path))
			mustCopy(targetFor(path, filepath.Ext(path)), path)
			Infof("%s transformed to %s verbatim", path, dst)
		}
		return nil
	}
}

func renderTemplate(path string, input []byte, metadata map[string]interface{}) []byte {
	funcMap := template.FuncMap{
		"importcss": func(filename string) template.CSS {
			filename = filepath.Join(filepath.Dir(path), filename)
			return template.CSS(mustRead(filename))
		},
		"importjs": func(filename string) template.JS {
			filename = filepath.Join(filepath.Dir(path), filename)
			return template.JS(mustRead(filename))
		},
		"importhtml": func(filename string) template.HTML {
			filename = filepath.Join(filepath.Dir(path), filename)
			return template.HTML(mustRead(filename))
		},
		"sortkey": sortedValues,
	}
	templateName := diffPath(*sourceDir, path)
	tmpl, err := template.New(templateName).Funcs(funcMap).Parse(string(input))
	if err != nil {
		Fatalf("%s", err)
	}
	output := bytes.Buffer{}
	if err := tmpl.Execute(&output, metadata); err != nil {
		Fatalf("%s", err)
	}
	return output.Bytes()
}

func renderMarkdown(input []byte) []byte {
	htmlOptions := 0
	htmlOptions = htmlOptions | blackfriday.HTML_GITHUB_BLOCKCODE
	htmlOptions = htmlOptions | blackfriday.HTML_USE_SMARTYPANTS
	title, css := "", ""
	htmlRenderer := blackfriday.HtmlRenderer(htmlOptions, title, css)

	mdOptions := 0
	mdOptions = mdOptions | blackfriday.EXTENSION_FENCED_CODE

	return blackfriday.Markdown(input, htmlRenderer, mdOptions)
}
<|endoftext|>


<commit_before>package main

import (
	"appengine"
	"appengine/user"
	"fmt"
	"github.com/gorilla/sessions"
	"github.com/icco/natnatnat/handlers"
	"github.com/pilu/traffic"
	"github.com/russross/blackfriday"
	"html/template"
	"net/http"
	"regexp"
	"time"
)

var store *sessions.CookieStore
var TwitterHandleRegex *regexp.Regexp = regexp.MustCompile(`\s@([_A-Za-z0-9]+)`)

func HstsMiddleware(w traffic.ResponseWriter, r *traffic.Request) {
	w.Header().Add("Strict-Transport-Security", "max-age=15768000")
}

func IsAdmin(c appengine.Context) bool {
	return c != nil && user.IsAdmin(c)
}

func fmtTime(t time.Time) string {
	const layout = "03:04 on Jan 2, 2006"
	return t.Format(layout)
}

func markdown(args ...interface{}) template.HTML {
	inc := []byte(fmt.Sprintf("%s", args...))
	inc = twitterHandleToMarkdown(inc)
	s := blackfriday.MarkdownCommon(inc)
	return template.HTML(s)
}

func twitterHandleToMarkdown(in []byte) []byte {
	return TwitterHandleRegex.ReplaceAll(in, []byte("[@$2](http://twitter.com/$2)"))
}

// init is one of those magic functions that runs once on project create.
func init() {
	if !appengine.IsDevAppServer() {
		traffic.SetVar("env", "production")
	}

	traffic.TemplateFunc("fmttime", fmtTime)
	traffic.TemplateFunc("mrkdwn", markdown)

	router := traffic.New()
	router.Get("/", handlers.RootHandler)

	router.Get("/post/new/?", handlers.NewPostGetHandler)
	router.Post("/post/new/?", handlers.NewPostPostHandler)

	router.Get("/post/:id/?", handlers.PostHandler)

	router.Get("/settings", handlers.SettingsGetHandler)
	router.Post("/settings", handlers.SettingsPostHandler)

	router.Get("/mention", handlers.WebMentionGetHandler)
	router.Post("/mention", handlers.WebMentionPostHandler)

	router.AddBeforeFilter(HstsMiddleware)
	router.Use(NewStaticMiddleware(traffic.PublicPath()))

	http.Handle("/", router)
}

// Entry point for go server.
func main() {}
<commit_msg>s/2/1<commit_after>package main

import (
	"appengine"
	"appengine/user"
	"fmt"
	"github.com/gorilla/sessions"
	"github.com/icco/natnatnat/handlers"
	"github.com/pilu/traffic"
	"github.com/russross/blackfriday"
	"html/template"
	"net/http"
	"regexp"
	"time"
)

var store *sessions.CookieStore
var TwitterHandleRegex *regexp.Regexp = regexp.MustCompile(`\s@([_A-Za-z0-9]+)`)

func HstsMiddleware(w traffic.ResponseWriter, r *traffic.Request) {
	w.Header().Add("Strict-Transport-Security", "max-age=15768000")
}

func IsAdmin(c appengine.Context) bool {
	return c != nil && user.IsAdmin(c)
}

func fmtTime(t time.Time) string {
	const layout = "03:04 on Jan 2, 2006"
	return t.Format(layout)
}

func markdown(args ...interface{}) template.HTML {
	inc := []byte(fmt.Sprintf("%s", args...))
	inc = twitterHandleToMarkdown(inc)
	s := blackfriday.MarkdownCommon(inc)
	return template.HTML(s)
}

func twitterHandleToMarkdown(in []byte) []byte {
	return TwitterHandleRegex.ReplaceAll(in, []byte("[@$1](http://twitter.com/$1)"))
}

// init is one of those magic functions that runs once on project create.
func init() {
	if !appengine.IsDevAppServer() {
		traffic.SetVar("env", "production")
	}

	traffic.TemplateFunc("fmttime", fmtTime)
	traffic.TemplateFunc("mrkdwn", markdown)

	router := traffic.New()
	router.Get("/", handlers.RootHandler)

	router.Get("/post/new/?", handlers.NewPostGetHandler)
	router.Post("/post/new/?", handlers.NewPostPostHandler)

	router.Get("/post/:id/?", handlers.PostHandler)

	router.Get("/settings", handlers.SettingsGetHandler)
	router.Post("/settings", handlers.SettingsPostHandler)

	router.Get("/mention", handlers.WebMentionGetHandler)
	router.Post("/mention", handlers.WebMentionPostHandler)

	router.AddBeforeFilter(HstsMiddleware)
	router.Use(NewStaticMiddleware(traffic.PublicPath()))

	http.Handle("/", router)
}

// Entry point for go server.
func main() {}
<|endoftext|>