<commit_before>package main

import (
	"fmt"
	"image"
	"os"
	"time"

	_ "image/jpeg"
	_ "image/png"

	"github.com/nsf/termbox-go"
)

func draw(img image.Image) {
	// Get terminal size and cursor width/height ratio
	width, height, whratio := canvasSize()

	bounds := img.Bounds()
	imgW, imgH := bounds.Dx(), bounds.Dy()

	imgScale := scale(imgW, imgH, width, height, whratio)

	// Resize canvas to fit scaled image
	width, height = int(float64(imgW)/imgScale), int(float64(imgH)/(imgScale*whratio))

	termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {
			// Calculate average color for the corresponding image rectangle
			// fitting in this cell. We use a half-block trick, wherein the
			// lower half of the cell displays the character ▄, effectively
			// doubling the resolution of the canvas.
			startX, startY, endX, endY := imgArea(x, y, imgScale, whratio)

			r, g, b := avgRGB(img, startX, startY, endX, (startY+endY)/2)
			colorUp := termbox.Attribute(termColor(r, g, b))

			r, g, b = avgRGB(img, startX, (startY+endY)/2, endX, endY)
			colorDown := termbox.Attribute(termColor(r, g, b))

			termbox.SetCell(x, y, '▄', colorDown, colorUp)
		}
	}
	termbox.Flush()
}

func showInUI(image string) {
	img, err := load(image)
	if err != nil {
		panic(err)
	}

	draw(img)

loop:
	for {
		switch ev := termbox.PollEvent(); ev.Type {
		case termbox.EventKey:
			if ev.Key == termbox.KeyEsc || ev.Ch == 'q' {
				break loop
			}
		case termbox.EventResize:
			draw(img)
		default:
			time.Sleep(10 * time.Millisecond)
		}
	}
}

func main() {
	if len(os.Args) < 2 {
		fmt.Printf("Usage: %s <filename>...\n\n", os.Args[0])
		fmt.Println("Close the image with <ESC> or by pressing 'q'.")
		os.Exit(1)
	}

	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()
	termbox.SetOutputMode(termbox.Output256)

	for i := 1; i < len(os.Args); i++ {
		showInUI(os.Args[i])
	}
}
<commit_msg>clean up<commit_after>package main

import (
	"fmt"
	"image"
	"os"
	"time"

	_ "image/jpeg"
	_ "image/png"

	"github.com/nsf/termbox-go"
)

func draw(img image.Image) {
	// Get terminal size and cursor width/height ratio
	width, height, whratio := canvasSize()

	bounds := img.Bounds()
	imgW, imgH := bounds.Dx(), bounds.Dy()

	imgScale := scale(imgW, imgH, width, height, whratio)

	// Resize canvas to fit scaled image
	width, height = int(float64(imgW)/imgScale), int(float64(imgH)/(imgScale*whratio))

	termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {
			// Calculate average color for the corresponding image rectangle
			// fitting in this cell. We use a half-block trick, wherein the
			// lower half of the cell displays the character ▄, effectively
			// doubling the resolution of the canvas.
			startX, startY, endX, endY := imgArea(x, y, imgScale, whratio)

			r, g, b := avgRGB(img, startX, startY, endX, (startY+endY)/2)
			colorUp := termbox.Attribute(termColor(r, g, b))

			r, g, b = avgRGB(img, startX, (startY+endY)/2, endX, endY)
			colorDown := termbox.Attribute(termColor(r, g, b))

			termbox.SetCell(x, y, '▄', colorDown, colorUp)
		}
	}
	termbox.Flush()
}

func display(image string) {
	img, err := load(image)
	if err != nil {
		panic(err)
	}

	draw(img)

	for {
		switch ev := termbox.PollEvent(); ev.Type {
		case termbox.EventKey:
			if ev.Key == termbox.KeyEsc || ev.Ch == 'q' {
				return
			}
		case termbox.EventResize:
			draw(img)
		default:
			time.Sleep(10 * time.Millisecond)
		}
	}
}

func main() {
	if len(os.Args) < 2 {
		fmt.Printf("Usage: %s <filename>...\n\n", os.Args[0])
		fmt.Println("Close the image with <ESC> or by pressing 'q'.")
		os.Exit(1)
	}

	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()
	termbox.SetOutputMode(termbox.Output256)

	for i := 1; i < len(os.Args); i++ {
		display(os.Args[i])
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"net/http"
	"os"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"

	log "github.com/Sirupsen/logrus"
)

const (
	waitTime  = 3 * time.Second
	execDigit = 5
	baseURL   = "https://git.io"
	okFmt     = "%s OK!\n"
	ngFmt     = "%s NG!\n"
	locFmt    = "Location: %s\n"
)

var (
	n = kingpin.Flag("dry-run", "dry run mode.").Short('n').Bool()
	c = new(http.Client)
)

func init() {
	kingpin.Parse()
	c.CheckRedirect = func(req *http.Request, via []*http.Request) error { return errors.New("not redirect") }
}

func main() {
	runes := []rune{'0'}

	for {
		checkPath("/" + string(runes))

		runes = advanceRunes(runes)

		if len(runes) > execDigit {
			// exit
			break
		}

		time.Sleep(waitTime)
	}
}

func checkPath(path string) {
	if *n {
		okLog(path)
		return
	}

	resp, err := c.Get(baseURL + path)
	if err == nil {
		resp.Body.Close()
	}

	if resp.StatusCode == 404 {
		okLog(path)
	} else {
		fmt.Fprintf(os.Stderr, ngFmt, path)
		fmt.Fprintf(os.Stderr, locFmt, resp.Header.Get("Location"))
	}
}

func advanceRunes(runes []rune) []rune {
	if runes[len(runes)-1] == 'Z' {
		// carry over
		addFlg := true
		for i := len(runes) - 1; i > -1; i-- {
			beforeRune := runes[i]
			runes[i] = getNextRune(runes[i])
			if beforeRune != 'Z' {
				addFlg = false
				break
			}
		}

		if addFlg {
			runes = append(runes, '0')
		}
	} else {
		runes[len(runes)-1] = getNextRune(runes[len(runes)-1])
	}

	return runes
}

func getNextRune(r rune) rune {
	// 0 -> 9, a -> z, A -> Z
	if r == '9' {
		return 'a'
	} else if r == 'z' {
		return 'A'
	} else if r == 'Z' {
		return '0'
	}

	r++
	return r
}

func okLog(path string) {
	log.WithFields(log.Fields{"path": path}).Info("ok!")
}
<commit_msg>add ng log<commit_after>package main

import (
	"errors"
	"fmt"
	"net/http"
	"os"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"

	log "github.com/Sirupsen/logrus"
)

const (
	waitTime  = 3 * time.Second
	execDigit = 5
	baseURL   = "https://git.io"
	okFmt     = "%s OK!\n"
	ngFmt     = "%s NG!\n"
	locFmt    = "Location: %s\n"
)

var (
	n = kingpin.Flag("dry-run", "dry run mode.").Short('n').Bool()
	c = new(http.Client)
)

func init() {
	kingpin.Parse()
	c.CheckRedirect = func(req *http.Request, via []*http.Request) error { return errors.New("not redirect") }
}

func main() {
	runes := []rune{'0'}

	for {
		checkPath("/" + string(runes))

		runes = advanceRunes(runes)

		if len(runes) > execDigit {
			// exit
			break
		}

		time.Sleep(waitTime)
	}
}

func checkPath(path string) {
	if *n {
		okLog(path)
		return
	}

	resp, err := c.Get(baseURL + path)
	if err == nil {
		resp.Body.Close()
	}

	if resp.StatusCode == 404 {
		okLog(path)
	} else {
		ngLog(path, resp.Header.Get("Location"))
	}
}

func advanceRunes(runes []rune) []rune {
	if runes[len(runes)-1] == 'Z' {
		// carry over
		addFlg := true
		for i := len(runes) - 1; i > -1; i-- {
			beforeRune := runes[i]
			runes[i] = getNextRune(runes[i])
			if beforeRune != 'Z' {
				addFlg = false
				break
			}
		}

		if addFlg {
			runes = append(runes, '0')
		}
	} else {
		runes[len(runes)-1] = getNextRune(runes[len(runes)-1])
	}

	return runes
}

func getNextRune(r rune) rune {
	// 0 -> 9, a -> z, A -> Z
	if r == '9' {
		return 'a'
	} else if r == 'z' {
		return 'A'
	} else if r == 'Z' {
		return '0'
	}

	r++
	return r
}

func okLog(path string) {
	log.WithFields(log.Fields{"path": path}).Info("ok!")
}

func ngLog(path string, location string) {
	fmt.Fprintf(os.Stderr, ngFmt, path)
	fmt.Fprintf(os.Stderr, locFmt, location)
}
<|endoftext|>


<commit_before>package main

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

	"github.com/gin-gonic/contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/google/go-github/github"
	"github.com/pkg/errors"
	"golang.org/x/oauth2"
	githuboauth "golang.org/x/oauth2/github"
)

const (
	AppName = "paus"
)

func initialize(config *Config, etcd *Etcd) error {
	if !etcd.HasKey("/paus") {
		if err := etcd.Mkdir("/paus"); err != nil {
			return errors.Wrap(err, "Failed to create root directory.")
		}
	}

	if !etcd.HasKey("/paus/users") {
		if err := etcd.Mkdir("/paus/users"); err != nil {
			return errors.Wrap(err, "Failed to create users directory.")
		}
	}

	if err := etcd.Set("/paus/uri-scheme", config.URIScheme); err != nil {
		return errors.Wrap(err, "Failed to set URI scheme in etcd.")
	}

	return nil
}

