<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/garyburd/redigo/redis"
	"github.com/scottjbarr/yahoofinance"
)

// Display a usage message.
func usage() {
	fmt.Printf("Usage : %s symbol -config filename,yml\n", os.Args[0])
}

// Publish a new Quote to the Redis server.
func publish(quote *yahoofinance.Quote) {
	js, _ := json.Marshal(quote)

	// format the JSON with a root element
	price := fmt.Sprintf("{price:%s}", js)

	redisClient.Send("PUBLISH", config.Redis.Room, price)
	redisClient.Flush()
}

// Repeatedly poll for Quote changes.
func poll(config *Config) {
	cache := make(map[string]yahoofinance.Quote)
	client := yahoofinance.CreateClient()

	for true {
		// get quotes
		quotes, err := client.GetQuotes(config.Symbols)

		if err != nil {
			log.Printf("ERROR : %v", err)
			continue
		}

		for _, quote := range quotes {
			if cache[quote.Symbol] != quote {
				// quote has changed, publish it
				cache[quote.Symbol] = quote
				publish(&quote)
			}
		}

		time.Sleep(time.Duration(config.SleepTime) * time.Millisecond)
	}
}

var redisClient redis.Conn
var config *Config

func main() {
	configFile := flag.String("config", "", "Config file")

	flag.Parse()

	if *configFile == "" {
		fmt.Println("A -config must be given. See config/example.conf.sample")
		os.Exit(1)
	}

	// parse the config file
	config = ParseConfig(*configFile)

	f, err := os.OpenFile(
		config.LogFile,
		os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)

	if err != nil {
		fmt.Printf("Error opening file: %v", err)
	}
	defer f.Close()

	// send log output to the log file
	log.SetOutput(f)

	log.Printf("Loaded config file %v with config %v", *configFile, *config)

	// create the Redis client
	redisClient = Connect(&config.Redis)
	defer redisClient.Close()

	poll(config)
}
<commit_msg>Fix the JSON string that is created.<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/garyburd/redigo/redis"
	"github.com/scottjbarr/yahoofinance"
)

// Display a usage message.
func usage() {
	fmt.Printf("Usage : %s symbol -config filename,yml\n", os.Args[0])
}

// Publish a new Quote to the Redis server.
func publish(quote *yahoofinance.Quote) {

	// format the JSON with a root element
	price := fmt.Sprintf("{price:%s}", js)
	js, _ := json.Marshal(quote)
	price := fmt.Sprintf("{\"price\":%s}", js)

	redisClient.Send("PUBLISH", config.Redis.Room, price)
	redisClient.Flush()
}

// Repeatedly poll for Quote changes.
func poll(config *Config) {
	cache := make(map[string]yahoofinance.Quote)
	client := yahoofinance.CreateClient()

	for true {
		// get quotes
		quotes, err := client.GetQuotes(config.Symbols)

		if err != nil {
			log.Printf("ERROR : %v", err)
			continue
		}

		for _, quote := range quotes {
			if cache[quote.Symbol] != quote {
				// quote has changed, publish it
				cache[quote.Symbol] = quote
				publish(&quote)
			}
		}

		time.Sleep(time.Duration(config.SleepTime) * time.Millisecond)
	}
}

var redisClient redis.Conn
var config *Config

func main() {
	configFile := flag.String("config", "", "Config file")

	flag.Parse()

	if *configFile == "" {
		fmt.Println("A -config must be given. See config/example.conf.sample")
		os.Exit(1)
	}

	// parse the config file
	config = ParseConfig(*configFile)

	f, err := os.OpenFile(
		config.LogFile,
		os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)

	if err != nil {
		fmt.Printf("Error opening file: %v", err)
	}
	defer f.Close()

	// send log output to the log file
	log.SetOutput(f)

	log.Printf("Loaded config file %v with config %v", *configFile, *config)

	// create the Redis client
	redisClient = Connect(&config.Redis)
	defer redisClient.Close()

	poll(config)
}
<|endoftext|>


<commit_before>package main

import "goretech/comparison/sqlInjections"

func main() {
	// 10er examples
	sqlInjections.UnprepStmtArg()
	sqlInjections.UnprepStmtConst()
	sqlInjections.UnprepStmtConstDecl()
	sqlInjections.UnprepStmtConstDeclUntypedString()
	sqlInjections.UnprepStmtConstDeclTypedString()
	sqlInjections.UnprepStmtConstIsConstRetVal()
	sqlInjections.UnprepStmtConstIsConstRetValFlowSens()
	sqlInjections.UnprepStmtConstDeclChangeAfterQueryFunCall()

	// 20er examples
	sqlInjections.UnprepStmtConstDeclUntypedStringQueryRow()
	sqlInjections.UnprepStmtDeclStringQueryRow()
	sqlInjections.UnprepStmtFormatedString()
	sqlInjections.UnprepStmtConstDeclSmallKeywords()
}
<commit_msg>Correct import path<commit_after>package main

import "github.com/akwick/sqinco/sqlInjections"

func main() {
	// 10er examples
	sqlInjections.UnprepStmtArg()
	sqlInjections.UnprepStmtConst()
	sqlInjections.UnprepStmtConstDecl()
	sqlInjections.UnprepStmtConstDeclUntypedString()
	sqlInjections.UnprepStmtConstDeclTypedString()
	sqlInjections.UnprepStmtConstIsConstRetVal()
	sqlInjections.UnprepStmtConstIsConstRetValFlowSens()
	sqlInjections.UnprepStmtConstDeclChangeAfterQueryFunCall()

	// 20er examples
	sqlInjections.UnprepStmtConstDeclUntypedStringQueryRow()
	sqlInjections.UnprepStmtDeclStringQueryRow()
	sqlInjections.UnprepStmtFormatedString()
	sqlInjections.UnprepStmtConstDeclSmallKeywords()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"github.com/codegangsta/martini"
	"github.com/gamingrobot/steamgo"
	. "github.com/gamingrobot/steamgo/internal"
	"github.com/gorilla/websocket"
	"log"
	"net"
	"net/http"
	"os"
	"runtime"
	"sync"
)

type WebConn struct {
	webSocket *websocket.Conn
	clientIp  net.Addr
}

type Router struct {
	mutex        sync.RWMutex
	requestCount uint64
	connections  map[uint64]WebConn
}

var router Router
var logger *log.Logger
var lastnum int

func main() {
	logger = log.New(os.Stdout, "[debug] ", log.Lshortfile|log.Lmicroseconds)
	runtime.GOMAXPROCS(4)
	webevents := make(chan string)
	steamevents := make(chan string, 100)
	go startRouter(steamevents)
	go startHttp(webevents)
	startSteam(webevents, steamevents)
}

func startRouter(steamevents <-chan string) {
	logger.Println("startRouter")
	router.connections = make(map[uint64]WebConn)
	for event := range steamevents {
		router.mutex.RLock()
		logger.Println("Number of connections", len(router.connections))
		for _, connection := range router.connections {
			err := connection.webSocket.WriteMessage(websocket.TextMessage, []byte(event))
			logger.Println("Write Error", err)
		}
		router.mutex.RUnlock()
		logger.Println("Event routed")
	}
}

func WebSocketHandler(res http.ResponseWriter, req *http.Request, webevents chan<- string) {
	ws, err := websocket.Upgrade(res, req, nil, 1024, 1024)
	if _, ok := err.(websocket.HandshakeError); ok {
		http.Error(res, "Not a websocket handshake", 400)
		return
	} else if err != nil {
		logger.Println(err)
		return
	}
	client := ws.RemoteAddr()
	sockCli := WebConn{ws, client}
	clientId := addClient(sockCli)

	for {
		_, message, err := ws.ReadMessage() //blocking
		if err != nil {
			removeClient(clientId)
			return
		} else {
			webevents <- string(message)
		}
		logger.Println("Looping read", clientId)
	}
}

func startHttp(webevents chan<- string) {
	m := martini.Classic()
	m.Get("/ws", func(res http.ResponseWriter, req *http.Request) {
		WebSocketHandler(res, req, webevents)
	})
	m.Run()
}

func startSteam(webevents <-chan string, steamevents chan<- string) {
	file, _ := os.Open("config.json")
	decoder := json.NewDecoder(file)
	login := steamgo.LogOnDetails{}
	decoder.Decode(&login)
	client := steamgo.NewClient()
	server := client.ConnectNorthAmerica()
	logger.Println("Connected to server:", server)
	for {
		select {
		case webevent := <-webevents:
			logger.Println("WebEvent", webevent)
		case steamevent := <-client.Events():
			switch e := steamevent.(type) {
			case *steamgo.ConnectedEvent:
				client.Auth.LogOn(&login)
			case *steamgo.LoggedOnEvent:
				client.Social.SetPersonaState(EPersonaState_Online)
			case steamgo.FatalError:
				client.Connect() // please do some real error handling here
				logger.Print("FatalError")
				logger.Print(e)
			case error:
				logger.Print(e)
			}
			logger.Println("Event Got from Steam", steamevent)
			m, err := json.Marshal(steamevent)
			if err != nil {
				logger.Println("Failed to encode event")
			} else {
				steamevents <- string(m)
				//logger.Println("Event Sent to Router", string(m))
			}
		}
	}
}

func addClient(connection WebConn) uint64 {
	router.mutex.Lock()
	defer router.mutex.Unlock()
	router.requestCount += 1
	router.connections[router.requestCount] = connection
	return router.requestCount
}

func removeClient(id uint64) {
	logger.Println("Removing Client ", id)
	router.mutex.Lock()
	defer router.mutex.Unlock()
	delete(router.connections, id)
}
<commit_msg>Added event struct with reflect<commit_after>package main

import (
	"encoding/json"
	"github.com/codegangsta/martini"
	"github.com/gamingrobot/steamgo"
	. "github.com/gamingrobot/steamgo/internal"
	"github.com/gorilla/websocket"
	"log"
	"net"
	"net/http"
	"os"
	"reflect"
	"runtime"
	"sync"
)

type WebConn struct {
	webSocket *websocket.Conn
	clientIp  net.Addr
}

type Router struct {
	mutex        sync.RWMutex
	requestCount uint64
	connections  map[uint64]WebConn
}

type Event struct {
	Name  string
	Event interface{}
}

var router Router
var logger *log.Logger
var lastnum int

func main() {
	logger = log.New(os.Stdout, "[debug] ", log.Lshortfile|log.Lmicroseconds)
	runtime.GOMAXPROCS(4)
	webevents := make(chan string)
	steamevents := make(chan string, 100)
	go startRouter(steamevents)
	go startHttp(webevents)
	startSteam(webevents, steamevents)
}

func startRouter(steamevents <-chan string) {
	logger.Println("startRouter")
	router.connections = make(map[uint64]WebConn)
	for event := range steamevents {
		router.mutex.RLock()
		logger.Println("Number of connections", len(router.connections))
		for _, connection := range router.connections {
			err := connection.webSocket.WriteMessage(websocket.TextMessage, []byte(event))
			logger.Println("Write Error", err)
		}
		router.mutex.RUnlock()
		logger.Println("Event routed")
	}
}

func WebSocketHandler(res http.ResponseWriter, req *http.Request, webevents chan<- string) {
	ws, err := websocket.Upgrade(res, req, nil, 1024, 1024)
	if _, ok := err.(websocket.HandshakeError); ok {
		http.Error(res, "Not a websocket handshake", 400)
		return
	} else if err != nil {
		logger.Println(err)
		return
	}
	client := ws.RemoteAddr()
	sockCli := WebConn{webSocket: ws, clientIp: client}
	clientId := addClient(sockCli)

	for {
		_, message, err := ws.ReadMessage() //blocking
		if err != nil {
			removeClient(clientId)
			return
		} else {
			webevents <- string(message)
		}
		logger.Println("Looping read", clientId)
	}
}

