<commit_before>package server

import (
	log "github.com/Sirupsen/logrus"
	"github.com/casey-chow/tigertrade/server/models"
	"github.com/getsentry/raven-go"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"strconv"
	"time"
)

// ReadListings performs a customizable request defined by r for a collection of listings, and writes them to w
func ReadListings(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	query := models.NewListingQuery()

	// Get limit from params
	if limit, err := strconv.ParseUint(r.URL.Query().Get("limit"), 10, 64); err == nil && limit != 0 {
		query.Limit = limit
	}

	query.OnlyStarred, _ = strconv.ParseBool(r.URL.Query().Get("isStarred"))
	query.OnlyMine, _ = strconv.ParseBool(r.URL.Query().Get("isMine"))

	if offset, err := strconv.ParseUint(r.URL.Query().Get("offset"), 10, 64); err == nil {
		query.Offset = offset
	}

	// Get User ID if we happen to be logged in
	if user, err := models.GetUser(db, getUsername(r)); err == nil {
		query.UserID = user.KeyID
	}

	// Get optional search query from params
	query.Query = r.URL.Query().Get("query")

	// Get optional price filter limits
	if minPrice, err := strconv.Atoi(r.URL.Query().Get("minPrice")); err == nil {
		query.MinPrice = minPrice
	}
	if maxPrice, err := strconv.Atoi(r.URL.Query().Get("maxPrice")); err == nil {
		query.MaxPrice = maxPrice
	}

	// Get optional expiration date filter limits
	iso := "Mon Jan 2 15:04:05 -0700 MST 2006"
	if minExpDate, err := time.Parse(iso, r.URL.Query().Get("minExpDate")); err == nil {
		query.MinExpDate = minExpDate
	}
	if maxExpDate, err := time.Parse(iso, r.URL.Query().Get("maxExpDate")); err == nil {
		query.MaxExpDate = maxExpDate
	}

	// Get optional creation date filter limits
	if minCreateDate, err := time.Parse(iso, r.URL.Query().Get("minCreateDate")); err == nil {
		query.MinCreateDate = minCreateDate
	}
	if maxCreateDate, err := time.Parse(iso, r.URL.Query().Get("maxCreateDate")); err == nil {
		query.MaxCreateDate = maxCreateDate
	}

	listings, code, err := models.ReadListings(db, query)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while reading recent or queried listings")
		Error(w, code)
		return
	}

	Serve(w, listings)
}

// ReadListing writes a listing identified in r to w
func ReadListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Get ID from params
	id := ps.ByName("id")
	if id == "" {
		Error(w, http.StatusBadRequest)
		return
	}

	listings, code, err := models.ReadListing(db, id)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while getting listing by ID")
		Error(w, code)
		return
	}

	Serve(w, listings)
}

// CreateListing creates a new listing based on the contents of r, owned by the current user,
// and then writes it to w with its keyId set
func CreateListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Get listing to add from request body
	listing := models.Listing{}
	err := ParseJSONFromBody(r, &listing)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while parsing JSON file")
		Error(w, http.StatusUnprocessableEntity)
		return
	}

	// Retrieve UserID
	user, err := models.GetUser(db, getUsername(r))
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while authenticating user: not authorized")
		Error(w, http.StatusUnauthorized)
		return
	}

	listing, code, err := models.CreateListing(db, listing, user.KeyID)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while adding new listing")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusCreated)
	Serve(w, listing)
}

// UpdateListing updates the requested listing if it is owned by the current user
func UpdateListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Get ID from params
	id := ps.ByName("id")
	if id == "" {
		Error(w, http.StatusBadRequest)
		return
	}

	// Get listing to add from request body
	listing := models.Listing{}
	err := ParseJSONFromBody(r, &listing)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while parsing JSON file")
		Error(w, http.StatusUnprocessableEntity)
		return
	}

	// Retrieve UserID
	user, err := models.GetUser(db, getUsername(r))
	if err != nil { // Not authorized
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while authenticating user: not authorized")
		Error(w, http.StatusUnauthorized)
		return
	}

	if code, err := models.UpdateListing(db, id, listing, user.KeyID); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while updating listing by ID")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}

// DeleteListing deletes the requested listing if it is owned by the current user
func DeleteListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Get ID from params
	id := ps.ByName("id")
	if id == "" {
		Error(w, http.StatusBadRequest)
		return
	}

	// Retrieve UserID
	user, err := models.GetUser(db, getUsername(r))
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while authenticating user: not authorized")
		Error(w, http.StatusUnauthorized)
		return
	}

	if code, err := models.DeleteListing(db, id, user.KeyID); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while deleting listing by ID")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}

// UpdateListingStar adds or removes a star to a listing for the current user
func UpdateListingStar(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {

	// Get ID from params
	id := ps.ByName("id")
	if id == "" {
		Error(w, http.StatusBadRequest)
		return
	}

	// Get isStarred status to change
	input := models.IsStarred{}
	err := ParseJSONFromBody(r, &input)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while parsing JSON")
		Error(w, http.StatusUnprocessableEntity)
		return
	}

	// Retrieve UserID
	user, err := models.GetUser(db, getUsername(r))
	if err != nil { // Not authorized
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while authenticating user: not authorized")
		Error(w, http.StatusUnauthorized)
		return
	}

	// Update Listing data
	if code, err := models.SetStar(db, input.IsStarred, id, user.KeyID); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while removing star from listing")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}
<commit_msg>Only check for User ID when necessary.<commit_after>package server

import (
	log "github.com/Sirupsen/logrus"
	"github.com/casey-chow/tigertrade/server/models"
	"github.com/getsentry/raven-go"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"strconv"
	"time"
)

// ReadListings performs a customizable request defined by r for a collection of listings, and writes them to w
func ReadListings(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	query := models.NewListingQuery()

	// Get limit from params
	if limit, err := strconv.ParseUint(r.URL.Query().Get("limit"), 10, 64); err == nil && limit != 0 {
		query.Limit = limit
	}

	query.OnlyStarred, _ = strconv.ParseBool(r.URL.Query().Get("isStarred"))
	query.OnlyMine, _ = strconv.ParseBool(r.URL.Query().Get("isMine"))

	if offset, err := strconv.ParseUint(r.URL.Query().Get("offset"), 10, 64); err == nil {
		query.Offset = offset
	}

	// Get User ID if we happen to be logged in (if necessary)
	// getUsername makes a network call every time to see if the user is
	// still authenticated with CAS, so it should only be used when necessary.
	if query.OnlyMine {
		if user, err := models.GetUser(db, getUsername(r)); err == nil {
			query.UserID = user.KeyID
		}
	}

	// Get optional search query from params
	query.Query = r.URL.Query().Get("query")

	// Get optional price filter limits
	if minPrice, err := strconv.Atoi(r.URL.Query().Get("minPrice")); err == nil {
		query.MinPrice = minPrice
	}
	if maxPrice, err := strconv.Atoi(r.URL.Query().Get("maxPrice")); err == nil {
		query.MaxPrice = maxPrice
	}

	// Get optional expiration date filter limits
	iso := "Mon Jan 2 15:04:05 -0700 MST 2006"
	if minExpDate, err := time.Parse(iso, r.URL.Query().Get("minExpDate")); err == nil {
		query.MinExpDate = minExpDate
	}
	if maxExpDate, err := time.Parse(iso, r.URL.Query().Get("maxExpDate")); err == nil {
		query.MaxExpDate = maxExpDate
	}

	// Get optional creation date filter limits
	if minCreateDate, err := time.Parse(iso, r.URL.Query().Get("minCreateDate")); err == nil {
		query.MinCreateDate = minCreateDate
	}
	if maxCreateDate, err := time.Parse(iso, r.URL.Query().Get("maxCreateDate")); err == nil {
		query.MaxCreateDate = maxCreateDate
	}

	listings, code, err := models.ReadListings(db, query)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while reading recent or queried listings")
		Error(w, code)
		return
	}

	Serve(w, listings)
}

// ReadListing writes a listing identified in r to w
func ReadListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Get ID from params
	id := ps.ByName("id")
	if id == "" {
		Error(w, http.StatusBadRequest)
		return
	}

	listings, code, err := models.ReadListing(db, id)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while getting listing by ID")
		Error(w, code)
		return
	}

	Serve(w, listings)
}

// CreateListing creates a new listing based on the contents of r, owned by the current user,
// and then writes it to w with its keyId set
func CreateListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Get listing to add from request body
	listing := models.Listing{}
	err := ParseJSONFromBody(r, &listing)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while parsing JSON file")
		Error(w, http.StatusUnprocessableEntity)
		return
	}

	// Retrieve UserID
	user, err := models.GetUser(db, getUsername(r))
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while authenticating user: not authorized")
		Error(w, http.StatusUnauthorized)
		return
	}

	listing, code, err := models.CreateListing(db, listing, user.KeyID)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while adding new listing")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusCreated)
	Serve(w, listing)
}

// UpdateListing updates the requested listing if it is owned by the current user
func UpdateListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Get ID from params
	id := ps.ByName("id")
	if id == "" {
		Error(w, http.StatusBadRequest)
		return
	}

	// Get listing to add from request body
	listing := models.Listing{}
	err := ParseJSONFromBody(r, &listing)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while parsing JSON file")
		Error(w, http.StatusUnprocessableEntity)
		return
	}

	// Retrieve UserID
	user, err := models.GetUser(db, getUsername(r))
	if err != nil { // Not authorized
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while authenticating user: not authorized")
		Error(w, http.StatusUnauthorized)
		return
	}

	if code, err := models.UpdateListing(db, id, listing, user.KeyID); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while updating listing by ID")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}

// DeleteListing deletes the requested listing if it is owned by the current user
func DeleteListing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Get ID from params
	id := ps.ByName("id")
	if id == "" {
		Error(w, http.StatusBadRequest)
		return
	}

	// Retrieve UserID
	user, err := models.GetUser(db, getUsername(r))
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while authenticating user: not authorized")
		Error(w, http.StatusUnauthorized)
		return
	}

	if code, err := models.DeleteListing(db, id, user.KeyID); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while deleting listing by ID")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}

// UpdateListingStar adds or removes a star to a listing for the current user
func UpdateListingStar(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {

	// Get ID from params
	id := ps.ByName("id")
	if id == "" {
		Error(w, http.StatusBadRequest)
		return
	}

	// Get isStarred status to change
	input := models.IsStarred{}
	err := ParseJSONFromBody(r, &input)
	if err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while parsing JSON")
		Error(w, http.StatusUnprocessableEntity)
		return
	}

	// Retrieve UserID
	user, err := models.GetUser(db, getUsername(r))
	if err != nil { // Not authorized
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while authenticating user: not authorized")
		Error(w, http.StatusUnauthorized)
		return
	}

	// Update Listing data
	if code, err := models.SetStar(db, input.IsStarred, id, user.KeyID); err != nil {
		raven.CaptureError(err, nil)
		log.WithError(err).Error("error while removing star from listing")
		Error(w, code)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}
<|endoftext|>


<commit_before>package main

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

func main() {
	var help = false
	var configFile = ".config"
	var debug string
	var verbose bool
	var verboseTooltip = "Enable the debug mode"
	flag.BoolVar(&help, "help", false, "Display Help")

	flag.BoolVar(&verbose, "verbose", false, verboseTooltip)
	flag.BoolVar(&verbose, "v", false, verboseTooltip)

	flag.StringVar(&configFile, "config", ".config", "Configuration file to use")
	flag.StringVar(&debug, "debug", "", "Use the debug mode")
	flag.StringVar(&debug, "d", "", "Use the debug mode")

	var picasa string
	flag.StringVar(&picasa, "picasa", "", "Use picasa as destination")
	flag.StringVar(&picasa, "p", "", "Use picasa as destination")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, "Mandatory argument:\n  sync_folder\n")
	}
	flag.Parse()
	if 1 != flag.NArg() {
		flag.Usage()
		os.Exit(0)
	}

	var local_folder = flag.Arg(0)

	if help {
		flag.Usage()
		os.Exit(0)
	}

	var syncPlugin SyncPlugin

	var err error
	if debug != "" {
		syncPlugin, err = NewDebugSyncPlugin(debug)
	} else if picasa != "" {
		syncPlugin, err = NewPicasaSyncPlugin(picasa)
	}
	if nil != err {
		fmt.Println("Failed to instantiate plugin with error ", err)
		os.Exit(1)
	}

	var debugIO io.Writer
	if verbose {
		debugIO = os.Stdout
	} else {
		debugIO = ioutil.Discard
	}

	LogInit(debugIO, os.Stdout, os.Stdout, os.Stderr)

	var syncer = NewSyncer(local_folder)
	syncer.Sync(syncPlugin)

}
<commit_msg>Remove config argument the config is per plugin<commit_after>package main

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