func main() {
	var out string

	config, err := LoadConfig()

	if err != nil {
		errors.Fprint(os.Stderr, err)
		os.Exit(1)
	}

	if config.ReleaseMode {
		gin.SetMode(gin.ReleaseMode)
	}

	etcd, err := NewEtcd(config.EtcdEndpoint)

	if err != nil {
		errors.Fprint(os.Stderr, err)
		os.Exit(1)
	}

	if err = initialize(config, etcd); err != nil {
		errors.Fprint(os.Stderr, err)
		os.Exit(1)
	}

	oauthConf := oauth2.Config{
		ClientID:     config.GitHubClientID,
		ClientSecret: config.GitHubClientSecret,
		Scopes:       []string{"user", "read:public_key"},
		Endpoint:     githuboauth.Endpoint,
	}

	store := sessions.NewCookieStore([]byte(config.SecretKeyBase))

	r := gin.Default()
	r.Use(sessions.Sessions(AppName, store))
	r.Static("/assets", "assets")
	r.LoadHTMLGlob("templates/*")

	r.GET("/", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.HTML(http.StatusOK, "index.tmpl", gin.H{
				"alert":      false,
				"error":      false,
				"logged_in":  false,
				"message":    "",
				"baseDomain": config.BaseDomain,
			})
		} else {
			oauthClient := oauthConf.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token.(string)})
			client := github.NewClient(oauthClient)

			user, _, err := client.Users.Get("")

			if err != nil {
				c.String(http.StatusNotFound, "User not found.")
				return
			}

			c.HTML(http.StatusOK, "index.tmpl", gin.H{
				"alert":      false,
				"error":      false,
				"logged_in":  true,
				"message":    "",
				"name":       user.Name,
				"baseDomain": config.BaseDomain,
			})
		}
	})

	r.GET("/apps", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		if !UserExists(etcd, username) {
			c.HTML(http.StatusNotFound, "user.tmpl", gin.H{
				"error":   true,
				"message": fmt.Sprintf("User %s does not exist.", username),
			})

			return
		}

		apps, err := Apps(etcd, username)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "user.tmpl", gin.H{
				"error":   true,
				"message": "Failed to list apps.",
			})

			return
		}

		c.HTML(http.StatusOK, "user.tmpl", gin.H{
			"error": false,
			"user":  username,
			"apps":  apps,
		})
	})

	r.POST("/apps", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.PostForm("appName")

		err := CreateApp(etcd, username, appName)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "users.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to create app.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	r.GET("/apps/:appName", func(c *gin.Context) {
		var latestURL string

		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		if !UserExists(etcd, username) {
			c.HTML(http.StatusNotFound, "user.tmpl", gin.H{
				"error":   true,
				"message": fmt.Sprintf("User %s does not exist.", username),
			})

			return
		}

		appName := c.Param("appName")

		if !AppExists(etcd, username, appName) {
			c.HTML(http.StatusNotFound, "user.tmpl", gin.H{
				"error":   true,
				"message": fmt.Sprintf("Application %s does not exist.", appName),
			})

			return
		}

		urls, err := AppURLs(etcd, config.URIScheme, config.BaseDomain, username, appName)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"error":   true,
				"message": "Failed to list app URLs.",
			})

			return
		}

		envs, err := EnvironmentVariables(etcd, username, appName)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"error":   true,
				"message": "Failed to list environment variables.",
			})

			return
		}

		buildArgs, err := BuildArgs(etcd, username, appName)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"error":   true,
				"message": "Failed to list build args.",
			})

			return
		}

		if len(urls) > 0 {
			latestURL = LatestAppURLOfUser(config.URIScheme, config.BaseDomain, username, appName)
		}

		c.HTML(http.StatusOK, "app.tmpl", gin.H{
			"error":     false,
			"user":      username,
			"app":       appName,
			"latestURL": latestURL,
			"urls":      urls,
			"buildArgs": buildArgs,
			"envs":      envs,
		})
	})

	r.POST("/apps/:appName/build-args", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")
		key := c.PostForm("key")
		value := c.PostForm("value")

		err := AddBuildArg(etcd, username, appName, key, value)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to add build arg.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	// TODO: DELETE /apps/:appName/build-args
	r.POST("/apps/:appName/build-args/delete", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")
		key := c.PostForm("key")

		err := DeleteBuildArg(etcd, username, appName, key)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to delete build arg.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	r.POST("/apps/:appName/envs", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")
		key := c.PostForm("key")
		value := c.PostForm("value")

		err := AddEnvironmentVariable(etcd, username, appName, key, value)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to add environment variable.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	// TODO: DELETE /apps/:appName/envs
	r.POST("/apps/:appName/envs/delete", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")
		key := c.PostForm("key")

		fmt.Println(key)

		err := DeleteEnvironmentVariable(etcd, username, appName, key)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to detele environment variable.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	r.POST("/apps/:appName/envs/upload", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")

		dotenvFile, _, err := c.Request.FormFile("dotenv")

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to upload dotenv.",
			})

			return
		}

		if err = LoadDotenv(etcd, username, appName, dotenvFile); err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to load dotenv.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	r.GET("/signin", func(c *gin.Context) {
		url := oauthConf.AuthCodeURL("hoge", oauth2.AccessTypeOnline)
		c.Redirect(http.StatusFound, url)
	})

	r.GET("/callback", func(c *gin.Context) {
		code := c.Query("code")

		// TODO: compare to stored code in session

		token, err := oauthConf.Exchange(oauth2.NoContext, code)

		if err != nil {
			c.String(http.StatusBadRequest, "Error: %s", err)
			return
		}

		if !token.Valid() {
			c.String(http.StatusBadRequest, "%v", token)
			return
		}

		oauthClient := oauthConf.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token.AccessToken})
		client := github.NewClient(oauthClient)

		user, _, err := client.Users.Get("")

		if err != nil {
			c.String(http.StatusBadRequest, "Failed to retrive GitHub user profile.")
		}

		keys, _, err := client.Users.ListKeys("", &github.ListOptions{})

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.String(http.StatusBadRequest, "Failed to retrive SSH public keys from GitHub.")
			return
		}

		for _, key := range keys {
			if !config.SkipKeyUpload {
				_, err := UploadPublicKey(*user.Login, *key.Key)

				if err != nil {
					errors.Fprint(os.Stderr, err)

					c.String(http.StatusBadRequest, "Failed to register SSH public key.")
					return
				}
			} else {
				fmt.Printf("User: %s, Key: %s\n", *user.Login, *key.Key)
			}
		}

		if !UserExists(etcd, *user.Login) {
			if err := CreateUser(etcd, user); err != nil {
				errors.Fprint(os.Stderr, err)

				c.String(http.StatusBadRequest, "Failed to create user.")
				return
			}
		}

		if err := RegisterAccessToken(etcd, *user.Login, token.AccessToken); err != nil {
			errors.Fprint(os.Stderr, err)

			c.String(http.StatusBadRequest, "Failed to register access token.")
			return
		}

		session := sessions.Default(c)
		session.Set("token", token.AccessToken)
		session.Save()

		c.Redirect(http.StatusFound, "/apps")
	})

	r.Run()
}
<commit_msg>Remove unused variable declaration<commit_after>package main

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

	"github.com/gin-gonic/contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/google/go-github/github"
	"github.com/pkg/errors"
	"golang.org/x/oauth2"
	githuboauth "golang.org/x/oauth2/github"
)

const (
	AppName = "paus"
)

func initialize(config *Config, etcd *Etcd) error {
	if !etcd.HasKey("/paus") {
		if err := etcd.Mkdir("/paus"); err != nil {
			return errors.Wrap(err, "Failed to create root directory.")
		}
	}

	if !etcd.HasKey("/paus/users") {
		if err := etcd.Mkdir("/paus/users"); err != nil {
			return errors.Wrap(err, "Failed to create users directory.")
		}
	}

	if err := etcd.Set("/paus/uri-scheme", config.URIScheme); err != nil {
		return errors.Wrap(err, "Failed to set URI scheme in etcd.")
	}

	return nil
}

func main() {
	config, err := LoadConfig()

	if err != nil {
		errors.Fprint(os.Stderr, err)
		os.Exit(1)
	}

	if config.ReleaseMode {
		gin.SetMode(gin.ReleaseMode)
	}

	etcd, err := NewEtcd(config.EtcdEndpoint)

	if err != nil {
		errors.Fprint(os.Stderr, err)
		os.Exit(1)
	}

	if err = initialize(config, etcd); err != nil {
		errors.Fprint(os.Stderr, err)
		os.Exit(1)
	}

	oauthConf := oauth2.Config{
		ClientID:     config.GitHubClientID,
		ClientSecret: config.GitHubClientSecret,
		Scopes:       []string{"user", "read:public_key"},
		Endpoint:     githuboauth.Endpoint,
	}

	store := sessions.NewCookieStore([]byte(config.SecretKeyBase))

	r := gin.Default()
	r.Use(sessions.Sessions(AppName, store))
	r.Static("/assets", "assets")
	r.LoadHTMLGlob("templates/*")

	r.GET("/", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.HTML(http.StatusOK, "index.tmpl", gin.H{
				"alert":      false,
				"error":      false,
				"logged_in":  false,
				"message":    "",
				"baseDomain": config.BaseDomain,
			})
		} else {
			oauthClient := oauthConf.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token.(string)})
			client := github.NewClient(oauthClient)

			user, _, err := client.Users.Get("")

			if err != nil {
				c.String(http.StatusNotFound, "User not found.")
				return
			}

			c.HTML(http.StatusOK, "index.tmpl", gin.H{
				"alert":      false,
				"error":      false,
				"logged_in":  true,
				"message":    "",
				"name":       user.Name,
				"baseDomain": config.BaseDomain,
			})
		}
	})

	r.GET("/apps", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		if !UserExists(etcd, username) {
			c.HTML(http.StatusNotFound, "user.tmpl", gin.H{
				"error":   true,
				"message": fmt.Sprintf("User %s does not exist.", username),
			})

			return
		}

		apps, err := Apps(etcd, username)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "user.tmpl", gin.H{
				"error":   true,
				"message": "Failed to list apps.",
			})

			return
		}

		c.HTML(http.StatusOK, "user.tmpl", gin.H{
			"error": false,
			"user":  username,
			"apps":  apps,
		})
	})

	r.POST("/apps", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.PostForm("appName")

		err := CreateApp(etcd, username, appName)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "users.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to create app.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	r.GET("/apps/:appName", func(c *gin.Context) {
		var latestURL string

		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		if !UserExists(etcd, username) {
			c.HTML(http.StatusNotFound, "user.tmpl", gin.H{
				"error":   true,
				"message": fmt.Sprintf("User %s does not exist.", username),
			})

			return
		}

		appName := c.Param("appName")

		if !AppExists(etcd, username, appName) {
			c.HTML(http.StatusNotFound, "user.tmpl", gin.H{
				"error":   true,
				"message": fmt.Sprintf("Application %s does not exist.", appName),
			})

			return
		}

		urls, err := AppURLs(etcd, config.URIScheme, config.BaseDomain, username, appName)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"error":   true,
				"message": "Failed to list app URLs.",
			})

			return
		}

		envs, err := EnvironmentVariables(etcd, username, appName)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"error":   true,
				"message": "Failed to list environment variables.",
			})

			return
		}

		buildArgs, err := BuildArgs(etcd, username, appName)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"error":   true,
				"message": "Failed to list build args.",
			})

			return
		}

		if len(urls) > 0 {
			latestURL = LatestAppURLOfUser(config.URIScheme, config.BaseDomain, username, appName)
		}

		c.HTML(http.StatusOK, "app.tmpl", gin.H{
			"error":     false,
			"user":      username,
			"app":       appName,
			"latestURL": latestURL,
			"urls":      urls,
			"buildArgs": buildArgs,
			"envs":      envs,
		})
	})

	r.POST("/apps/:appName/build-args", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")
		key := c.PostForm("key")
		value := c.PostForm("value")

		err := AddBuildArg(etcd, username, appName, key, value)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to add build arg.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	// TODO: DELETE /apps/:appName/build-args
	r.POST("/apps/:appName/build-args/delete", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")
		key := c.PostForm("key")

		err := DeleteBuildArg(etcd, username, appName, key)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to delete build arg.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	r.POST("/apps/:appName/envs", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")
		key := c.PostForm("key")
		value := c.PostForm("value")

		err := AddEnvironmentVariable(etcd, username, appName, key, value)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to add environment variable.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	// TODO: DELETE /apps/:appName/envs
	r.POST("/apps/:appName/envs/delete", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")
		key := c.PostForm("key")

		fmt.Println(key)

		err := DeleteEnvironmentVariable(etcd, username, appName, key)

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to detele environment variable.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	r.POST("/apps/:appName/envs/upload", func(c *gin.Context) {
		session := sessions.Default(c)
		token := session.Get("token")

		if token == nil {
			c.Redirect(http.StatusFound, "/")

			return
		}

		username := GetLoginUser(etcd, token.(string))

		if username == "" {
			c.Redirect(http.StatusFound, "/")

			return
		}

		appName := c.Param("appName")

		dotenvFile, _, err := c.Request.FormFile("dotenv")

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to upload dotenv.",
			})

			return
		}

		if err = LoadDotenv(etcd, username, appName, dotenvFile); err != nil {
			errors.Fprint(os.Stderr, err)

			c.HTML(http.StatusInternalServerError, "app.tmpl", gin.H{
				"alert":   true,
				"error":   true,
				"message": "Failed to load dotenv.",
			})

			return
		}

		c.Redirect(http.StatusMovedPermanently, "/apps/"+appName)
	})

	r.GET("/signin", func(c *gin.Context) {
		url := oauthConf.AuthCodeURL("hoge", oauth2.AccessTypeOnline)
		c.Redirect(http.StatusFound, url)
	})

	r.GET("/callback", func(c *gin.Context) {
		code := c.Query("code")

		// TODO: compare to stored code in session

		token, err := oauthConf.Exchange(oauth2.NoContext, code)

		if err != nil {
			c.String(http.StatusBadRequest, "Error: %s", err)
			return
		}

		if !token.Valid() {
			c.String(http.StatusBadRequest, "%v", token)
			return
		}

		oauthClient := oauthConf.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token.AccessToken})
		client := github.NewClient(oauthClient)

		user, _, err := client.Users.Get("")

		if err != nil {
			c.String(http.StatusBadRequest, "Failed to retrive GitHub user profile.")
		}

		keys, _, err := client.Users.ListKeys("", &github.ListOptions{})

		if err != nil {
			errors.Fprint(os.Stderr, err)

			c.String(http.StatusBadRequest, "Failed to retrive SSH public keys from GitHub.")
			return
		}

		for _, key := range keys {
			if !config.SkipKeyUpload {
				_, err := UploadPublicKey(*user.Login, *key.Key)

				if err != nil {
					errors.Fprint(os.Stderr, err)

					c.String(http.StatusBadRequest, "Failed to register SSH public key.")
					return
				}
			} else {
				fmt.Printf("User: %s, Key: %s\n", *user.Login, *key.Key)
			}
		}

		if !UserExists(etcd, *user.Login) {
			if err := CreateUser(etcd, user); err != nil {
				errors.Fprint(os.Stderr, err)

				c.String(http.StatusBadRequest, "Failed to create user.")
				return
			}
		}

		if err := RegisterAccessToken(etcd, *user.Login, token.AccessToken); err != nil {
			errors.Fprint(os.Stderr, err)

			c.String(http.StatusBadRequest, "Failed to register access token.")
			return
		}

		session := sessions.Default(c)
		session.Set("token", token.AccessToken)
		session.Save()

		c.Redirect(http.StatusFound, "/apps")
	})

	r.Run()
}
<|endoftext|>


