<commit_before>package main

import (
	"log"
	"net/http"
	"net/url"
	"strings"

	"github.com/go-martini/martini"
	"github.com/martini-contrib/sessions"

	"github.com/tomsteele/dmv"

	"net/http/httputil"

	"github.com/boltdb/bolt"
	gsessions "github.com/gorilla/sessions"
	"github.com/yosssi/boltstore/reaper"
	bstore "github.com/yosssi/boltstore/store"

	"github.com/joeshaw/envdecode"
)

type Config struct {
	ClientId      string `env:"CLIENT_ID,required"`      // Google Client ID
	ClientSecret  string `env:"CLIENT_SECRET,required"`  // Google Client Secret
	SessionSecret []byte `env:"SESSION_SECRET,required"` // Random session encruption token
	DNSName       string `env:"DNS_NAME,required"`       // Public facing DNS Hostname

	SessionDBPath string `env:"SESSION_DB_PATH,default=./sessions.db"` // Path to session database, including db name
	CookieMaxAge  int    `env:"COOKIE_MAX_AGE,default=1440"`           // Cookie MaxAge, Defaults to 1 day
	CookieName    string `env:"COOKIE_NAME,default=sproxy_session"`    // The name of the cookie

	ProxyURL string `env:"PROXY_URL,default=http://localhost:8000/"` // URL to Proxy to

	CallBackPath string `env:"CALLBACK_PATH,default=/auth/callback/google"` // Callback URL
	AuthPath     string `env:"AUTH_PATH,default=/auth/google"`              // Auth Path

	HealthCheckPath string `env:"HEALTH_CHECK_PATH,default=/en-US/static/html/status.html"` // Health Check path in splunk, this path is proxied w/o auth. The default is a static file served by the splunk web server

	EmailSuffix string `env:"EMAIL_SUFFIX,default=@heroku.com"` // Required email suffix. Emails w/o this suffix will not be let in
}

var (
	cfg              = Config{}
	oAuthScopes      = []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"}
	sessionOptions   = gsessions.Options{Secure: true, HttpOnly: true}
	boltStoreOptions = bstore.Config{SessionOptions: sessionOptions}
)

// Authorize the user based on email and a set OpenIDUser
func authorize(s sessions.Session, rw http.ResponseWriter, req *http.Request) {
	email := s.Get("email")
	if email == nil || !strings.HasSuffix(email.(string), cfg.EmailSuffix) {
		http.Redirect(rw, req, cfg.AuthPath, http.StatusFound)
		return
	}

	openIDUser := s.Get("OpenIDUser")
	if openIDUser != nil && openIDUser != "" {
		req.Header.Set("X-Openid-User", openIDUser.(string))
	} else {
		// No openIDUser set, so abort and restart the auth flow
		http.Redirect(rw, req, cfg.AuthPath, http.StatusFound)
	}
}

// Set the OpenIDUser and other session values based on the data from Google
func handleCallback(goog *dmv.Google, s sessions.Session, rw http.ResponseWriter, req *http.Request) {
	// Handle any errors.
	if len(goog.Errors) > 0 {
		http.Error(rw, "Oauth failure", http.StatusInternalServerError)
		return
	}

	s.Set("GoogleID", goog.Profile.ID)
	s.Set("email", goog.Profile.Email)

	parts := strings.SplitN(goog.Profile.Email, "@", 2)
	if len(parts) < 2 {
		http.Error(rw, "Unable to determine OpenIDUser from email `"+goog.Profile.Email+"`", http.StatusInternalServerError)
		return
	}
	s.Set("OpenIDUser", parts[0])

	http.Redirect(rw, req, "/", http.StatusFound)
}

// Ensure that we're being proxied to ourselves via https
func enforceXForwardedProto(rw http.ResponseWriter, req *http.Request) {
	xff := req.Header.Get("X-Forwarded-Proto")
	if xff != "https" {
		u := new(url.URL)
		*u = *req.URL
		u.Scheme = "https"
		if u.Host == "" {
			u.Host = req.Host
		}

		http.Redirect(rw, req, u.String(), http.StatusFound)
	}
}