func startHttp(webevents chan<- string) {
	m := martini.Classic()
	m.Get("/ws", func(res http.ResponseWriter, req *http.Request) {
		WebSocketHandler(res, req, webevents)
	})
	m.Run()
}

func startSteam(webevents <-chan string, steamevents chan<- string) {
	file, _ := os.Open("config.json")
	decoder := json.NewDecoder(file)
	login := steamgo.LogOnDetails{}
	decoder.Decode(&login)
	client := steamgo.NewClient()
	server := client.ConnectNorthAmerica()
	logger.Println("Connected to server:", server)
	for {
		select {
		case webevent := <-webevents:
			logger.Println("WebEvent", webevent)
		case steamevent := <-client.Events():
			switch e := steamevent.(type) {
			case steamgo.ConnectedEvent:
				client.Auth.LogOn(&login)
			case steamgo.LoggedOnEvent:
				client.Social.SetPersonaState(EPersonaState_Online)
			case steamgo.FatalError:
				client.Connect() // please do some real error handling here
				logger.Print("FatalError")
				logger.Print(e)
			case error:
				logger.Print(e)
			}
			//logger.Println("Event Got from Steam", steamevent)
			outevent := Event{Name: reflect.TypeOf(steamevent).Name(), Event: steamevent}
			m, err := json.Marshal(outevent)
			if err != nil {
				logger.Println("Failed to encode event")
			} else {
				steamevents <- string(m)
				logger.Println("Event Sent to Router", string(m))
			}
		}
	}
}

func addClient(connection WebConn) uint64 {
	router.mutex.Lock()
	defer router.mutex.Unlock()
	router.requestCount += 1
	router.connections[router.requestCount] = connection
	return router.requestCount
}

func removeClient(id uint64) {
	logger.Println("Removing Client ", id)
	router.mutex.Lock()
	defer router.mutex.Unlock()
	delete(router.connections, id)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"

	log "github.com/Sirupsen/logrus"
	haikunator "github.com/atrox/haikunatorgo"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/msoedov/hacker-slides/files"
)

const sessionHeader = "slide-session"

func Header(c *gin.Context, key string) string {
	if values, _ := c.Request.Header[key]; len(values) > 0 {
		return values[0]
	}
	return ""
}

func BasicAuth() gin.HandlerFunc {
	realm := "Authorization Required"
	realm = "Basic realm=" + strconv.Quote(realm)
	user := os.Getenv("USER")
	password := os.Getenv("PASSWORD")
	enabled := isEnabled(user, password)
	if enabled {
		log.Warn("Auth mode enabled")
		log.Warn(fmt.Sprintf("Visit http://%s:%s@0.0.0.0:8080", user, password))
	}
	return func(c *gin.Context) {
		header := Header(c, "Authorization")
		if enabled && header != authorizationHeader(user, password) {
			// Credentials doesn't match, we return 401 and abort handlers chain.
			c.Header("WWW-Authenticate", realm)
			c.AbortWithStatus(401)
			return
		}
		c.Next()
	}
}

func isEnabled(user, password string) bool {
	switch {
	case user == "":
		return false
	case password == "":
		return false
	default:
		return true
	}
}

func authorizationHeader(user, password string) string {
	base := user + ":" + password
	return "Basic " + base64.StdEncoding.EncodeToString([]byte(base))
}

func NewApp() *gin.Engine {

	r := gin.Default()

	store := sessions.NewCookieStore([]byte("secret"))
	r.Use(sessions.Sessions(sessionHeader, store))
	r.Use(BasicAuth())

	r.LoadHTMLGlob("templates/*.tmpl")
	r.Static("/static", "./static")

	r.GET("/", func(c *gin.Context) {
		isNew := c.Query("new")
		latest := files.LatestFileIn("slides")
		log.WithFields(log.Fields{
			"name":  latest,
			"isNew": isNew,
		}).Info("Restoring latest point")

		var path, name string
		if latest == "" || isNew != "" {
			haikunator := haikunator.New()
			haikunator.TokenLength = 0
			name = haikunator.Haikunate()
		} else {
			name = strings.Replace(latest, ".md", "", 1)
		}
		path = fmt.Sprintf("slides/%s.md", name)

		log.WithFields(log.Fields{
			"path": path,
		}).Info("A new session")
		session := sessions.Default(c)
		session.Set("name", path)
		session.Save()

		c.Writer.Header().Set("Location", fmt.Sprintf("/stash/edit/%s", name))
		c.HTML(302, "index.tmpl", gin.H{
			"pubTo": path,
		})
	})

	mustHaveSession := func(c *gin.Context) (string, error) {
		session := sessions.Default(c)
		val := session.Get("name")
		emptySession := errors.New("Emtpy session")
		if val == nil {
			c.String(400, "No context")
			return "", emptySession
		}
		log.WithFields(log.Fields{
			"path": val,
		}).Info("Got session")
		path, ok := val.(string)
		if !ok {
			c.String(400, "No context")
			return "", emptySession
		}
		return path, nil
	}

	r.GET("/slides.md", func(c *gin.Context) {
		path, err := mustHaveSession(c)
		if err != nil {
			return
		}
		if _, err := os.Stat(path); err != nil {
			// copy sample markdown file to the path
			body, err := ioutil.ReadFile("initial-slides.md")
			if err != nil {
				panic(err)
			}
			ioutil.WriteFile(path, body, 0644)
			c.String(200, string(body))
			return
		}

		body, err := ioutil.ReadFile(path)
		if err != nil {
			panic(err)
		}
		c.String(200, string(body))
	})

	r.PUT("/slides.md", func(c *gin.Context) {
		path, err := mustHaveSession(c)
		if err != nil {
			return
		}
		body, _ := ioutil.ReadAll(c.Request.Body)
		ioutil.WriteFile(path, body, 0644)
		log.WithFields(log.Fields{
			"size": len(body),
			"file": path,
		}).Info("Wrote to file")
		c.String(200, "")
	})

	r.GET("/stash", func(c *gin.Context) {
		files, err := ioutil.ReadDir("slides")
		if err != nil {
			log.Fatal(err)
		}
		var stash []string
		for _, file := range files {
			stash = append(stash, file.Name())
		}
		c.HTML(200, "stash.tmpl", gin.H{
			"stash": stash,
		})
	})

	r.GET("/stash/edit/:name", func(c *gin.Context) {

		name := c.Param("name")
		log.WithFields(log.Fields{
			"name": name,
		}).Info("Restore session?")

		if strings.HasSuffix(name, ".md") {
			name = name[0 : len(name)-3]
		}
		path := fmt.Sprintf("slides/%s.md", name)
		session := sessions.Default(c)
		session.Set("name", path)
		session.Save()

		c.HTML(200, "index.tmpl", gin.H{
			"pubTo": path,
		})
	})

	r.GET("/published/slides/:name", func(c *gin.Context) {

		name := c.Param("name")
		log.WithFields(log.Fields{
			"name": name,
		}).Info("Published")

		if strings.HasSuffix(name, ".md") {
			name = name[0 : len(name)-3]
		}
		path := fmt.Sprintf("slides/%s.md", name)
		session := sessions.Default(c)
		session.Set("name", path)
		session.Save()
		c.HTML(200, "slides.tmpl", gin.H{
			"pubTo": path,
		})
	})

	return r

}

func main() {
	r := NewApp()
	port := "8080"
	if len(os.Args) > 1 {
		port = os.Args[1]
	} else {
		envPort := os.Getenv("PORT")
		if len(envPort) > 0 {
			port = envPort
		}
	}
	log.Info("Started http://0.0.0.0:8080")
	r.Run(fmt.Sprintf(":%s", port))
}
<commit_msg>Add Path function<commit_after>package main

import (
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"

	log "github.com/Sirupsen/logrus"
	haikunator "github.com/atrox/haikunatorgo"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/msoedov/hacker-slides/files"
)

const sessionHeader = "slide-session"

func Header(c *gin.Context, key string) string {
	if values, _ := c.Request.Header[key]; len(values) > 0 {
		return values[0]
	}
	return ""
}

func BasicAuth() gin.HandlerFunc {
	realm := "Authorization Required"
	realm = "Basic realm=" + strconv.Quote(realm)
	user := os.Getenv("USER")
	password := os.Getenv("PASSWORD")
	enabled := isEnabled(user, password)
	if enabled {
		log.Warn("Auth mode enabled")
		log.Warn(fmt.Sprintf("Visit http://%s:%s@0.0.0.0:8080", user, password))
	}
	return func(c *gin.Context) {
		header := Header(c, "Authorization")
		if enabled && header != authorizationHeader(user, password) {
			// Credentials doesn't match, we return 401 and abort handlers chain.
			c.Header("WWW-Authenticate", realm)
			c.AbortWithStatus(401)
			return
		}
		c.Next()
	}
}

func isEnabled(user, password string) bool {
	switch {
	case user == "":
		return false
	case password == "":
		return false
	default:
		return true
	}
}

func authorizationHeader(user, password string) string {
	base := user + ":" + password
	return "Basic " + base64.StdEncoding.EncodeToString([]byte(base))
}

func SlidePath(name string) string {
	return fmt.Sprintf("slides/%s.md", name)
}

func NewApp() *gin.Engine {

	r := gin.Default()

	store := sessions.NewCookieStore([]byte("secret"))
	r.Use(sessions.Sessions(sessionHeader, store))
	r.Use(BasicAuth())

	r.LoadHTMLGlob("templates/*.tmpl")
	r.Static("/static", "./static")

	r.GET("/", func(c *gin.Context) {
		isNew := c.Query("new")
		latest := files.LatestFileIn("slides")
		log.WithFields(log.Fields{
			"name":  latest,
			"isNew": isNew,
		}).Info("Restoring latest point")

		var path, name string
		if latest == "" || isNew != "" {
			haikunator := haikunator.New()
			haikunator.TokenLength = 0
			name = haikunator.Haikunate()
		} else {
			name = strings.Replace(latest, ".md", "", 1)
		}
		path = SlidePath(name)

		log.WithFields(log.Fields{
			"path": path,
		}).Info("A new session")
		session := sessions.Default(c)
		session.Set("name", path)
		session.Save()

		c.Writer.Header().Set("Location", fmt.Sprintf("/stash/edit/%s", name))
		c.HTML(302, "index.tmpl", gin.H{
			"pubTo": path,
		})
	})

	mustHaveSession := func(c *gin.Context) (string, error) {
		session := sessions.Default(c)
		val := session.Get("name")
		emptySession := errors.New("Emtpy session")
		if val == nil {
			c.String(400, "No context")
			return "", emptySession
		}
		log.WithFields(log.Fields{
			"path": val,
		}).Info("Got session")
		path, ok := val.(string)
		if !ok {
			c.String(400, "No context")
			return "", emptySession
		}
		return path, nil
	}

	r.GET("/slides.md", func(c *gin.Context) {
		path, err := mustHaveSession(c)
		if err != nil {
			return
		}
		if _, err := os.Stat(path); err != nil {
			// copy sample markdown file to the path
			body, err := ioutil.ReadFile("initial-slides.md")
			if err != nil {
				panic(err)
			}
			ioutil.WriteFile(path, body, 0644)
			c.String(200, string(body))
			return
		}

		body, err := ioutil.ReadFile(path)
		if err != nil {
			panic(err)
		}
		c.String(200, string(body))
	})

	r.PUT("/slides.md", func(c *gin.Context) {
		path, err := mustHaveSession(c)
		if err != nil {
			return
		}
		body, _ := ioutil.ReadAll(c.Request.Body)
		ioutil.WriteFile(path, body, 0644)
		log.WithFields(log.Fields{
			"size": len(body),
			"file": path,
		}).Info("Wrote to file")
		c.String(200, "")
	})

	r.GET("/stash", func(c *gin.Context) {
		files, err := ioutil.ReadDir("slides")
		if err != nil {
			log.Fatal(err)
		}
		var stash []string
		for _, file := range files {
			stash = append(stash, file.Name())
		}
		c.HTML(200, "stash.tmpl", gin.H{
			"stash": stash,
		})
	})

	r.GET("/stash/edit/:name", func(c *gin.Context) {

		name := c.Param("name")
		log.WithFields(log.Fields{
			"name": name,
		}).Info("Restore session?")

		if strings.HasSuffix(name, ".md") {
			name = name[0 : len(name)-3]
		}
		path := SlidePath(name)
		session := sessions.Default(c)
		session.Set("name", path)
		session.Save()

		c.HTML(200, "index.tmpl", gin.H{
			"pubTo": path,
		})
	})

	r.GET("/published/slides/:name", func(c *gin.Context) {

		name := c.Param("name")
		log.WithFields(log.Fields{
			"name": name,
		}).Info("Published")

		if strings.HasSuffix(name, ".md") {
			name = name[0 : len(name)-3]
		}
		path := SlidePath(name)
		session := sessions.Default(c)
		session.Set("name", path)
		session.Save()
		c.HTML(200, "slides.tmpl", gin.H{
			"pubTo": path,
		})
	})

	return r

}