<commit_before>package main

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

var maxAge string

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

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

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

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

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

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

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

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

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

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

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

var maxAge string

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

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

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

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

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

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

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

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

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

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


<commit_before>package main

import (
	"log"

	"github.com/mediocregopher/lever"
	"github.com/miekg/dns"
)

var dnsServers []string

func tryProxy(m *dns.Msg, addr string) *dns.Msg {
	aM, err := dns.Exchange(m, addr)
	if err != nil {
		log.Printf("forwarding to %s got err: %s", addr, err)
		return nil
	} else if len(aM.Answer) == 0 {
		return nil
	}
	return aM
}

func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
	chs := make([]chan *dns.Msg, len(dnsServers))
	for i := range dnsServers {
		chs[i] = make(chan *dns.Msg, 1)
		go func(ch chan *dns.Msg) {
			ch <- tryProxy(r, dnsServers[i])
		}(chs[i])
	}

	var m *dns.Msg
	for i := range dnsServers {
		if m = <-chs[i]; m != nil {
			break
		}
	}
	if m == nil {
		dns.HandleFailed(w, r)
		return
	}
	m.SetReply(r)
	w.WriteMsg(m)
}

func main() {

	l := lever.New("struggledns", nil)
	l.Add(lever.Param{
		Name:        "--listen-addr",
		Description: "Address to listen on for dns requests. Will bind to both tcp and udp",
		Default:     ":53",
	})
	l.Add(lever.Param{
		Name:        "--fwd-to",
		Description: "Address (ip:port) of a dns server to attempt forward requests to. Specify multiple times to make multiple request attempts. Order specified dictates precedence should more than one server respond for a request",
	})
	l.Parse()

	addr, _ := l.ParamStr("--listen-addr")
	dnsServers, _ = l.ParamStrs("--fwd-to")

	handler := dns.HandlerFunc(handleRequest)
	go func() {
		log.Printf("Listening on %s (udp)", addr)
		log.Fatal(dns.ListenAndServe(addr, "udp", handler))
	}()
	go func() {
		log.Printf("Listening on %s (tcp)", addr)
		log.Fatal(dns.ListenAndServe(addr, "tcp", handler))
	}()

	select {}
}
<commit_msg>fix bug with how addresses were being distributed<commit_after>package main

import (
	"log"

	"github.com/mediocregopher/lever"
	"github.com/miekg/dns"
)

var dnsServers []string

func tryProxy(m *dns.Msg, addr string) *dns.Msg {
	aM, err := dns.Exchange(m, addr)
	if err != nil {
		log.Printf("forwarding to %s got err: %s", addr, err)
		return nil
	} else if len(aM.Answer) == 0 {
		return nil
	}
	return aM
}

func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
	chs := make([]chan *dns.Msg, len(dnsServers))
	for i := range dnsServers {
		chs[i] = make(chan *dns.Msg, 1)
		go func(ch chan *dns.Msg, addr string) {
			ch <- tryProxy(r, addr)
		}(chs[i], dnsServers[i])
	}

	var m *dns.Msg
	for i := range dnsServers {
		if m = <-chs[i]; m != nil {
			break
		}
	}
	if m == nil {
		dns.HandleFailed(w, r)
		return
	}
	m.SetReply(r)
	w.WriteMsg(m)
}

func main() {

	l := lever.New("struggledns", nil)
	l.Add(lever.Param{
		Name:        "--listen-addr",
		Description: "Address to listen on for dns requests. Will bind to both tcp and udp",
		Default:     ":53",
	})
	l.Add(lever.Param{
		Name:        "--fwd-to",
		Description: "Address (ip:port) of a dns server to attempt forward requests to. Specify multiple times to make multiple request attempts. Order specified dictates precedence should more than one server respond for a request",
	})
	l.Parse()

	addr, _ := l.ParamStr("--listen-addr")
	dnsServers, _ = l.ParamStrs("--fwd-to")

	handler := dns.HandlerFunc(handleRequest)
	go func() {
		log.Printf("Listening on %s (udp)", addr)
		log.Fatal(dns.ListenAndServe(addr, "udp", handler))
	}()
	go func() {
		log.Printf("Listening on %s (tcp)", addr)
		log.Fatal(dns.ListenAndServe(addr, "tcp", handler))
	}()

	select {}
}
<|endoftext|>


<commit_before>package main

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

	yaml "gopkg.in/yaml.v2"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatchevents"
	"github.com/aws/aws-sdk-go/service/lambda"
)

var Version = "0.2.0"

func main() {
	var (
		apply, dryrun                           bool
		file, awsRegion                         string
		err                                     error
		sess                                    *session.Session
		cweRulesBeforeApply, cweRulesAfterApply *cloudwatchevents.ListRulesOutput
	)

	flag.BoolVar(&apply, "apply", false, "apply to CloudWatch Events")
	flag.BoolVar(&dryrun, "dry-run", false, "dry-run")
	flag.StringVar(&file, "file", "config.yml", "file path to setting yaml")
	flag.StringVar(&file, "f", "config.yml", "file path to setting yaml (shorthand)")
	flag.StringVar(&awsRegion, "region", os.Getenv("AWS_REGION"), "aws region")
	flag.Parse()

	sess, err = session.NewSession(
		&aws.Config{
			Region: aws.String(awsRegion),
		},
	)
	if err != nil {
		fmt.Printf("Session error %v\n", err)
		os.Exit(1)
	}

	cweClient := cloudwatchevents.New(sess)
	lambdaClient := lambda.New(sess)

	cweRulesBeforeApply, err = cweClient.ListRules(nil)
	if err != nil {
		fmt.Printf("API error %v\n", err)
		os.Exit(1)
	}

	describedRules := Rules{}
	err = loadYaml(file, &describedRules)
	if err != nil {
		fmt.Printf("File error %v\n", err)
		os.Exit(1)
	}

	describedRules.Rules = AssociateRules(cweRulesBeforeApply.Rules, describedRules.Rules)
	for i, rule := range describedRules.Rules {
		t, _ := fetchActualTargetsByRule(cweClient, rule)
		describedRules.Rules[i].Targets = AssociateTargets(t, describedRules.Rules[i].Targets)
	}
	CheckIsNeedUpdateOrDelete(describedRules.Rules)
	displayWhatWillChange(describedRules.Rules)

	if apply && !dryrun {
		err = updateCloudWatchEvents(cweClient, describedRules.Rules)
		if err != nil {
			fmt.Printf("API error %v\n", err)
			os.Exit(1)
		}
		// Grant permission to invoke lambda function from CloudWatch Events
		cweRulesAfterApply, err = cweClient.ListRules(nil)
		describedRules.Rules = AssociateRules(cweRulesAfterApply.Rules, describedRules.Rules)
		for i, rule := range describedRules.Rules {
			t, _ := fetchActualTargetsByRule(cweClient, rule)
			describedRules.Rules[i].Targets = AssociateTargets(t, describedRules.Rules[i].Targets)
		}

		err = addPermissionToLambdaFromCloudWatchEvents(lambdaClient, describedRules.Rules)
		if err != nil {
			fmt.Print("Grant permission error %v\n", err)
		}
	}
}

func loadYaml(file string, r *Rules) error {

	buf, err := ioutil.ReadFile(file)
	if err != nil {
		return err
	}

	err = yaml.Unmarshal(buf, &r)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Remove permission from deleted lambda function<commit_after>package main

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

	yaml "gopkg.in/yaml.v2"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatchevents"
	"github.com/aws/aws-sdk-go/service/lambda"
)

var Version = "0.2.0"

func main() {
	var (
		apply, dryrun                           bool
		file, awsRegion                         string
		err                                     error
		sess                                    *session.Session
		cweRulesBeforeApply, cweRulesAfterApply *cloudwatchevents.ListRulesOutput
	)

	flag.BoolVar(&apply, "apply", false, "apply to CloudWatch Events")
	flag.BoolVar(&dryrun, "dry-run", false, "dry-run")
	flag.StringVar(&file, "file", "config.yml", "file path to setting yaml")
	flag.StringVar(&file, "f", "config.yml", "file path to setting yaml (shorthand)")
	flag.StringVar(&awsRegion, "region", os.Getenv("AWS_REGION"), "aws region")
	flag.Parse()

	sess, err = session.NewSession(
		&aws.Config{
			Region: aws.String(awsRegion),
		},
	)
	if err != nil {
		fmt.Printf("Session error %v\n", err)
		os.Exit(1)
	}

	cweClient := cloudwatchevents.New(sess)
	lambdaClient := lambda.New(sess)

	cweRulesBeforeApply, err = cweClient.ListRules(nil)
	if err != nil {
		fmt.Printf("API error %v\n", err)
		os.Exit(1)
	}

	describedRules := Rules{}
	err = loadYaml(file, &describedRules)
	if err != nil {
		fmt.Printf("File error %v\n", err)
		os.Exit(1)
	}

	describedRules.Rules = AssociateRules(cweRulesBeforeApply.Rules, describedRules.Rules)
	for i, rule := range describedRules.Rules {
		t, _ := fetchActualTargetsByRule(cweClient, rule)
		describedRules.Rules[i].Targets = AssociateTargets(t, describedRules.Rules[i].Targets)
	}
	CheckIsNeedUpdateOrDelete(describedRules.Rules)
	displayWhatWillChange(describedRules.Rules)

	if apply && !dryrun {
		err = updateCloudWatchEvents(cweClient, describedRules.Rules)
		if err != nil {
			fmt.Printf("API error %v\n", err)
			os.Exit(1)
		}

		err = removePermissonFromLambda(lambdaClient, describedRules.Rules)
		if err != nil {
			fmt.Printf("API error %v\n", err)
			os.Exit(1)
		}

		// Grant permission to invoke lambda function from CloudWatch Events
		cweRulesAfterApply, err = cweClient.ListRules(nil)
		describedRules.Rules = AssociateRules(cweRulesAfterApply.Rules, describedRules.Rules)
		for i, rule := range describedRules.Rules {
			t, _ := fetchActualTargetsByRule(cweClient, rule)
			describedRules.Rules[i].Targets = AssociateTargets(t, describedRules.Rules[i].Targets)
		}

		err = addPermissionToLambdaFromCloudWatchEvents(lambdaClient, describedRules.Rules)
		if err != nil {
			fmt.Print("Grant permission error %v\n", err)
		}
	}
}