func main() {

	err := envdecode.Decode(&cfg)
	if err != nil {
		log.Fatal(err)
	}
	sessionOptions.MaxAge = cfg.CookieMaxAge

	googleOpts := &dmv.OAuth2Options{
		ClientID:     cfg.ClientId,
		ClientSecret: cfg.ClientSecret,
		RedirectURL:  "https://" + cfg.DNSName + cfg.CallBackPath,
		Scopes:       oAuthScopes,
	}

	sessionDB, err := bolt.Open(cfg.SessionDBPath, 0666, nil)
	if err != nil {
		log.Fatal(err)
	}

	defer sessionDB.Close()
	defer reaper.Quit(reaper.Run(sessionDB, reaper.Options{}))

	m := martini.Classic()

	pUrl, err := url.Parse(cfg.ProxyURL)

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

	store, err := bstore.New(sessionDB, boltStoreOptions, cfg.SessionSecret)
	if err != nil {
		log.Fatal(err)
	}

	// Inject a session when it's needed
	m.Use(sessions.Sessions(cfg.CookieName, store))

	proxy := httputil.NewSingleHostReverseProxy(pUrl)

	// Health Check URL, so just proxy w/o any processing
	m.Get(cfg.HealthCheckPath, proxy.ServeHTTP)

	// Google Auth
	m.Get(cfg.AuthPath, dmv.AuthGoogle(googleOpts))
	m.Get(cfg.CallBackPath, dmv.AuthGoogle(googleOpts), handleCallback)

	// Proxy the rest
	m.Get("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Put("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Post("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Delete("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Options("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Run()
}
<commit_msg>String, not []byte<commit_after>package main

import (
	"log"
	"net/http"
	"net/url"
	"strings"

	"github.com/go-martini/martini"
	"github.com/martini-contrib/sessions"

	"github.com/tomsteele/dmv"

	"net/http/httputil"

	"github.com/boltdb/bolt"
	gsessions "github.com/gorilla/sessions"
	"github.com/yosssi/boltstore/reaper"
	bstore "github.com/yosssi/boltstore/store"

	"github.com/joeshaw/envdecode"
)

type Config struct {
	ClientId      string `env:"CLIENT_ID,required"`      // Google Client ID
	ClientSecret  string `env:"CLIENT_SECRET,required"`  // Google Client Secret
	SessionSecret string `env:"SESSION_SECRET,required"` // Random session encruption token
	DNSName       string `env:"DNS_NAME,required"`       // Public facing DNS Hostname

	SessionDBPath string `env:"SESSION_DB_PATH,default=./sessions.db"` // Path to session database, including db name
	CookieMaxAge  int    `env:"COOKIE_MAX_AGE,default=1440"`           // Cookie MaxAge, Defaults to 1 day
	CookieName    string `env:"COOKIE_NAME,default=sproxy_session"`    // The name of the cookie

	ProxyURL string `env:"PROXY_URL,default=http://localhost:8000/"` // URL to Proxy to

	CallBackPath string `env:"CALLBACK_PATH,default=/auth/callback/google"` // Callback URL
	AuthPath     string `env:"AUTH_PATH,default=/auth/google"`              // Auth Path

	HealthCheckPath string `env:"HEALTH_CHECK_PATH,default=/en-US/static/html/status.html"` // Health Check path in splunk, this path is proxied w/o auth. The default is a static file served by the splunk web server

	EmailSuffix string `env:"EMAIL_SUFFIX,default=@heroku.com"` // Required email suffix. Emails w/o this suffix will not be let in
}

var (
	cfg              = Config{}
	oAuthScopes      = []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"}
	sessionOptions   = gsessions.Options{Secure: true, HttpOnly: true}
	boltStoreOptions = bstore.Config{SessionOptions: sessionOptions}
)

// Authorize the user based on email and a set OpenIDUser
func authorize(s sessions.Session, rw http.ResponseWriter, req *http.Request) {
	email := s.Get("email")
	if email == nil || !strings.HasSuffix(email.(string), cfg.EmailSuffix) {
		http.Redirect(rw, req, cfg.AuthPath, http.StatusFound)
		return
	}

	openIDUser := s.Get("OpenIDUser")
	if openIDUser != nil && openIDUser != "" {
		req.Header.Set("X-Openid-User", openIDUser.(string))
	} else {
		// No openIDUser set, so abort and restart the auth flow
		http.Redirect(rw, req, cfg.AuthPath, http.StatusFound)
	}
}

// Set the OpenIDUser and other session values based on the data from Google
func handleCallback(goog *dmv.Google, s sessions.Session, rw http.ResponseWriter, req *http.Request) {
	// Handle any errors.
	if len(goog.Errors) > 0 {
		http.Error(rw, "Oauth failure", http.StatusInternalServerError)
		return
	}

	s.Set("GoogleID", goog.Profile.ID)
	s.Set("email", goog.Profile.Email)

	parts := strings.SplitN(goog.Profile.Email, "@", 2)
	if len(parts) < 2 {
		http.Error(rw, "Unable to determine OpenIDUser from email `"+goog.Profile.Email+"`", http.StatusInternalServerError)
		return
	}
	s.Set("OpenIDUser", parts[0])

	http.Redirect(rw, req, "/", http.StatusFound)
}

// Ensure that we're being proxied to ourselves via https
func enforceXForwardedProto(rw http.ResponseWriter, req *http.Request) {
	xff := req.Header.Get("X-Forwarded-Proto")
	if xff != "https" {
		u := new(url.URL)
		*u = *req.URL
		u.Scheme = "https"
		if u.Host == "" {
			u.Host = req.Host
		}

		http.Redirect(rw, req, u.String(), http.StatusFound)
	}
}

func main() {

	err := envdecode.Decode(&cfg)
	if err != nil {
		log.Fatal(err)
	}
	sessionOptions.MaxAge = cfg.CookieMaxAge

	googleOpts := &dmv.OAuth2Options{
		ClientID:     cfg.ClientId,
		ClientSecret: cfg.ClientSecret,
		RedirectURL:  "https://" + cfg.DNSName + cfg.CallBackPath,
		Scopes:       oAuthScopes,
	}

	sessionDB, err := bolt.Open(cfg.SessionDBPath, 0666, nil)
	if err != nil {
		log.Fatal(err)
	}

	defer sessionDB.Close()
	defer reaper.Quit(reaper.Run(sessionDB, reaper.Options{}))

	m := martini.Classic()

	pUrl, err := url.Parse(cfg.ProxyURL)

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

	store, err := bstore.New(sessionDB, boltStoreOptions, []byte(cfg.SessionSecret))
	if err != nil {
		log.Fatal(err)
	}

	// Inject a session when it's needed
	m.Use(sessions.Sessions(cfg.CookieName, store))

	proxy := httputil.NewSingleHostReverseProxy(pUrl)

	// Health Check URL, so just proxy w/o any processing
	m.Get(cfg.HealthCheckPath, proxy.ServeHTTP)

	// Google Auth
	m.Get(cfg.AuthPath, dmv.AuthGoogle(googleOpts))
	m.Get(cfg.CallBackPath, dmv.AuthGoogle(googleOpts), handleCallback)

	// Proxy the rest
	m.Get("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Put("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Post("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Delete("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Options("/**", enforceXForwardedProto, authorize, proxy.ServeHTTP)
	m.Run()
}
<|endoftext|>


<commit_before>package main

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

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

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

const ServerName = "Snake-Server"

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

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

var (
	address string

	flagEnableTLS bool
	certFile      string
	keyFile       string

	groupsLimit int
	connsLimit  int
	seed        int64

	flagJSONLog bool
	logLevel    string
)

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

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

func logger() *logrus.Logger {
	logger := logrus.New()
	if flagJSONLog {
		logger.Formatter = &logrus.JSONFormatter{}
	} else {
		// TODO: Set up formatter with colors for windows ?
		// https://github.com/sirupsen/logrus/issues/172
	}
	if level, err := logrus.ParseLevel(logLevel); err != nil {
		logger.SetLevel(logrus.InfoLevel)
	} else {
		logger.SetLevel(level)
	}
	return logger
}

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

func main() {
	logger := logger()

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

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

	rand.Seed(seed)

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

	rootRouter := mux.NewRouter()

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

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

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

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

	if err := serve(n); err != nil {
		logger.Fatalf("server error: %s", err)
	}
}
<commit_msg>Create OS detecting to disable color output for windows<commit_after>package main

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

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

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

const ServerName = "Snake-Server"

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

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

var (
	address string

	flagEnableTLS bool
	certFile      string
	keyFile       string

	groupsLimit int
	connsLimit  int
	seed        int64

	flagJSONLog bool
	logLevel    string
)

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

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

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

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

func main() {
	logger := logger()

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

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

	rand.Seed(seed)

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

	rootRouter := mux.NewRouter()

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

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

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

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

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


<commit_before>package main

import (
	"fmt"
	"time"
)

const TWSEURL string = "http://mis.tse.com.tw/"

//STOCKPATH = '/stock/api/getStockInfo.jsp?ex_ch=%(exchange)s_%(no)s.tw_%(date)s&json=1&delay=%(delay)s&_=%(timestamp)s'

type StockOption struct {
	no        string
	timestamp int64
	date      time.Time
}

func (stock StockOption) GenStockUrl() string {
	return fmt.Sprintf(
		"%sstock/api/getStockInfo.jsp?ex_ch=%s_%s.tw_%s&json=1&delay=0&_=%d",
		TWSEURL,
		"tse",
		stock.no,
		fmt.Sprintf(
			"%d%02d%02d",
			stock.date.Year(),
			int(stock.date.Month()),
			stock.date.Day(),
		),
		stock.timestamp,
	)
}

type jsonBlob struct {
	Args    map[string]interface{}
	Headers map[string]interface{}
}

func main() {
	//url := "http://httpbin.org/get?name=Toomore"
	//resp, _ := http.Get(url)
	//defer resp.Body.Close()
	//resp_data, _ := ioutil.ReadAll(resp.Body)
	//var json_blob jsonBlob
	//json.Unmarshal(resp_data, &json_blob)
	//fmt.Printf("%+v", json_blob)
	//fmt.Println(json_blob.Args["name"], TWSEURL)
	option := StockOption{
		no:        "2618",
		timestamp: time.Now().Unix(),
		date:      time.Date(2014, time.August, 11, 0, 0, 0, 0, time.Local),
	}
	fmt.Println(option)
	fmt.Println(option.GenStockUrl())
}
<commit_msg>JSON parse.<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

const TWSEURL string = "http://mis.tse.com.tw/"

//STOCKPATH = '/stock/api/getStockInfo.jsp?ex_ch=%(exchange)s_%(no)s.tw_%(date)s&json=1&delay=%(delay)s&_=%(timestamp)s'

type StockOption struct {
	no        string
	timestamp int64
	date      time.Time
}

func (stock StockOption) GenStockUrl() string {
	return fmt.Sprintf(
		"%sstock/api/getStockInfo.jsp?ex_ch=%s_%s.tw_%s&json=1&delay=0&_=%d",
		TWSEURL,
		"tse",
		stock.no,
		fmt.Sprintf(
			"%d%02d%02d",
			stock.date.Year(),
			int(stock.date.Month()),
			stock.date.Day(),
		),
		stock.timestamp,
	)
}

func (stock StockOption) GetData() (value stockBlob) {
	url := stock.GenStockUrl()
	resp, _ := http.Get(url)
	defer resp.Body.Close()
	json.NewDecoder(resp.Body).Decode(&value)
	return
}

type jsonBlob struct {
	Args    map[string]interface{}
	Headers map[string]interface{}
}

type QueryTimeBlob struct {
	sysTime           string
	sessionLatestTime int
	sysDate           string
}

type stockBlob struct {
	Rtcode    string
	UserDelay int
	Rtmessage string
	Referer   string
	MsgArray  []map[string]string
	QueryTime map[string]interface{}
}

func main() {
	stock := StockOption{
		no:        "2618",
		timestamp: time.Now().Unix(),
		date:      time.Date(2014, time.August, 11, 0, 0, 0, 0, time.Local),
	}
	fmt.Println(stock.GenStockUrl())
	store_data := stock.GetData()
	fmt.Printf("%+v\n", store_data)
	fmt.Printf("%+v\n", store_data.QueryTime)
	fmt.Printf("%s\n", store_data.QueryTime["sysTime"])
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	"github.com/urfave/cli"
)

var Version string = "0.8.0"

func main() {
	newApp().Run(os.Args)
}

func newApp() *cli.App {
	app := cli.NewApp()
	app.Name = "ghq"
	app.Usage = "Manage GitHub repository clones"
	app.Version = Version
	app.Author = "motemen"
	app.Email = "motemen@gmail.com"
	app.Commands = Commands
	return app
}
<commit_msg>bump version to 0.9.0<commit_after>package main

import (
	"os"

	"github.com/urfave/cli"
)

var Version string = "0.9.0"

func main() {
	newApp().Run(os.Args)
}

func newApp() *cli.App {
	app := cli.NewApp()
	app.Name = "ghq"
	app.Usage = "Manage GitHub repository clones"
	app.Version = Version
	app.Author = "motemen"
	app.Email = "motemen@gmail.com"
	app.Commands = Commands
	return app
}
<|endoftext|>


<commit_before>package main

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

	log "github.com/Sirupsen/logrus"
	"github.com/Sirupsen/logrus/hooks/sentry"
	"github.com/facebookgo/inject"
	"github.com/robfig/cron"

	"github.com/oursky/skygear/asset"
	"github.com/oursky/skygear/authtoken"
	"github.com/oursky/skygear/handler"
	"github.com/oursky/skygear/plugin"
	_ "github.com/oursky/skygear/plugin/exec"
	"github.com/oursky/skygear/plugin/hook"
	"github.com/oursky/skygear/plugin/provider"
	_ "github.com/oursky/skygear/plugin/zmq"
	pp "github.com/oursky/skygear/preprocessor"
	"github.com/oursky/skygear/pubsub"
	"github.com/oursky/skygear/push"
	"github.com/oursky/skygear/router"
	"github.com/oursky/skygear/skyconfig"
	"github.com/oursky/skygear/skydb"
	_ "github.com/oursky/skygear/skydb/pq"
	"github.com/oursky/skygear/subscription"
)

func usage() {
	fmt.Println("Usage: skygear [<config file>]")
}

func main() {
	var configPath string
	if len(os.Args) < 2 {
		configPath = os.Getenv("OD_CONFIG")
		if configPath == "" {
			usage()
			return
		}
	} else {
		configPath = os.Args[1]
	}

	config := skyconfig.Configuration{}
	if err := skyconfig.ReadFileInto(&config, configPath); err != nil {
		fmt.Println(err.Error())
		return
	}

	initLogger(config)
	connOpener := ensureDB(config) // Fatal on DB failed

	// Init all the services
	r := router.NewRouter()
	pushSender := initPushSender(config, connOpener)

	tokenStore := authtoken.InitTokenStore(config.TokenStore.ImplName, config.TokenStore.Path)

	preprocessorRegistry := router.PreprocessorRegistry{}

	cronjob := cron.New()
	initContext := plugin.InitContext{
		Router:           r,
		Preprocessors:    preprocessorRegistry,
		HookRegistry:     hook.NewRegistry(),
		ProviderRegistry: provider.NewRegistry(),
		Scheduler:        cronjob,
		Config:           config,
	}

	internalHub := pubsub.NewHub()
	initSubscription(config, connOpener, internalHub, pushSender)
	initDevice(config, connOpener)

	// Preprocessor
	preprocessorRegistry["notification"] = &pp.NotificationPreprocessor{
		NotificationSender: pushSender,
	}
	preprocessorRegistry["accesskey"] = &pp.AccessKeyValidatonPreprocessor{
		Key:     config.App.APIKey,
		AppName: config.App.Name,
	}
	preprocessorRegistry["authenticator"] = &pp.UserAuthenticator{
		APIKey:     config.App.APIKey,
		AppName:    config.App.Name,
		TokenStore: tokenStore,
	}
	preprocessorRegistry["dbconn"] = &pp.ConnPreprocessor{
		AppName:       config.App.Name,
		AccessControl: config.App.AccessControl,
		DBOpener:      skydb.Open,
		DBImpl:        config.DB.ImplName,
		Option:        config.DB.Option,
	}
	preprocessorRegistry["plugin"] = &pp.EnsurePluginReadyPreprocessor{&initContext}
	preprocessorRegistry["inject_user"] = &pp.InjectUserIfPresent{}
	preprocessorRegistry["require_user"] = &pp.RequireUserForWrite{}
	preprocessorRegistry["inject_db"] = &pp.InjectDatabase{}
	preprocessorRegistry["inject_public_db"] = &pp.InjectPublicDatabase{}
	preprocessorRegistry["dev_only"] = &pp.DevOnlyProcessor{config.App.DevMode}

	r.Map("", &handler.HomeHandler{}, preprocessorRegistry["dev_only"])

	g := &inject.Graph{}
	injectErr := g.Provide(
		&inject.Object{Value: initContext.ProviderRegistry, Complete: true, Name: "ProviderRegistry"},
		&inject.Object{Value: initContext.HookRegistry, Complete: true, Name: "HookRegistry"},
		&inject.Object{Value: tokenStore, Complete: true, Name: "TokenStore"},
		&inject.Object{Value: initAssetStore(config), Complete: true, Name: "AssetStore"},
		&inject.Object{Value: pushSender, Complete: true, Name: "PushSender"},
		&inject.Object{
			Value:    skydb.GetAccessModel(config.App.AccessControl),
			Complete: true,
			Name:     "AccessModel",
		},
	)
	if injectErr != nil {
		panic(fmt.Sprintf("Unable to set up handler: %v", injectErr))
	}

	injector := router.HandlerInjector{
		g,
		&preprocessorRegistry,
	}

	r.Map("auth:signup", injector.Inject(&handler.SignupHandler{}))
	r.Map("auth:login", injector.Inject(&handler.LoginHandler{}))
	r.Map("auth:logout", injector.Inject(&handler.LogoutHandler{}))
	r.Map("auth:password", injector.Inject(&handler.PasswordHandler{}))

	r.Map("record:fetch", injector.Inject(&handler.RecordFetchHandler{}))
	r.Map("record:query", injector.Inject(&handler.RecordQueryHandler{}))
	r.Map("record:save", injector.Inject(&handler.RecordSaveHandler{}))
	r.Map("record:delete", injector.Inject(&handler.RecordDeleteHandler{}))

	r.Map("device:register", injector.Inject(&handler.DeviceRegisterHandler{}))

	// subscription shares the same set of preprocessor as record read at the moment
	r.Map("subscription:fetch_all", injector.Inject(&handler.SubscriptionFetchAllHandler{}))
	r.Map("subscription:delete", injector.Inject(&handler.SubscriptionDeleteHandler{}))

	// relation shares the same setof preprocessor
	r.Map("relation:query", injector.Inject(&handler.RelationQueryHandler{}))
	r.Map("relation:add", injector.Inject(&handler.RelationAddHandler{}))
	r.Map("relation:remove", injector.Inject(&handler.RelationRemoveHandler{}))

	r.Map("user:query", injector.Inject(&handler.UserQueryHandler{}))
	r.Map("user:update", injector.Inject(&handler.UserUpdateHandler{}))
	r.Map("user:link", injector.Inject(&handler.UserLinkHandler{}))

	r.Map("role:default", injector.Inject(&handler.RoleDefaultHandler{}))
	r.Map("role:admin", injector.Inject(&handler.RoleAdminHandler{}))

	r.Map("push:user", injector.Inject(&handler.PushToUserHandler{}))
	r.Map("push:device", injector.Inject(&handler.PushToDeviceHandler{}))

	// Following section is for Gateway
	pubSub := pubsub.NewWsPubsub(nil)
	pubSubGateway := router.NewGateway(`pubSub`)
	pubSubGateway.GET(injector.InjectProcessors(&handler.PubSubHandler{
		WebSocket: pubSub,
	}))

	internalPubSub := pubsub.NewWsPubsub(internalHub)
	internalPubSubGateway := router.NewGateway(`internalpubSub`)
	internalPubSubGateway.GET(injector.InjectProcessors(&handler.PubSubHandler{
		WebSocket: internalPubSub,
	}))

	http.Handle("/", router.LoggingMiddleware(r, false))
	http.Handle("/pubsub", router.LoggingMiddleware(pubSubGateway, false))
	http.Handle("/_/pubsub", router.LoggingMiddleware(internalPubSubGateway, false))

	fileGateway := router.NewGateway(`files/(.+)`)
	fileGateway.GET(injector.Inject(&handler.AssetGetURLHandler{}))
	fileGateway.PUT(injector.Inject(&handler.AssetUploadURLHandler{}))
	http.Handle("/files/", router.LoggingMiddleware(fileGateway, true))

	// Bootstrap finished, starting services
	cronjob.Start()
	initPlugin(config, &initContext)

	log.Printf("Listening on %v...", config.HTTP.Host)
	err := http.ListenAndServe(config.HTTP.Host, nil)
	if err != nil {
		log.Printf("Failed: %v", err)
	}
}

func ensureDB(config skyconfig.Configuration) func() (skydb.Conn, error) {
	connOpener := func() (skydb.Conn, error) {
		return skydb.Open(
			config.DB.ImplName,
			config.App.Name,
			config.App.AccessControl,
			config.DB.Option,
		)
	}

	// Attempt to open connection to database. Retry for a number of
	// times before giving up.
	attempt := 0
	for {
		conn, connError := connOpener()
		if connError == nil {
			conn.Close()
			return connOpener
		}

		attempt++
		log.Errorf("Failed to start skygear: %v", connError)
		if attempt >= 5 {
			log.Fatalf("Failed to start skygear because connection to database cannot be opened.")
		}

		log.Info("Retrying in 1 second...")
		time.Sleep(time.Second * time.Duration(1))
	}
}

func initAssetStore(config skyconfig.Configuration) asset.Store {
	var store asset.Store
	switch config.AssetStore.ImplName {
	default:
		panic("unrecgonized asset store implementation: " + config.AssetStore.ImplName)
	case "fs":
		store = asset.NewFileStore(
			config.AssetStore.Path,
			config.AssetURLSigner.URLPrefix,
			config.AssetURLSigner.Secret,
			config.AssetStore.Public,
		)
	case "s3":
		s3Store, err := asset.NewS3Store(
			config.AssetStore.AccessToken,
			config.AssetStore.SecretToken,
			config.AssetStore.Region,
			config.AssetStore.Bucket,
			config.AssetStore.Public,
		)
		if err != nil {
			panic("failed to initialize asset.S3Store: " + err.Error())
		}
		store = s3Store
	}
	return store
}

func initDevice(config skyconfig.Configuration, connOpener func() (skydb.Conn, error)) {
	// TODO: Create a device service to check APNs to remove obsolete devices.
	// The current implementaion deletes pubsub devices if the last registered
	// time is more than 1 day old.
	conn, err := connOpener()
	if err != nil {
		log.Warnf("Failed to delete outdated devices: %v", err)
	}

	conn.DeleteEmptyDevicesByTime(time.Now().AddDate(0, 0, -1))
}

func initPushSender(config skyconfig.Configuration, connOpener func() (skydb.Conn, error)) push.Sender {
	routeSender := push.NewRouteSender()
	if config.APNS.Enable {
		apns := initAPNSPusher(config, connOpener)
		routeSender.Route("aps", apns)
		routeSender.Route("ios", apns)
	}
	if config.GCM.Enable {
		gcm := initGCMPusher(config)
		routeSender.Route("gcm", gcm)
		routeSender.Route("android", gcm)
	}
	return routeSender
}

func initAPNSPusher(config skyconfig.Configuration, connOpener func() (skydb.Conn, error)) *push.APNSPusher {
	apnsPushSender, err := push.NewAPNSPusher(connOpener, push.GatewayType(config.APNS.Env), config.APNS.Cert, config.APNS.Key)
	if err != nil {
		log.Fatalf("Failed to set up push sender: %v", err)
	}
	go apnsPushSender.Run()
	go apnsPushSender.RunFeedback()

	return apnsPushSender
}

func initGCMPusher(config skyconfig.Configuration) *push.GCMPusher {
	return &push.GCMPusher{APIKey: config.GCM.APIKey}
}

func initSubscription(config skyconfig.Configuration, connOpener func() (skydb.Conn, error), hub *pubsub.Hub, pushSender push.Sender) {
	notifiers := []subscription.Notifier{subscription.NewHubNotifier(hub)}
	if pushSender != nil {
		notifiers = append(notifiers, subscription.NewPushNotifier(pushSender))
	}

	subscriptionService := &subscription.Service{
		ConnOpener: connOpener,
		Notifier:   subscription.NewMultiNotifier(notifiers...),
	}
	log.Infoln("Subscription Service listening...")
	go subscriptionService.Run()
}

func initPlugin(config skyconfig.Configuration, initContext *plugin.InitContext) {
	for _, pluginConfig := range config.Plugin {
		initContext.AddPluginConfiguration(pluginConfig.Transport, pluginConfig.Path, pluginConfig.Args)
	}

	initContext.InitPlugins()
}

func initLogger(config skyconfig.Configuration) {
	// Setup Logging
	log.SetOutput(os.Stderr)
	level, err := log.ParseLevel(config.LOG.Level)
	if err != nil {
		log.Warnf("log: error parsing config: %v", err)
		log.Warnln("log: fall back to `debug`")
		level = log.DebugLevel
	}
	log.SetLevel(level)

	if config.LogHook.SentryDSN != "" {
		initSentry(config)
	}
}

func higherLogLevels(minLevel log.Level) []log.Level {
	levels := []log.Level{
		log.PanicLevel,
		log.FatalLevel,
		log.ErrorLevel,
		log.WarnLevel,
		log.InfoLevel,
		log.DebugLevel,
	}

	output := make([]log.Level, 0, len(levels))
	for _, level := range levels {
		if level <= minLevel {
			output = append(output, level)
		}
	}
	return output
}

func initSentry(config skyconfig.Configuration) {
	level, err := log.ParseLevel(config.LogHook.SentryLevel)
	if err != nil {
		log.Fatalf("log-hook: error parsing sentry-level: %v", err)
		return
	}

	levels := higherLogLevels(level)

	hook, err := logrus_sentry.NewSentryHook(config.LogHook.SentryDSN, levels)
	hook.Timeout = 1 * time.Second
	if err != nil {
		log.Errorf("Failed to initialize Sentry: %v", err)
		return
	}
	log.Infof("Logging to Sentry: %v", levels)
	log.AddHook(hook)
}
<commit_msg>Remove dev_only preprocessor for home handler<commit_after>package main

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

	log "github.com/Sirupsen/logrus"
	"github.com/Sirupsen/logrus/hooks/sentry"
	"github.com/facebookgo/inject"
	"github.com/robfig/cron"

	"github.com/oursky/skygear/asset"
	"github.com/oursky/skygear/authtoken"
	"github.com/oursky/skygear/handler"
	"github.com/oursky/skygear/plugin"
	_ "github.com/oursky/skygear/plugin/exec"
	"github.com/oursky/skygear/plugin/hook"
	"github.com/oursky/skygear/plugin/provider"
	_ "github.com/oursky/skygear/plugin/zmq"
	pp "github.com/oursky/skygear/preprocessor"
	"github.com/oursky/skygear/pubsub"
	"github.com/oursky/skygear/push"
	"github.com/oursky/skygear/router"
	"github.com/oursky/skygear/skyconfig"
	"github.com/oursky/skygear/skydb"
	_ "github.com/oursky/skygear/skydb/pq"
	"github.com/oursky/skygear/subscription"
)

func usage() {
	fmt.Println("Usage: skygear [<config file>]")
}

func main() {
	var configPath string
	if len(os.Args) < 2 {
		configPath = os.Getenv("OD_CONFIG")
		if configPath == "" {
			usage()
			return
		}
	} else {
		configPath = os.Args[1]
	}

	config := skyconfig.Configuration{}
	if err := skyconfig.ReadFileInto(&config, configPath); err != nil {
		fmt.Println(err.Error())
		return
	}

	initLogger(config)
	connOpener := ensureDB(config) // Fatal on DB failed

	// Init all the services
	r := router.NewRouter()
	pushSender := initPushSender(config, connOpener)

	tokenStore := authtoken.InitTokenStore(config.TokenStore.ImplName, config.TokenStore.Path)

	preprocessorRegistry := router.PreprocessorRegistry{}

	cronjob := cron.New()
	initContext := plugin.InitContext{
		Router:           r,
		Preprocessors:    preprocessorRegistry,
		HookRegistry:     hook.NewRegistry(),
		ProviderRegistry: provider.NewRegistry(),
		Scheduler:        cronjob,
		Config:           config,
	}

	internalHub := pubsub.NewHub()
	initSubscription(config, connOpener, internalHub, pushSender)
	initDevice(config, connOpener)

	// Preprocessor
	preprocessorRegistry["notification"] = &pp.NotificationPreprocessor{
		NotificationSender: pushSender,
	}
	preprocessorRegistry["accesskey"] = &pp.AccessKeyValidatonPreprocessor{
		Key:     config.App.APIKey,
		AppName: config.App.Name,
	}
	preprocessorRegistry["authenticator"] = &pp.UserAuthenticator{
		APIKey:     config.App.APIKey,
		AppName:    config.App.Name,
		TokenStore: tokenStore,
	}
	preprocessorRegistry["dbconn"] = &pp.ConnPreprocessor{
		AppName:       config.App.Name,
		AccessControl: config.App.AccessControl,
		DBOpener:      skydb.Open,
		DBImpl:        config.DB.ImplName,
		Option:        config.DB.Option,
	}
	preprocessorRegistry["plugin"] = &pp.EnsurePluginReadyPreprocessor{&initContext}
	preprocessorRegistry["inject_user"] = &pp.InjectUserIfPresent{}
	preprocessorRegistry["require_user"] = &pp.RequireUserForWrite{}
	preprocessorRegistry["inject_db"] = &pp.InjectDatabase{}
	preprocessorRegistry["inject_public_db"] = &pp.InjectPublicDatabase{}
	preprocessorRegistry["dev_only"] = &pp.DevOnlyProcessor{config.App.DevMode}

	r.Map("", &handler.HomeHandler{})

	g := &inject.Graph{}
	injectErr := g.Provide(
		&inject.Object{Value: initContext.ProviderRegistry, Complete: true, Name: "ProviderRegistry"},
		&inject.Object{Value: initContext.HookRegistry, Complete: true, Name: "HookRegistry"},
		&inject.Object{Value: tokenStore, Complete: true, Name: "TokenStore"},
		&inject.Object{Value: initAssetStore(config), Complete: true, Name: "AssetStore"},
		&inject.Object{Value: pushSender, Complete: true, Name: "PushSender"},
		&inject.Object{
			Value:    skydb.GetAccessModel(config.App.AccessControl),
			Complete: true,
			Name:     "AccessModel",
		},
	)
	if injectErr != nil {
		panic(fmt.Sprintf("Unable to set up handler: %v", injectErr))
	}

	injector := router.HandlerInjector{
		g,
		&preprocessorRegistry,
	}

	r.Map("auth:signup", injector.Inject(&handler.SignupHandler{}))
	r.Map("auth:login", injector.Inject(&handler.LoginHandler{}))
	r.Map("auth:logout", injector.Inject(&handler.LogoutHandler{}))
	r.Map("auth:password", injector.Inject(&handler.PasswordHandler{}))

	r.Map("record:fetch", injector.Inject(&handler.RecordFetchHandler{}))
	r.Map("record:query", injector.Inject(&handler.RecordQueryHandler{}))
	r.Map("record:save", injector.Inject(&handler.RecordSaveHandler{}))
	r.Map("record:delete", injector.Inject(&handler.RecordDeleteHandler{}))

	r.Map("device:register", injector.Inject(&handler.DeviceRegisterHandler{}))

	// subscription shares the same set of preprocessor as record read at the moment
	r.Map("subscription:fetch_all", injector.Inject(&handler.SubscriptionFetchAllHandler{}))
	r.Map("subscription:delete", injector.Inject(&handler.SubscriptionDeleteHandler{}))

	// relation shares the same setof preprocessor
	r.Map("relation:query", injector.Inject(&handler.RelationQueryHandler{}))
	r.Map("relation:add", injector.Inject(&handler.RelationAddHandler{}))
	r.Map("relation:remove", injector.Inject(&handler.RelationRemoveHandler{}))

	r.Map("user:query", injector.Inject(&handler.UserQueryHandler{}))
	r.Map("user:update", injector.Inject(&handler.UserUpdateHandler{}))
	r.Map("user:link", injector.Inject(&handler.UserLinkHandler{}))

	r.Map("role:default", injector.Inject(&handler.RoleDefaultHandler{}))
	r.Map("role:admin", injector.Inject(&handler.RoleAdminHandler{}))

	r.Map("push:user", injector.Inject(&handler.PushToUserHandler{}))
	r.Map("push:device", injector.Inject(&handler.PushToDeviceHandler{}))

	// Following section is for Gateway
	pubSub := pubsub.NewWsPubsub(nil)
	pubSubGateway := router.NewGateway(`pubSub`)
	pubSubGateway.GET(injector.InjectProcessors(&handler.PubSubHandler{
		WebSocket: pubSub,
	}))

	internalPubSub := pubsub.NewWsPubsub(internalHub)
	internalPubSubGateway := router.NewGateway(`internalpubSub`)
	internalPubSubGateway.GET(injector.InjectProcessors(&handler.PubSubHandler{
		WebSocket: internalPubSub,
	}))

	http.Handle("/", router.LoggingMiddleware(r, false))
	http.Handle("/pubsub", router.LoggingMiddleware(pubSubGateway, false))
	http.Handle("/_/pubsub", router.LoggingMiddleware(internalPubSubGateway, false))

	fileGateway := router.NewGateway(`files/(.+)`)
	fileGateway.GET(injector.Inject(&handler.AssetGetURLHandler{}))
	fileGateway.PUT(injector.Inject(&handler.AssetUploadURLHandler{}))
	http.Handle("/files/", router.LoggingMiddleware(fileGateway, true))

	// Bootstrap finished, starting services
	cronjob.Start()
	initPlugin(config, &initContext)

	log.Printf("Listening on %v...", config.HTTP.Host)
	err := http.ListenAndServe(config.HTTP.Host, nil)
	if err != nil {
		log.Printf("Failed: %v", err)
	}
}

func ensureDB(config skyconfig.Configuration) func() (skydb.Conn, error) {
	connOpener := func() (skydb.Conn, error) {
		return skydb.Open(
			config.DB.ImplName,
			config.App.Name,
			config.App.AccessControl,
			config.DB.Option,
		)
	}

	// Attempt to open connection to database. Retry for a number of
	// times before giving up.
	attempt := 0
	for {
		conn, connError := connOpener()
		if connError == nil {
			conn.Close()
			return connOpener
		}

		attempt++
		log.Errorf("Failed to start skygear: %v", connError)
		if attempt >= 5 {
			log.Fatalf("Failed to start skygear because connection to database cannot be opened.")
		}

		log.Info("Retrying in 1 second...")
		time.Sleep(time.Second * time.Duration(1))
	}
}

func initAssetStore(config skyconfig.Configuration) asset.Store {
	var store asset.Store
	switch config.AssetStore.ImplName {
	default:
		panic("unrecgonized asset store implementation: " + config.AssetStore.ImplName)
	case "fs":
		store = asset.NewFileStore(
			config.AssetStore.Path,
			config.AssetURLSigner.URLPrefix,
			config.AssetURLSigner.Secret,
			config.AssetStore.Public,
		)
	case "s3":
		s3Store, err := asset.NewS3Store(
			config.AssetStore.AccessToken,
			config.AssetStore.SecretToken,
			config.AssetStore.Region,
			config.AssetStore.Bucket,
			config.AssetStore.Public,
		)
		if err != nil {
			panic("failed to initialize asset.S3Store: " + err.Error())
		}
		store = s3Store
	}
	return store
}

func initDevice(config skyconfig.Configuration, connOpener func() (skydb.Conn, error)) {
	// TODO: Create a device service to check APNs to remove obsolete devices.
	// The current implementaion deletes pubsub devices if the last registered
	// time is more than 1 day old.
	conn, err := connOpener()
	if err != nil {
		log.Warnf("Failed to delete outdated devices: %v", err)
	}

	conn.DeleteEmptyDevicesByTime(time.Now().AddDate(0, 0, -1))
}

func initPushSender(config skyconfig.Configuration, connOpener func() (skydb.Conn, error)) push.Sender {
	routeSender := push.NewRouteSender()
	if config.APNS.Enable {
		apns := initAPNSPusher(config, connOpener)
		routeSender.Route("aps", apns)
		routeSender.Route("ios", apns)
	}
	if config.GCM.Enable {
		gcm := initGCMPusher(config)
		routeSender.Route("gcm", gcm)
		routeSender.Route("android", gcm)
	}
	return routeSender
}

func initAPNSPusher(config skyconfig.Configuration, connOpener func() (skydb.Conn, error)) *push.APNSPusher {
	apnsPushSender, err := push.NewAPNSPusher(connOpener, push.GatewayType(config.APNS.Env), config.APNS.Cert, config.APNS.Key)
	if err != nil {
		log.Fatalf("Failed to set up push sender: %v", err)
	}
	go apnsPushSender.Run()
	go apnsPushSender.RunFeedback()

	return apnsPushSender
}

func initGCMPusher(config skyconfig.Configuration) *push.GCMPusher {
	return &push.GCMPusher{APIKey: config.GCM.APIKey}
}

func initSubscription(config skyconfig.Configuration, connOpener func() (skydb.Conn, error), hub *pubsub.Hub, pushSender push.Sender) {
	notifiers := []subscription.Notifier{subscription.NewHubNotifier(hub)}
	if pushSender != nil {
		notifiers = append(notifiers, subscription.NewPushNotifier(pushSender))
	}

	subscriptionService := &subscription.Service{
		ConnOpener: connOpener,
		Notifier:   subscription.NewMultiNotifier(notifiers...),
	}
	log.Infoln("Subscription Service listening...")
	go subscriptionService.Run()
}

func initPlugin(config skyconfig.Configuration, initContext *plugin.InitContext) {
	for _, pluginConfig := range config.Plugin {
		initContext.AddPluginConfiguration(pluginConfig.Transport, pluginConfig.Path, pluginConfig.Args)
	}

	initContext.InitPlugins()
}

func initLogger(config skyconfig.Configuration) {
	// Setup Logging
	log.SetOutput(os.Stderr)
	level, err := log.ParseLevel(config.LOG.Level)
	if err != nil {
		log.Warnf("log: error parsing config: %v", err)
		log.Warnln("log: fall back to `debug`")
		level = log.DebugLevel
	}
	log.SetLevel(level)

	if config.LogHook.SentryDSN != "" {
		initSentry(config)
	}
}

func higherLogLevels(minLevel log.Level) []log.Level {
	levels := []log.Level{
		log.PanicLevel,
		log.FatalLevel,
		log.ErrorLevel,
		log.WarnLevel,
		log.InfoLevel,
		log.DebugLevel,
	}

	output := make([]log.Level, 0, len(levels))
	for _, level := range levels {
		if level <= minLevel {
			output = append(output, level)
		}
	}
	return output
}

func initSentry(config skyconfig.Configuration) {
	level, err := log.ParseLevel(config.LogHook.SentryLevel)
	if err != nil {
		log.Fatalf("log-hook: error parsing sentry-level: %v", err)
		return
	}

	levels := higherLogLevels(level)

	hook, err := logrus_sentry.NewSentryHook(config.LogHook.SentryDSN, levels)
	hook.Timeout = 1 * time.Second
	if err != nil {
		log.Errorf("Failed to initialize Sentry: %v", err)
		return
	}
	log.Infof("Logging to Sentry: %v", levels)
	log.AddHook(hook)
}
<|endoftext|>


<commit_before>// Copyright 2014 Joseph Hager. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/elazarl/go-bindata-assetfs"
	"github.com/go-on/gopherjslib"
	"html/template"
	"net/http"
	"os"
	"path"
	"strings"
)

func programHandler(w http.ResponseWriter, r *http.Request) {
	// Determine the program to build.
	path := r.URL.Path[1:]
	if strings.HasSuffix(r.URL.Path, "/") {
		path += "main"
	}

	// Open the program's source.
	f, err := os.Open(fmt.Sprintf("%s.go", path))
	if err != nil {
		errorTemplate.Execute(w, &Error{err})
		return
	}

	// Compile the program's source.
	var out bytes.Buffer
	err = gopherjslib.Build(f, &out, nil)
	if err != nil {
		errorTemplate.Execute(w, &Error{err})
		return
	}
	script := out.String()

	// Plug in the compiled javascript.
	successTemplate.Execute(w, &Success{template.JS(script)})
}

func staticHandler(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, r.URL.Path[1:])
}

func main() {
	static := flag.String("static", "data", "The relative path to your assets")
	host := flag.String("host", "127.0.0.1", "The host at which to serve")
	port := flag.Int("port", 8080, "The port at which to serve")

	banner := `   _______ _   ___
  / __/ _ \ | / (_)
 _\ \/ , _/ |/ / /
/___/_/|_||___/_/  says...
`

	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, banner)
		fmt.Fprintln(os.Stderr, "Configure me with these flags!")
		flag.PrintDefaults()
	}

	flag.Parse()

	http.HandleFunc("/", programHandler)
	http.Handle("/favicon.png", http.FileServer(&assetfs.AssetFS{Asset, AssetDir, "."}))
	http.HandleFunc(fmt.Sprintf("/%s/", path.Clean(*static)), staticHandler)

	fmt.Println(banner)
	fmt.Printf("Open your browser to http://%s:%d!\n", *host, *port)

	http.ListenAndServe(fmt.Sprintf("%s:%d", *host, *port), nil)
}
<commit_msg>Add error handling to listenAndServe<commit_after>// Copyright 2014 Joseph Hager. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/elazarl/go-bindata-assetfs"
	"github.com/go-on/gopherjslib"
	"html/template"
	"net/http"
	"os"
	"path"
	"strings"
)