func main() {
	r := NewApp()
	port := "8080"
	if len(os.Args) > 1 {
		port = os.Args[1]
	} else {
		envPort := os.Getenv("PORT")
		if len(envPort) > 0 {
			port = envPort
		}
	}
	log.Info("Started http://0.0.0.0:8080")
	r.Run(fmt.Sprintf(":%s", port))
}
<|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.2"
	user_agent = fmt.Sprint("github-markdown-toc.go v", version)
)

type GHToc []string

//
// 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) *GHToc {
	return GrabTocX(html, "")
}

func GrabTocX(html string, absPath string) *GHToc {
	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 := GHToc{}
	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"])
		link := groups["href"]
		if len(absPath) > 0 {
			link = absPath + link
		}
		toc_item := strings.Repeat("  ", n) + "* " +
			"[" + removeStuf(groups["name"]) + "]" +
			"(" + link + ")"
		//fmt.Println(toc_item)
		toc = append(toc, toc_item)
	}

	return &toc
}

// Generate TOC for document (path in filesystem or url)
func GenerateToc(path string) *GHToc {
	return GenerateTocX(path, false)
}

func GenerateTocX(path string, absPaths bool) *GHToc {
	htmlBody := GetHmtlBody(path)
	if absPaths {
		return GrabTocX(htmlBody, path)
	} else {
		return GrabToc(htmlBody)
	}
}

// PrintToc print on console string array
func PrintToc(toc *GHToc) {
	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()
	serial := kingpin.Flag("serial", "Grab TOCs in the serial mode").Bool()
	kingpin.Version(version)
	kingpin.Parse()

	pathsCount := len(*paths)

	if pathsCount == 1 {
		fmt.Println()
		fmt.Println("Table of Contents")
		fmt.Println("=================")
		fmt.Println()
	}

	// read file paths | urls from args
	absPathsInToc := pathsCount > 1
	ch := make(chan *GHToc, pathsCount)
	for _, p := range *paths {
		if *serial {
			ch <- GenerateTocX(p, absPathsInToc)
		} else {
			go func(path string, showAbsPath bool) {
				ch <- GenerateTocX(path, absPathsInToc)
			}(p, absPathsInToc)
		}
	}

	for i := 1; i <= pathsCount; i++ {
		PrintToc(<-ch)
	}

	// read md from stdin
	if pathsCount == 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>0.4.0<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.4.0"
	user_agent = fmt.Sprint("github-markdown-toc.go v", version)
)

type GHToc []string

//
// 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) *GHToc {
	return GrabTocX(html, "")
}

func GrabTocX(html string, absPath string) *GHToc {
	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 := GHToc{}
	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"])
		link := groups["href"]
		if len(absPath) > 0 {
			link = absPath + link
		}
		toc_item := strings.Repeat("  ", n) + "* " +
			"[" + removeStuf(groups["name"]) + "]" +
			"(" + link + ")"
		//fmt.Println(toc_item)
		toc = append(toc, toc_item)
	}

	return &toc
}

// Generate TOC for document (path in filesystem or url)
func GenerateToc(path string) *GHToc {
	return GenerateTocX(path, false)
}

func GenerateTocX(path string, absPaths bool) *GHToc {
	htmlBody := GetHmtlBody(path)
	if absPaths {
		return GrabTocX(htmlBody, path)
	} else {
		return GrabToc(htmlBody)
	}
}

// PrintToc print on console string array
func PrintToc(toc *GHToc) {
	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()
	serial := kingpin.Flag("serial", "Grab TOCs in the serial mode").Bool()
	kingpin.Version(version)
	kingpin.Parse()

	pathsCount := len(*paths)

	if pathsCount == 1 {
		fmt.Println()
		fmt.Println("Table of Contents")
		fmt.Println("=================")
		fmt.Println()
	}

	// read file paths | urls from args
	absPathsInToc := pathsCount > 1
	ch := make(chan *GHToc, pathsCount)
	for _, p := range *paths {
		if *serial {
			ch <- GenerateTocX(p, absPathsInToc)
		} else {
			go func(path string, showAbsPath bool) {
				ch <- GenerateTocX(path, absPathsInToc)
			}(p, absPathsInToc)
		}
	}

	for i := 1; i <= pathsCount; i++ {
		PrintToc(<-ch)
	}

	// read md from stdin
	if pathsCount == 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 (
	"flag"
	"fmt"
	"os"

	"github.com/codemodus/sigmon"
)

var (
	// slow enables a slowing of the digest function and may help users to
	// better understand the implementation of concurrency
	slow = false

	// width controls the amount of goroutines running the digest function
	width = 8
)

func main() {
	sm := sigmon.New(nil)
	sm.Run()

	// define and parse flags
	flag.BoolVar(&slow, "slow", slow, `slow processing to clarify behavior`)
	flag.IntVar(&width, "width", width, `set concurrency width`)
	flag.Parse()

	// get fileInfoGroup
	fig, err := newFileInfoGroup("./testfiles")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	// get new conch and setup cleanup
	c := newConch(fig)

	sm.Set(func(s *sigmon.SignalMonitor) {
		close(c.doneChan())
	})

	// get fileOutput and error channels
	fos, errc := c.run()

	// print file contents
	for fo := range fos {
		fmt.Println(fo.path, fo.data, fo.err)
	}

	// print error, if any
	select {
	case err := <-errc:
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	default:
	}

	sm.Stop()
}
<commit_msg>Call Stop() on signal monitor to prevent close on closed chan.<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/codemodus/sigmon"
)

var (
	// slow enables a slowing of the digest function and may help users to
	// better understand the implementation of concurrency
	slow = false

	// width controls the amount of goroutines running the digest function
	width = 8
)

func main() {
	sm := sigmon.New(nil)
	sm.Run()

	// define and parse flags
	flag.BoolVar(&slow, "slow", slow, `slow processing to clarify behavior`)
	flag.IntVar(&width, "width", width, `set concurrency width`)
	flag.Parse()

	// get fileInfoGroup
	fig, err := newFileInfoGroup("./testfiles")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	// get new conch and setup cleanup
	c := newConch(fig)

	sm.Set(func(s *sigmon.SignalMonitor) {
		close(c.doneChan())
		sm.Stop()
	})

	// get fileOutput and error channels
	fos, errc := c.run()

	// print file contents
	for fo := range fos {
		fmt.Println(fo.path, fo.data, fo.err)
	}

	// print error, if any
	select {
	case err := <-errc:
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	default:
	}

	sm.Stop()
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"database/sql"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	_ "github.com/mattn/go-sqlite3"
	"github.com/pkg/errors"
)

type tagType int

const (
	GTAGS tagType = iota
	GRTAGS
	GPATH
)

func (t tagType) String() string {
	switch t {
	case GTAGS:
		return "GTAGS"
	case GRTAGS:
		return "GRTAGS"
	case GPATH:
		return "GPATH"
	}
	panic("invalid tagType")
}

type standard struct {
	tagName    string
	fileID     int
	lineNumber int
	lineImage  string
}

func (s standard) String() string {
	return fmt.Sprintf("%d @n %d %s", s.fileID, s.lineNumber, s.lineImage)
}

type compact struct {
	fileID      int
	lineNumbers []int
}

func (c compact) String() string {
	continueCounter := 0
	output := fmt.Sprintf("%d", c.lineNumbers[0]) // [0] must be exist
	for l := 1; l < len(c.lineNumbers); l++ {
		diff := c.lineNumbers[l] - c.lineNumbers[l-1]
		if continueCounter == 0 {
			if diff == 1 {
				output += "-"
				continueCounter++
			} else {
				output += fmt.Sprintf(",%d", diff)
			}
		} else {
			if diff == 1 {
				continueCounter++
			} else {
				output += fmt.Sprintf("%d,%d", continueCounter, diff)
				continueCounter = 0
			}
		}
	}
	if continueCounter != 0 {
		output += fmt.Sprintf("%d", continueCounter)
	}
	return fmt.Sprintf("%d @n %s", c.fileID, output)
}

type global struct {
	fileID     int
	gtagsData  []standard
	grtagsData map[string]*compact
	db         map[tagType]*sql.DB
	// lineImageScanner
	basePath       string
	currentFile    *os.File
	currentRelPath string
	currentLine    int
	scanner        *bufio.Scanner
	fset           *token.FileSet
}

func newGlobal(fset *token.FileSet, basePath string) (*global, error) {
	g := &global{
		fileID:      0,
		gtagsData:   make([]standard, 0),
		grtagsData:  make(map[string]*compact),
		db:          make(map[tagType]*sql.DB),
		basePath:    basePath,
		currentFile: nil,
		currentLine: 0,
		scanner:     nil,
		fset:        fset,
	}

	dbfiles := []tagType{
		GTAGS,
		GRTAGS,
		GPATH,
	}

	var err error
	for _, file := range dbfiles {
		os.Remove("./" + file.String())
		g.db[file], err = sql.Open("sqlite3", file.String())
		if err != nil {
			return nil, err
		}
		_, err = g.db[file].Exec(`create table db (key text, dat text, extra text)`)
		if err != nil {
			return nil, err
		}
	}

	g.insertEntry(GTAGS, " __.COMPRESS", " __.COMPRESS ddefine ttypedef", nil)
	g.insertEntry(GTAGS, " __.COMPNAME", " __.COMPNAME", nil)
	g.insertEntry(GTAGS, " __.VERSION", " __.VERSION 6", nil)

	g.insertEntry(GRTAGS, " __.COMPACT", " __.COMPACT", nil)
	g.insertEntry(GRTAGS, " __.COMPLINE", " __.COMPLINE", nil)
	g.insertEntry(GRTAGS, " __.COMPNAME", " __.COMPNAME", nil)
	g.insertEntry(GRTAGS, " __.VERSION", " __.VERSION 6", nil)

	g.insertEntry(GPATH, " __.VERSION", " __.VERSION 2", nil)
	g.insertEntry(GPATH, " __.NEXTKEY", "1", nil)

	return g, nil
}

func (g *global) insertEntry(tag tagType, key, dat, extra interface{}) {
	stmt, err := g.db[tag].Prepare(`insert into db (key, dat, extra) values (?, ?, ?)`)
	if err != nil {
		log.Println(err, "tag:", tag, "|key:", key, "|dat:", dat, "|extra:", extra)
		panic("failed to prepare")
	}
	_, err = stmt.Exec(key, dat, extra)
	if err != nil {
		log.Println(err, "tag:", tag, "|key:", key, "|dat:", dat, "|extra:", extra)
		panic("failed to exec")
	}
}