func loadYaml(file string, r *Rules) error {

	buf, err := ioutil.ReadFile(file)
	if err != nil {
		return err
	}

	err = yaml.Unmarshal(buf, &r)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

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

func ProxyServer(w http.ResponseWriter, req *http.Request) {
	req.Header.Set("Host", req.Host)

	fmt.Printf("> %s %s %s\n", req.Method, reqPath(req), req.Proto)

	for k, v := range req.Header {
		fmt.Printf("> %s - %s\n", k, strings.Join(v, ","))
	}

	content, err := ioutil.ReadAll(req.Body)
	req.Body.Close()
	if err == nil {
		fmt.Println(string(content))
	}

	fmt.Println("")

	fmt.Fprintln(w, "ok")
}

func reqPath(req *http.Request) string {
	path := req.URL.Path
	query := []string{}
	for k, v := range req.URL.Query() {
		query = append(query, fmt.Sprintf("%s=%s", k, strings.Join(v, ",")))
	}

	if len(query) > 0 {
		path = fmt.Sprintf("%s?%s", path, strings.Join(query, "&"))
	}

	return path
}

func main() {
	http.HandleFunc("/", ProxyServer)
	err := http.ListenAndServe(":12345", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<commit_msg>Use colon to separate headers<commit_after>package main

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

func ProxyServer(w http.ResponseWriter, req *http.Request) {
	req.Header.Set("Host", req.Host)

	fmt.Printf("> %s %s %s\n", req.Method, reqPath(req), req.Proto)

	for k, v := range req.Header {
		fmt.Printf("> %s: %s\n", k, strings.Join(v, ","))
	}

	content, err := ioutil.ReadAll(req.Body)
	req.Body.Close()
	if err == nil {
		fmt.Println(string(content))
	}

	fmt.Println("")

	fmt.Fprintln(w, "ok")
}

func reqPath(req *http.Request) string {
	path := req.URL.Path
	query := []string{}
	for k, v := range req.URL.Query() {
		query = append(query, fmt.Sprintf("%s=%s", k, strings.Join(v, ",")))
	}

	if len(query) > 0 {
		path = fmt.Sprintf("%s?%s", path, strings.Join(query, "&"))
	}

	return path
}

func main() {
	http.HandleFunc("/", ProxyServer)
	err := http.ListenAndServe(":12345", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"

	"github.com/jirwin/xpost-quadlek/pkg"

	"github.com/Bullpeen/infobot"
	"github.com/Bullpeen/slices"
	"github.com/Bullpeen/stox"
	log "github.com/Sirupsen/logrus"
	"github.com/jirwin/gifs-quadlek/src"
	"github.com/jirwin/quadlek/plugins/comics"
	"github.com/jirwin/quadlek/plugins/echo"
	"github.com/jirwin/quadlek/plugins/eslogs"
	"github.com/jirwin/quadlek/plugins/karma"
	"github.com/jirwin/quadlek/plugins/nextep"
	"github.com/jirwin/quadlek/plugins/random"
	"github.com/jirwin/quadlek/plugins/spotify"
	"github.com/jirwin/quadlek/plugins/twitter"
	"github.com/jirwin/quadlek/quadlek"
	"github.com/morgabra/cointip/quadlek"
	twitch "github.com/morgabra/libtwitch/quadlek"
	"github.com/urfave/cli"
)

const Version = "0.0.1"

func run(c *cli.Context) error {
	var apiToken string
	if c.IsSet("api-key") {
		apiToken = c.String("api-key")
	} else {
		cli.ShowAppHelp(c)
		return cli.NewExitError("Missing --api-key arg.", 1)
	}

	var verificationToken string
	if c.IsSet("verification-token") {
		verificationToken = c.String("verification-token")
	} else {
		cli.ShowAppHelp(c)
		return cli.NewExitError("Missing --verification-token arg.", 1)
	}

	dbPath := c.String("db-path")

	bot, err := quadlek.NewBot(context.Background(), apiToken, verificationToken, dbPath)
	if err != nil {
		log.WithFields(log.Fields{
			"err": err,
		}).Error("error creating bot")
		return nil
	}

	err = bot.RegisterPlugin(echo.Register())
	if err != nil {
		fmt.Printf("error registering echo plugin: %s\n", err.Error())
		return nil
	}

	err = bot.RegisterPlugin(karma.Register())
	if err != nil {
		fmt.Printf("error registering karma plugin: %s\n", err.Error())
		return nil
	}

	err = bot.RegisterPlugin(random.Register())
	if err != nil {
		fmt.Printf("error registering random plugin: %s\n", err.Error())
		return nil
	}

	err = bot.RegisterPlugin(spotify.Register())
	if err != nil {
		fmt.Printf("error registering spotify plugin: %s\n", err.Error())
		return nil
	}

	if c.IsSet("tvdb-key") {
		tvdbKey := c.String("tvdb-key")

		err = bot.RegisterPlugin(nextep.Register(tvdbKey))
		if err != nil {
			fmt.Printf("error registering nextep plugin: %s\n", err.Error())
			return nil
		}
	}

	err = bot.RegisterPlugin(infobot.Register())
	if err != nil {
		fmt.Printf("error registering infobot plugin: %s\n", err.Error())
		return nil
	}

	err = bot.RegisterPlugin(twitter.Register(
		c.String("twitter-consumer-key"),
		c.String("twitter-consumer-secret"),
		c.String("twitter-access-token"),
		c.String("twitter-access-secret"),
		// These must be twitter user ids, not names. https://tweeterid.com/ for easy conversion between the two.
		map[string]string{
			"25073877":           "politics-feed", // @realDonaldTrump
			"830896623689547776": "politics-feed", // @PresVillain
			"934474767645724672": "politics-feed", // @realtrumpweathr
			"138203134":          "politics-feed", // @AOC
			"976366106561490944": "artfolio",      // @DrawnDavidsOff
			"921111554371682304": "artfolio",      // @DrawnDavidson
			"1581511":            "wwdc",          //@macrumorslive
			//added for retweet testing
			"778682": "quadlek-chat", // @jirwin

		},
	))

	coinbasePlugin := cointip.Register(
		c.String("coinbase-key"),
		c.String("coinbase-secret"),
		c.String("coinbase-account"),
	)
	if coinbasePlugin != nil {
		err = bot.RegisterPlugin(coinbasePlugin)
		if err != nil {
			panic(err)
		}
	}

	err = bot.RegisterPlugin(comics.Register(
		c.String("imgur-client-id"),
		"/opt/quad-assets/Arial.ttf",
	))
	if err != nil {
		fmt.Printf("error registering comic plugin: %s\n", err.Error())
		return err
	}
	esPlugin, err := eslogs.Register(c.String("es-endpoint"), c.String("es-index"))
	if err != nil {
		fmt.Printf("Error creating eslogs plugin: %s\n", err.Error())
		return err
	}
	err = bot.RegisterPlugin(esPlugin)
	if err != nil {
		fmt.Printf("Error registering eslogs plugin: %s\n", err.Error())
		return err
	}

	xpostPlugin := xpost.Register()
	err = bot.RegisterPlugin(xpostPlugin)
	if err != nil {
		fmt.Printf("error registering xpost plugin: %s\n", err.Error())
		return err
	}

	stoxPlugin := stox.Register(c.String("av-key"))
	err = bot.RegisterPlugin(stoxPlugin)
	if err != nil {
		fmt.Printf("Error registering stox plugin: %s\n", err.Error())
		return err
	}

	gifPlugin := gifs.Register(c.String("giphy-api-key"))
	err = bot.RegisterPlugin(gifPlugin)
	if err != nil {
		fmt.Printf("Error registering gifs plugin: %s\n", err.Error())
		return err
	}

	twitchFollows := []*twitch.TwitchFollow{
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "kitboga",
			WatchStream:   true,
		},
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "khryo72",
			SlackUser:     "morgabra",
			WatchStream:   true,
			WatchFollows:  true,
		},
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "mekilek",
			SlackUser:     "jirwin",
			WatchStream:   true,
			WatchFollows:  true,
		},
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "sonicdm",
			SlackUser:     "sonicdm",
			WatchStream:   true,
			WatchFollows:  true,
		},
	}

	twitchPlugin := twitch.Register(c.String("twitch-oauth-client-id"), "", "https://quadlek.jirw.in/slack/plugin/twitch", false, twitchFollows)
	if twitchPlugin != nil {
		err = bot.RegisterPlugin(twitchPlugin)
		if err != nil {
			fmt.Printf("error registering twitch plugin: %s\n", err.Error())
			return err
		}
	}

	err = bot.RegisterPlugin(slices.Register([]string {
		"1841289615922336", // sonicdm
		"76561197976367183", // morgabra
		"76561198057633471", // greenjeans
		"76561198002272597", // newsomr
		"76561197974723967", // purdyk
		//"76561197969022064", // schonstal?
	}))
	if err != nil {
		fmt.Printf("error registering slices plugin: %s\n", err.Error())
		return nil
	}

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, os.Interrupt)

	bot.Start()
	<-signals
	bot.Stop()

	return nil
}

func main() {
	app := cli.NewApp()
	app.Name = "quadlek"
	app.Version = Version
	app.Usage = "a slack bot"
	app.Action = run
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "api-key",
			Usage:  "The slack api token for the bot",
			EnvVar: "QUADLEK_API_TOKEN",
		},
		cli.StringFlag{
			Name:   "verification-token",
			Usage:  "The slack webhook verification token.",
			EnvVar: "QUADLEK_VERIFICATION_TOKEN",
		},
		cli.StringFlag{
			Name:   "db-path",
			Usage:  "The path where the database is stored.",
			Value:  "quadlek.db",
			EnvVar: "QUADLEK_DB_PATH",
		},
		cli.StringFlag{
			Name:   "tvdb-key",
			Usage:  "The TVDB api key for the bot, used by the nextep command",
			EnvVar: "QUADLEK_TVDB_TOKEN",
		},
		cli.StringFlag{
			Name:   "twitter-consumer-key",
			Usage:  "The consumer key for the twitter api",
			EnvVar: "QUADLEK_TWITTER_CONSUMER_KEY",
		},
		cli.StringFlag{
			Name:   "twitter-consumer-secret",
			Usage:  "The consumer secret for the twitter api",
			EnvVar: "QUADLEK_TWITTER_CONSUMER_SECRET",
		},
		cli.StringFlag{
			Name:   "twitter-access-token",
			Usage:  "The access key for the twitter api",
			EnvVar: "QUADLEK_TWITTER_ACCESS_TOKEN",
		},
		cli.StringFlag{
			Name:   "twitter-access-secret",
			Usage:  "The access secret for the twitter api",
			EnvVar: "QUADLEK_TWITTER_ACCESS_SECRET",
		},
		cli.StringFlag{
			Name:   "coinbase-key",
			Usage:  "The access key for the coinbase api",
			EnvVar: "QUADLEK_COINBASE_KEY",
		},
		cli.StringFlag{
			Name:   "coinbase-secret",
			Usage:  "The access secret for the coinbase api",
			EnvVar: "QUADLEK_COINBASE_SECRET",
		},
		cli.StringFlag{
			Name:   "coinbase-account",
			Usage:  "The bank account for the coinbase api",
			EnvVar: "QUADLEK_COINBASE_BANK_ACCOUNT",
		},
		cli.StringFlag{
			Name:   "imgur-client-id",
			Usage:  "The imgur client id",
			EnvVar: "QUADLEK_IMGUR_CLIENT_ID",
		},
		cli.StringFlag{
			Name:   "es-endpoint",
			Usage:  "The elastic search endpoint",
			EnvVar: "QUADLEK_ES_ENDPOINT",
		},
		cli.StringFlag{
			Name:   "es-index",
			Usage:  "The elastic search index",
			EnvVar: "QUADLEK_ES_INDEX",
		},
		cli.StringFlag{
			Name:   "av-key",
			Usage:  "Alpha Vantage Api Key",
			EnvVar: "QUADLEK_AV_KEY",
		},
		cli.StringFlag{
			Name:   "giphy-api-key",
			Usage:  "Giphy API Key",
			EnvVar: "QUADLEK_GIPHY_KEY",
		},
		cli.StringFlag{
			Name:   "twitch-oauth-client-id",
			Usage:  "OAuth application client id for twitch API",
			EnvVar: "QUADLEK_TWITCH_OAUTH_CLIENT_ID",
		},
	}

	app.Run(os.Args)
}
<commit_msg>Follow sakatana on twitch.<commit_after>package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"

	"github.com/jirwin/xpost-quadlek/pkg"

	"github.com/Bullpeen/infobot"
	"github.com/Bullpeen/slices"
	"github.com/Bullpeen/stox"
	log "github.com/Sirupsen/logrus"
	"github.com/jirwin/gifs-quadlek/src"
	"github.com/jirwin/quadlek/plugins/comics"
	"github.com/jirwin/quadlek/plugins/echo"
	"github.com/jirwin/quadlek/plugins/eslogs"
	"github.com/jirwin/quadlek/plugins/karma"
	"github.com/jirwin/quadlek/plugins/nextep"
	"github.com/jirwin/quadlek/plugins/random"
	"github.com/jirwin/quadlek/plugins/spotify"
	"github.com/jirwin/quadlek/plugins/twitter"
	"github.com/jirwin/quadlek/quadlek"
	"github.com/morgabra/cointip/quadlek"
	twitch "github.com/morgabra/libtwitch/quadlek"
	"github.com/urfave/cli"
)