func programHandler(w http.ResponseWriter, r *http.Request) {
	// Determine the program to build.
	path := r.URL.Path[1:]
	if strings.HasSuffix(r.URL.Path, "/") {
		path += "main"
	}

	// Open the program's source.
	f, err := os.Open(fmt.Sprintf("%s.go", path))
	if err != nil {
		errorTemplate.Execute(w, &Error{err})
		return
	}

	// Compile the program's source.
	var out bytes.Buffer
	err = gopherjslib.Build(f, &out, nil)
	if err != nil {
		errorTemplate.Execute(w, &Error{err})
		return
	}
	script := out.String()

	// Plug in the compiled javascript.
	successTemplate.Execute(w, &Success{template.JS(script)})
}

func staticHandler(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, r.URL.Path[1:])
}

func main() {
	static := flag.String("static", "data", "The relative path to your assets")
	host := flag.String("host", "127.0.0.1", "The host at which to serve")
	port := flag.Int("port", 8080, "The port at which to serve")

	banner := `   _______ _   ___
  / __/ _ \ | / (_)
 _\ \/ , _/ |/ / /
/___/_/|_||___/_/  says...
`

	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, banner)
		fmt.Fprintln(os.Stderr, "Configure me with these flags!")
		flag.PrintDefaults()
	}

	flag.Parse()

	http.HandleFunc("/", programHandler)
	http.Handle("/favicon.png", http.FileServer(&assetfs.AssetFS{Asset, AssetDir, "."}))
	http.HandleFunc(fmt.Sprintf("/%s/", path.Clean(*static)), staticHandler)

	fmt.Println(banner)
	fmt.Printf("Open your browser to http://%s:%d!\n", *host, *port)

	err := http.ListenAndServe(fmt.Sprintf("%s:%d", *host, *port), nil)
	if err != nil {
		panic("ListenAndServe: " + err.Error())
	}
}
<|endoftext|>