func main() {
	var help = false
	var debug string
	var verbose bool
	var verboseTooltip = "Enable the debug mode"
	flag.BoolVar(&help, "help", false, "Display Help")

	flag.BoolVar(&verbose, "verbose", false, verboseTooltip)
	flag.BoolVar(&verbose, "v", false, verboseTooltip)

	flag.StringVar(&debug, "debug", "", "Use the debug mode")
	flag.StringVar(&debug, "d", "", "Use the debug mode")

	var picasa string
	flag.StringVar(&picasa, "picasa", "", "picasa plugin configuration path")
	flag.StringVar(&picasa, "p", "", "Use picasa as destination")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, "Mandatory argument:\n  sync_folder\n")
	}
	flag.Parse()
	if 1 != flag.NArg() {
		flag.Usage()
		os.Exit(0)
	}

	var local_folder = flag.Arg(0)

	if help {
		flag.Usage()
		os.Exit(0)
	}

	var syncPlugin SyncPlugin

	var err error
	if debug != "" {
		syncPlugin, err = NewDebugSyncPlugin(debug)
	} else if picasa != "" {
		syncPlugin, err = NewPicasaSyncPlugin(picasa)
	} else {
		fmt.Println("What you didn't provide any backend")
		os.Exit(1)
	}
	if nil != err {
		fmt.Println("Failed to instantiate plugin with error ", err)
		os.Exit(1)
	}

	var debugIO io.Writer
	if verbose {
		debugIO = os.Stdout
	} else {
		debugIO = ioutil.Discard
	}

	LogInit(debugIO, os.Stdout, os.Stdout, os.Stderr)

	var syncer = NewSyncer(local_folder)
	syncer.Sync(syncPlugin)

}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"

	"github.com/goreleaser/goreleaser/config"
	"github.com/goreleaser/goreleaser/context"
	"github.com/goreleaser/goreleaser/pipeline"
	"github.com/goreleaser/goreleaser/pipeline/archive"
	"github.com/goreleaser/goreleaser/pipeline/brew"
	"github.com/goreleaser/goreleaser/pipeline/build"
	"github.com/goreleaser/goreleaser/pipeline/defaults"
	"github.com/goreleaser/goreleaser/pipeline/env"
	"github.com/goreleaser/goreleaser/pipeline/fpm"
	"github.com/goreleaser/goreleaser/pipeline/git"
	"github.com/goreleaser/goreleaser/pipeline/release"
	"github.com/goreleaser/goreleaser/pipeline/source"
	"github.com/urfave/cli"
)

var (
	version = "dev"
	commit  = "none"
	date    = "unknown"
)

func main() {
	var app = cli.NewApp()
	app.Name = "goreleaser"
	app.Version = version + ", commit: " + commit + ", built at " + date
	app.Usage = "Deliver Go binaries as fast and easily as possible"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "config, c",
			Usage: "Load configuration from `FILE`",
			Value: "goreleaser.yml",
		},
		cli.BoolFlag{
			Name:  "build-only, skip-release, no-release, nr",
			Usage: "Skip all the release processes and run only the build and packaging steps",
		},
	}
	app.Action = func(c *cli.Context) (err error) {
		var file = c.String("config")
		cfg, err := config.Load(file)
		// Allow failing to load the config file if file is not explicitly specified
		if err != nil && c.IsSet("config") {
			return cli.NewExitError(err.Error(), 1)
		}
		ctx := context.New(cfg)
		log.SetFlags(0)
		for _, pipe := range pipes(c.Bool("build-only")) {
			log.Println(pipe.Description())
			log.SetPrefix(" -> ")
			if err := pipe.Run(ctx); err != nil {
				return cli.NewExitError(err.Error(), 1)
			}
			log.SetPrefix("")
		}
		log.Println("Done!")
		return
	}
	if err := app.Run(os.Args); err != nil {
		log.Fatalln(err)
	}
}

func pipes(buildOnly bool) []pipeline.Pipe {
	var pipes = []pipeline.Pipe{
		defaults.Pipe{}, // load default configs
	}
	if !buildOnly {
		pipes = append(
			pipes,
			git.Pipe{},    // get current tag info
			env.Pipe{},    // load and validate environment variables
			source.Pipe{}, // validate current git state
		)
	}
	pipes = append(
		pipes,
		build.Pipe{},   // build
		archive.Pipe{}, // archive (tar.gz, zip, etc)
		fpm.Pipe{},     // archive via fpm (deb, rpm, etc)
	)
	if !buildOnly {
		pipes = append(
			pipes,
			release.Pipe{}, // release to github
			brew.Pipe{},    // push to brew tap
		)
	}
	return pipes
}
<commit_msg>removed :<commit_after>package main

import (
	"log"
	"os"

	"github.com/goreleaser/goreleaser/config"
	"github.com/goreleaser/goreleaser/context"
	"github.com/goreleaser/goreleaser/pipeline"
	"github.com/goreleaser/goreleaser/pipeline/archive"
	"github.com/goreleaser/goreleaser/pipeline/brew"
	"github.com/goreleaser/goreleaser/pipeline/build"
	"github.com/goreleaser/goreleaser/pipeline/defaults"
	"github.com/goreleaser/goreleaser/pipeline/env"
	"github.com/goreleaser/goreleaser/pipeline/fpm"
	"github.com/goreleaser/goreleaser/pipeline/git"
	"github.com/goreleaser/goreleaser/pipeline/release"
	"github.com/goreleaser/goreleaser/pipeline/source"
	"github.com/urfave/cli"
)

var (
	version = "dev"
	commit  = "none"
	date    = "unknown"
)

func main() {
	var app = cli.NewApp()
	app.Name = "goreleaser"
	app.Version = version + ", commit " + commit + ", built at " + date
	app.Usage = "Deliver Go binaries as fast and easily as possible"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "config, c",
			Usage: "Load configuration from `FILE`",
			Value: "goreleaser.yml",
		},
		cli.BoolFlag{
			Name:  "build-only, skip-release, no-release, nr",
			Usage: "Skip all the release processes and run only the build and packaging steps",
		},
	}
	app.Action = func(c *cli.Context) (err error) {
		var file = c.String("config")
		cfg, err := config.Load(file)
		// Allow failing to load the config file if file is not explicitly specified
		if err != nil && c.IsSet("config") {
			return cli.NewExitError(err.Error(), 1)
		}
		ctx := context.New(cfg)
		log.SetFlags(0)
		for _, pipe := range pipes(c.Bool("build-only")) {
			log.Println(pipe.Description())
			log.SetPrefix(" -> ")
			if err := pipe.Run(ctx); err != nil {
				return cli.NewExitError(err.Error(), 1)
			}
			log.SetPrefix("")
		}
		log.Println("Done!")
		return
	}
	if err := app.Run(os.Args); err != nil {
		log.Fatalln(err)
	}
}

func pipes(buildOnly bool) []pipeline.Pipe {
	var pipes = []pipeline.Pipe{
		defaults.Pipe{}, // load default configs
	}
	if !buildOnly {
		pipes = append(
			pipes,
			git.Pipe{},    // get current tag info
			env.Pipe{},    // load and validate environment variables
			source.Pipe{}, // validate current git state
		)
	}
	pipes = append(
		pipes,
		build.Pipe{},   // build
		archive.Pipe{}, // archive (tar.gz, zip, etc)
		fpm.Pipe{},     // archive via fpm (deb, rpm, etc)
	)
	if !buildOnly {
		pipes = append(
			pipes,
			release.Pipe{}, // release to github
			brew.Pipe{},    // push to brew tap
		)
	}
	return pipes
}
<|endoftext|>


<commit_before>package main

import (
	"os"
)

const esc = 27

var size = 4

var term *Terminal
var game *Game
var shouldReset = false

func main() {
	var err error
	term, err = NewTerminal(os.Stdin, os.Stdout, "")
	handle(err)
	defer term.Reset()
	term.Println("Controls: wasd or arrow keys.")

	game = NewGame(size)
	update()

	term.KeyCallback = doKeypress

	go func() {
		term.ReadLine()
		game.Finished.Done()
	}()

	game.Finished.Wait()

	if game.Won {
		term.Println("\nCongratulations!")
	} else if game.Lost {
		term.Println("\nYou lose.")
	}
}

func doKeypress(key int) {
	var dir Direction
	switch key {
	case 'w', KeyUp:
		dir = Up
	case 'a', KeyLeft:
		dir = Left
	case 's', KeyDown:
		dir = Down
	case 'd', KeyRight:
		dir = Right
	default:
		return
	}

	// Try the move.
	if game.Play(dir) {
		// Move was successful.
		update()
	}
}

func update() {
	if shouldReset {
		handle(reset())
	}
	term.Println("Score:", game.Score)
	term.Print(game)
	shouldReset = true
}

func reset() error {
	_, err := term.Write([]byte{'\r'})
	if err != nil {
		return err
	}
	term.ClearLine()
	for i := 0; i < size*2+1; i++ {
		_, err := term.Write([]byte{esc, '[', 'A'})
		if err != nil {
			return err
		}
		term.ClearLine()
	}
	return nil
}

func handle(err error) {
	if err != nil {
		panic(err)
	}
}
<commit_msg>Added runtime flags<commit_after>package main

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

var term *Terminal
var game *Game
var shouldReset = false

func main() {
	var size = flag.Int("size", 4, "Width/height of the grid.")
	var goal = flag.Int("goal", 2048, "Target score.")

	flag.Parse()

	if *size < 2 {
		fmt.Fprintln(os.Stderr, "Error: size must be at least 2.")
		os.Exit(1)
	}
	if *goal < 4 {
		fmt.Fprintln(os.Stderr, "Error: goal must be at least 4.")
		os.Exit(1)
	}
	SetGoal(*goal)

	var err error
	term, err = NewTerminal(os.Stdin, os.Stdout, "")
	handle(err)
	defer term.Reset()
	term.Println("Controls: wasd or arrow keys to play, enter to exit.")

	game = NewGame(*size)
	update()

	term.KeyCallback = doKeypress

	go func() {
		term.ReadLine()
		game.Finished.Done()
	}()

	game.Finished.Wait()

	if game.Won {
		term.Println("\nCongratulations!")
	} else if game.Lost {
		term.Println("\nYou lose.")
	}
}

func doKeypress(key int) {
	var dir Direction
	switch key {
	case 'w', KeyUp:
		dir = Up
	case 'a', KeyLeft:
		dir = Left
	case 's', KeyDown:
		dir = Down
	case 'd', KeyRight:
		dir = Right
	default:
		return
	}

	// Try the move.
	if game.Play(dir) {
		// Move was successful.
		update()
	}
}

func update() {
	if shouldReset {
		handle(reset())
	}
	term.Println("Score:", game.Score)
	term.Print(game)
	shouldReset = true
}

func reset() error {
	_, err := term.Write([]byte{'\r'})
	if err != nil {
		return err
	}
	term.ClearLine()
	for i := 0; i < game.Size*2+1; i++ {
		_, err := term.Write([]byte{keyEscape, '[', 'A'})
		if err != nil {
			return err
		}
		term.ClearLine()
	}
	return nil
}

func handle(err error) {
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package main

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

	"github.com/iron-io/iron_go3/api"
	"github.com/iron-io/iron_go3/cache"
	"github.com/iron-io/iron_go3/config"
	"github.com/iron-io/iron_go3/mq"
	"github.com/iron-io/iron_go3/worker"
)