const Version = "0.0.1"

func run(c *cli.Context) error {
	var apiToken string
	if c.IsSet("api-key") {
		apiToken = c.String("api-key")
	} else {
		cli.ShowAppHelp(c)
		return cli.NewExitError("Missing --api-key arg.", 1)
	}

	var verificationToken string
	if c.IsSet("verification-token") {
		verificationToken = c.String("verification-token")
	} else {
		cli.ShowAppHelp(c)
		return cli.NewExitError("Missing --verification-token arg.", 1)
	}

	dbPath := c.String("db-path")

	bot, err := quadlek.NewBot(context.Background(), apiToken, verificationToken, dbPath)
	if err != nil {
		log.WithFields(log.Fields{
			"err": err,
		}).Error("error creating bot")
		return nil
	}

	err = bot.RegisterPlugin(echo.Register())
	if err != nil {
		fmt.Printf("error registering echo plugin: %s\n", err.Error())
		return nil
	}

	err = bot.RegisterPlugin(karma.Register())
	if err != nil {
		fmt.Printf("error registering karma plugin: %s\n", err.Error())
		return nil
	}

	err = bot.RegisterPlugin(random.Register())
	if err != nil {
		fmt.Printf("error registering random plugin: %s\n", err.Error())
		return nil
	}

	err = bot.RegisterPlugin(spotify.Register())
	if err != nil {
		fmt.Printf("error registering spotify plugin: %s\n", err.Error())
		return nil
	}

	if c.IsSet("tvdb-key") {
		tvdbKey := c.String("tvdb-key")

		err = bot.RegisterPlugin(nextep.Register(tvdbKey))
		if err != nil {
			fmt.Printf("error registering nextep plugin: %s\n", err.Error())
			return nil
		}
	}

	err = bot.RegisterPlugin(infobot.Register())
	if err != nil {
		fmt.Printf("error registering infobot plugin: %s\n", err.Error())
		return nil
	}

	err = bot.RegisterPlugin(twitter.Register(
		c.String("twitter-consumer-key"),
		c.String("twitter-consumer-secret"),
		c.String("twitter-access-token"),
		c.String("twitter-access-secret"),
		// These must be twitter user ids, not names. https://tweeterid.com/ for easy conversion between the two.
		map[string]string{
			"25073877":           "politics-feed", // @realDonaldTrump
			"830896623689547776": "politics-feed", // @PresVillain
			"934474767645724672": "politics-feed", // @realtrumpweathr
			"138203134":          "politics-feed", // @AOC
			"976366106561490944": "artfolio",      // @DrawnDavidsOff
			"921111554371682304": "artfolio",      // @DrawnDavidson
			"1581511":            "wwdc",          //@macrumorslive
			//added for retweet testing
			"778682": "quadlek-chat", // @jirwin

		},
	))

	coinbasePlugin := cointip.Register(
		c.String("coinbase-key"),
		c.String("coinbase-secret"),
		c.String("coinbase-account"),
	)
	if coinbasePlugin != nil {
		err = bot.RegisterPlugin(coinbasePlugin)
		if err != nil {
			panic(err)
		}
	}

	err = bot.RegisterPlugin(comics.Register(
		c.String("imgur-client-id"),
		"/opt/quad-assets/Arial.ttf",
	))
	if err != nil {
		fmt.Printf("error registering comic plugin: %s\n", err.Error())
		return err
	}
	esPlugin, err := eslogs.Register(c.String("es-endpoint"), c.String("es-index"))
	if err != nil {
		fmt.Printf("Error creating eslogs plugin: %s\n", err.Error())
		return err
	}
	err = bot.RegisterPlugin(esPlugin)
	if err != nil {
		fmt.Printf("Error registering eslogs plugin: %s\n", err.Error())
		return err
	}

	xpostPlugin := xpost.Register()
	err = bot.RegisterPlugin(xpostPlugin)
	if err != nil {
		fmt.Printf("error registering xpost plugin: %s\n", err.Error())
		return err
	}

	stoxPlugin := stox.Register(c.String("av-key"))
	err = bot.RegisterPlugin(stoxPlugin)
	if err != nil {
		fmt.Printf("Error registering stox plugin: %s\n", err.Error())
		return err
	}

	gifPlugin := gifs.Register(c.String("giphy-api-key"))
	err = bot.RegisterPlugin(gifPlugin)
	if err != nil {
		fmt.Printf("Error registering gifs plugin: %s\n", err.Error())
		return err
	}

	twitchFollows := []*twitch.TwitchFollow{
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "kitboga",
			WatchStream:   true,
		},
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "khryo72",
			SlackUser:     "morgabra",
			WatchStream:   true,
			WatchFollows:  true,
		},
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "mekilek",
			SlackUser:     "jirwin",
			WatchStream:   true,
			WatchFollows:  true,
		},
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "sonicdm",
			SlackUser:     "sonicdm",
			WatchStream:   true,
			WatchFollows:  true,
		},
		{
			SlackChannels: []string{"vidyagames"},
			TwitchUser:    "sakatana",
			SlackUser:     "saka",
			WatchStream:   true,
			WatchFollows:  true,
		},
	}

	twitchPlugin := twitch.Register(c.String("twitch-oauth-client-id"), "", "https://quadlek.jirw.in/slack/plugin/twitch", false, twitchFollows)
	if twitchPlugin != nil {
		err = bot.RegisterPlugin(twitchPlugin)
		if err != nil {
			fmt.Printf("error registering twitch plugin: %s\n", err.Error())
			return err
		}
	}

	err = bot.RegisterPlugin(slices.Register([]string {
		"1841289615922336", // sonicdm
		"76561197976367183", // morgabra
		"76561198057633471", // greenjeans
		"76561198002272597", // newsomr
		"76561197974723967", // purdyk
		//"76561197969022064", // schonstal?
	}))
	if err != nil {
		fmt.Printf("error registering slices plugin: %s\n", err.Error())
		return nil
	}

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, os.Interrupt)

	bot.Start()
	<-signals
	bot.Stop()

	return nil
}

func main() {
	app := cli.NewApp()
	app.Name = "quadlek"
	app.Version = Version
	app.Usage = "a slack bot"
	app.Action = run
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "api-key",
			Usage:  "The slack api token for the bot",
			EnvVar: "QUADLEK_API_TOKEN",
		},
		cli.StringFlag{
			Name:   "verification-token",
			Usage:  "The slack webhook verification token.",
			EnvVar: "QUADLEK_VERIFICATION_TOKEN",
		},
		cli.StringFlag{
			Name:   "db-path",
			Usage:  "The path where the database is stored.",
			Value:  "quadlek.db",
			EnvVar: "QUADLEK_DB_PATH",
		},
		cli.StringFlag{
			Name:   "tvdb-key",
			Usage:  "The TVDB api key for the bot, used by the nextep command",
			EnvVar: "QUADLEK_TVDB_TOKEN",
		},
		cli.StringFlag{
			Name:   "twitter-consumer-key",
			Usage:  "The consumer key for the twitter api",
			EnvVar: "QUADLEK_TWITTER_CONSUMER_KEY",
		},
		cli.StringFlag{
			Name:   "twitter-consumer-secret",
			Usage:  "The consumer secret for the twitter api",
			EnvVar: "QUADLEK_TWITTER_CONSUMER_SECRET",
		},
		cli.StringFlag{
			Name:   "twitter-access-token",
			Usage:  "The access key for the twitter api",
			EnvVar: "QUADLEK_TWITTER_ACCESS_TOKEN",
		},
		cli.StringFlag{
			Name:   "twitter-access-secret",
			Usage:  "The access secret for the twitter api",
			EnvVar: "QUADLEK_TWITTER_ACCESS_SECRET",
		},
		cli.StringFlag{
			Name:   "coinbase-key",
			Usage:  "The access key for the coinbase api",
			EnvVar: "QUADLEK_COINBASE_KEY",
		},
		cli.StringFlag{
			Name:   "coinbase-secret",
			Usage:  "The access secret for the coinbase api",
			EnvVar: "QUADLEK_COINBASE_SECRET",
		},
		cli.StringFlag{
			Name:   "coinbase-account",
			Usage:  "The bank account for the coinbase api",
			EnvVar: "QUADLEK_COINBASE_BANK_ACCOUNT",
		},
		cli.StringFlag{
			Name:   "imgur-client-id",
			Usage:  "The imgur client id",
			EnvVar: "QUADLEK_IMGUR_CLIENT_ID",
		},
		cli.StringFlag{
			Name:   "es-endpoint",
			Usage:  "The elastic search endpoint",
			EnvVar: "QUADLEK_ES_ENDPOINT",
		},
		cli.StringFlag{
			Name:   "es-index",
			Usage:  "The elastic search index",
			EnvVar: "QUADLEK_ES_INDEX",
		},
		cli.StringFlag{
			Name:   "av-key",
			Usage:  "Alpha Vantage Api Key",
			EnvVar: "QUADLEK_AV_KEY",
		},
		cli.StringFlag{
			Name:   "giphy-api-key",
			Usage:  "Giphy API Key",
			EnvVar: "QUADLEK_GIPHY_KEY",
		},
		cli.StringFlag{
			Name:   "twitch-oauth-client-id",
			Usage:  "OAuth application client id for twitch API",
			EnvVar: "QUADLEK_TWITCH_OAUTH_CLIENT_ID",
		},
	}

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


<commit_before>package main

import (
	"flag"
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"runtime"
	"time"

	"github.com/gorilla/mux"
	"github.com/sirupsen/logrus"
	"github.com/urfave/negroni"

	"github.com/ivan1993spb/snake-server/connections"
	"github.com/ivan1993spb/snake-server/handlers"
	"github.com/ivan1993spb/snake-server/middlewares"
)

const ServerName = "Snake-Server"

const (
	defaultAddress     = ":8080"
	defaultGroupsLimit = 100
	defaultConnsLimit  = 1000
)

var (
	Version = "dev"
	Build   = "dev"
	Author  = "Ivan Pushkin"
	License = "MIT"
)

var (
	address string

	flagEnableTLS bool
	certFile      string
	keyFile       string

	groupsLimit int
	connsLimit  int
	seed        int64

	flagJSONLog bool
	logLevel    string
)

func usage() {
	fmt.Fprint(os.Stderr, "Wellcome to snake-server!\n\n")
	fmt.Fprintf(os.Stderr, "Server version %s, build %s\n\n", Version, Build)
	fmt.Fprintf(os.Stderr, "Usage: %s [options]\n\n", os.Args[0])
	flag.PrintDefaults()
}