func (g *global) dump() {
	if g.fileID == 0 {
		return
	}

	for _, s := range g.gtagsData {
		g.insertEntry(GTAGS, s.tagName, s.String(), strconv.Itoa(s.fileID))
	}
	for tagName, compact := range g.grtagsData {
		g.insertEntry(GRTAGS, tagName, compact.String(), strconv.Itoa(compact.fileID))
	}

	filepath, _ := filepath.Rel(g.basePath, g.currentFile.Name())
	filepath = "./" + filepath
	log.Println(filepath)

	g.insertEntry(GPATH, filepath, g.fileID, nil)
	g.insertEntry(GPATH, g.fileID, filepath, nil)
	g.insertEntry(GPATH, " __.NEXTKEY", strconv.Itoa(g.fileID+1), nil)
}

func (g *global) finalize() error {
	if g.currentFile != nil {
		err := g.currentFile.Close()
		if err != nil {
			return err
		}
	}
	g.dump()
	return nil
}

func (g *global) switchFile(abspath string) (err error) {
	// Close and Setup Scanner
	if g.currentFile != nil {
		err := g.currentFile.Close()
		if err != nil {
			return errors.Wrapf(err, "failed to close current file, current: %s abspath: %s", g.currentFile.Name(), abspath)
		}
	}
	g.currentFile, err = os.Open(abspath)
	if err != nil {
		return errors.Wrap(err, "failed to open next file ")
	}
	g.scanner = bufio.NewScanner(g.currentFile)
	g.currentLine = 0

	// Reset parsed data
	g.gtagsData = make([]standard, 0)
	g.grtagsData = make(map[string]*compact)
	g.fileID++

	return nil
}

func (g *global) addFuncDecl(node *ast.FuncDecl) {
	ident := node.Name
	pos := g.fset.Position(node.Pos())
	for ; g.currentLine < pos.Line; g.currentLine++ {
		g.scanner.Scan()
	}
	lineImage := strings.Replace(strings.TrimSpace(g.scanner.Text()), ident.Name, "@n", -1)

	g.gtagsData = append(g.gtagsData, standard{
		tagName:    ident.Name,
		fileID:     g.fileID,
		lineNumber: pos.Line,
		lineImage:  lineImage,
	})
}

func (g *global) addIdent(ident *ast.Ident) {
	pos := g.fset.Position(ident.Pos())
	r, found := g.grtagsData[ident.Name]
	if found {
		r.lineNumbers = append(r.lineNumbers, pos.Line)
	} else {
		g.grtagsData[ident.Name] = &compact{
			fileID:      g.fileID,
			lineNumbers: []int{pos.Line},
		}
	}
}

func (g *global) parse(node ast.Node) bool {
	if node == nil {
		return false
	}
	if _, ok := node.(*ast.Package); ok {
		return true
	}
	pos := g.fset.Position(node.Pos())
	absPath, err := filepath.Abs(pos.Filename)
	if err != nil {
		log.Fatal("failed to get absolute path: ", err)
	}
	if g.currentFile == nil || g.currentFile.Name() != absPath {
		g.dump()

		err = g.switchFile(absPath)
		if err != nil {
			log.Fatal("failed to switch file: ", err)
		}
	}

	switch node.(type) {
	case *ast.FuncDecl:
		g.addFuncDecl(node.(*ast.FuncDecl))
	case *ast.Ident:
		g.addIdent(node.(*ast.Ident))
	}
	return true
}

func main() {
	basePath, err := filepath.Abs(".")
	if err != nil {
		log.Fatal("failed to get absolute path: ", err)
	}

	fset := token.NewFileSet() // positions are relative to fset
	g, err := newGlobal(fset, basePath)
	if err != nil {
		log.Fatal(err)
	}

	err = filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			pkgs, err := parser.ParseDir(fset, path, nil, 0)
			if err != nil {
				log.Fatal(err)
			}
			for _, p := range pkgs {
				ast.Inspect(p, g.parse)
			}
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}

	err = g.finalize()
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Remove prepare<commit_after>package main

import (
	"bufio"
	"database/sql"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	_ "github.com/mattn/go-sqlite3"
	"github.com/pkg/errors"
)

type tagType int

const (
	GTAGS tagType = iota
	GRTAGS
	GPATH
)

func (t tagType) String() string {
	switch t {
	case GTAGS:
		return "GTAGS"
	case GRTAGS:
		return "GRTAGS"
	case GPATH:
		return "GPATH"
	}
	panic("invalid tagType")
}

type standard struct {
	tagName    string
	fileID     int
	lineNumber int
	lineImage  string
}

func (s standard) String() string {
	return fmt.Sprintf("%d @n %d %s", s.fileID, s.lineNumber, s.lineImage)
}

type compact struct {
	fileID      int
	lineNumbers []int
}

func (c compact) String() string {
	continueCounter := 0
	output := fmt.Sprintf("%d", c.lineNumbers[0]) // [0] must be exist
	for l := 1; l < len(c.lineNumbers); l++ {
		diff := c.lineNumbers[l] - c.lineNumbers[l-1]
		if continueCounter == 0 {
			if diff == 1 {
				output += "-"
				continueCounter++
			} else {
				output += fmt.Sprintf(",%d", diff)
			}
		} else {
			if diff == 1 {
				continueCounter++
			} else {
				output += fmt.Sprintf("%d,%d", continueCounter, diff)
				continueCounter = 0
			}
		}
	}
	if continueCounter != 0 {
		output += fmt.Sprintf("%d", continueCounter)
	}
	return fmt.Sprintf("%d @n %s", c.fileID, output)
}

type global struct {
	fileID     int
	gtagsData  []standard
	grtagsData map[string]*compact
	db         map[tagType]*sql.DB
	// lineImageScanner
	basePath       string
	currentFile    *os.File
	currentRelPath string
	currentLine    int
	scanner        *bufio.Scanner
	fset           *token.FileSet
}

func newGlobal(fset *token.FileSet, basePath string) (*global, error) {
	g := &global{
		fileID:      0,
		gtagsData:   make([]standard, 0),
		grtagsData:  make(map[string]*compact),
		db:          make(map[tagType]*sql.DB),
		basePath:    basePath,
		currentFile: nil,
		currentLine: 0,
		scanner:     nil,
		fset:        fset,
	}

	dbfiles := []tagType{
		GTAGS,
		GRTAGS,
		GPATH,
	}

	var err error
	for _, file := range dbfiles {
		os.Remove("./" + file.String())
		g.db[file], err = sql.Open("sqlite3", file.String())
		if err != nil {
			return nil, err
		}
		_, err = g.db[file].Exec(`create table db (key text, dat text, extra text)`)
		if err != nil {
			return nil, err
		}
	}

	g.insertEntry(GTAGS, " __.COMPRESS", " __.COMPRESS ddefine ttypedef", nil)
	g.insertEntry(GTAGS, " __.COMPNAME", " __.COMPNAME", nil)
	g.insertEntry(GTAGS, " __.VERSION", " __.VERSION 6", nil)

	g.insertEntry(GRTAGS, " __.COMPACT", " __.COMPACT", nil)
	g.insertEntry(GRTAGS, " __.COMPLINE", " __.COMPLINE", nil)
	g.insertEntry(GRTAGS, " __.COMPNAME", " __.COMPNAME", nil)
	g.insertEntry(GRTAGS, " __.VERSION", " __.VERSION 6", nil)

	g.insertEntry(GPATH, " __.VERSION", " __.VERSION 2", nil)
	g.insertEntry(GPATH, " __.NEXTKEY", "1", nil)

	return g, nil
}

func (g *global) insertEntry(tag tagType, key, dat, extra interface{}) {
	_, err := g.db[tag].Exec(`insert into db (key, dat, extra) values (?, ?, ?)`, key, dat, extra)
	if err != nil {
		log.Println(err, "tag:", tag, "|key:", key, "|dat:", dat, "|extra:", extra)
		panic("failed to exec")
	}
}

func (g *global) dump() {
	if g.fileID == 0 {
		return
	}

	for _, s := range g.gtagsData {
		g.insertEntry(GTAGS, s.tagName, s.String(), strconv.Itoa(s.fileID))
	}
	for tagName, compact := range g.grtagsData {
		g.insertEntry(GRTAGS, tagName, compact.String(), strconv.Itoa(compact.fileID))
	}

	filepath, _ := filepath.Rel(g.basePath, g.currentFile.Name())
	filepath = "./" + filepath
	log.Println(filepath)

	g.insertEntry(GPATH, filepath, g.fileID, nil)
	g.insertEntry(GPATH, g.fileID, filepath, nil)
	g.insertEntry(GPATH, " __.NEXTKEY", strconv.Itoa(g.fileID+1), nil)
}

func (g *global) finalize() error {
	if g.currentFile != nil {
		err := g.currentFile.Close()
		if err != nil {
			return err
		}
	}
	g.dump()
	return nil
}

func (g *global) switchFile(abspath string) (err error) {
	// Close and Setup Scanner
	if g.currentFile != nil {
		err := g.currentFile.Close()
		if err != nil {
			return errors.Wrapf(err, "failed to close current file, current: %s abspath: %s", g.currentFile.Name(), abspath)
		}
	}
	g.currentFile, err = os.Open(abspath)
	if err != nil {
		return errors.Wrap(err, "failed to open next file ")
	}
	g.scanner = bufio.NewScanner(g.currentFile)
	g.currentLine = 0

	// Reset parsed data
	g.gtagsData = make([]standard, 0)
	g.grtagsData = make(map[string]*compact)
	g.fileID++

	return nil
}

func (g *global) addFuncDecl(node *ast.FuncDecl) {
	ident := node.Name
	pos := g.fset.Position(node.Pos())
	for ; g.currentLine < pos.Line; g.currentLine++ {
		g.scanner.Scan()
	}
	lineImage := strings.Replace(strings.TrimSpace(g.scanner.Text()), ident.Name, "@n", -1)

	g.gtagsData = append(g.gtagsData, standard{
		tagName:    ident.Name,
		fileID:     g.fileID,
		lineNumber: pos.Line,
		lineImage:  lineImage,
	})
}

func (g *global) addIdent(ident *ast.Ident) {
	pos := g.fset.Position(ident.Pos())
	r, found := g.grtagsData[ident.Name]
	if found {
		r.lineNumbers = append(r.lineNumbers, pos.Line)
	} else {
		g.grtagsData[ident.Name] = &compact{
			fileID:      g.fileID,
			lineNumbers: []int{pos.Line},
		}
	}
}

func (g *global) parse(node ast.Node) bool {
	if node == nil {
		return false
	}
	if _, ok := node.(*ast.Package); ok {
		return true
	}
	pos := g.fset.Position(node.Pos())
	absPath, err := filepath.Abs(pos.Filename)
	if err != nil {
		log.Fatal("failed to get absolute path: ", err)
	}
	if g.currentFile == nil || g.currentFile.Name() != absPath {
		g.dump()

		err = g.switchFile(absPath)
		if err != nil {
			log.Fatal("failed to switch file: ", err)
		}
	}

	switch node.(type) {
	case *ast.FuncDecl:
		g.addFuncDecl(node.(*ast.FuncDecl))
	case *ast.Ident:
		g.addIdent(node.(*ast.Ident))
	}
	return true
}

func main() {
	basePath, err := filepath.Abs(".")
	if err != nil {
		log.Fatal("failed to get absolute path: ", err)
	}

	fset := token.NewFileSet() // positions are relative to fset
	g, err := newGlobal(fset, basePath)
	if err != nil {
		log.Fatal(err)
	}

	err = filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			pkgs, err := parser.ParseDir(fset, path, nil, 0)
			if err != nil {
				log.Fatal(err)
			}
			for _, p := range pkgs {
				ast.Inspect(p, g.parse)
			}
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}

	err = g.finalize()
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/mattn/go-tty"
)