var (
	interval = 10 * time.Second
	runtime  = 30 * time.Minute
	swapi    = "worker-aws-us-east-1.iron.io"
)

const (
	TriggerFixed       = "fixed"
	TriggerProgressive = "progressive"
	TriggerRatio       = "ratio"
)

var (
	prev    map[string]int
	codeIds map[string]string
	client  *http.Client
)

type Config struct {
	Environments map[string]config.Settings `json:"envs"`
	Alerts       []QueueWorkerAlert         `json:"alerts"`
	CacheEnv     string                     `json:"cacheEnv"`
	Interval     *int                       `json:"interval,omitempty"`
	Runtime      *int                       `json:"runtime,omitempty"`
}

type QueueWorkerAlert struct {
	QueueName  string    `json:"queueName"`
	QueueEnv   string    `json:"queueEnv"`
	WorkerName string    `json:"workerName"`
	WorkerEnv  string    `json:"workerEnv"`
	Cluster    string    `json:"cluster"`
	Triggers   []Trigger `json:"triggers"`
}

type Trigger struct {
	Typ   string `json:"type"`
	Value int    `json:"value"`
}

func queueKey(qw QueueWorkerAlert) string {
	return qw.QueueEnv + "|" + qw.QueueName
}

func main() {
	start := time.Now()
	prev = make(map[string]int)
	codeIds = make(map[string]string)
	client = api.HttpClient

	// Retrieve configuration
	c := &Config{}
	worker.ParseFlags()
	err := worker.ConfigFromJSON(c)
	if err != nil {
		log.Fatalln("Could not unparse config", err)
	}

	if len(c.Alerts) == 0 || len(c.Environments) == 0 {
		fmt.Println("No config set")
		return
	}

	if c.Interval != nil {
		interval = time.Duration(*c.Interval) * time.Second
	}

	if c.Runtime != nil {
		runtime = time.Duration(*c.Runtime) * time.Second
	}

	cacheEnv, exists := c.Environments[c.CacheEnv]
	if !exists {
		log.Fatalln("No cache environment set")
		return
	}

	cacheConfig := config.ManualConfig("iron_cache", &cacheEnv)
	queueCache := &cache.Cache{Settings: cacheConfig, Name: "autoscale-prevs"}
	for {
		if time.Since(start) > runtime {
			break
		}

		for _, alert := range c.Alerts {
			if len(alert.Triggers) == 0 {
				fmt.Println("No triggers found for alert")
				continue
			}

			queueSize, prevQueueSize := 0, 0
			key := queueKey(alert)

			// Get previous size
			if _, e := prev[key]; !e {
				v, err := queueCache.Get(key)
				if err != nil {
					if !strings.Contains(err.Error(), "not found") {
						// Print errors not associated with cache/key not found errors
						fmt.Println(err)
					}
				} else {
					prev[key] = int(v.(float64))
				}
			}
			prevQueueSize = prev[key]

			queueEnv, exists := c.Environments[alert.QueueEnv]
			if !exists {
				fmt.Printf("Environment %q is not defined for queue %q\n", alert.QueueEnv, alert.QueueName)
				continue
			}

			queueConfig := config.ManualConfig("iron_mq", &queueEnv)
			q := mq.ConfigNew(alert.QueueName, &queueConfig)
			info, err := q.Info()
			if err != nil {
				fmt.Println("Could not get information about", alert.QueueName, err)
				continue
			}
			queueSize = info.Size
			// Update previous size
			go queueCache.Set(key, queueSize, 900)
			prev[key] = queueSize

			workerEnv, exists := c.Environments[alert.WorkerEnv]
			if !exists {
				fmt.Printf("Environment %q is not defined for worker %q\n", alert.WorkerEnv, alert.WorkerName)
				continue
			}
			queued, running, err := workerStats(&workerEnv, alert.WorkerName)
			if err != nil {
				fmt.Printf("Could not get code stats for %s, err: %v\n", alert.WorkerName, err)
				continue
			}

			launch := evalTriggers(queued, running, queueSize, prevQueueSize, alert.Triggers)
			fmt.Printf("%v | Queue: %s (size=%d, prev=%d), CodeName=%s (queued=%d, running=%d), Launching %d\n", time.Now().Format(time.ANSIC), alert.QueueName, queueSize, prevQueueSize, alert.WorkerName, queued, running, launch)

			if launch > 0 {
				workerConfig := config.ManualConfig("iron_worker", &workerEnv)
				w := &worker.Worker{Settings: workerConfig}

				tasks := make([]worker.Task, launch)
				for x := 0; x < len(tasks); x++ {
					tasks[x].CodeName = alert.WorkerName
					tasks[x].Cluster = alert.Cluster
				}

				_, err = w.TaskQueue(tasks...)
				if err != nil {
					fmt.Println("Could not create tasks for", alert.WorkerName)
					continue
				}
			}
		}

		time.Sleep(interval)
	}
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func workerKey(projectID, codeName string) string {
	return projectID + "|" + codeName
}

type CodeStats struct {
	Running int `json:"running"`
	Queued  int `json:"queued"`
	// ignore other states
}

func workerStats(env *config.Settings, codeName string) (queued, running int, err error) {
	codeID, exists := codeIds[workerKey(env.ProjectId, codeName)]
	if !exists {
		workerConfig := config.ManualConfig("iron_worker", env)
		w := &worker.Worker{Settings: workerConfig}
		codes, err := w.CodePackageList(0, 100)
		if err != nil {
			return 0, 0, err
		}

		for _, c := range codes {
			codeIds[workerKey(c.ProjectId, c.Name)] = c.Id
			if c.Name == codeName {
				codeID = c.Id
			}
		}
	}

	if len(codeID) == 0 {
		return 0, 0, fmt.Errorf("Could not find id for %q\n", codeName)
	}
	if len(env.ProjectId) == 0 || len(env.Token) == 0 {
		return 0, 0, fmt.Errorf("Could not get env for %q\n", codeName)
	}

	url := fmt.Sprintf("https://%s/2/projects/%s/codes/%s/stats?oauth=%s", swapi, env.ProjectId, codeID, env.Token)
	resp, err := client.Get(url)
	if err != nil {
		return 0, 0, err
	}
	defer resp.Body.Close()
	decoder := json.NewDecoder(resp.Body)
	var s CodeStats
	err = decoder.Decode(&s)
	if err != nil {
		return 0, 0, err
	}

	return s.Queued, s.Running, nil
}

func evalTriggers(queued, running, queueSize, prevQueueSize int, triggers []Trigger) (launch int) {
	for _, t := range triggers {
		switch t.Typ {
		case TriggerFixed:
			if queueSize >= t.Value {
				launch = max(launch, 1)
			}
		case TriggerProgressive:
			if queueSize < t.Value {
				continue
			}

			previous_level := prevQueueSize / t.Value
			current_level := queueSize / t.Value
			launch = max(launch, current_level-previous_level)
		case TriggerRatio:
			expected_runners := (queueSize + t.Value - 1) / t.Value // Only have 0 runners if qsize=0

			diff := expected_runners - (queued + running)
			launch = max(launch, diff)
		}
	}
	return
}
<commit_msg>Update fixed trigger to look at current worker state<commit_after>package main

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

	"github.com/iron-io/iron_go3/api"
	"github.com/iron-io/iron_go3/cache"
	"github.com/iron-io/iron_go3/config"
	"github.com/iron-io/iron_go3/mq"
	"github.com/iron-io/iron_go3/worker"
)

var (
	interval = 10 * time.Second
	runtime  = 30 * time.Minute
	swapi    = "worker-aws-us-east-1.iron.io"
)

const (
	TriggerFixed       = "fixed"
	TriggerProgressive = "progressive"
	TriggerRatio       = "ratio"
)

var (
	prev    map[string]int
	codeIds map[string]string
	client  *http.Client
)

type Config struct {
	Environments map[string]config.Settings `json:"envs"`
	Alerts       []QueueWorkerAlert         `json:"alerts"`
	CacheEnv     string                     `json:"cacheEnv"`
	Interval     *int                       `json:"interval,omitempty"`
	Runtime      *int                       `json:"runtime,omitempty"`
}

type QueueWorkerAlert struct {
	QueueName  string    `json:"queueName"`
	QueueEnv   string    `json:"queueEnv"`
	WorkerName string    `json:"workerName"`
	WorkerEnv  string    `json:"workerEnv"`
	Cluster    string    `json:"cluster"`
	Triggers   []Trigger `json:"triggers"`
}

type Trigger struct {
	Typ   string `json:"type"`
	Value int    `json:"value"`
}

func queueKey(qw QueueWorkerAlert) string {
	return qw.QueueEnv + "|" + qw.QueueName
}

func main() {
	start := time.Now()
	prev = make(map[string]int)
	codeIds = make(map[string]string)
	client = api.HttpClient

	// Retrieve configuration
	c := &Config{}
	worker.ParseFlags()
	err := worker.ConfigFromJSON(c)
	if err != nil {
		log.Fatalln("Could not unparse config", err)
	}

	if len(c.Alerts) == 0 || len(c.Environments) == 0 {
		fmt.Println("No config set")
		return
	}

	if c.Interval != nil {
		interval = time.Duration(*c.Interval) * time.Second
	}

	if c.Runtime != nil {
		runtime = time.Duration(*c.Runtime) * time.Second
	}

	cacheEnv, exists := c.Environments[c.CacheEnv]
	if !exists {
		log.Fatalln("No cache environment set")
		return
	}

	cacheConfig := config.ManualConfig("iron_cache", &cacheEnv)
	queueCache := &cache.Cache{Settings: cacheConfig, Name: "autoscale-prevs"}
	for {
		if time.Since(start) > runtime {
			break
		}

		for _, alert := range c.Alerts {
			if len(alert.Triggers) == 0 {
				fmt.Println("No triggers found for alert")
				continue
			}

			queueSize, prevQueueSize := 0, 0
			key := queueKey(alert)

			// Get previous size
			if _, e := prev[key]; !e {
				v, err := queueCache.Get(key)
				if err != nil {
					if !strings.Contains(err.Error(), "not found") {
						// Print errors not associated with cache/key not found errors
						fmt.Println(err)
					}
				} else {
					prev[key] = int(v.(float64))
				}
			}
			prevQueueSize = prev[key]

			queueEnv, exists := c.Environments[alert.QueueEnv]
			if !exists {
				fmt.Printf("Environment %q is not defined for queue %q\n", alert.QueueEnv, alert.QueueName)
				continue
			}

			queueConfig := config.ManualConfig("iron_mq", &queueEnv)
			q := mq.ConfigNew(alert.QueueName, &queueConfig)
			info, err := q.Info()
			if err != nil {
				fmt.Println("Could not get information about", alert.QueueName, err)
				continue
			}
			queueSize = info.Size
			// Update previous size
			go queueCache.Set(key, queueSize, 900)
			prev[key] = queueSize

			workerEnv, exists := c.Environments[alert.WorkerEnv]
			if !exists {
				fmt.Printf("Environment %q is not defined for worker %q\n", alert.WorkerEnv, alert.WorkerName)
				continue
			}
			queued, running, err := workerStats(&workerEnv, alert.WorkerName)
			if err != nil {
				fmt.Printf("Could not get code stats for %s, err: %v\n", alert.WorkerName, err)
				continue
			}

			launch := evalTriggers(queued, running, queueSize, prevQueueSize, alert.Triggers)
			fmt.Printf("%v | Queue: %s (size=%d, prev=%d), CodeName=%s (queued=%d, running=%d), Launching %d\n", time.Now().Format(time.ANSIC), alert.QueueName, queueSize, prevQueueSize, alert.WorkerName, queued, running, launch)

			if launch > 0 {
				workerConfig := config.ManualConfig("iron_worker", &workerEnv)
				w := &worker.Worker{Settings: workerConfig}

				tasks := make([]worker.Task, launch)
				for x := 0; x < len(tasks); x++ {
					tasks[x].CodeName = alert.WorkerName
					tasks[x].Cluster = alert.Cluster
				}

				_, err = w.TaskQueue(tasks...)
				if err != nil {
					fmt.Println("Could not create tasks for", alert.WorkerName)
					continue
				}
			}
		}

		time.Sleep(interval)
	}
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func workerKey(projectID, codeName string) string {
	return projectID + "|" + codeName
}

type CodeStats struct {
	Running int `json:"running"`
	Queued  int `json:"queued"`
	// ignore other states
}

func workerStats(env *config.Settings, codeName string) (queued, running int, err error) {
	codeID, exists := codeIds[workerKey(env.ProjectId, codeName)]
	if !exists {
		workerConfig := config.ManualConfig("iron_worker", env)
		w := &worker.Worker{Settings: workerConfig}
		codes, err := w.CodePackageList(0, 100)
		if err != nil {
			return 0, 0, err
		}

		for _, c := range codes {
			codeIds[workerKey(c.ProjectId, c.Name)] = c.Id
			if c.Name == codeName {
				codeID = c.Id
			}
		}
	}

	if len(codeID) == 0 {
		return 0, 0, fmt.Errorf("Could not find id for %q\n", codeName)
	}
	if len(env.ProjectId) == 0 || len(env.Token) == 0 {
		return 0, 0, fmt.Errorf("Could not get env for %q\n", codeName)
	}

	url := fmt.Sprintf("https://%s/2/projects/%s/codes/%s/stats?oauth=%s", swapi, env.ProjectId, codeID, env.Token)
	resp, err := client.Get(url)
	if err != nil {
		return 0, 0, err
	}
	defer resp.Body.Close()
	decoder := json.NewDecoder(resp.Body)
	var s CodeStats
	err = decoder.Decode(&s)
	if err != nil {
		return 0, 0, err
	}

	return s.Queued, s.Running, nil
}

func evalTriggers(queued, running, queueSize, prevQueueSize int, triggers []Trigger) (launch int) {
	for _, t := range triggers {
		switch t.Typ {
		case TriggerFixed:
			if queueSize >= t.Value && (queued+running) == 0 {
				launch = max(launch, 1)
			}
		case TriggerProgressive:
			if queueSize < t.Value {
				continue
			}

			previous_level := prevQueueSize / t.Value
			current_level := queueSize / t.Value
			launch = max(launch, current_level-previous_level)
		case TriggerRatio:
			expected_runners := (queueSize + t.Value - 1) / t.Value // Only have 0 runners if qsize=0

			diff := expected_runners - (queued + running)
			launch = max(launch, diff)
		}
	}
	return
}
<|endoftext|>


<commit_before>package main

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

func main() {
	var content []byte
	var err error
	if len(os.Args) == 1 {
		content, err = ioutil.ReadAll(os.Stdin)
	} else {
		content, err = ioutil.ReadFile(os.Args[1])
	}

	if err != nil {
		if os.IsNotExist(err) {
			fmt.Println("Gopl: the file does not exist.")
		} else {
			fmt.Println("Gopl: Huehoe it's embarrassing but an error occurs -> ", err)
		}
		return
	}

	url := "http://play.golang.org/share"
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(content))
	if err != nil {
		fmt.Println(err)
		return
	}
	req.Header.Set("Content-Type", "raw")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Println("http://play.golang.org/p/" + string(body))
}
<commit_msg>use http.Post instead of a custom request<commit_after>package main

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