<commit_before>package main

import "fmt"

// this file is only here to get "go get" to work.
func main() {
  fmt.Println("I AM HERE")
}
<commit_msg>Delete main.go<commit_after><|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	yaml "gopkg.in/yaml.v2"
)

// Command represents a command to run.
type Command struct {
	Path string   `yaml:"path"`
	Args []string `yaml:"args"`
}

// Validate the command is usable.
func (c Command) Validate() error {
	if c.Path == "" {
		return fmt.Errorf("command must specify 'path'")
	}
	return nil
}

// Config for gitbot.
type Config struct {
	Repos      []string  `yaml:"repos"`
	BasePath   string    `yaml:"base_path"`
	ChangeCmds []Command `yaml:"change_cmds"`
	PostCmds   []Command `yaml:"post_cmds"`
}

// NormalizePath will return an absolute path from a relative one, with
// the assumption that is is relative to the location of the configuration file.
func NormalizePath(configPath, commandPath string) string {
	if !strings.HasPrefix(commandPath, ".") {
		return commandPath
	}
	return filepath.Join(filepath.Dir(configPath), commandPath)
}

// Validate that the config is usable.
func (c Config) Validate() error {
	if len(c.Repos) == 0 {
		return fmt.Errorf("config must contain a non-empty 'repos' list")
	}
	for _, changecmd := range c.ChangeCmds {
		if err := changecmd.Validate(); err != nil {
			return err
		}
	}
	if len(c.PostCmds) == 0 {
		return fmt.Errorf("config must contain a non-empty 'post_cmds' list")
	}
	for _, postcmd := range c.PostCmds {
		if err := postcmd.Validate(); err != nil {
			return err
		}
	}
	return nil
}