type ActionType int

const (
	LABEL_AS_POSITIVE ActionType = iota
	LABEL_AS_NEGATIVE
	SAVE
	HELP
	SKIP
	EXIT
)

func input2ActionType() (ActionType, error) {
	t, err := tty.Open()
	defer t.Close()
	if err != nil {
		return EXIT, err
	}
	var r rune
	for r == 0 {
		r, err = t.ReadRune()
		if err != nil {
			return SKIP, err
		}
	}
	switch r {
	case 'p':
		return LABEL_AS_POSITIVE, nil
	case 'n':
		return LABEL_AS_NEGATIVE, nil
	case 's':
		return SAVE, nil
	case 'h':
		return HELP, nil
	case 'e':
		return EXIT, nil
	default:
		return SKIP, nil
	}
}

func main() {
	examples, _ := ReadExamples(os.Args[1])

	for {
		e := RandomSelectOneExample(examples)
		if e == nil {
			break
		}
		title, err := GetTitle(e.url)
		fmt.Println("Label this example: " + e.url + " (" + title + ")")

		act, err := input2ActionType()
		if err != nil {
			return
		}
		switch act {
		case LABEL_AS_POSITIVE:
			fmt.Println("Labeled as positive")
			e.Annotate(POSITIVE)
		case LABEL_AS_NEGATIVE:
			fmt.Println("Labeled as negative")
			e.Annotate(NEGATIVE)
		case SKIP:
			fmt.Println("Skiped this example")
			continue
		case SAVE:
			fmt.Println("Saved labeld examples")
		case HELP:
			fmt.Println("ToDo: SHOW HELP")
		case EXIT:
			return
		default:
			return
		}
	}

	for _, e := range examples {
		fmt.Println(e)
	}
}
<commit_msg>取れなかったら表示しないだけなので、変数にしなくてよい<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/mattn/go-tty"
)

type ActionType int

const (
	LABEL_AS_POSITIVE ActionType = iota
	LABEL_AS_NEGATIVE
	SAVE
	HELP
	SKIP
	EXIT
)

func input2ActionType() (ActionType, error) {
	t, err := tty.Open()
	defer t.Close()
	if err != nil {
		return EXIT, err
	}
	var r rune
	for r == 0 {
		r, err = t.ReadRune()
		if err != nil {
			return SKIP, err
		}
	}
	switch r {
	case 'p':
		return LABEL_AS_POSITIVE, nil
	case 'n':
		return LABEL_AS_NEGATIVE, nil
	case 's':
		return SAVE, nil
	case 'h':
		return HELP, nil
	case 'e':
		return EXIT, nil
	default:
		return SKIP, nil
	}
}