func main() {
	var content []byte
	var err error
	if len(os.Args) == 1 {
		content, err = ioutil.ReadAll(os.Stdin)
	} else {
		content, err = ioutil.ReadFile(os.Args[1])
	}

	if err != nil {
		if os.IsNotExist(err) {
			fmt.Println("Gopl: the file does not exist.")
		} else {
			fmt.Println("Gopl: Huehoe it's embarrassing but an error occurs -> ", err)
		}
		return
	}

	url := "http://play.golang.org/share"

	resp, err := http.Post(url, "raw", bytes.NewBuffer(content))
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Println("http://play.golang.org/p/" + string(body))
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"os/user"
	"strings"
	"sync"
	"text/template"

	ext "github.com/MattAitchison/remotectl/providers"
	sshutil "github.com/MattAitchison/remotectl/ssh"

	// Enabled Providers
	_ "github.com/MattAitchison/remotectl/aws"
	_ "github.com/MattAitchison/remotectl/digitalocean"
	_ "github.com/MattAitchison/remotectl/stdin"

	"github.com/MattAitchison/envconfig"
)

var (
	// Version number that gets set at compile time.
	Version string

	curUser, _ = user.Current()

	sshPort = envconfig.Int("remotectl_port", 22, "ssh port to use. Note: all ports must be the same on hosts for a run.")
	// Show default ident.
	ident         = envconfig.String("remotectl_identity", "", "private key file")
	usr           = envconfig.String("remotectl_user", curUser.Username, "user to connect as")
	provider      = envconfig.String("remotectl_provider", "do", "name or comma-sep list of provider modules to use for selecting hosts")
	namespace     = envconfig.String("remotectl_namespace", "", "")
	prefixTmplStr = envconfig.String("remotectl_prefix", "{{.Name}}: ", "prefix template for host log output")
	prefixTmpl    = template.Must(template.New("prefix").Parse(prefixTmplStr))

	showVersion = flag.Bool("version", false, "show version")
	showHelp    = flag.Bool("help", false, "show this help message")
	showList    = flag.Bool("list", false, "lists selected ips and names. /etc/hosts friendly output")

	// Use current working path.
	profile = flag.String("profile", "", "sources a bash profile to load a config") // Maybe a name will default to a file in ~/.remotectl
)

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

func parseArgs(args []string) (q, cmd string) {
	i := flag.NFlag() + 1

	cmd = strings.Join(flag.Args(), " ")
	if len(args) <= i {
		return "", cmd
	}

	if args[i] != "--" {
		return flag.Args()[0], strings.Join(flag.Args()[1:], " ")
	}

	return "", cmd
}
func main() {
	log.SetFlags(0)
	flag.Parse()

	switch {
	case *showHelp:
		helpCmd()
		os.Exit(0)
	case *showVersion:
		fmt.Printf("remotectl: %s", Version)
		os.Exit(0)
	}

	query, cmd := parseArgs(os.Args)

	var hosts []ext.Host
	for _, p := range ext.Providers.Select(strings.Fields(provider)) {
		if p == nil {
			log.Fatal("unknown provider")
		}

		// Setup the provider
		p.Setup()

		// Query the provider for hosts
		extHosts, err := p.Query(namespace, query)
		fatalErr(err)
		hosts = append(hosts, extHosts...)
	}

	if len(hosts) == 0 {
		log.Fatal("no hosts")
	}

	if *showList {
		log.Println(hosts)
		return
	}

	cfg, err := sshutil.NewClientConfig(usr)
	fatalErr(err)

	var wg sync.WaitGroup
	wg.Add(len(hosts))
	for _, host := range hosts {
		go func(h ext.Host) {
			s := setupSession(cfg, h)

			defer func() {
				s.Close()
				wg.Done()
			}()

			s.Run(cmd)
		}(host)
	}
	wg.Wait()
}

func setupSession(cfg *sshutil.ClientConfig, host ext.Host) *sshutil.Session {
	addr := fmt.Sprint(host.Addr, ":", sshPort)
	s, err := cfg.NewSession(addr)
	if err != nil {
		log.Fatalln(host.Name+":", addr, err)
	}

	outPipe, err := s.StdoutPipe()
	fatalErr(err)

	errPipe, err := s.StderrPipe()
	fatalErr(err)

	// Don't like this
	go hostStreamer(host, outPipe, os.Stdout)
	go hostStreamer(host, errPipe, os.Stderr)

	return s
}

func hostStreamer(host ext.Host, r io.Reader, w io.Writer) {
	// Locking? One writer?
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		prefixTmpl.Execute(w, host)
		fmt.Println(scanner.Text())
	}

	if err := scanner.Err(); err != nil {
		log.Fatalf("err streaming logs %s", err)
	}

}

func helpCmd() {
	usage := `Usage: remotectl <flags> <query> [--] <cmd>

Providers:
%s

Environment Vars:
`
	fmt.Printf(usage, ext.Providers.Names())
	envconfig.PrintDefaults()
	fmt.Println("\nFlags:")
	flag.PrintDefaults()

}
<commit_msg>Closes #3<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"os/user"
	"strings"
	"sync"
	"text/template"

	ext "github.com/MattAitchison/remotectl/providers"
	sshutil "github.com/MattAitchison/remotectl/ssh"

	// Enabled Providers
	_ "github.com/MattAitchison/remotectl/aws"
	_ "github.com/MattAitchison/remotectl/digitalocean"
	_ "github.com/MattAitchison/remotectl/stdin"

	"github.com/MattAitchison/envconfig"
)

var (
	// Version number that gets set at compile time.
	Version string

	curUser, _ = user.Current()

	sshPort = envconfig.Int("remotectl_port", 22, "ssh port to use. Note: all ports must be the same on hosts for a run.")
	// Show default ident.
	ident         = envconfig.String("remotectl_identity", "", "private key file")
	usr           = envconfig.String("remotectl_user", curUser.Username, "user to connect as")
	provider      = envconfig.String("remotectl_provider", "do", "name or comma-sep list of provider modules to use for selecting hosts")
	namespace     = envconfig.String("remotectl_namespace", "", "")
	prefixTmplStr = envconfig.String("remotectl_prefix", "{{.Name}}: ", "prefix template for host log output")
	prefixTmpl    = template.Must(template.New("prefix").Parse(prefixTmplStr))

	showVersion = flag.Bool("version", false, "show version")
	showHelp    = flag.Bool("help", false, "show this help message")
	showList    = flag.Bool("list", false, "lists selected ips and names. /etc/hosts friendly output")

	// Use current working path.
	profile = flag.String("profile", "", "sources a bash profile to load a config") // Maybe a name will default to a file in ~/.remotectl
)

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

func parseArgs(args []string) (q, cmd string) {
	i := flag.NFlag() + 1

	cmd = strings.Join(flag.Args(), " ")
	if len(args) <= i {
		return "", cmd
	}

	if args[i] != "--" {
		return flag.Args()[0], strings.Join(flag.Args()[1:], " ")
	}

	return "", cmd
}
func main() {
	log.SetFlags(0)
	flag.Parse()

	switch {
	case *showHelp:
		helpCmd()
		os.Exit(0)
	case *showVersion:
		fmt.Printf("remotectl: %s", Version)
		os.Exit(0)
	}

	query, cmd := parseArgs(os.Args)

	var hosts []ext.Host
	for _, p := range ext.Providers.Select(strings.Fields(provider)) {
		if p == nil {
			log.Fatal("unknown provider")
		}

		// Setup the provider
		p.Setup()

		// Query the provider for hosts
		extHosts, err := p.Query(namespace, query)
		fatalErr(err)
		hosts = append(hosts, extHosts...)
	}

	if len(hosts) == 0 {
		log.Fatal("no hosts")
	}

	if *showList {
		printHosts(os.Stderr, hosts)
		return
	}

	cfg, err := sshutil.NewClientConfig(usr)
	fatalErr(err)

	var wg sync.WaitGroup
	wg.Add(len(hosts))
	for _, host := range hosts {
		go func(h ext.Host) {
			s := setupSession(cfg, h)

			defer func() {
				s.Close()
				wg.Done()
			}()

			// Should probably use something else other than run
			s.Run(cmd)
		}(host)
	}
	wg.Wait()
}

func setupSession(cfg *sshutil.ClientConfig, host ext.Host) *sshutil.Session {
	addr := fmt.Sprint(host.Addr, ":", sshPort)
	s, err := cfg.NewSession(addr)
	if err != nil {
		log.Fatalln(host.Name+":", addr, err)
	}

	outPipe, err := s.StdoutPipe()
	fatalErr(err)

	errPipe, err := s.StderrPipe()
	fatalErr(err)

	// Don't like this
	go hostStreamer(host, outPipe, os.Stdout)
	go hostStreamer(host, errPipe, os.Stderr)

	return s
}

func hostStreamer(host ext.Host, r io.Reader, w io.Writer) {
	// Locking? One writer?
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		prefixTmpl.Execute(w, host)
		fmt.Println(scanner.Text())
	}

	if err := scanner.Err(); err != nil {
		log.Fatalf("err streaming logs %s", err)
	}

}