func main() {
	version := flag.Bool("version", false, "Shows version an exits")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [config]:\n", os.Args[0])
		fmt.Fprintf(os.Stderr, "Flags: \n")
		flag.PrintDefaults()
	}
	flag.Parse()

	if *version {
		fmt.Printf("gitbot %s\n", Version)
		os.Exit(0)
	}

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

	cfgfilePath := flag.Args()[0]
	cfgfile, err := os.Open(cfgfilePath)
	if err != nil {
		log.Fatal(err)
	}
	defer cfgfile.Close()
	cfgfiledata, err := ioutil.ReadAll(cfgfile)
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := yaml.Unmarshal(cfgfiledata, &cfg); err != nil {
		log.Fatal(err)
	}
	if err := cfg.Validate(); err != nil {
		log.Fatal(err)
	}

	base_path := cfg.BasePath

	for _, repo := range cfg.Repos {
		// clone repo to temp directory
		tempdir, err := ioutil.TempDir(base_path+os.TempDir(), "")
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("%s: cloning to %s", repo, tempdir)
		if os.Getenv("GITBOT_LEAVE_TEMPDIRS") == "" {
			defer os.RemoveAll(tempdir)
		}
		clonecmd := exec.Command("git", "clone", "--depth", "1", repo, tempdir)
		clonecmd.Dir = tempdir
		clonecmd.Stdout = os.Stdout
		clonecmd.Stderr = os.Stderr
		if err := clonecmd.Run(); err != nil {
			log.Fatalf("%s: error cloning: %s", repo, err)
		}

		// make changes
		log.Printf("%s: making changes", repo)
		noChangesMade := true
		for _, changecmd := range cfg.ChangeCmds {
			commandPath := NormalizePath(cfgfilePath, changecmd.Path)
			changecmd := exec.Command(commandPath, append(changecmd.Args, tempdir)...)
			var changecmdstdout bytes.Buffer
			changecmd.Stdout = io.MultiWriter(os.Stdout, &changecmdstdout)
			changecmd.Stderr = os.Stderr
			if err := changecmd.Run(); err != nil {
				log.Printf("%s: no changes to make", repo)
				continue
			}
			noChangesMade = false

			// commit changes
			log.Printf("%s: committing changes", repo)
			gitaddcmd := exec.Command("git", "add", "-A")
			gitaddcmd.Dir = tempdir
			gitaddcmd.Stdout = os.Stdout
			gitaddcmd.Stderr = os.Stderr
			if err := gitaddcmd.Run(); err != nil {
				log.Fatalf("%s: error adding: %s", repo, err)
			}
			commitcmd := exec.Command("git", "commit", "-m", changecmdstdout.String())
			commitcmd.Dir = tempdir
			commitcmd.Stdout = os.Stdout
			commitcmd.Stderr = os.Stderr
			if err := commitcmd.Run(); err != nil {
				log.Fatalf("%s: error committing: %s", repo, err)
			}
		}

		// don't run post commands if none of the change commands made a change
		if noChangesMade {
			continue
		}

		// run post commands
		log.Printf("%s: running post commands", repo)
		for _, postcmd := range cfg.PostCmds {
			postcmdPath := NormalizePath(cfgfilePath, postcmd.Path)
			cmd := exec.Command(postcmdPath, postcmd.Args...)
			cmd.Dir = tempdir
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			if err := cmd.Run(); err != nil {
				log.Fatalf("%s: error running post command: %s", repo, err)
			}
		}
	}
}
<commit_msg>Fix typo in -version help message<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	yaml "gopkg.in/yaml.v2"
)

// Command represents a command to run.
type Command struct {
	Path string   `yaml:"path"`
	Args []string `yaml:"args"`
}

// Validate the command is usable.
func (c Command) Validate() error {
	if c.Path == "" {
		return fmt.Errorf("command must specify 'path'")
	}
	return nil
}

// Config for gitbot.
type Config struct {
	Repos      []string  `yaml:"repos"`
	BasePath   string    `yaml:"base_path"`
	ChangeCmds []Command `yaml:"change_cmds"`
	PostCmds   []Command `yaml:"post_cmds"`
}

// NormalizePath will return an absolute path from a relative one, with
// the assumption that is is relative to the location of the configuration file.
func NormalizePath(configPath, commandPath string) string {
	if !strings.HasPrefix(commandPath, ".") {
		return commandPath
	}
	return filepath.Join(filepath.Dir(configPath), commandPath)
}

// Validate that the config is usable.
func (c Config) Validate() error {
	if len(c.Repos) == 0 {
		return fmt.Errorf("config must contain a non-empty 'repos' list")
	}
	for _, changecmd := range c.ChangeCmds {
		if err := changecmd.Validate(); err != nil {
			return err
		}
	}
	if len(c.PostCmds) == 0 {
		return fmt.Errorf("config must contain a non-empty 'post_cmds' list")
	}
	for _, postcmd := range c.PostCmds {
		if err := postcmd.Validate(); err != nil {
			return err
		}
	}
	return nil
}