func init() {
	flag.StringVar(&address, "address", defaultAddress, "address to serve")
	flag.BoolVar(&flagEnableTLS, "tls-enable", false, "enable TLS")
	flag.StringVar(&certFile, "tls-cert", "", "path to certificate file")
	flag.StringVar(&keyFile, "tls-key", "", "path to key file")
	flag.IntVar(&groupsLimit, "groups-limit", defaultGroupsLimit, "groups limit")
	flag.IntVar(&connsLimit, "conns-limit", defaultConnsLimit, "web-socket connections limit")
	flag.Int64Var(&seed, "seed", time.Now().UnixNano(), "random seed")
	flag.BoolVar(&flagJSONLog, "log-json", false, "use json format for logger")
	flag.StringVar(&logLevel, "log-level", "info", "set log level: panic, fatal, error, warning (warn), info or debug")
	flag.Usage = usage
	flag.Parse()
}

func logger() *logrus.Logger {
	logger := logrus.New()
	if flagJSONLog {
		logger.Formatter = &logrus.JSONFormatter{}
	} else if runtime.GOOS == "windows" {
		// Log Output on Windows shows Bash format
		// See: https://gitlab.com/gitlab-org/gitlab-runner/issues/6
		// See: https://github.com/sirupsen/logrus/issues/172
		logger.Formatter = &logrus.TextFormatter{
			DisableColors: true,
		}
	}
	if level, err := logrus.ParseLevel(logLevel); err != nil {
		logger.SetLevel(logrus.InfoLevel)
	} else {
		logger.SetLevel(level)
	}
	return logger
}

func serve(h http.Handler) error {
	if flagEnableTLS {
		return http.ListenAndServeTLS(address, certFile, keyFile, h)
	}
	return http.ListenAndServe(address, h)
}

func main() {
	logger := logger()

	logger.WithFields(logrus.Fields{
		"author":  Author,
		"license": License,
		"version": Version,
		"build":   Build,
	}).Info("wellcome to snake server!")

	logger.WithFields(logrus.Fields{
		"conns_limit":  connsLimit,
		"groups_limit": groupsLimit,
		"seed":         seed,
		"log_level":    logLevel,
	}).Info("preparing to start server")

	rand.Seed(seed)

	groupManager, err := connections.NewConnectionGroupManager(logger, groupsLimit, connsLimit)
	if err != nil {
		logger.Fatalln("cannot create connections group manager:", err)
	}

	rootRouter := mux.NewRouter()

	// Web-Socket route
	rootRouter.Path(handlers.URLRouteGameWebSocketByID).Methods(handlers.MethodGame).Handler(handlers.NewGameWebSocketHandler(logger, groupManager))

	// API routes
	apiRouter := mux.NewRouter().StrictSlash(true)
	apiRouter.Path(handlers.URLRouteWellcome).Methods(handlers.MethodWellcome).Handler(handlers.NewWellcomeHandler(logger))
	apiRouter.Path(handlers.URLRouteGetInfo).Methods(handlers.MethodGetInfo).Handler(handlers.NewGetInfoHandler(logger, Author, License, Version, Build))
	apiRouter.Path(handlers.URLRouteGetCapacity).Methods(handlers.MethodGetCapacity).Handler(handlers.NewGetCapacityHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteCreateGame).Methods(handlers.MethodCreateGame).Handler(handlers.NewCreateGameHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteGetGameByID).Methods(handlers.MethodGetGame).Handler(handlers.NewGetGameHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteDeleteGameByID).Methods(handlers.MethodDeleteGame).Handler(handlers.NewDeleteGameHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteGetGames).Methods(handlers.MethodGetGames).Handler(handlers.NewGetGamesHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteBroadcast).Methods(handlers.MethodBroadcast).Handler(handlers.NewBroadcastHandler(logger, groupManager))
	// Use middlewares for API routes
	rootRouter.NewRoute().Handler(negroni.New(
		middlewares.NewRecovery(logger),
		middlewares.NewLogger(logger, "api"),
		middlewares.NewCORS(),
		negroni.Wrap(apiRouter),
	))

	n := negroni.New()
	n.Use(middlewares.NewServerInfo(ServerName, Version, Build))
	n.UseHandler(rootRouter)

	logger.WithFields(logrus.Fields{
		"address": address,
		"tls":     flagEnableTLS,
	}).Info("starting server")

	if err := serve(n); err != nil {
		logger.Fatalf("server error: %s", err)
	}
}
<commit_msg>Create logName const<commit_after>package main

import (
	"flag"
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"runtime"
	"time"

	"github.com/gorilla/mux"
	"github.com/sirupsen/logrus"
	"github.com/urfave/negroni"

	"github.com/ivan1993spb/snake-server/connections"
	"github.com/ivan1993spb/snake-server/handlers"
	"github.com/ivan1993spb/snake-server/middlewares"
)

const ServerName = "Snake-Server"

const (
	defaultAddress     = ":8080"
	defaultGroupsLimit = 100
	defaultConnsLimit  = 1000
)

var (
	Version = "dev"
	Build   = "dev"
	Author  = "Ivan Pushkin"
	License = "MIT"
)

var (
	address string

	flagEnableTLS bool
	certFile      string
	keyFile       string

	groupsLimit int
	connsLimit  int
	seed        int64

	flagJSONLog bool
	logLevel    string
)

const logName = "api"

func usage() {
	fmt.Fprint(os.Stderr, "Wellcome to snake-server!\n\n")
	fmt.Fprintf(os.Stderr, "Server version %s, build %s\n\n", Version, Build)
	fmt.Fprintf(os.Stderr, "Usage: %s [options]\n\n", os.Args[0])
	flag.PrintDefaults()
}

func init() {
	flag.StringVar(&address, "address", defaultAddress, "address to serve")
	flag.BoolVar(&flagEnableTLS, "tls-enable", false, "enable TLS")
	flag.StringVar(&certFile, "tls-cert", "", "path to certificate file")
	flag.StringVar(&keyFile, "tls-key", "", "path to key file")
	flag.IntVar(&groupsLimit, "groups-limit", defaultGroupsLimit, "groups limit")
	flag.IntVar(&connsLimit, "conns-limit", defaultConnsLimit, "web-socket connections limit")
	flag.Int64Var(&seed, "seed", time.Now().UnixNano(), "random seed")
	flag.BoolVar(&flagJSONLog, "log-json", false, "use json format for logger")
	flag.StringVar(&logLevel, "log-level", "info", "set log level: panic, fatal, error, warning (warn), info or debug")
	flag.Usage = usage
	flag.Parse()
}

func logger() *logrus.Logger {
	logger := logrus.New()
	if flagJSONLog {
		logger.Formatter = &logrus.JSONFormatter{}
	} else if runtime.GOOS == "windows" {
		// Log Output on Windows shows Bash format
		// See: https://gitlab.com/gitlab-org/gitlab-runner/issues/6
		// See: https://github.com/sirupsen/logrus/issues/172
		logger.Formatter = &logrus.TextFormatter{
			DisableColors: true,
		}
	}
	if level, err := logrus.ParseLevel(logLevel); err != nil {
		logger.SetLevel(logrus.InfoLevel)
	} else {
		logger.SetLevel(level)
	}
	return logger
}

func serve(h http.Handler) error {
	if flagEnableTLS {
		return http.ListenAndServeTLS(address, certFile, keyFile, h)
	}
	return http.ListenAndServe(address, h)
}

func main() {
	logger := logger()

	logger.WithFields(logrus.Fields{
		"author":  Author,
		"license": License,
		"version": Version,
		"build":   Build,
	}).Info("wellcome to snake server!")

	logger.WithFields(logrus.Fields{
		"conns_limit":  connsLimit,
		"groups_limit": groupsLimit,
		"seed":         seed,
		"log_level":    logLevel,
	}).Info("preparing to start server")

	rand.Seed(seed)

	groupManager, err := connections.NewConnectionGroupManager(logger, groupsLimit, connsLimit)
	if err != nil {
		logger.Fatalln("cannot create connections group manager:", err)
	}

	rootRouter := mux.NewRouter()

	// Web-Socket route
	rootRouter.Path(handlers.URLRouteGameWebSocketByID).Methods(handlers.MethodGame).Handler(handlers.NewGameWebSocketHandler(logger, groupManager))

	// API routes
	apiRouter := mux.NewRouter().StrictSlash(true)
	apiRouter.Path(handlers.URLRouteWellcome).Methods(handlers.MethodWellcome).Handler(handlers.NewWellcomeHandler(logger))
	apiRouter.Path(handlers.URLRouteGetInfo).Methods(handlers.MethodGetInfo).Handler(handlers.NewGetInfoHandler(logger, Author, License, Version, Build))
	apiRouter.Path(handlers.URLRouteGetCapacity).Methods(handlers.MethodGetCapacity).Handler(handlers.NewGetCapacityHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteCreateGame).Methods(handlers.MethodCreateGame).Handler(handlers.NewCreateGameHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteGetGameByID).Methods(handlers.MethodGetGame).Handler(handlers.NewGetGameHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteDeleteGameByID).Methods(handlers.MethodDeleteGame).Handler(handlers.NewDeleteGameHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteGetGames).Methods(handlers.MethodGetGames).Handler(handlers.NewGetGamesHandler(logger, groupManager))
	apiRouter.Path(handlers.URLRouteBroadcast).Methods(handlers.MethodBroadcast).Handler(handlers.NewBroadcastHandler(logger, groupManager))
	// Use middlewares for API routes
	rootRouter.NewRoute().Handler(negroni.New(
		middlewares.NewRecovery(logger),
		middlewares.NewLogger(logger, logName),
		middlewares.NewCORS(),
		negroni.Wrap(apiRouter),
	))

	n := negroni.New()
	n.Use(middlewares.NewServerInfo(ServerName, Version, Build))
	n.UseHandler(rootRouter)

	logger.WithFields(logrus.Fields{
		"address": address,
		"tls":     flagEnableTLS,
	}).Info("starting server")

	if err := serve(n); err != nil {
		logger.Fatalf("server error: %s", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strings"
	"github.com/ethragur/i3ipc-go"
	"database/sql"
	_ "github.com/mattn/go-sqlite3"
	"flag"
)

func main() {
	db, err := sql.Open("sqlite3", "./gorename.db")
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error could not create database: " + err.Error())
		return
	}
	defer db.Close()

	err = createWindowDB(db)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error could not create table: " + err.Error())
		return
	}

	insertPtr := flag.Bool("i", false, "Insert Icon Class Into DB")
	keyPtr	  := flag.String("class", "", "The Class of the Window")
	iconPtr  := flag.String("icon", "", "The Icon of the Window")

	flag.Parse()

	if *insertPtr {
		if *keyPtr != "" && *iconPtr != "" {
			err := insertIconPair(db, *keyPtr, *iconPtr)
			if err != nil {
				fmt.Fprintln(os.Stderr, "Error inserting Win/Icon pair: " + err.Error())
			} else {
				fmt.Println("Succesfully inserted Win/Icon pair: " + *keyPtr + " " + *iconPtr)
			}
		} else {
			fmt.Fprintln(os.Stderr, "Please enter Class and Icon with -class=... & -icon=...")
		}
		return
	}

	window_icons, err := getWindowIcons(db)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error could not read table: " + err.Error())
		return
	}

	i3ipc.StartEventListener()
	windowEvents, err := i3ipc.Subscribe(i3ipc.I3WindowEvent)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Could not subscribe to i3ipc: " + err.Error())
		return
	}

	ipcSocket, err := i3ipc.GetIPCSocket()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Cannot get i3ipc Socket: ", err)
		return
	}

	for {
		event := <-windowEvents

		if event.Change == "close" || event.Change == "new" || event.Change == "move" {
			tree, err := ipcSocket.GetTree()

			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				continue
			}
			//workspace, err := ipcSocket.GetWorkspaces();
			workspaces := GetWorkspaces(tree.Nodes...)
			for _, workspace := range workspaces {
				newWsName := fmt.Sprintf("%d", workspace.Num)

				for i , window := range GetWindows(workspace) {
					if i == 0 {
						newWsName += ": "
					}
					icon := window_icons[strings.ToLower(window.Window_Properties.Class)]
					if icon == "" {
						icon = "*"
					}
					newWsName += icon + "    "

				}
				ipcSocket.Command(fmt.Sprintf("rename workspace \"%s\" to \"%s\"", workspace.Name, newWsName))
			}
		}
	}
}