func printHosts(w io.Writer, hosts []ext.Host) {
	for _, h := range hosts {
		fmt.Fprintf(w, "%-20s %s\n", h.Addr, h.Name)
	}
}

func helpCmd() {
	usage := `Usage: remotectl <flags> <query> [--] <cmd>

Providers:
%s

Environment Vars:
`
	fmt.Printf(usage, ext.Providers.Names())
	envconfig.PrintDefaults()
	fmt.Println("\nFlags:")
	flag.PrintDefaults()

}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"net/http"
	_ "net/http/pprof"
	"os"
	"time"

	WardenClient "github.com/cloudfoundry-incubator/garden/client"
	WardenConnection "github.com/cloudfoundry-incubator/garden/client/connection"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/http_server"
	"github.com/tedsuo/ifrit/sigmon"
	"github.com/tedsuo/rata"

	"github.com/concourse/turbine/api"
	"github.com/concourse/turbine/builder"
	"github.com/concourse/turbine/builder/outputs"
	"github.com/concourse/turbine/config"
	"github.com/concourse/turbine/event"
	"github.com/concourse/turbine/resource"
	"github.com/concourse/turbine/routes"
	"github.com/concourse/turbine/scheduler"
	"github.com/concourse/turbine/snapshotter"
)

var listenAddr = flag.String(
	"listenAddr",
	"0.0.0.0:4637",
	"listening address",
)

var peerAddr = flag.String(
	"peerAddr",
	"127.0.0.1:4637",
	"external address of the api server, used for callbacks",
)

var debugListenAddr = flag.String(
	"debugListenAddr",
	":4636",
	"port for the pprof debugger to listen on",
)

var wardenNetwork = flag.String(
	"wardenNetwork",
	"unix",
	"warden API connection network (unix or tcp)",
)

var wardenAddr = flag.String(
	"wardenAddr",
	"/tmp/warden.sock",
	"warden API connection address",
)

var resourceTypes = flag.String(
	"resourceTypes",
	`{
		"git": "docker:///concourse/git-resource",
		"archive": "docker:///concourse/archive-resource",
		"docker-image": "docker:///concourse/docker-image-resource",
		"time": "docker:///concourse/time-resource",
		"s3": "docker:///concourse/s3-resource",
		"tracker": "docker:///concourse/tracker-resource"
	}`,
	"map of resource type to its docker image",
)

var snapshotPath = flag.String(
	"snapshotPath",
	"/tmp/builds-snapshot.json",
	"path to file to store/load snapshots from",
)

func main() {
	flag.Parse()

	wardenClient := WardenClient.New(WardenConnection.New(
		*wardenNetwork,
		*wardenAddr,
	))

	logger := lager.NewLogger("turbine")
	logger.RegisterSink(lager.NewWriterSink(os.Stdout, lager.DEBUG))

	resourceTypesMap := map[string]string{}
	err := json.Unmarshal([]byte(*resourceTypes), &resourceTypesMap)
	if err != nil {
		logger.Fatal("failed-to-parse-resource-types", err)
	}

	var resourceTypesConfig config.ResourceTypes
	for typ, image := range resourceTypesMap {
		resourceTypesConfig = append(resourceTypesConfig, config.ResourceType{
			Name:  typ,
			Image: image,
		})
	}

	resourceTracker := resource.NewTracker(resourceTypesConfig, wardenClient)

	builder := builder.NewBuilder(resourceTracker, wardenClient, outputs.NewParallelPerformer(resourceTracker))

	scheduler := scheduler.NewScheduler(logger.Session("scheduler"), builder, event.NewWebSocketEmitter)

	generator := rata.NewRequestGenerator("http://"+*peerAddr, routes.Routes)

	drain := make(chan struct{})

	handler, err := api.New(logger.Session("api"), scheduler, resourceTracker, generator, drain)
	if err != nil {
		logger.Fatal("failed-to-initialize-handler", err)
	}

	var pingErr error
	for i := 0; i < 10; i++ {
		pingErr = wardenClient.Ping()
		if pingErr == nil {
			break
		}

		time.Sleep(10 * time.Second)
	}

	if pingErr != nil {
		logger.Fatal("failed-to-ping-warden", err)
	}

	group := grouper.RunGroup{
		"api":         http_server.New(*listenAddr, handler),
		"debug":       http_server.New(*debugListenAddr, http.DefaultServeMux),
		"snapshotter": snapshotter.NewSnapshotter(logger.Session("snapshotter"), *snapshotPath, scheduler),
		"drainer": ifrit.RunFunc(func(signals <-chan os.Signal, ready chan<- struct{}) error {
			close(ready)
			<-signals
			close(drain)
			return nil
		}),
	}

	running := ifrit.Envoke(sigmon.New(group))

	logger.Info("listening", lager.Data{
		"api": *listenAddr,
	})

	err = <-running.Wait()
	if err == nil {
		logger.Info("exited")
	} else {
		logger.Error("failed", err)
		os.Exit(1)
	}
}
<commit_msg>add semver to default resources flag set<commit_after>package main

import (
	"encoding/json"
	"flag"
	"net/http"
	_ "net/http/pprof"
	"os"
	"time"

	WardenClient "github.com/cloudfoundry-incubator/garden/client"
	WardenConnection "github.com/cloudfoundry-incubator/garden/client/connection"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/http_server"
	"github.com/tedsuo/ifrit/sigmon"
	"github.com/tedsuo/rata"

	"github.com/concourse/turbine/api"
	"github.com/concourse/turbine/builder"
	"github.com/concourse/turbine/builder/outputs"
	"github.com/concourse/turbine/config"
	"github.com/concourse/turbine/event"
	"github.com/concourse/turbine/resource"
	"github.com/concourse/turbine/routes"
	"github.com/concourse/turbine/scheduler"
	"github.com/concourse/turbine/snapshotter"
)

var listenAddr = flag.String(
	"listenAddr",
	"0.0.0.0:4637",
	"listening address",
)

var peerAddr = flag.String(
	"peerAddr",
	"127.0.0.1:4637",
	"external address of the api server, used for callbacks",
)

var debugListenAddr = flag.String(
	"debugListenAddr",
	":4636",
	"port for the pprof debugger to listen on",
)

var wardenNetwork = flag.String(
	"wardenNetwork",
	"unix",
	"warden API connection network (unix or tcp)",
)

var wardenAddr = flag.String(
	"wardenAddr",
	"/tmp/warden.sock",
	"warden API connection address",
)

var resourceTypes = flag.String(
	"resourceTypes",
	`{
		"git": "docker:///concourse/git-resource",
		"archive": "docker:///concourse/archive-resource",
		"docker-image": "docker:///concourse/docker-image-resource",
		"time": "docker:///concourse/time-resource",
		"s3": "docker:///concourse/s3-resource",
		"tracker": "docker:///concourse/tracker-resource",
		"semver": "docker:///concourse/semver-resource"
	}`,
	"map of resource type to its docker image",
)

var snapshotPath = flag.String(
	"snapshotPath",
	"/tmp/builds-snapshot.json",
	"path to file to store/load snapshots from",
)

func main() {
	flag.Parse()

	wardenClient := WardenClient.New(WardenConnection.New(
		*wardenNetwork,
		*wardenAddr,
	))

	logger := lager.NewLogger("turbine")
	logger.RegisterSink(lager.NewWriterSink(os.Stdout, lager.DEBUG))

	resourceTypesMap := map[string]string{}
	err := json.Unmarshal([]byte(*resourceTypes), &resourceTypesMap)
	if err != nil {
		logger.Fatal("failed-to-parse-resource-types", err)
	}

	var resourceTypesConfig config.ResourceTypes
	for typ, image := range resourceTypesMap {
		resourceTypesConfig = append(resourceTypesConfig, config.ResourceType{
			Name:  typ,
			Image: image,
		})
	}

	resourceTracker := resource.NewTracker(resourceTypesConfig, wardenClient)

	builder := builder.NewBuilder(resourceTracker, wardenClient, outputs.NewParallelPerformer(resourceTracker))

	scheduler := scheduler.NewScheduler(logger.Session("scheduler"), builder, event.NewWebSocketEmitter)

	generator := rata.NewRequestGenerator("http://"+*peerAddr, routes.Routes)

	drain := make(chan struct{})

	handler, err := api.New(logger.Session("api"), scheduler, resourceTracker, generator, drain)
	if err != nil {
		logger.Fatal("failed-to-initialize-handler", err)
	}

	var pingErr error
	for i := 0; i < 10; i++ {
		pingErr = wardenClient.Ping()
		if pingErr == nil {
			break
		}

		time.Sleep(10 * time.Second)
	}

	if pingErr != nil {
		logger.Fatal("failed-to-ping-warden", err)
	}

	group := grouper.RunGroup{
		"api":         http_server.New(*listenAddr, handler),
		"debug":       http_server.New(*debugListenAddr, http.DefaultServeMux),
		"snapshotter": snapshotter.NewSnapshotter(logger.Session("snapshotter"), *snapshotPath, scheduler),
		"drainer": ifrit.RunFunc(func(signals <-chan os.Signal, ready chan<- struct{}) error {
			close(ready)
			<-signals
			close(drain)
			return nil
		}),
	}

	running := ifrit.Envoke(sigmon.New(group))

	logger.Info("listening", lager.Data{
		"api": *listenAddr,
	})

	err = <-running.Wait()
	if err == nil {
		logger.Info("exited")
	} else {
		logger.Error("failed", err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"html"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"

	"github.com/line/line-bot-sdk-go/linebot"
)

var ImgSrv string = "https://img-cache-server.herokuapp.com/"
var bot *linebot.Client

//PetDB :
var PetDB *Pets

func main() {
	var err error
	PetDB = NewPets()
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func getSecureImageAddress(oriAdd string) string {
	eURL := url.QueryEscape(oriAdd)
	imgGetUrl := fmt.Sprintf("%surl?%s", ImgSrv, eURL)
	log.Println("eURL:", eURL, " url:", imgGetUrl, " ImgApi:", ImgSrv)

	response, err := http.Get(imgGetUrl)
	if err != nil {
		log.Println("Error while downloading:", err)
		return ""
	}
	defer response.Body.Close()

	if response.StatusCode != 200 {
		return ""
	}

	totalBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Println("Error while parsing:", err)
		return ""
	}
	log.Println("Got data:", string(totalBody))
	return fmt.Sprintf("%simgs?%s.jpg", ImgSrv, string(totalBody))

}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)
	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	for _, event := range events {
		switch event.Type {
		case linebot.EventTypeMessage:
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				var pet *Pet
				log.Println(message.Text)
				inText := strings.ToLower(message.Text)
				if strings.Contains(inText, "狗") || strings.Contains(inText, "dog") {
					pet = PetDB.GetNextDog()
				} else if strings.Contains(inText, "貓") || strings.Contains(inText, "cat") {
					pet = PetDB.GetNextCat()
				} else if strings.Contains(inText, "link") {
					var userID string
					if event.Source != nil {
						userID = event.Source.UserID
					}

					if err := bot.IssueLinkToken(userID).Do; err != nil {
						fmt.Println("Issue link error:", err, " userID is:", userID)
					}
					pet = PetDB.GetNextDog()
				}

				if pet == nil {
					pet = PetDB.GetNextPet()
				}

				var emojiStr string
				emoji := [][]int{
					// Emoticons icons.
					{128513, 128591},
					// Dingbats.
					{9986, 10160},
					// Transport and map symbols.
					{128640, 128704},
				}

				for _, value := range emoji {
					for x := value[0]; x < value[1]; x++ {
						// Unescape the string (HTML Entity -> String).
						emojiStr += html.UnescapeString("&#" + strconv.Itoa(x) + ";")
					}
				}
				out := fmt.Sprintf("您好，目前的動物名為%s, 所在地為:%s, 電話為:%s  %s", pet.Name, pet.Resettlement, pet.Phone, emojiStr)
				log.Println("Current msg:", out)
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(out)).Do(); err != nil {
					log.Print(err)
				}

			}
		case linebot.EventTypeBeacon:
			log.Println(" Beacon event....")
			if b := event.Beacon; b != nil {
				ret := fmt.Sprintln("Msg:", string(b.DeviceMessage), " hwid:", b.Hwid, " type:", b.Type)
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(ret)).Do(); err != nil {
					log.Print(err)
				}
			}
		}
	}
}
<commit_msg>LINE emoji<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"html"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"

	"github.com/line/line-bot-sdk-go/linebot"
)