func main() {
	examples, _ := ReadExamples(os.Args[1])

	for {
		e := RandomSelectOneExample(examples)
		if e == nil {
			break
		}
		title, _ := GetTitle(e.url)
		fmt.Println("Label this example: " + e.url + " (" + title + ")")

		act, err := input2ActionType()
		if err != nil {
			return
		}
		switch act {
		case LABEL_AS_POSITIVE:
			fmt.Println("Labeled as positive")
			e.Annotate(POSITIVE)
		case LABEL_AS_NEGATIVE:
			fmt.Println("Labeled as negative")
			e.Annotate(NEGATIVE)
		case SKIP:
			fmt.Println("Skiped this example")
			continue
		case SAVE:
			fmt.Println("Saved labeld examples")
		case HELP:
			fmt.Println("ToDo: SHOW HELP")
		case EXIT:
			return
		default:
			return
		}
	}

	for _, e := range examples {
		fmt.Println(e)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang/groupcache"
	"github.com/jessevdk/go-flags"
	_ "github.com/mattn/go-sqlite3"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"strings"
)

var options struct {
	Port     int    `long:"port" description:"Server port" default:"8080"`
	Tilesets string `long:"tilesets" description:"path to tilesets" default:"./tilesets"`
}

var (
	pool        *groupcache.HTTPPool
	cache       *groupcache.Group
	connections map[string]*sql.DB
	pngQueries  map[string]*sql.Stmt
)

func main() {
	_, err := flags.ParseArgs(&options, os.Args)
	if err != nil {
		log.Fatal(err)
	}

	connections = make(map[string]*sql.DB)
	pngQueries = make(map[string]*sql.Stmt)
	tilesets, _ := filepath.Glob(path.Join(options.Tilesets, "*.mbtiles"))
	fmt.Println(tilesets)

	for i, filename := range tilesets {
		_, service := filepath.Split(filename)
		service = strings.Split(service, ".")[0]

		fmt.Println(i, filename, service)

		db, err := sql.Open("sqlite3", filename)
		if err != nil {
			log.Fatal(err)
		}
		defer db.Close()
		connections[service] = db

		stmt, err := db.Prepare("select tile_data from tiles where zoom_level = ? and tile_column = ? and tile_row = ?")
		if err != nil {
			log.Fatal(err)
		}
		defer stmt.Close()
		pngQueries[service] = stmt
	}

	pool = groupcache.NewHTTPPool("http://127.0.0.1:8000")
	cache = groupcache.NewGroup("TileCache", 64<<20, groupcache.GetterFunc(
		func(ctx groupcache.Context, key string, dest groupcache.Sink) error {
			// log.Println("Requested", key)

			pathParams := strings.Split(key, "/")
			service := pathParams[1]
			yParams := strings.Split(pathParams[4], ".")
			z, _ := strconv.ParseUint(pathParams[2], 0, 64)
			x, _ := strconv.ParseUint(pathParams[3], 0, 64)
			y, _ := strconv.ParseUint(yParams[0], 0, 64)

			//flip y to match TMS spec
			y = (1 << z) - 1 - y

			var stmt *sql.Stmt
			if yParams[1] == "png" {
				stmt = pngQueries[service]
			}

			var tile_data []byte
			err := stmt.QueryRow(uint8(z), uint16(x), uint16(y)).Scan(&tile_data)
			if err != nil {
				if err == sql.ErrNoRows {
					// log.Println("No tile found")
					// tile_data = make([]byte, 1, 1)
					// tile_data[0] = 0
				} else {
					log.Fatal(err)
				}
			}
			dest.SetBytes(tile_data)
			return nil
		}))

	router := gin.Default()

	router.GET("/*key", func(c *gin.Context) {
		var data []byte
		pathParams := strings.Split(c.Params.ByName("key"), "/")
		// fmt.Println("path segments", pathParams, len(pathParams))
		if len(pathParams) != 5 {
			c.Abort(400)
			return
		}
		//TODO: validate x, y, z, and extension

		key := c.Params.ByName("key")
		err := cache.Get(nil, key, groupcache.AllocatingByteSliceSink(&data))
		if err != nil {
			log.Println("Error fetching key", key)
			c.Abort(500)
			return
		}
		if len(data) <= 1 {
			// log.Println("Empty data")
			data, _ = ioutil.ReadFile("blank.png")
		}

		// log.Println("Bytes returned:", len(data))
		//TODO: make based on data
		c.Data(200, "image/png", data)
	})

	// router.GET("/:service/:z/:x/:y", func(c *gin.Context) {
	// 	service := c.Params.ByName("service")
	// 	stmt, ok := pngQueries[service]
	// 	if !ok {
	// 		log.Printf("Service not found: %s", service)
	// 		c.Abort(404)
	// 		return
	// 	}

	// 	//TODO: cache response data in memory

	// 	var tile_data []byte
	// 	y_params := strings.Split(c.Params.ByName("y"), ".")
	// 	if len(y_params) != 2 {
	// 		c.Abort(400)
	// 		return
	// 	}

	// 	z, _ := strconv.ParseUint(c.Params.ByName("z"), 0, 64)
	// 	y, _ := strconv.ParseUint(y_params[0], 0, 64)
	// 	extension := y_params[1]
	// 	log.Println(extension)
	// 	//flip y to match TMS spec
	// 	y = (1 << z) - 1 - y

	// 	err := stmt.QueryRow(z, c.Params.ByName("x"), y).Scan(&tile_data)
	// 	if err != nil {
	// 		if err == sql.ErrNoRows {
	// 			tile_data, _ = ioutil.ReadFile("blank.png")
	// 		} else {
	// 			log.Fatal(err)
	// 		}
	// 	}
	// 	//TODO set headers for cache control
	// 	c.Writer.Header().Add("Cache-Control", "public, max-age= 300")
	// 	c.Data(200, "image/png", tile_data)
	// })

	router.Run(fmt.Sprintf(":%v", options.Port))
}
<commit_msg>Minor cleanup, made blank PNG data a global<commit_after>package main

import (
	"database/sql"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang/groupcache"
	"github.com/jessevdk/go-flags"
	_ "github.com/mattn/go-sqlite3"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"strings"
)

var options struct {
	Port      int    `long:"port" description:"Server port" default:"8080"`
	Tilesets  string `long:"tilesets" description:"path to tilesets" default:"./tilesets"`
	CachePort int    `long:"cacheport" description:"GroupCache port" default:"8000"`
	CacheSize int64  `long:"cachesize" description:"Size of Cache (MB)" default:"10"`
}

var (
	pool        *groupcache.HTTPPool
	cache       *groupcache.Group
	connections map[string]*sql.DB
	pngQueries  map[string]*sql.Stmt
	blankPNG    []byte
)

func main() {
	_, err := flags.ParseArgs(&options, os.Args)
	if err != nil {
		log.Fatal(err)
	}
	blankPNG, _ = ioutil.ReadFile("blank.png")

	connections = make(map[string]*sql.DB)
	pngQueries = make(map[string]*sql.Stmt)
	tilesets, _ := filepath.Glob(path.Join(options.Tilesets, "*.mbtiles"))
	fmt.Println(tilesets)

	for i, filename := range tilesets {
		_, service := filepath.Split(filename)
		service = strings.Split(service, ".")[0]

		fmt.Println(i, filename, service)

		db, err := sql.Open("sqlite3", filename)
		if err != nil {
			log.Fatal(err)
		}
		defer db.Close()
		connections[service] = db

		stmt, err := db.Prepare("select tile_data from tiles where zoom_level = ? and tile_column = ? and tile_row = ?")
		if err != nil {
			log.Fatal(err)
		}
		defer stmt.Close()
		pngQueries[service] = stmt
	}

	pool = groupcache.NewHTTPPool(fmt.Sprintf("http://127.0.0.1:%v", options.CachePort))
	cache = groupcache.NewGroup("TileCache", options.CacheSize*1048576, groupcache.GetterFunc(
		func(ctx groupcache.Context, key string, dest groupcache.Sink) error {
			// log.Println("Requested", key)

			pathParams := strings.Split(key, "/")
			service := pathParams[1]
			yParams := strings.Split(pathParams[4], ".")
			z, _ := strconv.ParseUint(pathParams[2], 0, 64)
			x, _ := strconv.ParseUint(pathParams[3], 0, 64)
			y, _ := strconv.ParseUint(yParams[0], 0, 64)

			//flip y to match TMS spec
			y = (1 << z) - 1 - y

			var stmt *sql.Stmt
			if yParams[1] == "png" {
				stmt = pngQueries[service]
			}

			var tile_data []byte
			err := stmt.QueryRow(uint8(z), uint16(x), uint16(y)).Scan(&tile_data)
			if err != nil {
				if err != sql.ErrNoRows {
					log.Fatal(err)
				}
			}
			dest.SetBytes(tile_data)
			return nil
		}))

	router := gin.Default()

	router.GET("/*key", func(c *gin.Context) {
		var data []byte
		pathParams := strings.Split(c.Params.ByName("key"), "/")
		// fmt.Println("path segments", pathParams, len(pathParams))

		// fmt.Println(cache.CacheStats(1))

		if len(pathParams) != 5 {
			c.Abort(400)
			return
		}
		//TODO: validate x, y, z, and extension

		key := c.Params.ByName("key")
		err := cache.Get(nil, key, groupcache.AllocatingByteSliceSink(&data))
		if err != nil {
			log.Println("Error fetching key", key)
			c.Abort(500)
			return
		}
		if len(data) <= 1 {
			data = blankPNG
		}

		//TODO: make based on data
		c.Data(200, "image/png", data)
	})

	router.Run(fmt.Sprintf(":%v", options.Port))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"go/build"
	"os"
	"regexp"
	"runtime"
	"strings"

	"github.com/kisielk/errcheck/internal/errcheck"
	"github.com/kisielk/gotool"
)

const (
	exitCodeOk int = iota
	exitUncheckedError
	exitFatalError
)

var abspath bool

type ignoreFlag map[string]*regexp.Regexp

func (f ignoreFlag) String() string {
	pairs := make([]string, 0, len(f))
	for pkg, re := range f {
		prefix := ""
		if pkg != "" {
			prefix = pkg + ":"
		}
		pairs = append(pairs, prefix+re.String())
	}
	return fmt.Sprintf("%q", strings.Join(pairs, ","))
}

func (f ignoreFlag) Set(s string) error {
	if s == "" {
		return nil
	}
	for _, pair := range strings.Split(s, ",") {
		colonIndex := strings.Index(pair, ":")
		var pkg, re string
		if colonIndex == -1 {
			pkg = ""
			re = pair
		} else {
			pkg = pair[:colonIndex]
			re = pair[colonIndex+1:]
		}
		regex, err := regexp.Compile(re)
		if err != nil {
			return err
		}
		f[pkg] = regex
	}
	return nil
}

type tagsFlag []string

func (f *tagsFlag) String() string {
	return fmt.Sprintf("%q", strings.Join(*f, " "))
}

func (f *tagsFlag) Set(s string) error {
	if s == "" {
		return nil
	}
	tags := strings.Split(s, " ")
	if tags == nil {
		return nil
	}
	for _, tag := range tags {
		if tag != "" {
			*f = append(*f, tag)
		}
	}
	return nil
}

var dotStar = regexp.MustCompile(".*")

func reportUncheckedErrors(e errcheck.UncheckedErrors) {
	for _, uncheckedError := range e.Errors {
		pos := uncheckedError.Pos.String()
		if !abspath {
			if i := strings.Index(pos, "/src/"); i != -1 {
				pos = pos[i+len("/src/"):]
			}
		}
		fmt.Printf("%s\t%s\n", pos, uncheckedError.Line)
	}
}

func mainCmd(args []string) int {
	runtime.GOMAXPROCS(runtime.NumCPU())

	checker := &errcheck.Checker{}
	paths, err := parseFlags(checker, args)
	if err != exitCodeOk {
		return err
	}

	if err := checker.CheckPackages(paths...); err != nil {
		if e, ok := err.(errcheck.UncheckedErrors); ok {
			reportUncheckedErrors(e)
			return exitUncheckedError
		} else if err == errcheck.ErrNoGoFiles {
			fmt.Fprintln(os.Stderr, err)
			return exitCodeOk
		}
		fmt.Fprintf(os.Stderr, "error: failed to check packages: %s\n", err)
		return exitFatalError
	}
	return exitCodeOk
}

func parseFlags(checker *errcheck.Checker, args []string) ([]string, int) {
	flags := flag.NewFlagSet(args[0], flag.ContinueOnError)
	flags.BoolVar(&checker.Blank, "blank", false, "if true, check for errors assigned to blank identifier")
	flags.BoolVar(&checker.Asserts, "asserts", false, "if true, check for ignored type assertion results")
	flags.BoolVar(&checker.Verbose, "verbose", false, "produce more verbose logging")

	flags.BoolVar(&abspath, "abspath", false, "print absolute paths to files")

	tags := tagsFlag{}
	flags.Var(&tags, "tags", "space-separated list of build tags to include")
	ignorePkg := flags.String("ignorepkg", "", "comma-separated list of package paths to ignore")
	ignore := ignoreFlag(map[string]*regexp.Regexp{
		"fmt": dotStar,
	})
	flags.Var(ignore, "ignore", "comma-separated list of pairs of the form pkg:regex\n"+
		"            the regex is used to ignore names within pkg")

	if err := flags.Parse(args[1:]); err != nil {
		return nil, exitFatalError
	}

	checker.Tags = tags
	for _, pkg := range strings.Split(*ignorePkg, ",") {
		if pkg != "" {
			ignore[pkg] = dotStar
		}
	}
	checker.Ignore = ignore

	ctx := gotool.Context{
		BuildContext: build.Default,
	}
	ctx.BuildContext.BuildTags = tags

	// ImportPaths normalizes paths and expands '...'
	return gotool.ImportPaths(flags.Args()), exitCodeOk
}

func main() {
	os.Exit(mainCmd(os.Args))
}
<commit_msg>Use own packages<commit_after>package main

import (
	"flag"
	"fmt"
	"go/build"
	"os"
	"regexp"
	"runtime"
	"strings"

	"github.com/gdm85/errcheck/internal/errcheck"
	"github.com/gdm85/gotool"
)

const (
	exitCodeOk int = iota
	exitUncheckedError
	exitFatalError
)

var abspath bool

type ignoreFlag map[string]*regexp.Regexp

func (f ignoreFlag) String() string {
	pairs := make([]string, 0, len(f))
	for pkg, re := range f {
		prefix := ""
		if pkg != "" {
			prefix = pkg + ":"
		}
		pairs = append(pairs, prefix+re.String())
	}
	return fmt.Sprintf("%q", strings.Join(pairs, ","))
}

func (f ignoreFlag) Set(s string) error {
	if s == "" {
		return nil
	}
	for _, pair := range strings.Split(s, ",") {
		colonIndex := strings.Index(pair, ":")
		var pkg, re string
		if colonIndex == -1 {
			pkg = ""
			re = pair
		} else {
			pkg = pair[:colonIndex]
			re = pair[colonIndex+1:]
		}
		regex, err := regexp.Compile(re)
		if err != nil {
			return err
		}
		f[pkg] = regex
	}
	return nil
}

type tagsFlag []string

func (f *tagsFlag) String() string {
	return fmt.Sprintf("%q", strings.Join(*f, " "))
}

func (f *tagsFlag) Set(s string) error {
	if s == "" {
		return nil
	}
	tags := strings.Split(s, " ")
	if tags == nil {
		return nil
	}
	for _, tag := range tags {
		if tag != "" {
			*f = append(*f, tag)
		}
	}
	return nil
}

var dotStar = regexp.MustCompile(".*")

func reportUncheckedErrors(e errcheck.UncheckedErrors) {
	for _, uncheckedError := range e.Errors {
		pos := uncheckedError.Pos.String()
		if !abspath {
			if i := strings.Index(pos, "/src/"); i != -1 {
				pos = pos[i+len("/src/"):]
			}
		}
		fmt.Printf("%s\t%s\n", pos, uncheckedError.Line)
	}
}

func mainCmd(args []string) int {
	runtime.GOMAXPROCS(runtime.NumCPU())

	checker := &errcheck.Checker{}
	paths, err := parseFlags(checker, args)
	if err != exitCodeOk {
		return err
	}

	if err := checker.CheckPackages(paths...); err != nil {
		if e, ok := err.(errcheck.UncheckedErrors); ok {
			reportUncheckedErrors(e)
			return exitUncheckedError
		} else if err == errcheck.ErrNoGoFiles {
			fmt.Fprintln(os.Stderr, err)
			return exitCodeOk
		}
		fmt.Fprintf(os.Stderr, "error: failed to check packages: %s\n", err)
		return exitFatalError
	}
	return exitCodeOk
}

func parseFlags(checker *errcheck.Checker, args []string) ([]string, int) {
	flags := flag.NewFlagSet(args[0], flag.ContinueOnError)
	flags.BoolVar(&checker.Blank, "blank", false, "if true, check for errors assigned to blank identifier")
	flags.BoolVar(&checker.Asserts, "asserts", false, "if true, check for ignored type assertion results")
	flags.BoolVar(&checker.Verbose, "verbose", false, "produce more verbose logging")

	flags.BoolVar(&abspath, "abspath", false, "print absolute paths to files")

	tags := tagsFlag{}
	flags.Var(&tags, "tags", "space-separated list of build tags to include")
	ignorePkg := flags.String("ignorepkg", "", "comma-separated list of package paths to ignore")
	ignore := ignoreFlag(map[string]*regexp.Regexp{
		"fmt": dotStar,
	})
	flags.Var(ignore, "ignore", "comma-separated list of pairs of the form pkg:regex\n"+
		"            the regex is used to ignore names within pkg")

	if err := flags.Parse(args[1:]); err != nil {
		return nil, exitFatalError
	}

	checker.Tags = tags
	for _, pkg := range strings.Split(*ignorePkg, ",") {
		if pkg != "" {
			ignore[pkg] = dotStar
		}
	}
	checker.Ignore = ignore

	ctx := gotool.Context{
		BuildContext: build.Default,
	}
	ctx.BuildContext.BuildTags = tags

	// ImportPaths normalizes paths and expands '...'
	return gotool.ImportPaths(flags.Args()), exitCodeOk
}

func main() {
	os.Exit(mainCmd(os.Args))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"

	"github.com/olekukonko/tablewriter"
)

func main() {

	// read yaml
	manifest, err := readManifest(".estafette.yaml")
	if err != nil {
		log.Fatal(err)
	}

	// get current working directory
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("[estafette] Running %v pipelines\n", len(manifest.Pipelines))

	envvars := collectEstafetteEnvvars(manifest)

	result, firstErr := runPipelines(manifest, dir, envvars)

	renderStats(result)

	handleExit(firstErr)
}

func handleExit(firstErr error) {

	if firstErr != nil {
		os.Exit(1)
	}
	os.Exit(0)
}

func renderStats(result estafetteRunPipelinesResult) {

	data := make([][]string, 0)

	dockerPullDurationTotal := 0.0
	dockerRunDurationTotal := 0.0
	for _, s := range result.PipelineResults {

		data = append(data, []string{
			s.Pipeline.Name,
			s.Pipeline.ContainerImage,
			fmt.Sprintf("%.0f", s.DockerPullDuration.Seconds()),
			fmt.Sprintf("%.0f", s.DockerRunDuration.Seconds()),
			fmt.Sprintf("%.0f", s.DockerPullDuration.Seconds()+s.DockerRunDuration.Seconds()),
			s.Status,
			s.Detail,
		})

		dockerPullDurationTotal += s.DockerPullDuration.Seconds()
		dockerRunDurationTotal += s.DockerRunDuration.Seconds()
	}

	fmt.Println("")
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Pipeline", "Image", "Pull (s)", "Run (s)", "Total (s)", "Status", "Detail"})
	table.SetFooter([]string{"", "Total", fmt.Sprintf("%.0f", dockerPullDurationTotal), fmt.Sprintf("%.0f", dockerRunDurationTotal), fmt.Sprintf("%.0f", dockerPullDurationTotal+dockerRunDurationTotal)})
	table.SetBorder(false)
	table.AppendBulk(data)
	table.Render()
	fmt.Println("")
}
<commit_msg>make footer as wide as rest of table<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"

	"github.com/olekukonko/tablewriter"
)