func GetWorkspaces(Nodes ...i3ipc.I3Node) (workspaces []i3ipc.I3Node) {
	if len(Nodes) == 0 {
		return
	}
	for _, Node := range Nodes {
		//get All of type workspace execpt the internal __i3_scratch space
		if Node.Type == "workspace" && Node.Num != -1 {
			workspaces = append(workspaces, Node)
		} else {
			workspaces = append(workspaces, GetWorkspaces(Node.Nodes...)...)
		}
	}
	return
}

func GetWindows(Nodes ...i3ipc.I3Node) (windows []i3ipc.I3Node) {
	if len(Nodes) == 0 {
		return
	}
	for _, Node := range Nodes {
		//get All of type workspace execpt the internal __i3_scratch space
		if (Node.Type == "con" || Node.Type == "floating_con") && Node.Window > 0 {
			windows = append(windows, Node)
		} else {
			windows = append(windows, GetWindows(Node.Nodes...)...)
		}
	}
	return
}

func createWindowDB(db *sql.DB) (err error) {
	//sqlStmt := "CREATE TABLE IF NOT EXISTS window_type(window_class TEXT, window_type TEXT);"
	//_, err = db.Exec(sqlStmt)
	//sqlStmt = "CREATE TABLE IF NOT EXISTS type_icon(window_type TEXT, window_icon TEXT);"
	//_, err = db.Exec(sqlStmt)
	sqlStmt := "CREATE TABLE IF NOT EXISTS window_db(window_class TEXT, window_icon TEXT);"
	_, err = db.Exec(sqlStmt)
	return err
}

func insertIconPair(db *sql.DB, class string, icon string) (err error) {
	sqlStmt := fmt.Sprintf("INSERT INTO window_db(window_class, window_icon) VALUES(\"%s\", \"%s\");", class, icon)
	_, err = db.Exec(sqlStmt)
	return err
}

func getWindowIcons(db *sql.DB) (window_infos map[string]string, err error) {
	window_infos = make(map[string]string)
	sqlStmt := "SELECT * FROM window_db;"
	rows, err := db.Query(sqlStmt)
	if err != nil {
		return window_infos, err
	}
	defer rows.Close()

	for rows.Next() {
		var winClass string
		var winIcon string
		err = rows.Scan(&winClass, &winIcon)
		if err != nil {
			return window_infos, err
		}
		window_infos[strings.ToLower(winClass)] = winIcon
	}
	return window_infos, rows.Err()
}

<commit_msg>Better home directory finding<commit_after>package main

import (
	"fmt"
	"os"
	"os/user"
	"strings"
	"github.com/ethragur/i3ipc-go"
	"database/sql"
	_ "github.com/mattn/go-sqlite3"
	"flag"
)

func main() {

	confDir, err := createConfigDir()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error could not get User Config Dir" + err.Error())
		return
	}

	db, err := sql.Open("sqlite3", confDir + "gorename.db")
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error could not create database: " + err.Error())
		return
	}
	defer db.Close()

	err = createWindowDB(db)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error could not create table: " + err.Error())
		return
	}

	insertPtr := flag.Bool("i", false, "Insert Icon Class Into DB")
	keyPtr	  := flag.String("class", "", "The Class of the Window")
	iconPtr  := flag.String("icon", "", "The Icon of the Window")

	flag.Parse()

	if *insertPtr {
		if *keyPtr != "" && *iconPtr != "" {
			err := insertIconPair(db, *keyPtr, *iconPtr)
			if err != nil {
				fmt.Fprintln(os.Stderr, "Error inserting Win/Icon pair: " + err.Error())
			} else {
				fmt.Println("Succesfully inserted Win/Icon pair: " + *keyPtr + " " + *iconPtr)
			}
		} else {
			fmt.Fprintln(os.Stderr, "Please enter Class and Icon with -class=... & -icon=...")
		}
		return
	}

	window_icons, err := getWindowIcons(db)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error could not read table: " + err.Error())
		return
	}

	i3ipc.StartEventListener()
	windowEvents, err := i3ipc.Subscribe(i3ipc.I3WindowEvent)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Could not subscribe to i3ipc: " + err.Error())
		return
	}

	ipcSocket, err := i3ipc.GetIPCSocket()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Cannot get i3ipc Socket: ", err)
		return
	}

	for {
		event := <-windowEvents

		if event.Change == "close" || event.Change == "new" || event.Change == "move" {
			tree, err := ipcSocket.GetTree()

			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				continue
			}
			//workspace, err := ipcSocket.GetWorkspaces();
			workspaces := GetWorkspaces(tree.Nodes...)
			for _, workspace := range workspaces {
				newWsName := fmt.Sprintf("%d", workspace.Num)

				for i , window := range GetWindows(workspace) {
					if i == 0 {
						newWsName += ": "
					}
					icon := window_icons[strings.ToLower(window.Window_Properties.Class)]
					if icon == "" {
						icon = ""
					}
					newWsName += icon + "    "

				}
				ipcSocket.Command(fmt.Sprintf("rename workspace \"%s\" to \"%s\"", workspace.Name, newWsName))
			}
		}
	}
}

func GetWorkspaces(Nodes ...i3ipc.I3Node) (workspaces []i3ipc.I3Node) {
	if len(Nodes) == 0 {
		return
	}
	for _, Node := range Nodes {
		//get All of type workspace execpt the internal __i3_scratch space
		if Node.Type == "workspace" && Node.Num != -1 {
			workspaces = append(workspaces, Node)
		} else {
			workspaces = append(workspaces, GetWorkspaces(Node.Nodes...)...)
		}
	}
	return
}

func GetWindows(Nodes ...i3ipc.I3Node) (windows []i3ipc.I3Node) {
	if len(Nodes) == 0 {
		return
	}
	for _, Node := range Nodes {
		//get All of type workspace execpt the internal __i3_scratch space
		if (Node.Type == "con" || Node.Type == "floating_con") && Node.Window > 0 {
			windows = append(windows, Node)
		} else {
			windows = append(windows, GetWindows(Node.Nodes...)...)
		}
	}
	return
}

func createWindowDB(db *sql.DB) (err error) {
	//sqlStmt := "CREATE TABLE IF NOT EXISTS window_type(window_class TEXT, window_type TEXT);"
	//_, err = db.Exec(sqlStmt)
	//sqlStmt = "CREATE TABLE IF NOT EXISTS type_icon(window_type TEXT, window_icon TEXT);"
	//_, err = db.Exec(sqlStmt)
	sqlStmt := "CREATE TABLE IF NOT EXISTS window_db(window_class TEXT, window_icon TEXT);"
	_, err = db.Exec(sqlStmt)
	return err
}

func insertIconPair(db *sql.DB, class string, icon string) (err error) {
	sqlStmt := fmt.Sprintf("INSERT INTO window_db(window_class, window_icon) VALUES(\"%s\", \"%s\");", class, icon)
	_, err = db.Exec(sqlStmt)
	return err
}

func getWindowIcons(db *sql.DB) (window_infos map[string]string, err error) {
	window_infos = make(map[string]string)
	sqlStmt := "SELECT * FROM window_db;"
	rows, err := db.Query(sqlStmt)
	if err != nil {
		return window_infos, err
	}
	defer rows.Close()

	for rows.Next() {
		var winClass string
		var winIcon string
		err = rows.Scan(&winClass, &winIcon)
		if err != nil {
			return window_infos, err
		}
		window_infos[strings.ToLower(winClass)] = winIcon
	}
	return window_infos, rows.Err()
}

func createConfigDir() (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", err
	}
	db_dir := usr.HomeDir + "/.config/i3-autorename/"
	os.MkdirAll(db_dir, 0700)
	return db_dir, nil
}

<|endoftext|>


<commit_before>package main

import (
	html "code.google.com/p/go.net/html"
	atom "code.google.com/p/go.net/html/atom"
	"github.com/PuerkitoBio/goquery"
	log "github.com/cihub/seelog"
)

func main() {

	// Flush logs before exit
	defer log.Flush()

	// Crawl the specified site
	Crawl("http://golang.org/")
}

// Crawl takes a URL and recursively crawls pages
func Crawl(url string) {

	_, urls, err := fetch(url)
	if err != nil {
		log.Errorf("Error:", err)
		return
	}

	log.Infof("URLs found: %+v", urls)
}

// fetch retrieves the page at the specified URL and extracts URLs
func fetch(url string) (string, []string, error) {

	doc, err := goquery.NewDocument(url)
	if err != nil {
		return "", nil, err
	}

	urls, err := extractLinks(doc)
	if err != nil {
		return "", urls, err
	}

	log.Debugf("URLs: %+v", urls)

	return "", urls, nil
}

// extractLinks from a document
func extractLinks(doc *goquery.Document) ([]string, error) {

	// Blank slice to hold our links on this page
	urls := make([]string, 0)

	// Extract all 'a' elements from the document
	sel := doc.Find("a")
	if sel == nil {
		// Assume zero links on failure
		return nil, nil
	}

	// Range over links, and add them to our list if valid
	for i, n := range sel.Nodes {
		if n.Type != html.ElementNode || n.DataAtom != atom.A {
			log.Debugf("Node is not an anchor: %v", n.Type)
			continue
		}

		var href string

		for _, a := range n.Attr {
			if a.Key != "href" {
				continue
			}
			href = a.Val
		}

		if href == "" {
			continue
		}

		log.Debugf("Node %v: %s", i, href)
		urls = append(urls, href)
	}

	return urls, nil
}
<commit_msg>Refactor link node validation<commit_after>package main

import (
	"errors"

	html "code.google.com/p/go.net/html"
	atom "code.google.com/p/go.net/html/atom"
	"github.com/PuerkitoBio/goquery"
	log "github.com/cihub/seelog"
)

func main() {

	// Flush logs before exit
	defer log.Flush()

	// Crawl the specified site
	Crawl("http://golang.org/")
}

// Crawl takes a URL and recursively crawls pages
func Crawl(url string) {

	_, urls, err := fetch(url)
	if err != nil {
		log.Errorf("Error:", err)
		return
	}

	log.Infof("URLs found: %+v", urls)
}

// fetch retrieves the page at the specified URL and extracts URLs
func fetch(url string) (string, []string, error) {

	doc, err := goquery.NewDocument(url)
	if err != nil {
		return "", nil, err
	}

	urls, err := extractLinks(doc)
	if err != nil {
		return "", urls, err
	}

	log.Debugf("URLs: %+v", urls)

	return "", urls, nil
}

// extractLinks from a document
func extractLinks(doc *goquery.Document) ([]string, error) {

	// Blank slice to hold our links on this page
	urls := make([]string, 0)

	// Extract all 'a' elements from the document
	sel := doc.Find("a")
	if sel == nil {
		// Assume zero links on failure
		return nil, nil
	}

	// Range over links, and add them to our list if valid
	for i, n := range sel.Nodes {
		href, err := validateLink(n)
		if err != nil || href == "" {
			continue
		}

		log.Debugf("Node %v: %s", i, href)
		urls = append(urls, href)
	}

	return urls, nil
}

func validateLink(n *html.Node) (string, error) {
	var href string

	// Confirm this node is an anchor element
	if n == nil || n.Type != html.ElementNode || n.DataAtom != atom.A {
		return href, errors.New("Node is not an anchor")
	}

	// Return the value of the href attr if it exists
	for _, a := range n.Attr {
		if a.Key == "href" && a.Val != "" {
			return a.Val, nil
		}
	}

	return "", errors.New("Anchor does not contain a href attribute")
}
<|endoftext|>


<commit_before>package main

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

// @author Robin Verlangen
// Indispenso: Distribute, manage, regulate, arrange. Simple & secure management based on consensus.