var ImgSrv string = "https://img-cache-server.herokuapp.com/"
var bot *linebot.Client

//PetDB :
var PetDB *Pets

func main() {
	var err error
	PetDB = NewPets()
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func getSecureImageAddress(oriAdd string) string {
	eURL := url.QueryEscape(oriAdd)
	imgGetUrl := fmt.Sprintf("%surl?%s", ImgSrv, eURL)
	log.Println("eURL:", eURL, " url:", imgGetUrl, " ImgApi:", ImgSrv)

	response, err := http.Get(imgGetUrl)
	if err != nil {
		log.Println("Error while downloading:", err)
		return ""
	}
	defer response.Body.Close()

	if response.StatusCode != 200 {
		return ""
	}

	totalBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Println("Error while parsing:", err)
		return ""
	}
	log.Println("Got data:", string(totalBody))
	return fmt.Sprintf("%simgs?%s.jpg", ImgSrv, string(totalBody))

}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)
	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	for _, event := range events {
		switch event.Type {
		case linebot.EventTypeMessage:
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				var pet *Pet
				log.Println(message.Text)
				inText := strings.ToLower(message.Text)
				if strings.Contains(inText, "狗") || strings.Contains(inText, "dog") {
					pet = PetDB.GetNextDog()
				} else if strings.Contains(inText, "貓") || strings.Contains(inText, "cat") {
					pet = PetDB.GetNextCat()
				} else if strings.Contains(inText, "link") {
					var userID string
					if event.Source != nil {
						userID = event.Source.UserID
					}

					if err := bot.IssueLinkToken(userID).Do; err != nil {
						fmt.Println("Issue link error:", err, " userID is:", userID)
					}
					pet = PetDB.GetNextDog()
				}

				if pet == nil {
					pet = PetDB.GetNextPet()
				}

				var emojiStr string
				// emoji := [][]int{
				// 	// Emoticons icons.
				// 	{128513, 128591},
				// 	// Dingbats.
				// 	{9986, 10160},
				// 	// Transport and map symbols.
				// 	{128640, 128704},
				// }

				// for _, value := range emoji {
				// 	for x := value[0]; x < value[1]; x++ {
				// Unescape the string (HTML Entity -> String).
				emojiStr += html.UnescapeString("&#" + strconv.Itoa(56256) + ";")
				emojiStr += html.UnescapeString("&#" + strconv.Itoa(56452) + ";")
				// 	}
				// }
				out := fmt.Sprintf("您好，目前的動物名為%s, 所在地為:%s, 電話為:%s  %s", pet.Name, pet.Resettlement, pet.Phone, emojiStr)
				log.Println("Current msg:", out)
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(out)).Do(); err != nil {
					log.Print(err)
				}

			}
		case linebot.EventTypeBeacon:
			log.Println(" Beacon event....")
			if b := event.Beacon; b != nil {
				ret := fmt.Sprintln("Msg:", string(b.DeviceMessage), " hwid:", b.Hwid, " type:", b.Type)
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(ret)).Do(); err != nil {
					log.Print(err)
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/go.net/websocket"
	"flag"
	"fmt"
	"github.com/ugorji/go-msgpack"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"time"
)

const (
	CHAT_DIR   = "chat"
	IMAGES_DIR = "img"
	LOG_DIR    = "log"
	STATIC_DIR = "static"
)

var (
	GlobalLock     sync.Mutex
	port           *int  = flag.Int("p", 8000, "Port to listen.")
	foreground     *bool = flag.Bool("f", false, "Log on stdout.")
	save_wait      sync.WaitGroup
	index_template = template.Must(template.ParseFiles("templates/index.html"))
	Log            *log.Logger
)

func socket_handler(ws *websocket.Conn) {
	save_wait.Add(1)
	user := NewUser(ws)
	if user == nil {
		save_wait.Done()
		return
	}
	Log.Println("New user", user.UserId, "joins", user.Location.Url)
	for {
		var buf []byte
		err := websocket.Message.Receive(ws, &buf)
		if err != nil {
			Log.Printf("error while reading socket for user %v: %v\n", user.UserId, err)
			break
		}
		var v []interface{}
		err = msgpack.Unmarshal(buf, &v, nil)
		if err != nil {
			Log.Printf("this is not msgpack: '%v'\n", buf)
		} else {
			Log.Println("GotMessage", "want Lock")
			GlobalLock.Lock()
			Log.Println("GotMessage", "got Lock")
			user.GotMessage(v)
			GlobalLock.Unlock()
			Log.Println("GotMessage", "released Lock")
		}
	}
	Log.Println("OnClose", "want Lock")
	GlobalLock.Lock()
	Log.Println("OnClose", "got Lock")
	user.OnClose()
	GlobalLock.Unlock()
	Log.Println("OnClose", "released Lock")
	ws.Close()
	save_wait.Done()
}

func signal_handler(c chan os.Signal) {
	Log.Printf("signal %v\n", <-c)
	GlobalLock.Lock()
	for _, loc := range Locations {
		for _, user := range loc.Users {
			user.Socket.Close()
		}
	}
	GlobalLock.Unlock()
	save_wait.Wait()
	// Why do we become a daemon here ?
	Log.Printf("exit\n")
	os.Exit(0)
}

func init() {
	os.MkdirAll(CHAT_DIR, 0777)
	os.MkdirAll(IMAGES_DIR, 0777)
	os.MkdirAll(LOG_DIR, 0777)
	flag.Parse()
	now := time.Now()
	var log_file io.Writer
	var err error
	if *foreground == true {
		log_file = os.Stdout
	} else {
		log_file, err = os.Create(LOG_DIR + "/" + now.Format("2006-01-02_15:04:05"))
		if err != nil {
			fmt.Println(err)
			panic("Couldn't open log file.")
		}
	}
	Log = log.New(log_file, "", log.LstdFlags)
}

func index_handler(w http.ResponseWriter, r *http.Request) {
	err := index_template.Execute(w, CurrentlyUsedSites)
	if err != nil {
		Log.Printf("Couldn't execute template: %v\n", err)
	}
}

func main() {
	SignalChan := make(chan os.Signal)
	go signal_handler(SignalChan)
	signal.Notify(SignalChan, os.Interrupt, os.Kill)

	go func() {
		tick := time.Tick(10 * time.Second)
		for _ = range tick {
			UpdateCurrentlyUsedSites()
		}
	}()

	go func() {
		tick := time.Tick(1 * time.Minute)
		for _ = range tick {
			SaveAllLocations()
		}
	}()

	http.Handle("/ws", websocket.Handler(socket_handler))
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(STATIC_DIR))))
	http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir(IMAGES_DIR))))
	http.Handle("/", http.HandlerFunc(index_handler))
	Log.Printf("Listening on http://localhost:%d/\n", *port)
	err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)
	if err != nil {
		panic("ListenAndServe: " + err.Error())
	}
}
<commit_msg>corrected listening message<commit_after>package main

import (
	"code.google.com/p/go.net/websocket"
	"flag"
	"fmt"
	"github.com/ugorji/go-msgpack"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"time"
)

const (
	CHAT_DIR   = "chat"
	IMAGES_DIR = "img"
	LOG_DIR    = "log"
	STATIC_DIR = "static"
)

var (
	GlobalLock     sync.Mutex
	port           *int  = flag.Int("p", 8000, "Port to listen.")
	foreground     *bool = flag.Bool("f", false, "Log on stdout.")
	save_wait      sync.WaitGroup
	index_template = template.Must(template.ParseFiles("templates/index.html"))
	Log            *log.Logger
)

func socket_handler(ws *websocket.Conn) {
	save_wait.Add(1)
	user := NewUser(ws)
	if user == nil {
		save_wait.Done()
		return
	}
	Log.Println("New user", user.UserId, "joins", user.Location.Url)
	for {
		var buf []byte
		err := websocket.Message.Receive(ws, &buf)
		if err != nil {
			Log.Printf("error while reading socket for user %v: %v\n", user.UserId, err)
			break
		}
		var v []interface{}
		err = msgpack.Unmarshal(buf, &v, nil)
		if err != nil {
			Log.Printf("this is not msgpack: '%v'\n", buf)
		} else {
			Log.Println("GotMessage", "want Lock")
			GlobalLock.Lock()
			Log.Println("GotMessage", "got Lock")
			user.GotMessage(v)
			GlobalLock.Unlock()
			Log.Println("GotMessage", "released Lock")
		}
	}
	Log.Println("OnClose", "want Lock")
	GlobalLock.Lock()
	Log.Println("OnClose", "got Lock")
	user.OnClose()
	GlobalLock.Unlock()
	Log.Println("OnClose", "released Lock")
	ws.Close()
	save_wait.Done()
}

func signal_handler(c chan os.Signal) {
	Log.Printf("signal %v\n", <-c)
	GlobalLock.Lock()
	for _, loc := range Locations {
		for _, user := range loc.Users {
			user.Socket.Close()
		}
	}
	GlobalLock.Unlock()
	save_wait.Wait()
	// Why do we become a daemon here ?
	Log.Printf("exit\n")
	os.Exit(0)
}

func init() {
	os.MkdirAll(CHAT_DIR, 0777)
	os.MkdirAll(IMAGES_DIR, 0777)
	os.MkdirAll(LOG_DIR, 0777)
	flag.Parse()
	now := time.Now()
	var log_file io.Writer
	var err error
	if *foreground == true {
		log_file = os.Stdout
	} else {
		log_file, err = os.Create(LOG_DIR + "/" + now.Format("2006-01-02_15:04:05"))
		if err != nil {
			fmt.Println(err)
			panic("Couldn't open log file.")
		}
	}
	Log = log.New(log_file, "", log.LstdFlags)
}

func index_handler(w http.ResponseWriter, r *http.Request) {
	err := index_template.Execute(w, CurrentlyUsedSites)
	if err != nil {
		Log.Printf("Couldn't execute template: %v\n", err)
	}
}

func main() {
	SignalChan := make(chan os.Signal)
	go signal_handler(SignalChan)
	signal.Notify(SignalChan, os.Interrupt, os.Kill)

	go func() {
		tick := time.Tick(10 * time.Second)
		for _ = range tick {
			UpdateCurrentlyUsedSites()
		}
	}()

	go func() {
		tick := time.Tick(1 * time.Minute)
		for _ = range tick {
			SaveAllLocations()
		}
	}()

	http.Handle("/ws", websocket.Handler(socket_handler))
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(STATIC_DIR))))
	http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir(IMAGES_DIR))))
	http.Handle("/", http.HandlerFunc(index_handler))
	Log.Printf("Listening on port %d\n", *port)
	err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)
	if err != nil {
		panic("ListenAndServe: " + err.Error())
	}
}
<|endoftext|>


<commit_before>package main

import (
	log "github.com/Sirupsen/logrus"
	"github.com/TrilliumIT/docker-arp-ipam/driver"
	"github.com/docker/go-plugins-helpers/ipam"
	"github.com/urfave/cli"
	"os"
	"os/signal"
	"sync"
	"syscall"
)

func main() {

	app := cli.NewApp()
	app.Name = "docker-arp-ipam"
	app.Usage = "Docker ARP IPAM Plugin"
	app.Version = "0.4"
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug, d",
			Usage: "Enable debugging.",
		},
		cli.StringFlag{
			Name:  "plugin-name, name",
			Value: "arp-ipam",
			Usage: "Plugin Name. Useful if you want to run multiple instances of the plugin.",
		},
		cli.StringFlag{
			Name:  "address, addr",
			Value: ":8080",
			Usage: "TCP Address to bind the plugin on.",
		},
	}
	app.Action = Run
	app.Run(os.Args)
}