func main() {

	// read yaml
	manifest, err := readManifest(".estafette.yaml")
	if err != nil {
		log.Fatal(err)
	}

	// get current working directory
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("[estafette] Running %v pipelines\n", len(manifest.Pipelines))

	envvars := collectEstafetteEnvvars(manifest)

	result, firstErr := runPipelines(manifest, dir, envvars)

	renderStats(result)

	handleExit(firstErr)
}

func handleExit(firstErr error) {

	if firstErr != nil {
		os.Exit(1)
	}
	os.Exit(0)
}

func renderStats(result estafetteRunPipelinesResult) {

	data := make([][]string, 0)

	dockerPullDurationTotal := 0.0
	dockerRunDurationTotal := 0.0
	for _, s := range result.PipelineResults {

		data = append(data, []string{
			s.Pipeline.Name,
			s.Pipeline.ContainerImage,
			fmt.Sprintf("%.0f", s.DockerPullDuration.Seconds()),
			fmt.Sprintf("%.0f", s.DockerRunDuration.Seconds()),
			fmt.Sprintf("%.0f", s.DockerPullDuration.Seconds()+s.DockerRunDuration.Seconds()),
			s.Status,
			s.Detail,
		})

		dockerPullDurationTotal += s.DockerPullDuration.Seconds()
		dockerRunDurationTotal += s.DockerRunDuration.Seconds()
	}

	fmt.Println("")
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Pipeline", "Image", "Pull (s)", "Run (s)", "Total (s)", "Status", "Detail"})
	table.SetFooter([]string{"", "Total", fmt.Sprintf("%.0f", dockerPullDurationTotal), fmt.Sprintf("%.0f", dockerRunDurationTotal), fmt.Sprintf("%.0f", dockerPullDurationTotal+dockerRunDurationTotal), "", ""})
	table.SetBorder(false)
	table.AppendBulk(data)
	table.Render()
	fmt.Println("")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"sync"
	"time"

	"github.com/codegangsta/cli"
	docker "github.com/fsouza/go-dockerclient"
	"github.com/montanaflynn/stats"
)

func worker(requests int, image string, args []string, completeCh chan time.Duration) {
	client, err := docker.NewClientFromEnv()
	if err != nil {
		panic(err)
	}

	for i := 0; i < requests; i++ {
		start := time.Now()

		container, err := client.CreateContainer(docker.CreateContainerOptions{
			Config: &docker.Config{
				Image: image,
				Cmd:   args,
			}})
		if err != nil {
			panic(err)
		}

		err = client.StartContainer(container.ID, nil)
		if err != nil {
			panic(err)
		}

		completeCh <- time.Since(start)
	}
}

func session(requests, concurrency int, images []string, args []string, completeCh chan time.Duration) {
	var wg sync.WaitGroup
	var size = len(images)
	n := requests / concurrency

	for i := 0; i < concurrency; i++ {
		wg.Add(1)
		image := images[i%size]
		go func() {
			worker(n, image, args, completeCh)
			wg.Done()
		}()
	}
	wg.Wait()
}

func bench(requests, concurrency int, images []string, args []string) {
	start := time.Now()

	timings := make([]float64, requests)
	// Create a buffered channel so our display goroutine can't slow down the workers.
	completeCh := make(chan time.Duration, requests)
	doneCh := make(chan struct{})
	current := 0
	go func() {
		for timing := range completeCh {
			timings = append(timings, timing.Seconds())
			current++
			percent := float64(current) / float64(requests) * 100
			fmt.Printf("[%3.f%%] %d/%d containers started\n", percent, current, requests)
		}
		doneCh <- struct{}{}
	}()
	session(requests, concurrency, images, args, completeCh)
	close(completeCh)
	<-doneCh

	total := time.Since(start)
	mean, _ := stats.Mean(timings)
	p90th, _ := stats.Percentile(timings, 90)
	p99th, _ := stats.Percentile(timings, 99)

	fmt.Printf("\n")
	fmt.Printf("Time taken for tests: %s\n", total.String())
	fmt.Printf("Time per container: %vms [mean] | %vms [90th] | %vms [99th]\n", int(mean*1000), int(p90th*1000), int(p99th*1000))
}

func main() {
	app := cli.NewApp()
	app.Name = "swarm-bench"
	app.Usage = "Swarm Benchmarking Tool"
	app.Version = "0.1.0"
	app.Author = ""
	app.Email = ""
	app.Flags = []cli.Flag{
		cli.IntFlag{
			Name:  "concurrency, c",
			Value: 1,
			Usage: "Number of multiple requests to perform at a time. Default is one request at a time.",
		},
		cli.IntFlag{
			Name:  "requests, n",
			Value: 1,
			Usage: "Number of containers to start for the benchmarking session. The default is to just start a single container.",
		},
		cli.StringSliceFlag{
			Name:  "image, i",
			Value: &cli.StringSlice{},
			Usage: "Image(s) to use for benchmarking.",
		},
	}

	app.Action = func(c *cli.Context) {
		if !c.IsSet("image") && !c.IsSet("i") {
			cli.ShowAppHelp(c)
			os.Exit(1)
		}
		bench(c.Int("requests"), c.Int("concurrency"), c.StringSlice("image"), c.Args())
	}

	app.Run(os.Args)
}
<commit_msg>Use floats with formatting for results<commit_after>package main

import (
	"fmt"
	"os"
	"sync"
	"time"

	"github.com/codegangsta/cli"
	docker "github.com/fsouza/go-dockerclient"
	"github.com/montanaflynn/stats"
)

const MILLIS_IN_SECOND = 1000

func worker(requests int, image string, args []string, completeCh chan time.Duration) {
	client, err := docker.NewClientFromEnv()
	if err != nil {
		panic(err)
	}

	for i := 0; i < requests; i++ {
		start := time.Now()

		container, err := client.CreateContainer(docker.CreateContainerOptions{
			Config: &docker.Config{
				Image: image,
				Cmd:   args,
			}})
		if err != nil {
			panic(err)
		}

		err = client.StartContainer(container.ID, nil)
		if err != nil {
			panic(err)
		}

		completeCh <- time.Since(start)
	}
}

func session(requests, concurrency int, images []string, args []string, completeCh chan time.Duration) {
	var wg sync.WaitGroup
	var size = len(images)
	n := requests / concurrency

	for i := 0; i < concurrency; i++ {
		wg.Add(1)
		image := images[i%size]
		go func() {
			worker(n, image, args, completeCh)
			wg.Done()
		}()
	}
	wg.Wait()
}

func bench(requests, concurrency int, images []string, args []string) {
	start := time.Now()

	timings := make([]float64, requests)
	// Create a buffered channel so our display goroutine can't slow down the workers.
	completeCh := make(chan time.Duration, requests)
	doneCh := make(chan struct{})
	current := 0
	go func() {
		for timing := range completeCh {
			timings = append(timings, timing.Seconds())
			current++
			percent := float64(current) / float64(requests) * 100
			fmt.Printf("[%3.f%%] %d/%d containers started\n", percent, current, requests)
		}
		doneCh <- struct{}{}
	}()
	session(requests, concurrency, images, args, completeCh)
	close(completeCh)
	<-doneCh

	total := time.Since(start)
	mean, _ := stats.Mean(timings)
	p90th, _ := stats.Percentile(timings, 90)
	p99th, _ := stats.Percentile(timings, 99)

	meanMillis := mean * MILLIS_IN_SECOND
	p90thMillis := p90th * MILLIS_IN_SECOND
	p99thMillis := p99th * MILLIS_IN_SECOND

	fmt.Printf("\n")
	fmt.Printf("Time taken for tests: %.3fs\n", total.Seconds())
	fmt.Printf("Time per container: %.3fms [mean] | %.3fms [90th] | %.3fms [99th]\n", meanMillis, p90thMillis, p99thMillis)
}

func main() {
	app := cli.NewApp()
	app.Name = "swarm-bench"
	app.Usage = "Swarm Benchmarking Tool"
	app.Version = "0.1.0"
	app.Author = ""
	app.Email = ""
	app.Flags = []cli.Flag{
		cli.IntFlag{
			Name:  "concurrency, c",
			Value: 1,
			Usage: "Number of multiple requests to perform at a time. Default is one request at a time.",
		},
		cli.IntFlag{
			Name:  "requests, n",
			Value: 1,
			Usage: "Number of containers to start for the benchmarking session. The default is to just start a single container.",
		},
		cli.StringSliceFlag{
			Name:  "image, i",
			Value: &cli.StringSlice{},
			Usage: "Image(s) to use for benchmarking.",
		},
	}

	app.Action = func(c *cli.Context) {
		if !c.IsSet("image") && !c.IsSet("i") {
			cli.ShowAppHelp(c)
			os.Exit(1)
		}
		bench(c.Int("requests"), c.Int("concurrency"), c.StringSlice("image"), c.Args())
	}

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


<commit_before>package rfbServer

<commit_msg>Add security constants<commit_after>package main

import (
)

const (
	INVALID = 0
	NONE = 1
	VNC_AUTH = 2
	RA2 = 5
	RA2ne = 6
	Tight = 16
	Ultra = 17
	TLS = 18
	VENCRYPT = 19
	GTK_VNC_SASL = 20
	MD5_HASH = 21
	COLIN_DEAN_XVP = 22
)

func main() {

}

<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"time"

	"github.com/ninjasphere/go-ninja/api"
	nlog "github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/support"
	"github.com/ninjasphere/sphere-go-led-controller/model"
	"github.com/paypal/gatt"
)

const WirelessNetworkInterface = "wlan0"

// consider the wifi to be invalid after this timeout
const WirelessStaleTimeout = time.Second * 30 // FIXME: INCREASE THIS. a few minutes at least when not in testing.

var firewallHook = flag.Bool("firewall-hook", false, "Sets up the firewall based on configuration options, and nothing else.")
var factoryReset = false

// factoryReset - we can't use anything that requires MQTT in this mode

var logger = nlog.GetLogger("sphere-setup")