func main() {
	version := flag.Bool("version", false, "Shows version and exits")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [config]:\n", os.Args[0])
		fmt.Fprintf(os.Stderr, "Flags: \n")
		flag.PrintDefaults()
	}
	flag.Parse()

	if *version {
		fmt.Printf("gitbot %s\n", Version)
		os.Exit(0)
	}

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

	cfgfilePath := flag.Args()[0]
	cfgfile, err := os.Open(cfgfilePath)
	if err != nil {
		log.Fatal(err)
	}
	defer cfgfile.Close()
	cfgfiledata, err := ioutil.ReadAll(cfgfile)
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	if err := yaml.Unmarshal(cfgfiledata, &cfg); err != nil {
		log.Fatal(err)
	}
	if err := cfg.Validate(); err != nil {
		log.Fatal(err)
	}

	base_path := cfg.BasePath

	for _, repo := range cfg.Repos {
		// clone repo to temp directory
		tempdir, err := ioutil.TempDir(base_path+os.TempDir(), "")
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("%s: cloning to %s", repo, tempdir)
		if os.Getenv("GITBOT_LEAVE_TEMPDIRS") == "" {
			defer os.RemoveAll(tempdir)
		}
		clonecmd := exec.Command("git", "clone", "--depth", "1", repo, tempdir)
		clonecmd.Dir = tempdir
		clonecmd.Stdout = os.Stdout
		clonecmd.Stderr = os.Stderr
		if err := clonecmd.Run(); err != nil {
			log.Fatalf("%s: error cloning: %s", repo, err)
		}

		// make changes
		log.Printf("%s: making changes", repo)
		noChangesMade := true
		for _, changecmd := range cfg.ChangeCmds {
			commandPath := NormalizePath(cfgfilePath, changecmd.Path)
			changecmd := exec.Command(commandPath, append(changecmd.Args, tempdir)...)
			var changecmdstdout bytes.Buffer
			changecmd.Stdout = io.MultiWriter(os.Stdout, &changecmdstdout)
			changecmd.Stderr = os.Stderr
			if err := changecmd.Run(); err != nil {
				log.Printf("%s: no changes to make", repo)
				continue
			}
			noChangesMade = false

			// commit changes
			log.Printf("%s: committing changes", repo)
			gitaddcmd := exec.Command("git", "add", "-A")
			gitaddcmd.Dir = tempdir
			gitaddcmd.Stdout = os.Stdout
			gitaddcmd.Stderr = os.Stderr
			if err := gitaddcmd.Run(); err != nil {
				log.Fatalf("%s: error adding: %s", repo, err)
			}
			commitcmd := exec.Command("git", "commit", "-m", changecmdstdout.String())
			commitcmd.Dir = tempdir
			commitcmd.Stdout = os.Stdout
			commitcmd.Stderr = os.Stderr
			if err := commitcmd.Run(); err != nil {
				log.Fatalf("%s: error committing: %s", repo, err)
			}
		}

		// don't run post commands if none of the change commands made a change
		if noChangesMade {
			continue
		}

		// run post commands
		log.Printf("%s: running post commands", repo)
		for _, postcmd := range cfg.PostCmds {
			postcmdPath := NormalizePath(cfgfilePath, postcmd.Path)
			cmd := exec.Command(postcmdPath, postcmd.Args...)
			cmd.Dir = tempdir
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			if err := cmd.Run(); err != nil {
				log.Fatalf("%s: error running post command: %s", repo, err)
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"code.google.com/p/go-netrc/netrc"
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"
)

var (
	apiURL    = "https://api.heroku.com"
	hkHome    = filepath.Join(homePath, ".hk")
	netrcPath = filepath.Join(os.Getenv("HOME"), ".netrc")
	stdin     = bufio.NewReader(os.Stdin)
)

var updater = Updater{
	hkURL:   "https://hk.heroku.com/",
	binURL:  "https://hkdist.s3.amazonaws.com/",
	diffURL: "https://hkpatch.s3.amazonaws.com/",
	dir:     hkHome + "/update/",
}

type Command struct {
	// args does not include the command name
	Run  func(cmd *Command, args []string)
	Flag flag.FlagSet

	Usage string // first word is the command name
	Short string // `hk help` output
	Long  string // `hk help cmd` output
}

func (c *Command) printUsage() {
	if c.Runnable() {
		fmt.Printf("Usage: hk %s\n\n", c.Usage)
	}
	fmt.Println(strings.Trim(c.Long, "\n"))
}

func (c *Command) Name() string {
	name := c.Usage
	i := strings.Index(name, " ")
	if i >= 0 {
		name = name[:i]
	}
	return name
}

func (c *Command) Runnable() bool {
	return c.Run != nil
}

func (c *Command) HasShort() bool {
	return c.Short != ""
}

// Running `hk help` will list commands in this order.
var commands = []*Command{
	cmdCreate,
	cmdLs,
	cmdPs,
	cmdScale,
	cmdRestart,
	cmdEnv,
	cmdGet,
	cmdSet,
	cmdRun,
	cmdTail,
	cmdDestroy,
	cmdCreds,
	cmdSSHAuth,
	cmdUpdate,
	cmdUnset,
	cmdInfo,
	cmdOpen,
	cmdRename,
	cmdURL,
	cmdVersion,
	cmdHelp,

	helpEnviron,
	helpPlugins,
}

var (
	flagApp  string
	flagLong bool
)

func main() {
	if s := os.Getenv("HEROKU_API_URL"); s != "" {
		apiURL = strings.TrimRight(s, "/")
	}
	if s := os.Getenv("HKURL"); s != "" {
		updater.hkURL = strings.TrimRight(s, "/") + "/"
	}
	defer updater.run() // doesn't run if os.Exit is called
	log.SetFlags(0)
	if hkExpired() {
		fmt.Fprintln(os.Stderr, "This dev build of hk expired at", hkExpiration())
		fmt.Fprintln(os.Stderr, "Obtain a new version from https://hk.heroku.com/")
		fmt.Fprintln(os.Stderr, "or run go get -u github.com/kr/hk")
		os.Exit(9)
	}

	args := os.Args[1:]
	if len(args) < 1 {
		usage()
	}

	for _, cmd := range commands {
		if cmd.Name() == args[0] && cmd.Run != nil {
			cmd.Flag.Usage = usage
			cmd.Flag.Parse(args[1:])
			cmd.Run(cmd, cmd.Flag.Args())
			return
		}
	}

	path := findPlugin(args[0])
	if path == "" {
		fmt.Fprintf(os.Stderr, "Unknown command: %s\n", args[0])
		usage()
	}
	err := execPlugin(path, args)
	log.Fatal("exec error: ", err)
}

func getCreds(u *url.URL) (user, pass string) {
	if u.User != nil {
		pw, _ := u.User.Password()
		return u.User.Username(), pw
	}

	m, err := netrc.FindMachine(netrcPath, u.Host)
	if err != nil {
		log.Fatalf("netrc error (%s): %v", u.Host, err)
	}

	return m.Login, m.Password
}

func app() (string, error) {
	if flagApp != "" {
		return flagApp, nil
	}

	b, err := exec.Command("git", "config", "remote.heroku.url").Output()
	if err != nil {
		if isNotFound(err) {
			wdir, _ := os.Getwd()
			return "", fmt.Errorf("could not find git remote heroku in %s", wdir)
		}
		return "", err
	}

	out := strings.Trim(string(b), "\r\n ")

	if !strings.HasPrefix(out, gitURLPre) || !strings.HasSuffix(out, gitURLSuf) {
		return "", fmt.Errorf("could not find app name in heroku git remote")
	}

	// Memoize for later use
	flagApp = out[len(gitURLPre) : len(out)-len(gitURLSuf)]

	return flagApp, nil
}

func isNotFound(err error) bool {
	if ee, ok := err.(*exec.ExitError); ok {
		if ws, ok := ee.ProcessState.Sys().(syscall.WaitStatus); ok {
			return ws.ExitStatus() == 1
		}
	}
	return false
}

func mustApp() string {
	name, err := app()
	if err != nil {
		log.Fatal(err)
	}
	return name
}

func must(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>print command-specific usage if flag parsing fails<commit_after>package main

import (
	"bufio"
	"code.google.com/p/go-netrc/netrc"
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"
)

var (
	apiURL    = "https://api.heroku.com"
	hkHome    = filepath.Join(homePath, ".hk")
	netrcPath = filepath.Join(os.Getenv("HOME"), ".netrc")
	stdin     = bufio.NewReader(os.Stdin)
)

var updater = Updater{
	hkURL:   "https://hk.heroku.com/",
	binURL:  "https://hkdist.s3.amazonaws.com/",
	diffURL: "https://hkpatch.s3.amazonaws.com/",
	dir:     hkHome + "/update/",
}

type Command struct {
	// args does not include the command name
	Run  func(cmd *Command, args []string)
	Flag flag.FlagSet

	Usage string // first word is the command name
	Short string // `hk help` output
	Long  string // `hk help cmd` output
}

func (c *Command) printUsage() {
	if c.Runnable() {
		fmt.Printf("Usage: hk %s\n\n", c.Usage)
	}
	fmt.Println(strings.Trim(c.Long, "\n"))
}

func (c *Command) Name() string {
	name := c.Usage
	i := strings.Index(name, " ")
	if i >= 0 {
		name = name[:i]
	}
	return name
}

func (c *Command) Runnable() bool {
	return c.Run != nil
}

func (c *Command) HasShort() bool {
	return c.Short != ""
}

// Running `hk help` will list commands in this order.
var commands = []*Command{
	cmdCreate,
	cmdLs,
	cmdPs,
	cmdScale,
	cmdRestart,
	cmdEnv,
	cmdGet,
	cmdSet,
	cmdRun,
	cmdTail,
	cmdDestroy,
	cmdCreds,
	cmdSSHAuth,
	cmdUpdate,
	cmdUnset,
	cmdInfo,
	cmdOpen,
	cmdRename,
	cmdURL,
	cmdVersion,
	cmdHelp,

	helpEnviron,
	helpPlugins,
}

var (
	flagApp  string
	flagLong bool
)

func main() {
	if s := os.Getenv("HEROKU_API_URL"); s != "" {
		apiURL = strings.TrimRight(s, "/")
	}
	if s := os.Getenv("HKURL"); s != "" {
		updater.hkURL = strings.TrimRight(s, "/") + "/"
	}
	defer updater.run() // doesn't run if os.Exit is called
	log.SetFlags(0)
	if hkExpired() {
		fmt.Fprintln(os.Stderr, "This dev build of hk expired at", hkExpiration())
		fmt.Fprintln(os.Stderr, "Obtain a new version from https://hk.heroku.com/")
		fmt.Fprintln(os.Stderr, "or run go get -u github.com/kr/hk")
		os.Exit(9)
	}

	args := os.Args[1:]
	if len(args) < 1 {
		usage()
	}

	for _, cmd := range commands {
		if cmd.Name() == args[0] && cmd.Run != nil {
			cmd.Flag.Usage = func() {
				cmd.printUsage()
			}
			if err := cmd.Flag.Parse(args[1:]); err != nil {
				os.Exit(2)
			}
			cmd.Run(cmd, cmd.Flag.Args())
			return
		}
	}

	path := findPlugin(args[0])
	if path == "" {
		fmt.Fprintf(os.Stderr, "Unknown command: %s\n", args[0])
		usage()
	}
	err := execPlugin(path, args)
	log.Fatal("exec error: ", err)
}

func getCreds(u *url.URL) (user, pass string) {
	if u.User != nil {
		pw, _ := u.User.Password()
		return u.User.Username(), pw
	}

	m, err := netrc.FindMachine(netrcPath, u.Host)
	if err != nil {
		log.Fatalf("netrc error (%s): %v", u.Host, err)
	}

	return m.Login, m.Password
}

func app() (string, error) {
	if flagApp != "" {
		return flagApp, nil
	}

	b, err := exec.Command("git", "config", "remote.heroku.url").Output()
	if err != nil {
		if isNotFound(err) {
			wdir, _ := os.Getwd()
			return "", fmt.Errorf("could not find git remote heroku in %s", wdir)
		}
		return "", err
	}

	out := strings.Trim(string(b), "\r\n ")

	if !strings.HasPrefix(out, gitURLPre) || !strings.HasSuffix(out, gitURLSuf) {
		return "", fmt.Errorf("could not find app name in heroku git remote")
	}

	// Memoize for later use
	flagApp = out[len(gitURLPre) : len(out)-len(gitURLSuf)]

	return flagApp, nil
}

func isNotFound(err error) bool {
	if ee, ok := err.(*exec.ExitError); ok {
		if ws, ok := ee.ProcessState.Sys().(syscall.WaitStatus); ok {
			return ws.ExitStatus() == 1
		}
	}
	return false
}

func mustApp() string {
	name, err := app()
	if err != nil {
		log.Fatal(err)
	}
	return name
}

func must(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/ConSol/sakuli-go-wrapper/execute"
	"github.com/ConSol/sakuli-go-wrapper/helper"
	"github.com/ConSol/sakuli-go-wrapper/input"
	"os"
	"path/filepath"
	"time"
)

func main() {
	var loop int
	var javaHome string
	var javaProperties input.StringSlice
	var preHooks input.StringSlice
	var postHooks input.StringSlice
	var browser string
	var inter string
	var sahiHome string
	var version bool

	sakuliJars := filepath.Join(os.Getenv("SAKULI_HOME"), "libs", "java")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, `Generic Sakuli test starter.
%d - The Sakuli team / Philip Griesbacher.
http://www.sakuli.org
https://github.com/ConSol/sakuli

Usage:   sakuli[.exe] COMMAND ARGUMENT [OPTIONS]
         sakuli -help
         sakuli -version
         sakuli -run <sakuli suite> [OPTIONS]
         sakuli -encrypt <secret> [OPTIONS]

Commands:
         run <sakuli suite>
         encrypt <secret>

Options:
         -loop <minutes>           Loop this suite, wait n seconds between
                                   executions, 0 means no loops (default: 0)
         -javaHome <folder>        Java bin dir (overrides PATH)
         -preHooks <programpath>   A programm which will be executed before
                                   sakuli (Can be added multiple times)
         -postHooks  <programpath> A programm which will be executed after
                                   sakuli (Can be added multiple times)
         -D <JVM option>           JVM option to set a property on runtime,
                                   overrides the 'sakuli.properties'
         -browser <browser>        Browser for the test execution
                                   (default: Firefox)
         -interface <interface>    Network interface used for encryption
         -sahiHome <folder>        Sahi installation folder
         -version                  Version info

`, time.Now().Year())
	}

	flag.IntVar(&loop, "loop", 0, "loop this suite, wait n seconds between executions, 0 means no loops (default: 0)")
	flag.StringVar(&javaHome, "javahome", "", "Java bin dir (overrides PATH)")
	flag.Var(&preHooks, "preHook", "A programm which will be executed before sakuli (Can be added multiple times)")
	flag.Var(&postHooks, "postHook", "A programm which will be executed after sakuli (Can be added multiple times)")

	flag.Var(&javaProperties, "D", "JVM option to set a property on runtime, overrides the 'sakuli.properties'")
	flag.StringVar(&browser, "browser", "", "browser for the test execution (default: Firefox)")
	flag.StringVar(&inter, "interface", "", "network interface used for encryption")
	flag.StringVar(&sahiHome, "sahi_home", "", "Sahi installation folder")
	flag.BoolVar(&version, "version", false, "version info")
	flag.Parse()

	if version {
		input.PrintVersion()
	}
	sakuliProperties := map[string]string{"sakuli_home": helper.GetSahiHome()}
	typ, argument := input.ParseArgs(flag.Args())
	switch typ {
	case input.RunMode:
		input.TestRun(argument)
		sakuliProperties[input.RunMode] = argument
	case input.EncryptMode:
		sakuliProperties[input.EncryptMode] = argument
	case input.Error:
		panic("can't pars args")
	}

	javaExecutable := input.TestJavaHome(javaHome)
	javaProperties = javaProperties.AddPrefix("-D")

	if browser != "" {
		sakuliProperties["browser"] = browser
	}
	if inter != "" {
		sakuliProperties["interface"] = inter
	}
	if sahiHome != "" {
		sakuliProperties["sahiHome"] = sahiHome
	}
	joinedSakuliProperties := genSakuliPropertiesList(sakuliProperties)

	if len(preHooks) > 0 {
		fmt.Println("=========== Starting Pre-Hooks ===========")
		for _, pre := range preHooks {
			execute.RunHandler(pre)
		}
		fmt.Println("=========== Finished Pre-Hooks ===========")
	}

	sakuliReturnCode := execute.RunSakuli(javaExecutable, sakuliJars, javaProperties, joinedSakuliProperties)
	for loop > 0 {
		fmt.Printf("*** Loop mode - sleeping for %d seconds... ***\n", loop)
		time.Sleep(time.Duration(loop) * time.Second)
		execute.RunSakuli(javaExecutable, sakuliJars, javaProperties, joinedSakuliProperties)
	}

	if len(postHooks) > 0 {
		fmt.Println("=========== Starting Post-Hooks ===========")
		for _, post := range postHooks {
			execute.RunHandler(post)
		}
		fmt.Println("=========== Finished Post-Hooks ===========")
	}
	os.Exit(sakuliReturnCode)
}

func genSakuliPropertiesList(properties map[string]string) input.StringSlice {
	propertiesString := []string{}
	for k, v := range properties {
		propertiesString = append(propertiesString, fmt.Sprintf("--%s", k))
		propertiesString = append(propertiesString, v)
	}
	return propertiesString
}
<commit_msg>changed sakulijar folder to dynamic selection<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/ConSol/sakuli-go-wrapper/execute"
	"github.com/ConSol/sakuli-go-wrapper/helper"
	"github.com/ConSol/sakuli-go-wrapper/input"
	"os"
	"path/filepath"
	"time"
)