// Run initializes the driver
func Run(ctx *cli.Context) error {
	if ctx.Bool("debug") {
		log.SetLevel(log.DebugLevel)
	}
	log.SetFormatter(&log.TextFormatter{
		ForceColors:      false,
		DisableColors:    true,
		DisableTimestamp: false,
		FullTimestamp:    true,
	})

	quit := make(chan struct{}) // tells other goroutines to quit
	var wg sync.WaitGroup       // waits for goroutines to quit
	done := make(chan struct{}) // tells main that we're done
	ech := make(chan error)     // catches an error from serveTCP
	var err error               // holds the final return value

	c := make(chan os.Signal)
	defer close(c)
	signal.Notify(c, os.Interrupt)
	signal.Notify(c, syscall.SIGTERM)
	go func() {
		select {
		case _ = <-c:
			log.Debugf("Sigterm caught. Closing")
		case err = <-ech:
			log.Error(err)
		}
		close(quit)
		wg.Wait()
		close(done)
	}()

	d, err := driver.NewDriver(quit, wg)
	if err != nil {
		log.Error("Error initializing driver")
		ech <- err
	}

	h := ipam.NewHandler(d)
	go func() {
		ech <- h.ServeTCP(ctx.String("plugin-name"), ctx.String("address"))
	}()

	<-done
	return nil
}
<commit_msg>increment version<commit_after>package main

import (
	log "github.com/Sirupsen/logrus"
	"github.com/TrilliumIT/docker-arp-ipam/driver"
	"github.com/docker/go-plugins-helpers/ipam"
	"github.com/urfave/cli"
	"os"
	"os/signal"
	"sync"
	"syscall"
)

func main() {

	app := cli.NewApp()
	app.Name = "docker-arp-ipam"
	app.Usage = "Docker ARP IPAM Plugin"
	app.Version = "0.5"
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug, d",
			Usage: "Enable debugging.",
		},
		cli.StringFlag{
			Name:  "plugin-name, name",
			Value: "arp-ipam",
			Usage: "Plugin Name. Useful if you want to run multiple instances of the plugin.",
		},
		cli.StringFlag{
			Name:  "address, addr",
			Value: ":8080",
			Usage: "TCP Address to bind the plugin on.",
		},
	}
	app.Action = Run
	app.Run(os.Args)
}

// Run initializes the driver
func Run(ctx *cli.Context) error {
	if ctx.Bool("debug") {
		log.SetLevel(log.DebugLevel)
	}
	log.SetFormatter(&log.TextFormatter{
		ForceColors:      false,
		DisableColors:    true,
		DisableTimestamp: false,
		FullTimestamp:    true,
	})

	quit := make(chan struct{}) // tells other goroutines to quit
	var wg sync.WaitGroup       // waits for goroutines to quit
	done := make(chan struct{}) // tells main that we're done
	ech := make(chan error)     // catches an error from serveTCP
	var err error               // holds the final return value

	c := make(chan os.Signal)
	defer close(c)
	signal.Notify(c, os.Interrupt)
	signal.Notify(c, syscall.SIGTERM)
	go func() {
		select {
		case _ = <-c:
			log.Debugf("Sigterm caught. Closing")
		case err = <-ech:
			log.Error(err)
		}
		close(quit)
		wg.Wait()
		close(done)
	}()

	d, err := driver.NewDriver(quit, wg)
	if err != nil {
		log.Error("Error initializing driver")
		ech <- err
	}

	h := ipam.NewHandler(d)
	go func() {
		ech <- h.ServeTCP(ctx.String("plugin-name"), ctx.String("address"))
	}()

	<-done
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	//"runtime"
	//"time"
	"strconv"
)

func main() {

	http.HandleFunc("/", rootHandler)      // root handler
	http.HandleFunc("/user/", userHandler) // user handler

	//registerStatic("/www/", currDir)

	addr := ":8080"

	if len(os.Args) > 1 {
		addr = os.Args[1]
	}

	log.Printf("serving on port TCP %s", addr)

	if err := http.ListenAndServe(addr, nil); err != nil {
		log.Panicf("ListenAndServe: %s: %s", addr, err)
	}
}

/*
type staticHandler struct {
	innerHandler http.Handler
}

func registerStatic(path, dir string) {
	http.Handle(path, staticHandler{http.StripPrefix(path, http.FileServer(http.Dir(dir)))})
	log.Printf("registering static directory %s as www path %s", dir, path)
}

func (handler staticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Printf("staticHandler.ServeHTTP url=%s from=%s", r.URL.Path, r.RemoteAddr)
	handler.innerHandler.ServeHTTP(w, r)
}
*/

func rootHandler(w http.ResponseWriter, r *http.Request) {
	me := "rootHandler"
	msg := fmt.Sprintf("%s: url=%s from=%s", me, r.URL.Path, r.RemoteAddr)
	log.Printf(msg)

	code := http.StatusNotFound
	http.Error(w, strconv.Itoa(code)+" - "+http.StatusText(code)+" - "+msg, code)

	//io.WriteString(w, msg)
}

func userHandler(w http.ResponseWriter, r *http.Request) {
	me := "userHandler"
	msg := fmt.Sprintf("%s: url=%s from=%s", me, r.URL.Path, r.RemoteAddr)
	log.Printf(msg)

	user := r.URL.Path[len("/user/"):]

	if user == "" || user == "errorc" {
		code := http.StatusNotFound
		http.Error(w, me+": "+strconv.Itoa(code)+" - "+http.StatusText(code), code)
		return
	}

	ticket, err := getTicket(user)
	if err != nil {
		code := http.StatusInternalServerError
		http.Error(w, me+": "+strconv.Itoa(code)+" - "+http.StatusText(code)+": "+err.Error(), code)
		return
	}

	io.WriteString(w, msg+" ticket="+ticket)
}

func getTicket(user string) (string, error) {
	if user == "errors" {
		return "", fmt.Errorf("getTicket(errors)")
	}
	return user, nil
}
<commit_msg>Cache/db/compute skeleton.<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	//"runtime"
	"strconv"
	"sync"
	"sync/atomic"
	"time"
)

const (
	rootPath = "/"
	userPath = "/user/"
)

type serverContext struct {
	tickets    int64
	dbreads    int32
	computes   int32
	dbmutex    sync.RWMutex
	cachemutex sync.RWMutex
	db         map[string]string
	cache      map[string]string
}

func (s *serverContext) getTicket(user string) (string, int, error) {
	if user == "" || user == "errorc" {
		return "", http.StatusNotFound, fmt.Errorf("getTicket(errorc)")
	}
	if user == "errors" {
		return "", http.StatusInternalServerError, fmt.Errorf("getTicket(errors)")
	}

	// try cache
	t1, errCache := s.cacheRead(user)
	if errCache == nil {
		return t1, http.StatusOK, nil
	}

	// try DB
	t2, errDB := s.dbRead(user)
	if errDB == nil {
		s.cacheWrite(user, t2)
		return t2, http.StatusOK, nil
	}

	// try compute
	t3, errCompute := s.compute(user)
	if errCompute == nil {
		s.dbWrite(user, t3)
		return t3, http.StatusOK, nil
	}

	return "", http.StatusInternalServerError, fmt.Errorf("getTicket() failure: %v", errCompute)
}

func (s *serverContext) cacheRead(user string) (string, error) {
	defer s.cachemutex.RUnlock()
	s.cachemutex.RLock()

	t, found := s.cache[user]
	if found {
		return t, nil
	}

	return "", fmt.Errorf("cacheread not found")
}

func (s *serverContext) cacheWrite(user, ticket string) {
	defer s.cachemutex.Unlock()
	s.cachemutex.Lock()

	s.cache[user] = ticket
}

func (s *serverContext) dbRead(user string) (string, error) {
	defer atomic.AddInt32(&s.dbreads, -1)
	r := atomic.AddInt32(&s.dbreads, 1)
	delay := time.Duration(r) * 200 * time.Millisecond

	log.Printf("dbreads=%d delay=%v", r, delay)

	timeout := 2000 * time.Millisecond
	if delay > timeout {
		time.Sleep(timeout)
		return "", fmt.Errorf("dbread timeout: %v", timeout)
	}

	time.Sleep(delay)

	defer s.dbmutex.RUnlock()
	s.dbmutex.RLock()

	t, found := s.db[user]
	if found {
		return t, nil
	}

	return "", fmt.Errorf("dbread not found")
}

func (s *serverContext) dbWrite(user, ticket string) {
	defer s.dbmutex.Unlock()
	s.dbmutex.Lock()

	s.db[user] = ticket
}

func (s *serverContext) compute(user string) (string, error) {

	defer atomic.AddInt32(&s.computes, -1)
	c := atomic.AddInt32(&s.computes, 1)
	delay := time.Duration(c) * 1000 * time.Millisecond

	log.Printf("computes=%d delay=%v", c, delay)

	timeout := 10000 * time.Millisecond
	if delay > timeout {
		time.Sleep(timeout)
		return "", fmt.Errorf("compute timeout: %v", timeout)
	}

	time.Sleep(delay)

	n := atomic.AddInt64(&s.tickets, 1)
	t := strconv.FormatInt(n, 16)
	return t, nil
}

func main() {

	s := &serverContext{
		db:    map[string]string{},
		cache: map[string]string{},
	}

	http.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) { contextHandle(w, r, s, rootHandler) })
	http.HandleFunc(userPath, func(w http.ResponseWriter, r *http.Request) { contextHandle(w, r, s, userHandler) })

	//registerStatic("/www/", currDir)

	addr := ":8080"

	if len(os.Args) > 1 {
		addr = os.Args[1]
	}

	log.Printf("serving on port TCP %s", addr)

	if err := http.ListenAndServe(addr, nil); err != nil {
		log.Panicf("ListenAndServe: %s: %s", addr, err)
	}
}

/*
type staticHandler struct {
	innerHandler http.Handler
}

func registerStatic(path, dir string) {
	http.Handle(path, staticHandler{http.StripPrefix(path, http.FileServer(http.Dir(dir)))})
	log.Printf("registering static directory %s as www path %s", dir, path)
}

func (handler staticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Printf("staticHandler.ServeHTTP url=%s from=%s", r.URL.Path, r.RemoteAddr)
	handler.innerHandler.ServeHTTP(w, r)
}
*/

func contextHandle(w http.ResponseWriter, r *http.Request, s *serverContext, handler func(http.ResponseWriter, *http.Request, *serverContext)) {
	handler(w, r, s)
}

func rootHandler(w http.ResponseWriter, r *http.Request, s *serverContext) {
	me := "rootHandler"
	msg := fmt.Sprintf("%s: url=%s from=%s", me, r.URL.Path, r.RemoteAddr)
	log.Print(msg)

	code := http.StatusNotFound
	http.Error(w, strconv.Itoa(code)+" - "+http.StatusText(code)+" - "+msg, code)

	//io.WriteString(w, msg)
}

func userHandler(w http.ResponseWriter, r *http.Request, s *serverContext) {
	me := "userHandler"
	msg := fmt.Sprintf("%s: url=%s from=%s", me, r.URL.Path, r.RemoteAddr)
	log.Print(msg)

	user := r.URL.Path[len(userPath):]

	begin := time.Now()

	ticket, code, err := s.getTicket(user)

	elapsed := time.Since(begin)
	e := fmt.Sprintf(" (elapsed=%v) ", elapsed)

	if err != nil {
		http.Error(w, me+": "+strconv.Itoa(code)+" - "+http.StatusText(code)+": "+err.Error()+e, code)
		return
	}

	io.WriteString(w, msg+" ticket="+ticket+e)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
)

func main() {
	InitState()
	reader := bufio.NewReader(os.Stdin)
	for {
		input, err := reader.ReadString('\n')
		if input == "quit\n" || err == io.EOF {
			return
		} else {
			fmt.Print(XboardParse(strings.TrimSpace(input)))
		}
	}
}
<commit_msg>add -cpuprofile flag<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"strings"
	"log"
	"runtime/pprof"
)