var conf *Conf
var isServer bool
var serverPort int
var isClient bool
var clientPort int
var seedUri string
var server *Server
var client *Client
var log *Log
var hostname string
var debug bool
var shutdown chan bool = make(chan bool)

func main() {
	// Log
	log = newLog()

	// Conf
	conf = newConf()

	// Read flags
	flag.BoolVar(&isServer, "server", false, "Should this run the server process")
	flag.BoolVar(&debug, "debug", false, "Enable debug logging")
	flag.StringVar(&seedUri, "seed", "", "Seed URI")
	flag.IntVar(&serverPort, "server-port", 897, "Server port")
	flag.IntVar(&clientPort, "client-port", 898, "Client port")
	flag.Parse()

	// Hostname
	hostname, _ = os.Hostname()

	// Server
	if isServer {
		server = newServer()
		server.Start()

		// Empty seed? Then go for local
		if len(seedUri) < 1 {
			seedUri = fmt.Sprintf("http://127.0.0.1:%d/", serverPort)
		}
	}

	// Client
	isClient = len(seedUri) > 0
	if isClient {
		client = newClient()
		client.Start()
	}

	// Wait for shutdown
	<- shutdown
}<commit_msg>Secure token<commit_after>package main

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

// @author Robin Verlangen
// Indispenso: Distribute, manage, regulate, arrange. Simple & secure management based on consensus.

var conf *Conf
var isServer bool
var serverPort int
var isClient bool
var clientPort int
var seedUri string
var server *Server
var client *Client
var log *Log
var hostname string
var debug bool
var secureToken string
var shutdown chan bool = make(chan bool)

func main() {
	// Log
	log = newLog()

	// Conf
	conf = newConf()

	// Read flags
	flag.BoolVar(&isServer, "server", false, "Should this run the server process")
	flag.BoolVar(&debug, "debug", false, "Enable debug logging")
	flag.StringVar(&seedUri, "seed", "", "Seed URI")
	flag.StringVar(&secureToken, "secure-token", "", "Secure token")
	flag.IntVar(&serverPort, "server-port", 897, "Server port")
	flag.IntVar(&clientPort, "client-port", 898, "Client port")
	flag.Parse()

	// Must have token
	minLen := 32
	if len(strings.TrimSpace(secureToken)) < minLen {
		log.Fatal(fmt.Sprintf("Must have secure token with minimum length of %d", minLen))
	}

	// Hostname
	hostname, _ = os.Hostname()

	// Server
	if isServer {
		server = newServer()
		server.Start()

		// Empty seed? Then go for local
		if len(seedUri) < 1 {
			seedUri = fmt.Sprintf("http://127.0.0.1:%d/", serverPort)
		}
	}

	// Client
	isClient = len(seedUri) > 0
	if isClient {
		client = newClient()
		client.Start()
	}

	// Wait for shutdown
	<- shutdown
}<|endoftext|>


<commit_before>// Copyright 2015 Stuart Glenn, OMRF. All rights reserved.
// Use of this code is governed by a 3 clause BSD style license
// Full license details in LICENSE file distributed with this software

package main

import (
	"github.com/oklasoft/mmatcher/matcher"
	"log"
	"os"
)

func main() {
	case_file, err := os.Open(os.Args[1])
	if nil != err {
		log.Fatal(err)
	}
	defer case_file.Close()

	cases, err := matcher.NewRecordsFromCSV(case_file, 2)
	log.Print("Read cases:", cases)

	control_file, err := os.Open(os.Args[2])
	if nil != err {
		log.Fatal(err)
	}
	defer control_file.Close()

	controls, err := matcher.NewRecordsFromCSV(control_file, 2)
	log.Print("Read controls:", controls)

	all_matches := matcher.NewMatchSet()

	positions := []int{0, 1, 2}
	ranges := []matcher.Atter{matcher.TextAtt{}, matcher.TextAtt{}, matcher.NumericAtt{5}}

	for _, r := range cases {
		spots := r.Matches(controls, positions, ranges...)
		for _, i := range spots {
			all_matches.AddPair(matcher.NewPair(r.ID, controls[i].ID))
		}
	}

	log.Print("First pass lookikng for matches found:", all_matches)

	opti := all_matches.QuantityOptimized()

	log.Print("After optimizing we got:", opti)

}
<commit_msg>Add basic CSV stdout in our starter/test main<commit_after>// Copyright 2015 Stuart Glenn, OMRF. All rights reserved.
// Use of this code is governed by a 3 clause BSD style license
// Full license details in LICENSE file distributed with this software

package main

import (
	"encoding/csv"
	"log"
	"os"

	"github.com/oklasoft/mmatcher/matcher"
)

func main() {
	case_file, err := os.Open(os.Args[1])
	if nil != err {
		log.Fatal(err)
	}
	defer case_file.Close()

	cases, err := matcher.NewRecordsFromCSV(case_file, 2)
	log.Print("Read cases:", cases)

	control_file, err := os.Open(os.Args[2])
	if nil != err {
		log.Fatal(err)
	}
	defer control_file.Close()

	controls, err := matcher.NewRecordsFromCSV(control_file, 2)
	log.Print("Read controls:", controls)

	all_matches := matcher.NewMatchSet()

	positions := []int{0, 1, 2}
	ranges := []matcher.Atter{matcher.TextAtt{}, matcher.TextAtt{}, matcher.NumericAtt{5}}

	for _, r := range cases {
		spots := r.Matches(controls, positions, ranges...)
		for _, i := range spots {
			all_matches.AddPair(matcher.NewPair(r.ID, controls[i].ID))
		}
	}

	log.Print("First pass lookikng for matches found:", all_matches)

	opti := all_matches.QuantityOptimized()

	log.Print("After optimizing we got:", opti)

	out := csv.NewWriter(os.Stdout)
	out.Write([]string{"case", "control"})

	for _, r := range cases {
		m := opti.MatchesFor(r.ID)
		if 0 == len(m) {
			continue
		}
		out.Write([]string{r.ID, m[0]})
	}
	out.Flush()

}
<|endoftext|>


<commit_before>package main

import (
	"./core"
	"fmt"
	opt "github.com/docopt/docopt-go"
	"regexp"
	"strconv"
	"strings"
)

func usage() string {
	return `

Usage:
    scan --ip <ip> [--port <port>][--timeout <timeout>]
    scan --ip-range <range> [--port <port>][--timeout <timeout>]

Options:
  -h --help             Show help
  --version             Show version
  --ip <ip>             Will scan ip
  --ip-range <range>    Will scan ip in ip range
  --port <port>         scan port
  --timeout <timeout>   timeout, default 1s
    `
}

func getPort(s string) []int {
	sep := ","
	if strings.Index(s, sep) == -1 {
		result, _ := strconv.Atoi(s)
		return []int{result}
	}
	splits := strings.Split(s, sep)
	ret := []int{}
	for _, ss := range splits {
		result, _ := strconv.Atoi(ss)
		ret = append(ret, result)
	}
	return ret
}

func getAllIp(ipRange string) []string {
	ips := []string{}
	p := strings.Index(ipRange, "-")
	if p < 0 {
		ips = append(ips, ipRange)
	} else {
		reg := regexp.MustCompile("(\\d+\\.\\d+\\.\\d+\\.)(\\d+)-(\\d+)")
		m := reg.FindStringSubmatch(ipRange)
		if len(m) > 0 {
			prefix := m[1]
			start, err := strconv.Atoi(m[2])
			if err != nil {
				panic(err)
			}
			end, err := strconv.Atoi(m[3])
			if err != nil {
				panic(err)
			}

			if start >= end {
				panic("error")
			}

			for v := start; v <= end; v++ {
				ips = append(ips, prefix+strconv.Itoa(v))
			}
		}
	}
	return ips
}

func run(id int, ip string, ports []int, reports *[]core.Report, timeout string) {
	task := core.NewTask(id, ip, ports, false)
	worker := core.NewWorker(1, &task, reports, timeout)
	worker.ScanHttp()
}

func main() {

	arguments, err := opt.Parse(usage(), nil, true, "2.0", false)

	if err != nil {
		panic(err)
	}

	ports := []int{80}
	if arguments["--port"] != nil {
		ports = getPort(arguments["--port"].(string))
	}

	timeout := "1s"
	if arguments["--timeout"] != nil {
		timeout = arguments["--timeout"].(string)
	}

	reports := []core.Report{}
	if arguments["--ip"] == nil {
		//ip range
		ipRange := arguments["--ip-range"].(string)
		ips := getAllIp(ipRange)
		fmt.Println(ips)
		howManyIp := len(ips)
		wait := make(chan (bool))
		for idx, ip := range ips {
			go func(idx int, ip string) {
				run(idx, ip, ports, &reports, timeout)
				wait <- true
			}(idx, ip)
		}
		//wait all child task done.
		for i := 0; i < howManyIp; i++ {
			<-wait
		}

	} else {
		//ip
		run(0, arguments["--ip"].(string), ports, &reports, timeout)
	}

	for _, r := range reports {
		r.Dump()
	}

	fmt.Println("done")
}
<commit_msg>rework<commit_after>package main

import (
	"./core"
	"fmt"
	opt "github.com/docopt/docopt-go"
	"regexp"
	"strconv"
	"strings"
)

func usage() string {
	return `

Usage:
    scan --ip <ip> [--port <port>][--timeout <timeout>]
    scan --ip-range <range> [--port <port>][--timeout <timeout>]

Options:
  -h --help             Show help
  --version             Show version
  --ip <ip>             Will scan ip
  --ip-range <range>    Will scan ip-range
  --port <port>         port
  --timeout <timeout>   timeout, default 1s
    `
}

func getPort(s string) []int {
	sep := ","
	if strings.Index(s, sep) == -1 {
		result, _ := strconv.Atoi(s)
		return []int{result}
	}
	splits := strings.Split(s, sep)
	ret := []int{}
	for _, ss := range splits {
		result, _ := strconv.Atoi(ss)
		ret = append(ret, result)
	}
	return ret
}

func getAllIp(ipRange string) []string {
	ips := []string{}
	p := strings.Index(ipRange, "-")
	if p < 0 {
		ips = append(ips, ipRange)
	} else {
		reg := regexp.MustCompile("(\\d+\\.\\d+\\.\\d+\\.)(\\d+)-(\\d+)")
		m := reg.FindStringSubmatch(ipRange)
		if len(m) > 0 {
			prefix := m[1]
			start, err := strconv.Atoi(m[2])
			if err != nil {
				panic(err)
			}
			end, err := strconv.Atoi(m[3])
			if err != nil {
				panic(err)
			}

			if start >= end {
				panic("error")
			}

			for v := start; v <= end; v++ {
				ips = append(ips, prefix+strconv.Itoa(v))
			}
		}
	}
	return ips
}

func run(id int, ip string, ports []int, reports *[]core.Report, timeout string) {
	task := core.NewTask(id, ip, ports, false)
	worker := core.NewWorker(1, &task, reports, timeout)
	worker.ScanHttp()
}

func main() {

	arguments, err := opt.Parse(usage(), nil, true, "2.0", false)

	if err != nil {
		panic(err)
	}

	ports := []int{80}
	if arguments["--port"] != nil {
		ports = getPort(arguments["--port"].(string))
	}

	timeout := "1s"
	if arguments["--timeout"] != nil {
		timeout = arguments["--timeout"].(string)
	}

	reports := []core.Report{}
	if arguments["--ip"] == nil {
		//ip range
		ipRange := arguments["--ip-range"].(string)
		ips := getAllIp(ipRange)
		fmt.Println(ips)
		howManyIp := len(ips)
		wait := make(chan (bool))
		for idx, ip := range ips {
			go func(idx int, ip string) {
				run(idx, ip, ports, &reports, timeout)
				wait <- true
			}(idx, ip)
		}
		//wait all child task done.
		for i := 0; i < howManyIp; i++ {
			<-wait
		}

	} else {
		//ip
		run(0, arguments["--ip"].(string), ports, &reports, timeout)
	}

	for _, r := range reports {
		r.Dump()
	}

	fmt.Println("done")
}
<|endoftext|>