func main() {
	var loop int
	var javaHome string
	var javaProperties input.StringSlice
	var preHooks input.StringSlice
	var postHooks input.StringSlice
	var browser string
	var inter string
	var sahiHome string
	var version bool

	sakuliJars := filepath.Join(helper.GetSahiHome(), "libs", "java")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, `Generic Sakuli test starter.
%d - The Sakuli team / Philip Griesbacher.
http://www.sakuli.org
https://github.com/ConSol/sakuli

Usage:   sakuli[.exe] COMMAND ARGUMENT [OPTIONS]
         sakuli -help
         sakuli -version
         sakuli -run <sakuli suite> [OPTIONS]
         sakuli -encrypt <secret> [OPTIONS]

Commands:
         run <sakuli suite>
         encrypt <secret>

Options:
         -loop <minutes>           Loop this suite, wait n seconds between
                                   executions, 0 means no loops (default: 0)
         -javaHome <folder>        Java bin dir (overrides PATH)
         -preHooks <programpath>   A programm which will be executed before
                                   sakuli (Can be added multiple times)
         -postHooks  <programpath> A programm which will be executed after
                                   sakuli (Can be added multiple times)
         -D <JVM option>           JVM option to set a property on runtime,
                                   overrides the 'sakuli.properties'
         -browser <browser>        Browser for the test execution
                                   (default: Firefox)
         -interface <interface>    Network interface used for encryption
         -sahiHome <folder>        Sahi installation folder
         -version                  Version info

`, time.Now().Year())
	}

	flag.IntVar(&loop, "loop", 0, "loop this suite, wait n seconds between executions, 0 means no loops (default: 0)")
	flag.StringVar(&javaHome, "javahome", "", "Java bin dir (overrides PATH)")
	flag.Var(&preHooks, "preHook", "A programm which will be executed before sakuli (Can be added multiple times)")
	flag.Var(&postHooks, "postHook", "A programm which will be executed after sakuli (Can be added multiple times)")

	flag.Var(&javaProperties, "D", "JVM option to set a property on runtime, overrides the 'sakuli.properties'")
	flag.StringVar(&browser, "browser", "", "browser for the test execution (default: Firefox)")
	flag.StringVar(&inter, "interface", "", "network interface used for encryption")
	flag.StringVar(&sahiHome, "sahi_home", "", "Sahi installation folder")
	flag.BoolVar(&version, "version", false, "version info")
	flag.Parse()

	if version {
		input.PrintVersion()
	}
	sakuliProperties := map[string]string{"sakuli_home": helper.GetSahiHome()}
	typ, argument := input.ParseArgs(flag.Args())
	switch typ {
	case input.RunMode:
		input.TestRun(argument)
		sakuliProperties[input.RunMode] = argument
	case input.EncryptMode:
		sakuliProperties[input.EncryptMode] = argument
	case input.Error:
		panic("can't pars args")
	}

	javaExecutable := input.TestJavaHome(javaHome)
	javaProperties = javaProperties.AddPrefix("-D")

	if browser != "" {
		sakuliProperties["browser"] = browser
	}
	if inter != "" {
		sakuliProperties["interface"] = inter
	}
	if sahiHome != "" {
		sakuliProperties["sahiHome"] = sahiHome
	}
	joinedSakuliProperties := genSakuliPropertiesList(sakuliProperties)

	if len(preHooks) > 0 {
		fmt.Println("=========== Starting Pre-Hooks ===========")
		for _, pre := range preHooks {
			execute.RunHandler(pre)
		}
		fmt.Println("=========== Finished Pre-Hooks ===========")
	}

	sakuliReturnCode := execute.RunSakuli(javaExecutable, sakuliJars, javaProperties, joinedSakuliProperties)
	for loop > 0 {
		fmt.Printf("*** Loop mode - sleeping for %d seconds... ***\n", loop)
		time.Sleep(time.Duration(loop) * time.Second)
		execute.RunSakuli(javaExecutable, sakuliJars, javaProperties, joinedSakuliProperties)
	}

	if len(postHooks) > 0 {
		fmt.Println("=========== Starting Post-Hooks ===========")
		for _, post := range postHooks {
			execute.RunHandler(post)
		}
		fmt.Println("=========== Finished Post-Hooks ===========")
	}
	os.Exit(sakuliReturnCode)
}

func genSakuliPropertiesList(properties map[string]string) input.StringSlice {
	propertiesString := []string{}
	for k, v := range properties {
		propertiesString = append(propertiesString, fmt.Sprintf("--%s", k))
		propertiesString = append(propertiesString, v)
	}
	return propertiesString
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"net"
    //"golang.org/x/crypto/openpgp"
)

func main() {
	outputChannel:=make(chan chan string)
	printAll(outputChannel)
	printMessage(outputChannel,"lol")
	listen()
}
func printMessage(outputChannel chan chan string,message string){
	messageChannel:=make(chan string)
	outputChannel<-messageChannel
	go func(){
		messageChannel<-"Processed message: "+message
		}()
}

func handleConn(conn net.Conn) {
    fmt.Println("CONNECTION BABE")
    status, err := bufio.NewReader(conn).ReadString('\n')
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf(status)
}

func listen() {
	ln, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Println(err)
	}
	for {
		conn, err := ln.Accept()
		if err != nil {
			fmt.Println(err)
		}
		go handleConn(conn)
	}
}

func printAll(stringChanChan <-chan chan string) {
	go func(){
		for{
			strChan:=<-stringChanChan
			str:=<-strChan
			fmt.Printf(str)
		}
	}()

}<commit_msg>updated<commit_after>package main

import (
	"bufio"
	"fmt"
	"net"
    //"golang.org/x/crypto/openpgp"
)

func main() {
	outputChannel:=make(chan chan string)
	printAll(outputChannel)
	onMessageReceived(outputChannel,"lol")
	listen()
}
func onMessageReceived(outputChannel chan chan string, message string){
	messageChannel:=make(chan string)
	outputChannel<-messageChannel
	go func(){
		messageChannel<-processMessage(message)
		}()
}
func processMessage(message string) string{
	return "Processed Message: "+message
}

func handleConn(conn net.Conn) {
    fmt.Println("CONNECTION BABE")
    status, err := bufio.NewReader(conn).ReadString('\n')
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf(status)
}

func listen() {
	ln, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Println(err)
	}
	for {
		conn, err := ln.Accept()
		if err != nil {
			fmt.Println(err)
		}
		go handleConn(conn)
	}
}

func printAll(stringChanChan <-chan chan string) {
	go func(){
		for{
			strChan:=<-stringChanChan
			str:=<-strChan
			fmt.Printf(str)
		}
	}()

}<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/zettio/weavedns/server"
	"io/ioutil"
	"net"
	"os"
)

func main() {
	var (
		ifaceName string
		apiPath   string
		dnsPort   int
		httpPort  int
		wait      int
		watch     bool
		debug     bool
	)

	flag.StringVar(&ifaceName, "iface", "", "name of interface to use for multicast")
	flag.StringVar(&apiPath, "api", "unix:///var/run/docker.sock", "Path to Docker API socket")
	flag.IntVar(&wait, "wait", 0, "number of seconds to wait for interface to be created and come up (defaults to 0)")
	flag.IntVar(&dnsPort, "dnsport", 53, "port to listen to dns requests (defaults to 53)")
	flag.IntVar(&httpPort, "httpport", 6785, "port to listen to HTTP requests (defaults to 6785)")
	flag.BoolVar(&watch, "watch", true, "watch the docker socket for container events")
	flag.BoolVar(&debug, "debug", false, "output debugging info to stderr")
	flag.Parse()

	debugOut := ioutil.Discard
	if debug {
		debugOut = os.Stderr
	}
	weavedns.InitLogging(debugOut, os.Stdout, os.Stdout, os.Stderr)

	var zone = new(weavedns.ZoneDb)

	if watch {
		err := weavedns.StartUpdater(apiPath, zone)
		if err != nil {
			weavedns.Error.Fatal("Unable to start watcher", err)
		}
	}

	var iface *net.Interface = nil
	if ifaceName != "" {
		var err error
		iface, err = weavedns.EnsureInterface(ifaceName, wait)
		if err != nil {
			weavedns.Error.Fatal(err)
		}
	}

	err := weavedns.StartServer(zone, iface, dnsPort, httpPort, wait)
	if err != nil {
		weavedns.Error.Fatal("Failed to start server", err)
	}
}
<commit_msg>No need to give defaults in docstrings for options<commit_after>package main

import (
	"flag"
	"github.com/zettio/weavedns/server"
	"io/ioutil"
	"net"
	"os"
)