var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func main() {
	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	InitState()
	reader := bufio.NewReader(os.Stdin)
	for {
		input, err := reader.ReadString('\n')
		if input == "quit\n" || err == io.EOF {
			return
		} else {
			fmt.Print(XboardParse(strings.TrimSpace(input)))
		}
	}
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

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

	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client

func main() {
	var err error
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {

			switch message := event.Message.(type) {
			case *linebot.TextMessage:

				msg := message.Text
				var keyword map[string]string
				keyword["罐罐"] = "肚子裡永遠少一罐"
				keyword["娜娜"] = "叫我嗎？叫一次一百萬"
				keyword["天氣"] = "不管天氣好壞,我都不想離開被窩"

				for index,element := range keyword {
					match, _ := regexp.MatchString(index, msg)
					if( match ){
						if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(element)).Do(); err != nil {
							log.Print(err)
						}

					} else {
						if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(msg)).Do(); err != nil {
							log.Print(err)
						}
					}
				}

			}
		}
	}
}
<commit_msg>keyword array<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

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

	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client

func main() {
	var err error
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {

			switch message := event.Message.(type) {
			case *linebot.TextMessage:

				msg := message.Text
				var keyword map[string]string
				keyword["罐罐"] = "肚子裡永遠少一罐"
				keyword["娜娜"] = "叫我嗎？叫一次一百萬"
				keyword["天氣"] = "不管天氣好壞,我都不想離開被窩"

				bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(keyword)).Do();
				for index,element := range keyword {
					match, _ := regexp.MatchString(index, msg)
					if( match ){
						if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(element)).Do(); err != nil {
							log.Print(err)
						}

					} else {
						if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(msg)).Do(); err != nil {
							log.Print(err)
						}
					}
				}

			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"os"
	"os/signal"

	reaperaws "github.com/mozilla-services/reaper/aws"
	reaperevents "github.com/mozilla-services/reaper/events"
	"github.com/mozilla-services/reaper/reaper"
	log "github.com/mozilla-services/reaper/reaperlog"
)

var (
	config         reaper.Config
	eventReporters []reaperevents.ReapableEventReporter
)

func init() {
	configFile := flag.String("config", "", "path to config file")
	dryRun := flag.Bool("dryrun", true, "dry run, don't trigger events")
	interactive := flag.Bool("interactive", false, "interactive mode, reap based on prompt")
	withoutCloudformationResources := flag.Bool("withoutCloudformationResources", false, "enables dependency checking for Cloudformations (slow!)")
	loadFromStateFile := flag.Bool("load", false, "load state from state file specified in config (overrides AWS state)")
	flag.Parse()

	// if no config file -> exit with error
	if *configFile == "" {
		log.Error("Config file is a required Argument. Specify with -config='filename'")
		os.Exit(1)
	}

	// if config file path specified, attempt to load it
	if c, err := reaper.LoadConfig(*configFile); err == nil {
		// catches panics loading config
		defer func() {
			if r := recover(); r != nil {
				log.Error("Invalid config ", r)
				os.Exit(1)
			}
		}()
		config = *c
		log.Info("Configuration loaded from ", *configFile)
	} else {
		// config not successfully loaded -> exit with error
		log.Error("toml", err)
		os.Exit(1)
	}

	// if log file path specified, attempt to load it
	if config.LogFile != "" {
		log.AddLogFile(config.LogFile)
	}

	// if Datadog EventReporter is enabled
	if config.Events.DataDog.Enabled {
		log.Info("DataDog EventReporter enabled.")
		eventReporters = append(eventReporters, reaperevents.NewDatadog(&config.Events.DataDog))
	}

	// if Email ReapableEventReporter is enabled
	if config.Events.Email.Enabled {
		log.Info("Email EventReporter enabled.")
		eventReporters = append(eventReporters, reaperevents.NewMailer(&config.Events.Email))
		// these methods have pointer receivers
		log.Debug("SMTP Config: %s", &config.Events.Email)
		log.Debug("SMTP From: %s", &config.Events.Email.From)
	}

	// if Tagger ReapableEventReporter is enabled
	if config.Events.Tagger.Enabled {
		log.Info("Tagger EventReporter enabled.")
		eventReporters = append(eventReporters, reaperevents.NewTagger(&config.Events.Tagger))
	}

	// if Reaper ReapableEventReporter is enabled
	if config.Events.Reaper.Enabled {
		log.Info("Reaper EventReporter enabled.")
		eventReporters = append(eventReporters, reaperevents.NewReaperEvent(&config.Events.Reaper))
	}

	// interactive mode disables all other EventReporters
	// TODO: interactive mode config flag does nothing
	config.Interactive = *interactive
	if *interactive {
		log.Info("Interactive mode enabled, you will be prompted to handle reapables. All other EventReporters are disabled.")
		eventReporters = []reaperevents.ReapableEventReporter{reaperevents.NewInteractiveEvent(&config.Events.Interactive)}
	}

	// if a WhitelistTag is set
	if config.WhitelistTag == "" {
		// set the config's WhitelistTag
		log.Error("WhitelistTag is empty, exiting")
		os.Exit(1)
	} else {
		// else use the default
		log.Info("Using WhitelistTag '%s'", config.WhitelistTag)
	}

	config.DryRun = *dryRun
	if *dryRun {
		log.Info("Dry run mode enabled, no events will be triggered. Enable Extras in Notifications for per-event DryRun notifications.")
		for _, eventReporter := range eventReporters {
			eventReporter.SetDryRun(true)
		}
	}

	if *withoutCloudformationResources {
		config.AWS.WithoutCloudformationResources = true
	}

	if *loadFromStateFile && config.StateFile != "" {
		config.LoadFromStateFile = *loadFromStateFile
		log.Info("State will be loaded from %s", config.StateFile)
	}
}

func main() {
	// config and events are vars in the reaper package
	// they NEED to be set before a reaper.Reaper can be initialized
	reaper.SetConfig(&config)
	reaper.SetEvents(&eventReporters)

	// Ready() NEEDS to be called after BOTH SetConfig() and SetEvents()
	// it uses those values to set individual EventReporter config values
	// and to init the Reapables map
	reaper.Ready()

	// sets the config variable in Reaper's AWS package
	// this also NEEDS to be set before a Reaper can be started
	reaperaws.SetConfig(&config.AWS)

	// single instance of reaper
	reapRunner := reaper.NewReaper()
	// Run the reaper process
	reapRunner.Start()

	// run the HTTP server
	api := reaper.NewHTTPApi(config.HTTP)
	if err := api.Serve(); err != nil {
		log.Error(err.Error())
	} else {
		// HTTP server successfully started
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)

		// waiting for an Interrupt or Kill signal
		// this channel blocks until it receives one
		sig := <-c
		log.Info("Got signal %s, stopping services", sig.String())
		log.Info("Stopping HTTP")
		api.Stop()
		log.Info("Stopping reaper runner")
		reapRunner.Stop()
	}
}
<commit_msg>fix deceptive wording in withoutCloudformationResources description<commit_after>package main

import (
	"flag"
	"os"
	"os/signal"

	reaperaws "github.com/mozilla-services/reaper/aws"
	reaperevents "github.com/mozilla-services/reaper/events"
	"github.com/mozilla-services/reaper/reaper"
	log "github.com/mozilla-services/reaper/reaperlog"
)

var (
	config         reaper.Config
	eventReporters []reaperevents.ReapableEventReporter
)

func init() {
	configFile := flag.String("config", "", "path to config file")
	dryRun := flag.Bool("dryrun", true, "dry run, don't trigger events")
	interactive := flag.Bool("interactive", false, "interactive mode, reap based on prompt")
	withoutCloudformationResources := flag.Bool("withoutCloudformationResources", false, "disables dependency checking for Cloudformations (which is slow!)")
	loadFromStateFile := flag.Bool("load", false, "load state from state file specified in config (overrides AWS state)")
	flag.Parse()

	// if no config file -> exit with error
	if *configFile == "" {
		log.Error("Config file is a required Argument. Specify with -config='filename'")
		os.Exit(1)
	}

	// if config file path specified, attempt to load it
	if c, err := reaper.LoadConfig(*configFile); err == nil {
		// catches panics loading config
		defer func() {
			if r := recover(); r != nil {
				log.Error("Invalid config ", r)
				os.Exit(1)
			}
		}()
		config = *c
		log.Info("Configuration loaded from ", *configFile)
	} else {
		// config not successfully loaded -> exit with error
		log.Error("toml", err)
		os.Exit(1)
	}

	// if log file path specified, attempt to load it
	if config.LogFile != "" {
		log.AddLogFile(config.LogFile)
	}

	// if Datadog EventReporter is enabled
	if config.Events.DataDog.Enabled {
		log.Info("DataDog EventReporter enabled.")
		eventReporters = append(eventReporters, reaperevents.NewDatadog(&config.Events.DataDog))
	}

	// if Email ReapableEventReporter is enabled
	if config.Events.Email.Enabled {
		log.Info("Email EventReporter enabled.")
		eventReporters = append(eventReporters, reaperevents.NewMailer(&config.Events.Email))
		// these methods have pointer receivers
		log.Debug("SMTP Config: %s", &config.Events.Email)
		log.Debug("SMTP From: %s", &config.Events.Email.From)
	}

	// if Tagger ReapableEventReporter is enabled
	if config.Events.Tagger.Enabled {
		log.Info("Tagger EventReporter enabled.")
		eventReporters = append(eventReporters, reaperevents.NewTagger(&config.Events.Tagger))
	}

	// if Reaper ReapableEventReporter is enabled
	if config.Events.Reaper.Enabled {
		log.Info("Reaper EventReporter enabled.")
		eventReporters = append(eventReporters, reaperevents.NewReaperEvent(&config.Events.Reaper))
	}

	// interactive mode disables all other EventReporters
	// TODO: interactive mode config flag does nothing
	config.Interactive = *interactive
	if *interactive {
		log.Info("Interactive mode enabled, you will be prompted to handle reapables. All other EventReporters are disabled.")
		eventReporters = []reaperevents.ReapableEventReporter{reaperevents.NewInteractiveEvent(&config.Events.Interactive)}
	}

	// if a WhitelistTag is set
	if config.WhitelistTag == "" {
		// set the config's WhitelistTag
		log.Error("WhitelistTag is empty, exiting")
		os.Exit(1)
	} else {
		// else use the default
		log.Info("Using WhitelistTag '%s'", config.WhitelistTag)
	}

	config.DryRun = *dryRun
	if *dryRun {
		log.Info("Dry run mode enabled, no events will be triggered. Enable Extras in Notifications for per-event DryRun notifications.")
		for _, eventReporter := range eventReporters {
			eventReporter.SetDryRun(true)
		}
	}

	if *withoutCloudformationResources {
		config.AWS.WithoutCloudformationResources = true
	}

	if *loadFromStateFile && config.StateFile != "" {
		config.LoadFromStateFile = *loadFromStateFile
		log.Info("State will be loaded from %s", config.StateFile)
	}
}

func main() {
	// config and events are vars in the reaper package
	// they NEED to be set before a reaper.Reaper can be initialized
	reaper.SetConfig(&config)
	reaper.SetEvents(&eventReporters)

	// Ready() NEEDS to be called after BOTH SetConfig() and SetEvents()
	// it uses those values to set individual EventReporter config values
	// and to init the Reapables map
	reaper.Ready()

	// sets the config variable in Reaper's AWS package
	// this also NEEDS to be set before a Reaper can be started
	reaperaws.SetConfig(&config.AWS)

	// single instance of reaper
	reapRunner := reaper.NewReaper()
	// Run the reaper process
	reapRunner.Start()

	// run the HTTP server
	api := reaper.NewHTTPApi(config.HTTP)
	if err := api.Serve(); err != nil {
		log.Error(err.Error())
	} else {
		// HTTP server successfully started
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)

		// waiting for an Interrupt or Kill signal
		// this channel blocks until it receives one
		sig := <-c
		log.Info("Got signal %s, stopping services", sig.String())
		log.Info("Stopping HTTP")
		api.Stop()
		log.Info("Stopping reaper runner")
		reapRunner.Stop()
	}
}
<|endoftext|>