func main() {
	// ap0 adhoc/hostap management
	flag.BoolVar(&factoryReset, "factory-reset", false, "Run in factory reset mode.")

	config := LoadConfig("/etc/opt/ninja/setup-assistant.conf")
	apManager := NewAccessPointManager(config)

	flag.Parse()
	if *firewallHook {
		logger.Debugf("Setting ip firewall rules...")
		apManager.SetupFirewall()
		return
	}
	var pairing_ui ConsolePairingUI
	var controlChecker *ControlChecker

	restartHeartbeat := false

	startResetMonitor(func(m *model.ResetMode) {
		if pairing_ui == nil || controlChecker == nil {
			return
		}
		if m.Mode == "none" {
			if restartHeartbeat {
				// only restart the heartbeat if we stopped it previously
				controlChecker.StartHeartbeat()
			}
		} else {
			restartHeartbeat = controlChecker.StopHeartbeat()
			pairing_ui.DisplayResetMode(m)
		}
	})

	apManager.WriteAPConfig()
	if config.Wireless_Host.Always_Active {
		apManager.StartHostAP()
	} else {
		apManager.StopHostAP()
	}

	// wlan0 client management
	wifi_manager, err := NewWifiManager(WirelessNetworkInterface)
	if err != nil {
		log.Fatal("Could not setup manager for wlan0, does the interface exist?: %v", err)
	}
	defer wifi_manager.Cleanup()

	// When in reset mode, this will talk to the led matrix directly,
	// otherwise, it will use sphere-go-led-controller via mqtt.
	pairing_ui, err = NewPairingUI()
	if err != nil {
		log.Fatal("Could not setup ninja connection")
	}

	// This name is sent in the BLE advertising packet,
	// and is used by the phone to see that this is a
	// sphere, and if it is in factory reset mode.
	serviceName := "ninjasphere"
	if factoryReset {
		serviceName = "ninjasphere-reset"
	}

	srv := &gatt.Server{
		Name: serviceName,
		Connect: func(c gatt.Conn) {
			logger.Infof("BLE Connect")
			pairing_ui.DisplayIcon("ble-connected.gif")
		},
		Disconnect: func(c gatt.Conn) {
			logger.Infof("BLE Disconnect")
			pairing_ui.DisplayIcon("ble-disconnected.gif")
		},
		StateChange: func(state string) {
			logger.Infof("BLE State Change: %s", state)
		},
	}

	var conn *ninja.Connection

	if !factoryReset {

		conn, err = ninja.Connect("sphere-setup-assistant-updates")

		if err != nil {
			logger.FatalErrorf(err, "Failed to connect to mqtt")
		}
	}

	// start by registering the RPC functions that will be accessible
	// once the client has authenticated
	// We pass in the ble server so that we can close the connection once the updates are installed
	// (THIS SHOULD HAPPEN OVER WIFI INSTEAD!)
	rpc_router := GetSetupRPCRouter(conn, wifi_manager, srv, pairing_ui)

	StartHTTPServer(conn, wifi_manager, pairing_ui)

	auth_handler := new(OneTimeAuthHandler)
	auth_handler.Init("spheramid")

	controlChecker = NewControlChecker(pairing_ui)

	RegisterSecuredRPCService(srv, rpc_router, auth_handler, pairing_ui)

	// Start the server
	//log.Println("Starting setup assistant...");
	//log.Fatal(srv.AdvertiseAndServe())

	states := wifi_manager.WatchState()

	//wifi_manager.WifiConfigured()

	var wireless_stale *time.Timer

	is_serving_pairer := false

	// start by forcing the state to Disconnected.
	// reloading the configuration in wpa_supplicant will also force this,
	// but we need to do it here in case we are already disconnected
	states <- WifiStateDisconnected
	wifi_manager.Controller.ReloadConfiguration()

	handleBadWireless := func() {
		logger.Warningf("Wireless is stale! Invalid SSID, router down, or not in range.")

		if !is_serving_pairer {
			is_serving_pairer = true
			logger.Infof("Launching BLE pairing assistant...")
			go srv.AdvertiseAndServe()

			// and if the hostap isn't normally active, make it active
			if !config.Wireless_Host.Always_Active {
				logger.Infof("Launching AdHoc pairing assistant...")
				apManager.StartHostAP()
			}
		}
	}

	wifi_configured, _ := wifi_manager.WifiConfigured()
	if !wifi_configured {
		// when wireless isn't configured at all, automatically start doing this, don't wait for staleness
		handleBadWireless()
	}

	if config.Wireless_Host.Enables_Control {
		// the wireless AP causes control to be enabled, so we just start the heartbeat immediately
		controlChecker.StartHeartbeat()
	}

	go func() {
		support.WaitUntilSignal()
	}()

	for {
		state := <-states
		logger.Infof("State: %v", state)

		switch state {
		case WifiStateConnected:
			if wireless_stale != nil {
				wireless_stale.Stop()
			}
			wireless_stale = nil
			logger.Infof("Connected and attempting to get IP.")

			/*if !config.Wireless_Host.Enables_Control {
				// if the wireless AP mode hasn't already enabled normal control, then enable it now that wifi works
				controlChecker.StartHeartbeat()
			}*/

			if is_serving_pairer {
				is_serving_pairer = false

				// We need to keep the server open for now, as we are sending update progress to it, and accepting
				// led drawing messages. Later, this will be over wifi and we can close it here.
				//srv.Close()

				// and if the hostap isn't normally active, turn it off again
				if !config.Wireless_Host.Always_Active {
					logger.Infof("Terminating AdHoc pairing assistant.")
					apManager.StopHostAP()
				}
			}

		case WifiStateDisconnected:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}

		case WifiStateInvalidKey:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}
			wifi_configured, _ = wifi_manager.WifiConfigured()
			if wifi_configured {
				// not stale, we actually know the key is wrong
				// FIXME: report back to the user! for now we're just going to let staleness timeout
				/*if wireless_stale != nil {
					wireless_stale.Stop()
				}
				wireless_stale = nil*/

				logger.Warningf("Wireless key is invalid!")
			}
		}
	}
}
<commit_msg>Change reset BLE ad name ninjasphere-reset->resetsphere<commit_after>package main

import (
	"flag"
	"log"
	"time"

	"github.com/ninjasphere/go-ninja/api"
	nlog "github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/support"
	"github.com/ninjasphere/sphere-go-led-controller/model"
	"github.com/paypal/gatt"
)

const WirelessNetworkInterface = "wlan0"

// consider the wifi to be invalid after this timeout
const WirelessStaleTimeout = time.Second * 30 // FIXME: INCREASE THIS. a few minutes at least when not in testing.

var firewallHook = flag.Bool("firewall-hook", false, "Sets up the firewall based on configuration options, and nothing else.")
var factoryReset = false

// factoryReset - we can't use anything that requires MQTT in this mode

var logger = nlog.GetLogger("sphere-setup")

func main() {
	// ap0 adhoc/hostap management
	flag.BoolVar(&factoryReset, "factory-reset", false, "Run in factory reset mode.")

	config := LoadConfig("/etc/opt/ninja/setup-assistant.conf")
	apManager := NewAccessPointManager(config)

	flag.Parse()
	if *firewallHook {
		logger.Debugf("Setting ip firewall rules...")
		apManager.SetupFirewall()
		return
	}
	var pairing_ui ConsolePairingUI
	var controlChecker *ControlChecker

	restartHeartbeat := false

	startResetMonitor(func(m *model.ResetMode) {
		if pairing_ui == nil || controlChecker == nil {
			return
		}
		if m.Mode == "none" {
			if restartHeartbeat {
				// only restart the heartbeat if we stopped it previously
				controlChecker.StartHeartbeat()
			}
		} else {
			restartHeartbeat = controlChecker.StopHeartbeat()
			pairing_ui.DisplayResetMode(m)
		}
	})

	apManager.WriteAPConfig()
	if config.Wireless_Host.Always_Active {
		apManager.StartHostAP()
	} else {
		apManager.StopHostAP()
	}

	// wlan0 client management
	wifi_manager, err := NewWifiManager(WirelessNetworkInterface)
	if err != nil {
		log.Fatal("Could not setup manager for wlan0, does the interface exist?: %v", err)
	}
	defer wifi_manager.Cleanup()

	// When in reset mode, this will talk to the led matrix directly,
	// otherwise, it will use sphere-go-led-controller via mqtt.
	pairing_ui, err = NewPairingUI()
	if err != nil {
		log.Fatal("Could not setup ninja connection")
	}

	// This name is sent in the BLE advertising packet,
	// and is used by the phone to see that this is a
	// sphere, and if it is in factory reset mode.
	serviceName := "ninjasphere"
	if factoryReset {
		serviceName = "resetsphere"
	}

	srv := &gatt.Server{
		Name: serviceName,
		Connect: func(c gatt.Conn) {
			logger.Infof("BLE Connect")
			pairing_ui.DisplayIcon("ble-connected.gif")
		},
		Disconnect: func(c gatt.Conn) {
			logger.Infof("BLE Disconnect")
			pairing_ui.DisplayIcon("ble-disconnected.gif")
		},
		StateChange: func(state string) {
			logger.Infof("BLE State Change: %s", state)
		},
	}

	var conn *ninja.Connection

	if !factoryReset {

		conn, err = ninja.Connect("sphere-setup-assistant-updates")

		if err != nil {
			logger.FatalErrorf(err, "Failed to connect to mqtt")
		}
	}

	// start by registering the RPC functions that will be accessible
	// once the client has authenticated
	// We pass in the ble server so that we can close the connection once the updates are installed
	// (THIS SHOULD HAPPEN OVER WIFI INSTEAD!)
	rpc_router := GetSetupRPCRouter(conn, wifi_manager, srv, pairing_ui)

	StartHTTPServer(conn, wifi_manager, pairing_ui)

	auth_handler := new(OneTimeAuthHandler)
	auth_handler.Init("spheramid")

	controlChecker = NewControlChecker(pairing_ui)

	RegisterSecuredRPCService(srv, rpc_router, auth_handler, pairing_ui)

	// Start the server
	//log.Println("Starting setup assistant...");
	//log.Fatal(srv.AdvertiseAndServe())

	states := wifi_manager.WatchState()

	//wifi_manager.WifiConfigured()

	var wireless_stale *time.Timer

	is_serving_pairer := false

	// start by forcing the state to Disconnected.
	// reloading the configuration in wpa_supplicant will also force this,
	// but we need to do it here in case we are already disconnected
	states <- WifiStateDisconnected
	wifi_manager.Controller.ReloadConfiguration()

	handleBadWireless := func() {
		logger.Warningf("Wireless is stale! Invalid SSID, router down, or not in range.")

		if !is_serving_pairer {
			is_serving_pairer = true
			logger.Infof("Launching BLE pairing assistant...")
			go srv.AdvertiseAndServe()

			// and if the hostap isn't normally active, make it active
			if !config.Wireless_Host.Always_Active {
				logger.Infof("Launching AdHoc pairing assistant...")
				apManager.StartHostAP()
			}
		}
	}

	wifi_configured, _ := wifi_manager.WifiConfigured()
	if !wifi_configured {
		// when wireless isn't configured at all, automatically start doing this, don't wait for staleness
		handleBadWireless()
	}

	if config.Wireless_Host.Enables_Control {
		// the wireless AP causes control to be enabled, so we just start the heartbeat immediately
		controlChecker.StartHeartbeat()
	}

	go func() {
		support.WaitUntilSignal()
	}()

	for {
		state := <-states
		logger.Infof("State: %v", state)

		switch state {
		case WifiStateConnected:
			if wireless_stale != nil {
				wireless_stale.Stop()
			}
			wireless_stale = nil
			logger.Infof("Connected and attempting to get IP.")

			/*if !config.Wireless_Host.Enables_Control {
				// if the wireless AP mode hasn't already enabled normal control, then enable it now that wifi works
				controlChecker.StartHeartbeat()
			}*/

			if is_serving_pairer {
				is_serving_pairer = false

				// We need to keep the server open for now, as we are sending update progress to it, and accepting
				// led drawing messages. Later, this will be over wifi and we can close it here.
				//srv.Close()

				// and if the hostap isn't normally active, turn it off again
				if !config.Wireless_Host.Always_Active {
					logger.Infof("Terminating AdHoc pairing assistant.")
					apManager.StopHostAP()
				}
			}

		case WifiStateDisconnected:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}

		case WifiStateInvalidKey:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}
			wifi_configured, _ = wifi_manager.WifiConfigured()
			if wifi_configured {
				// not stale, we actually know the key is wrong
				// FIXME: report back to the user! for now we're just going to let staleness timeout
				/*if wireless_stale != nil {
					wireless_stale.Stop()
				}
				wireless_stale = nil*/

				logger.Warningf("Wireless key is invalid!")
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/kataras/iris"
	"github.com/kataras/iris/context"
)

func main() {
	app := iris.New()
	app.Handle("GET", "/", func(ctx context.Context) {
		ctx.Writef("hello world\n")
	})

	app.Run(iris.Addr(":8080"))
}
<commit_msg>Update and make use of the existing templates folder<commit_after>package main

import (
	"github.com/kataras/iris"
	"github.com/kataras/iris/context"
	"github.com/kataras/iris/view"
)

func main() {
	app := iris.New()

	// load the ./templates/**.html
	templates := view.HTML("./templates", ".html"))
	app.AttachView(templates)

	app.Handle("GET", "/", func(ctx context.Context) {
	        // bind the {{ .Name }}
		ctx.ViewData("Name", "iris")
		// render the ./templates/hi.html
		ctx.View("hi.html")
	})

	app.Run(iris.Addr(":8080"))
}
<|endoftext|>