func main() {
	var (
		ifaceName string
		apiPath   string
		dnsPort   int
		httpPort  int
		wait      int
		watch     bool
		debug     bool
	)

	flag.StringVar(&ifaceName, "iface", "", "name of interface to use for multicast")
	flag.StringVar(&apiPath, "api", "unix:///var/run/docker.sock", "Path to Docker API socket")
	flag.IntVar(&wait, "wait", 0, "number of seconds to wait for interface to be created and come up")
	flag.IntVar(&dnsPort, "dnsport", 53, "port to listen to dns requests")
	flag.IntVar(&httpPort, "httpport", 6785, "port to listen to HTTP requests")
	flag.BoolVar(&watch, "watch", true, "watch the docker socket for container events")
	flag.BoolVar(&debug, "debug", false, "output debugging info to stderr")
	flag.Parse()

	debugOut := ioutil.Discard
	if debug {
		debugOut = os.Stderr
	}
	weavedns.InitLogging(debugOut, os.Stdout, os.Stdout, os.Stderr)

	var zone = new(weavedns.ZoneDb)

	if watch {
		err := weavedns.StartUpdater(apiPath, zone)
		if err != nil {
			weavedns.Error.Fatal("Unable to start watcher", err)
		}
	}

	var iface *net.Interface = nil
	if ifaceName != "" {
		var err error
		iface, err = weavedns.EnsureInterface(ifaceName, wait)
		if err != nil {
			weavedns.Error.Fatal(err)
		}
	}

	err := weavedns.StartServer(zone, iface, dnsPort, httpPort, wait)
	if err != nil {
		weavedns.Error.Fatal("Failed to start server", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"log"
	"math/rand"

	"github.com/somethingnew2-0/go-erasure"
	"github.com/somethingnew2-0/upnp"
)

func corrupt(source, errList []byte, shardLength int) []byte {
	corrupted := make([]byte, len(source))
	copy(corrupted, source)
	for _, err := range errList {
		for i := 0; i < shardLength; i++ {
			corrupted[int(err)*shardLength+i] = 0x00
		}
	}
	return corrupted
}

func main() {
	m := 12
	k := 8
	shardLength := 16       // Length of a shard
	size := k * shardLength // Length of the data blob to encode

	code := erasure.NewCode(m, k, size)

	source := make([]byte, size)
	for i := range source {
		source[i] = byte(rand.Int63() & 0xff) //0x62
	}

	encoded := code.Encode(source)

	errList := []byte{0, 2, 3, 4}

	corrupted := corrupt(append(source, encoded...), errList, shardLength)

	recovered := code.Decode(corrupted, errList)

	if !bytes.Equal(source, recovered) {
		log.Fatal("Source was not sucessfully recovered with 4 errors")
	}

	mapping := new(upnp.Upnp)
	if err := mapping.AddPortMapping(55789, 55789, "TCP"); err == nil {
		log.Println("Added port mapping")
		mapping.Reclaim()
	} else {
		log.Println("Couldn't add port mapping")
	}
}
<commit_msg>Forget about upnp for now<commit_after>package main

import (
	"bytes"
	"log"
	"math/rand"

	"github.com/somethingnew2-0/go-erasure"
)

func corrupt(source, errList []byte, shardLength int) []byte {
	corrupted := make([]byte, len(source))
	copy(corrupted, source)
	for _, err := range errList {
		for i := 0; i < shardLength; i++ {
			corrupted[int(err)*shardLength+i] = 0x00
		}
	}
	return corrupted
}

func main() {
	m := 12
	k := 8
	shardLength := 16       // Length of a shard
	size := k * shardLength // Length of the data blob to encode

	code := erasure.NewCode(m, k, size)

	source := make([]byte, size)
	for i := range source {
		source[i] = byte(rand.Int63() & 0xff) //0x62
	}

	encoded := code.Encode(source)

	errList := []byte{0, 2, 3, 4}

	corrupted := corrupt(append(source, encoded...), errList, shardLength)

	recovered := code.Decode(corrupted, errList)

	if !bytes.Equal(source, recovered) {
		log.Fatal("Source was not sucessfully recovered with 4 errors")
	}

}
<|endoftext|>


<commit_before>// Copyright 2014 The Prometheus Authors
// 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 (
	"net"
	"net/http"
	"net/http/pprof"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"strings"
	"syscall"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"
	"github.com/elazarl/go-bindata-assetfs"
	"github.com/julienschmidt/httprouter"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
	"github.com/prometheus/common/version"

	"github.com/prometheus/pushgateway/handler"
	"github.com/prometheus/pushgateway/storage"
)

func init() {
	prometheus.MustRegister(version.NewCollector("pushgateway"))
}

func main() {
	var (
		app = kingpin.New(filepath.Base(os.Args[0]), "The Pushgateway")

		listenAddress       = app.Flag("web.listen-address", "Address to listen on for the web interface, API, and telemetry.").Default(":9091").String()
		metricsPath         = app.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String()
		routePrefix         = app.Flag("web.route-prefix", "Prefix for the internal routes of web endpoints.").Default("").String()
		persistenceFile     = app.Flag("persistence.file", "File to persist metrics. If empty, metrics are only kept in memory.").Default("").String()
		persistenceInterval = app.Flag("persistence.interval", "The minimum interval at which to write out the persistence file.").Default("5m").Duration()
	)
	app.Version(version.Print("pushgateway"))
	app.HelpFlag.Short('h')
	kingpin.MustParse(app.Parse(os.Args[1:]))

	if *routePrefix == "/" {
		*routePrefix = ""
	}
	if *routePrefix != "" {
		*routePrefix = "/" + strings.Trim(*routePrefix, "/")
	}

	log.Infoln("Starting pushgateway", version.Info())
	log.Infoln("Build context", version.BuildContext())
	log.Debugf("Prefix path is '%s'", *routePrefix)

	flags := map[string]string{}
	for _, f := range app.Model().Flags {
		flags[f.Name] = f.Value.String()
	}
	ms := storage.NewDiskMetricStore(*persistenceFile, *persistenceInterval)
	prometheus.SetMetricFamilyInjectionHook(ms.GetMetricFamilies)
	// Enable collect checks for debugging.
	// prometheus.EnableCollectChecks(true)

	r := httprouter.New()
	r.Handler("GET", *routePrefix+"/-/healthy", prometheus.InstrumentHandlerFunc("healthy", handler.Healthy(ms)))
	r.Handler("GET", *routePrefix+"/-/ready", prometheus.InstrumentHandlerFunc("ready", handler.Ready(ms)))

	r.Handler("GET", path.Join(*routePrefix, *metricsPath), prometheus.Handler())

	// Handlers for pushing and deleting metrics.
	pushAPIPath := *routePrefix + "/metrics"
	r.PUT(pushAPIPath+"/job/:job/*labels", handler.Push(ms, true))
	r.POST(pushAPIPath+"/job/:job/*labels", handler.Push(ms, false))
	r.DELETE(pushAPIPath+"/job/:job/*labels", handler.Delete(ms))
	r.PUT(pushAPIPath+"/job/:job", handler.Push(ms, true))
	r.POST(pushAPIPath+"/job/:job", handler.Push(ms, false))
	r.DELETE(pushAPIPath+"/job/:job", handler.Delete(ms))

	// Handlers for the deprecated API.
	r.PUT(pushAPIPath+"/jobs/:job/instances/:instance", handler.LegacyPush(ms, true))
	r.POST(pushAPIPath+"/jobs/:job/instances/:instance", handler.LegacyPush(ms, false))
	r.DELETE(pushAPIPath+"/jobs/:job/instances/:instance", handler.LegacyDelete(ms))
	r.PUT(pushAPIPath+"/jobs/:job", handler.LegacyPush(ms, true))
	r.POST(pushAPIPath+"/jobs/:job", handler.LegacyPush(ms, false))
	r.DELETE(pushAPIPath+"/jobs/:job", handler.LegacyDelete(ms))

	r.Handler("GET", *routePrefix+"/static/*filepath", prometheus.InstrumentHandler(
		"static",
		http.FileServer(
			&assetfs.AssetFS{
				Asset: func(name string) ([]byte, error) {
					path := name[len(*routePrefix):]
					return Asset(path)
				},
				AssetDir: AssetDir, AssetInfo: AssetInfo},
		),
	))
	statusHandler := prometheus.InstrumentHandlerFunc("status", handler.Status(ms, Asset, flags))
	r.Handler("GET", *routePrefix+"/status", statusHandler)
	r.Handler("GET", *routePrefix+"/", statusHandler)

	// Re-enable pprof.
	r.GET(*routePrefix+"/debug/pprof/*pprof", handlePprof)

	log.Infof("Listening on %s.", *listenAddress)
	l, err := net.Listen("tcp", *listenAddress)
	if err != nil {
		log.Fatal(err)
	}
	go interruptHandler(l)
	err = (&http.Server{Addr: *listenAddress, Handler: r}).Serve(l)
	log.Errorln("HTTP server stopped:", err)
	// To give running connections a chance to submit their payload, we wait
	// for 1sec, but we don't want to wait long (e.g. until all connections
	// are done) to not delay the shutdown.
	time.Sleep(time.Second)
	if err := ms.Shutdown(); err != nil {
		log.Errorln("Problem shutting down metric storage:", err)
	}
}

func handlePprof(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	switch p.ByName("pprof") {
	case "/cmdline":
		pprof.Cmdline(w, r)
	case "/profile":
		pprof.Profile(w, r)
	case "/symbol":
		pprof.Symbol(w, r)
	default:
		pprof.Index(w, r)
	}
}

func interruptHandler(l net.Listener) {
	notifier := make(chan os.Signal)
	signal.Notify(notifier, os.Interrupt, syscall.SIGTERM)
	<-notifier
	log.Info("Received SIGINT/SIGTERM; exiting gracefully...")
	l.Close()
}
<commit_msg>Lex sort<commit_after>// Copyright 2014 The Prometheus Authors
// 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 (
	"net"
	"net/http"
	"net/http/pprof"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"strings"
	"syscall"
	"time"

	"github.com/elazarl/go-bindata-assetfs"
	"github.com/julienschmidt/httprouter"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
	"github.com/prometheus/common/version"
	"github.com/prometheus/pushgateway/handler"
	"github.com/prometheus/pushgateway/storage"
	"gopkg.in/alecthomas/kingpin.v2"
)

func init() {
	prometheus.MustRegister(version.NewCollector("pushgateway"))
}

func main() {
	var (
		app = kingpin.New(filepath.Base(os.Args[0]), "The Pushgateway")

		listenAddress       = app.Flag("web.listen-address", "Address to listen on for the web interface, API, and telemetry.").Default(":9091").String()
		metricsPath         = app.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String()
		routePrefix         = app.Flag("web.route-prefix", "Prefix for the internal routes of web endpoints.").Default("").String()
		persistenceFile     = app.Flag("persistence.file", "File to persist metrics. If empty, metrics are only kept in memory.").Default("").String()
		persistenceInterval = app.Flag("persistence.interval", "The minimum interval at which to write out the persistence file.").Default("5m").Duration()
	)
	app.Version(version.Print("pushgateway"))
	app.HelpFlag.Short('h')
	kingpin.MustParse(app.Parse(os.Args[1:]))

	if *routePrefix == "/" {
		*routePrefix = ""
	}
	if *routePrefix != "" {
		*routePrefix = "/" + strings.Trim(*routePrefix, "/")
	}

	log.Infoln("Starting pushgateway", version.Info())
	log.Infoln("Build context", version.BuildContext())
	log.Debugf("Prefix path is '%s'", *routePrefix)

	flags := map[string]string{}
	for _, f := range app.Model().Flags {
		flags[f.Name] = f.Value.String()
	}
	ms := storage.NewDiskMetricStore(*persistenceFile, *persistenceInterval)
	prometheus.SetMetricFamilyInjectionHook(ms.GetMetricFamilies)
	// Enable collect checks for debugging.
	// prometheus.EnableCollectChecks(true)

	r := httprouter.New()
	r.Handler("GET", *routePrefix+"/-/healthy", prometheus.InstrumentHandlerFunc("healthy", handler.Healthy(ms)))
	r.Handler("GET", *routePrefix+"/-/ready", prometheus.InstrumentHandlerFunc("ready", handler.Ready(ms)))

	r.Handler("GET", path.Join(*routePrefix, *metricsPath), prometheus.Handler())

	// Handlers for pushing and deleting metrics.
	pushAPIPath := *routePrefix + "/metrics"
	r.PUT(pushAPIPath+"/job/:job/*labels", handler.Push(ms, true))
	r.POST(pushAPIPath+"/job/:job/*labels", handler.Push(ms, false))
	r.DELETE(pushAPIPath+"/job/:job/*labels", handler.Delete(ms))
	r.PUT(pushAPIPath+"/job/:job", handler.Push(ms, true))
	r.POST(pushAPIPath+"/job/:job", handler.Push(ms, false))
	r.DELETE(pushAPIPath+"/job/:job", handler.Delete(ms))

	// Handlers for the deprecated API.
	r.PUT(pushAPIPath+"/jobs/:job/instances/:instance", handler.LegacyPush(ms, true))
	r.POST(pushAPIPath+"/jobs/:job/instances/:instance", handler.LegacyPush(ms, false))
	r.DELETE(pushAPIPath+"/jobs/:job/instances/:instance", handler.LegacyDelete(ms))
	r.PUT(pushAPIPath+"/jobs/:job", handler.LegacyPush(ms, true))
	r.POST(pushAPIPath+"/jobs/:job", handler.LegacyPush(ms, false))
	r.DELETE(pushAPIPath+"/jobs/:job", handler.LegacyDelete(ms))

	r.Handler("GET", *routePrefix+"/static/*filepath", prometheus.InstrumentHandler(
		"static",
		http.FileServer(
			&assetfs.AssetFS{
				Asset: func(name string) ([]byte, error) {
					path := name[len(*routePrefix):]
					return Asset(path)
				},
				AssetDir: AssetDir, AssetInfo: AssetInfo},
		),
	))
	statusHandler := prometheus.InstrumentHandlerFunc("status", handler.Status(ms, Asset, flags))
	r.Handler("GET", *routePrefix+"/status", statusHandler)
	r.Handler("GET", *routePrefix+"/", statusHandler)

	// Re-enable pprof.
	r.GET(*routePrefix+"/debug/pprof/*pprof", handlePprof)

	log.Infof("Listening on %s.", *listenAddress)
	l, err := net.Listen("tcp", *listenAddress)
	if err != nil {
		log.Fatal(err)
	}
	go interruptHandler(l)
	err = (&http.Server{Addr: *listenAddress, Handler: r}).Serve(l)
	log.Errorln("HTTP server stopped:", err)
	// To give running connections a chance to submit their payload, we wait
	// for 1sec, but we don't want to wait long (e.g. until all connections
	// are done) to not delay the shutdown.
	time.Sleep(time.Second)
	if err := ms.Shutdown(); err != nil {
		log.Errorln("Problem shutting down metric storage:", err)
	}
}

func handlePprof(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	switch p.ByName("pprof") {
	case "/cmdline":
		pprof.Cmdline(w, r)
	case "/profile":
		pprof.Profile(w, r)
	case "/symbol":
		pprof.Symbol(w, r)
	default:
		pprof.Index(w, r)
	}
}

func interruptHandler(l net.Listener) {
	notifier := make(chan os.Signal)
	signal.Notify(notifier, os.Interrupt, syscall.SIGTERM)
	<-notifier
	log.Info("Received SIGINT/SIGTERM; exiting gracefully...")
	l.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"ddget"
	"fmt"
	"log"
)

func init() {
	log.SetFlags(0)
}

func main() {
	defer func() {
		if err := recover(); err != nil {
			log.Fatal(err)
		}
	}()

	ddgf, err := ddget.ParseFlag()

	if err != nil {
		panic(err)
	}

	ddg := ddget.New()
	item, err := ddg.GetItem(ddgf.Table, ddgf.ValueAttrNmae, ddgf.Key)

	if err != nil {
		panic(err)
	}

	fmt.Println(item)
}
<commit_msg>Small fix<commit_after>package main

import (
	"ddget"
	"fmt"
	"log"
)

func init() {
	log.SetFlags(0)
}

func main() {
	defer func() {
		if err := recover(); err != nil {
			log.Fatal(err)
		}
	}()

	ddgf, err := ddget.ParseFlag()

	if err != nil {
		panic(err)
	}

	ddg := ddget.New()
	item, err := ddg.GetItem(ddgf.Table, ddgf.ValueAttrNmae, ddgf.Key)

	if err != nil {
		panic(err)
	}

	if ddgf.NoNewLine {
		fmt.Print(item)
	} else {
		fmt.Println(item)
	}
}
<|endoftext|>