<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/koding/logging"
)

var (
	listen    = flag.String("listen", ":8080", "Address to listen for requests on")
	servePath = flag.String("path", "./", "Path the server is started from")
	header    = flag.String("header", "", "Header sent with every response")
	redirect  = flag.String("redirect", "", "Respond to unknown requests with this file. Used to serve Single Page Applications.")

	proxyFrom = flag.String("proxy-from", "", "Proxy requests to this path to the the path specified by proxy-to.")
	proxyTo   = flag.String("proxy-to", "", "Proxy requests from proxy-from to this address")
)

func main() {
	flag.Parse()

	logging.Info("Starting server on %s at %s", emp(*listen), emp(*servePath))

	var headers map[string]string
	if *header != "" {
		s := strings.Split(*header, ":")
		headers = map[string]string{
			s[0]: s[1],
		}
	}

	for k, v := range headers {
		logging.Info("Adding Header: %s:%s", emp(k), emp(v))
	}

	mux := http.NewServeMux()

	if *redirect != "" {
		logging.Info("Redirecting 404s to: %s", emp(*redirect))
	}

	mux.Handle("/", HeaderHandler{
		Handler: http.FileServer(SinglePageFileSystem{
			backendSystem: http.Dir(*servePath),
			redirectTo:    *redirect,
		}),
		headers: headers,
	})

	if *proxyFrom != "" && *proxyTo != "" {
		// Handle Redirects
		logging.Info("Proxying: (%s) -> (%s)",
			emp(*proxyFrom),
			emp(*proxyTo),
		)

		proxyToUrl, err := url.Parse(*proxyTo)
		if err != nil {
			logging.Error("Bad -proxy-to URL:", err)
			return
		}

		basePath, err := url.Parse(*proxyFrom)
		if err != nil {
			logging.Error("Bad -proxy-from URL:", err)
			return
		}

		director := httputil.NewSingleHostReverseProxy(proxyToUrl).Director
		proxy := httputil.ReverseProxy{
			Director: func(r *http.Request) {
				// Remove Base Path
				oldPath := *r.URL
				r.URL.Path = strings.TrimPrefix(oldPath.Path, basePath.Path)

				logging.Info("[proxying] (%s) -> (%s)", emp(oldPath.String()), emp(r.URL.String()))
				director(r)
			},
			Transport: &ProxyRoundTripper{
				BasePath: basePath.Path,
			},
		}

		mux.Handle(*proxyFrom, &proxy)
	}

	server := http.Server{
		Addr:    *listen,
		Handler: LoggingHandler{mux},
	}

	err := server.ListenAndServe()
	if err != nil {
		logging.Error(fmt.Sprint(err))
	}
}

type HeaderHandler struct {
	headers map[string]string
	http.Handler
}

func (h HeaderHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	responseHeaders := w.Header()
	for k, v := range h.headers {
		responseHeaders.Set(k, v)
	}

	h.Handler.ServeHTTP(w, r)
}

type LoggingHandler struct {
	http.Handler
}

func (h LoggingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	logging.Info("%s %s", r.Method, r.URL)

	h.Handler.ServeHTTP(w, r)
}

func colorize(color logging.Color, s string) string {
	return fmt.Sprintf("\033[%dm%s\033[0m", color, s)
}

func emp(s string) string {
	return colorize(logging.CYAN, s)
}

// A http.FileSystem for serving single page applications by redirecting all
// unknown paths to a given path.
type SinglePageFileSystem struct {
	backendSystem http.Dir
	redirectTo    string
}

func (spa SinglePageFileSystem) Open(name string) (http.File, error) {
	var localPath string
	basePath := string(spa.backendSystem)
	reqPath := filepath.Join(basePath, name)

	if _, err := os.Stat(reqPath); os.IsNotExist(err) && spa.redirectTo != "" {
		localPath = spa.redirectTo
		logging.Info("[redirecting] (%s) -> (%s)\n", emp(name), emp(localPath))
	} else {
		localPath = name
	}

	return spa.backendSystem.Open(localPath)
}

type ProxyRoundTripper struct {
	BasePath string
}

func (t *ProxyRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
	// Round Trip
	resp, err := http.DefaultTransport.RoundTrip(r)
	if err != nil {
		return nil, err
	}

	// Rewrite Cookie Paths
	cookies := resp.Cookies()
	for i := range cookies {
		cookie := cookies[i]
		cookie.Path = path.Join(t.BasePath, cookie.Path)
	}

	// Remove Cookies
	resp.Header.Del("Set-Cookie")

	// Set Cookies
	for _, cookie := range cookies {
		resp.Header.Add("Set-Cookie", cookie.String())
	}

	return resp, nil
}
<commit_msg>Fixed Root Proxy and Added Better Help Text<commit_after>package main

import (
	"flag"
	"fmt"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/koding/logging"
)

var (
	listen    = flag.String("listen", ":8080", "Address to listen for requests on")
	servePath = flag.String("path", "./", "Path the server is started from")
	header    = flag.String("header", "", `Header sent with every response (ex: Access-Control-Allow-Origin: *`)
	redirect  = flag.String("redirect", "", `Respond to unknown requests with this file. Used to serve Single Page Applications. (ex: index.html)`)

	proxyFrom = flag.String("proxy-from", "", `Proxy requests to this path to the the path specified by proxy-to. (ex: /path)`)
	proxyTo   = flag.String("proxy-to", "", `Proxy requests from proxy-from to this address (ex: https://google.com)`)
)

func main() {
	flag.Parse()

	logging.Info("Starting server on %s at %s", emp(*listen), emp(*servePath))

	var headers map[string]string
	if *header != "" {
		s := strings.Split(*header, ":")
		headers = map[string]string{
			s[0]: s[1],
		}
	}

	for k, v := range headers {
		logging.Info("Adding Header: %s:%s", emp(k), emp(v))
	}

	mux := http.NewServeMux()

	if *redirect != "" {
		logging.Info("Redirecting 404s to: %s", emp(*redirect))
	}

	if *proxyFrom != "/" {
		// Don't step over the proxy if proxying from root.
		mux.Handle("/", HeaderHandler{
			Handler: http.FileServer(SinglePageFileSystem{
				backendSystem: http.Dir(*servePath),
				redirectTo:    *redirect,
			}),
			headers: headers,
		})
	}

	if *proxyFrom != "" && *proxyTo != "" {
		// Handle Redirects
		logging.Info("Proxying: (%s) -> (%s)",
			emp(*proxyFrom),
			emp(*proxyTo),
		)

		proxyToUrl, err := url.Parse(*proxyTo)
		if err != nil {
			logging.Error("Bad -proxy-to URL:", err)
			return
		}

		basePath, err := url.Parse(*proxyFrom)
		if err != nil {
			logging.Error("Bad -proxy-from URL:", err)
			return
		}

		director := httputil.NewSingleHostReverseProxy(proxyToUrl).Director
		proxy := httputil.ReverseProxy{
			Director: func(r *http.Request) {
				// Remove Base Path
				oldPath := *r.URL
				r.URL.Path = strings.TrimPrefix(oldPath.Path, basePath.Path)

				logging.Info("[proxying] (%s) -> (%s)", emp(oldPath.String()), emp(r.URL.String()))
				director(r)
			},
			Transport: &ProxyRoundTripper{
				BasePath: basePath.Path,
			},
		}

		mux.Handle(*proxyFrom, &proxy)
	}

	server := http.Server{
		Addr:    *listen,
		Handler: LoggingHandler{mux},
	}

	err := server.ListenAndServe()
	if err != nil {
		logging.Error(fmt.Sprint(err))
	}
}

type HeaderHandler struct {
	headers map[string]string
	http.Handler
}

func (h HeaderHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	responseHeaders := w.Header()
	for k, v := range h.headers {
		responseHeaders.Set(k, v)
	}

	h.Handler.ServeHTTP(w, r)
}

type LoggingHandler struct {
	http.Handler
}

func (h LoggingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	logging.Info("%s %s", r.Method, r.URL)

	h.Handler.ServeHTTP(w, r)
}

func colorize(color logging.Color, s string) string {
	return fmt.Sprintf("\033[%dm%s\033[0m", color, s)
}

func emp(s string) string {
	return colorize(logging.CYAN, s)
}

// A http.FileSystem for serving single page applications by redirecting all
// unknown paths to a given path.
type SinglePageFileSystem struct {
	backendSystem http.Dir
	redirectTo    string
}

func (spa SinglePageFileSystem) Open(name string) (http.File, error) {
	var localPath string
	basePath := string(spa.backendSystem)
	reqPath := filepath.Join(basePath, name)

	if _, err := os.Stat(reqPath); os.IsNotExist(err) && spa.redirectTo != "" {
		localPath = spa.redirectTo
		logging.Info("[redirecting] (%s) -> (%s)\n", emp(name), emp(localPath))
	} else {
		localPath = name
	}

	return spa.backendSystem.Open(localPath)
}

type ProxyRoundTripper struct {
	BasePath string
}

func (t *ProxyRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
	// Round Trip
	resp, err := http.DefaultTransport.RoundTrip(r)
	if err != nil {
		return nil, err
	}

	// Rewrite Cookie Paths
	cookies := resp.Cookies()
	for i := range cookies {
		cookie := cookies[i]
		cookie.Path = path.Join(t.BasePath, cookie.Path)
	}

	// Remove Cookies
	resp.Header.Del("Set-Cookie")

	// Set Cookies
	for _, cookie := range cookies {
		resp.Header.Add("Set-Cookie", cookie.String())
	}

	return resp, nil
}
<|endoftext|>


<commit_before>package main

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

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

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

const ServerName = "Snake-Server"

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

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

var (
	address string

	flagEnableTLS bool
	certFile      string
	keyFile       string

	groupsLimit int
	connsLimit  int
	seed        int64

	flagJSONLog bool
	logLevel    string
)

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

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

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

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

func main() {
	logger := logger()

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

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

	rand.Seed(seed)

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

	rootRouter := mux.NewRouter()

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

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

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

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

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


<commit_before>/*
hwaf manages hep-waf based applications and libraries.

 Subcommands:

 init [directory]

 self-update

 configure

 build/make

 install

 bdist
 bdist-rpm
 bdist-dmg
 bdist-deb

 run

 shell

 setup

 add-pkg <pkg-uri> [<pkg-version>]
 checkout|co == alias(add-pkg)
*/
package main

import (
	"os"
	"path/filepath"

	"github.com/gonuts/commander"
	"github.com/gonuts/flag"
	"github.com/hwaf/hwaf/hwaflib"
)

var g_cmd *commander.Commander
var g_ctx *hwaflib.Context

func init() {
	g_cmd = &commander.Commander{
		Name: os.Args[0],
		Commands: []*commander.Command{
			hwaf_make_cmd_asetup(),
			hwaf_make_cmd_init(),
			hwaf_make_cmd_setup(),
			hwaf_make_cmd_version(),

			hwaf_make_cmd_waf(),
			hwaf_make_cmd_waf_configure(),
			hwaf_make_cmd_waf_build(),
			hwaf_make_cmd_waf_check(),
			hwaf_make_cmd_waf_install(),
			hwaf_make_cmd_waf_clean(),
			hwaf_make_cmd_waf_distclean(),
			hwaf_make_cmd_waf_shell(),
			hwaf_make_cmd_waf_run(),

			hwaf_make_cmd_waf_sdist(),
			hwaf_make_cmd_waf_bdist(),
			hwaf_make_cmd_waf_bdist_deb(),
			hwaf_make_cmd_waf_bdist_rpm(),

			hwaf_make_cmd_dump_env(),
		},
		Flag: flag.NewFlagSet("hwaf", flag.ExitOnError),
		Commanders: []*commander.Commander{
			hwaf_make_cmd_git(),
			hwaf_make_cmd_pkg(),
			hwaf_make_cmd_waf_show(),
			hwaf_make_cmd_pmgr(),
			hwaf_make_cmd_self(),
		},
	}
}

func main() {

	if len(os.Args) == 1 && path_exists("wscript") {
		os.Args = append(os.Args, "waf", "build+install")
	}

	var err error
	pwd, err := os.Getwd()
	handle_err(err)

	wdir := pwd
	switch os.Args[1] {
	case "init", "setup", "asetup":
		// these are supposed to *create* the .hwaf directory...

	default:
		wdir = func() string {
			// try to find a workarea in a parent dir:
			for dir := wdir; dir != "/"; dir = filepath.Dir(dir) {
				if path_exists(filepath.Join(dir, ".hwaf")) {
					return dir
				}
			}
			return ""
		}()
	}

	switch wdir {
	case "":
		g_ctx, err = hwaflib.NewContext()
		handle_err(err)
	default:
		g_ctx, err = hwaflib.NewContextFrom(wdir)
		handle_err(err)
	}

	err = g_cmd.Flag.Parse(os.Args[1:])
	handle_err(err)

	args := g_cmd.Flag.Args()
	err = g_cmd.Run(args)
	handle_err(err)

	g_ctx.Exit(0)
	return
}
<commit_msg>main: dont crash and burn when 'hwaf' is run in a directory w/o wscript<commit_after>/*
hwaf manages hep-waf based applications and libraries.

 Subcommands:

 init [directory]

 self-update

 configure

 build/make

 install

 bdist
 bdist-rpm
 bdist-dmg
 bdist-deb

 run

 shell

 setup

 add-pkg <pkg-uri> [<pkg-version>]
 checkout|co == alias(add-pkg)
*/
package main

import (
	"os"
	"path/filepath"

	"github.com/gonuts/commander"
	"github.com/gonuts/flag"
	"github.com/hwaf/hwaf/hwaflib"
)

var g_cmd *commander.Commander
var g_ctx *hwaflib.Context

func init() {
	g_cmd = &commander.Commander{
		Name: os.Args[0],
		Commands: []*commander.Command{
			hwaf_make_cmd_asetup(),
			hwaf_make_cmd_init(),
			hwaf_make_cmd_setup(),
			hwaf_make_cmd_version(),

			hwaf_make_cmd_waf(),
			hwaf_make_cmd_waf_configure(),
			hwaf_make_cmd_waf_build(),
			hwaf_make_cmd_waf_check(),
			hwaf_make_cmd_waf_install(),
			hwaf_make_cmd_waf_clean(),
			hwaf_make_cmd_waf_distclean(),
			hwaf_make_cmd_waf_shell(),
			hwaf_make_cmd_waf_run(),

			hwaf_make_cmd_waf_sdist(),
			hwaf_make_cmd_waf_bdist(),
			hwaf_make_cmd_waf_bdist_deb(),
			hwaf_make_cmd_waf_bdist_rpm(),

			hwaf_make_cmd_dump_env(),
		},
		Flag: flag.NewFlagSet("hwaf", flag.ExitOnError),
		Commanders: []*commander.Commander{
			hwaf_make_cmd_git(),
			hwaf_make_cmd_pkg(),
			hwaf_make_cmd_waf_show(),
			hwaf_make_cmd_pmgr(),
			hwaf_make_cmd_self(),
		},
	}
}

func main() {

	if len(os.Args) == 1 {
		if path_exists("wscript") {
			os.Args = append(os.Args, "waf", "build+install")
		} else {
			g_ctx.Warn("'hwaf' needs a command to run. see 'hwaf help' for informations\n")
			os.Exit(1)
		}
	}

	var err error
	pwd, err := os.Getwd()
	handle_err(err)

	wdir := pwd
	switch os.Args[1] {
	case "init", "setup", "asetup":
		// these are supposed to *create* the .hwaf directory...

	default:
		wdir = func() string {
			// try to find a workarea in a parent dir:
			for dir := wdir; dir != "/"; dir = filepath.Dir(dir) {
				if path_exists(filepath.Join(dir, ".hwaf")) {
					return dir
				}
			}
			return ""
		}()
	}

	switch wdir {
	case "":
		g_ctx, err = hwaflib.NewContext()
		handle_err(err)
	default:
		g_ctx, err = hwaflib.NewContextFrom(wdir)
		handle_err(err)
	}

	err = g_cmd.Flag.Parse(os.Args[1:])
	handle_err(err)

	args := g_cmd.Flag.Args()
	err = g_cmd.Run(args)
	handle_err(err)

	g_ctx.Exit(0)
	return
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"os/exec"
	"log"
)

const (
	userBin = "/usr/bin/"
	userLocalBin = "/usr/local/bin/"
	grep = "grep"
	LS = "ls"
)

var l = flag.Bool("l", false, "List files from /usr/local/bin directory")
var a = flag.Bool("a", false, "List files from both /usr/bin and /usr/local/bin directory")
var s = flag.String("s", "", "Applies a grep 'char' filter to the output")
var i = flag.String("i", "", "Apllies a grep 'string' filter to the output")

func createBashCommand(local *bool, all *bool, grepStartsWith *string, grepIncludes* string) ([]string, []string) {
	lsArgs := []string{LS}
	if *all{
		lsArgs = append(lsArgs, userBin)
		lsArgs = append(lsArgs, userLocalBin)
	}else if *local {
		lsArgs = append(lsArgs, userLocalBin)
	} else {
		lsArgs = append(lsArgs, userBin)
	}

	grepArgs := []string{grep}

	if *grepStartsWith != "" || *grepIncludes != ""{
		if *grepStartsWith != ""{
			grepArgs = append(grepArgs, fmt.Sprintf("^%s", *grepStartsWith))
		} else {
			grepArgs = append(grepArgs, fmt.Sprintf("%s", *grepIncludes))
		}
	}
	return lsArgs, grepArgs

}

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

func runCommand(lsArgs []string, grepArgs []string, output bytes.Buffer) {
	var lsCmd *exec.Cmd
	var grepCmd *exec.Cmd

	numOfArgs := len(lsArgs)
	fmt.Printf("num of args: %d\n", numOfArgs)

	if numOfArgs == 2 {
		lsCmd = exec.Command(lsArgs[0], lsArgs[1])
	} else if numOfArgs == 3 {
		lsCmd = exec.Command(lsArgs[0], lsArgs[1], lsArgs[2])
	}

	if len(grepArgs) == 2 {
		grepCmd = exec.Command(grepArgs[0], grepArgs[1])
		var err error

		grepCmd.Stdout = &output

		grepCmd.Stdin, err = lsCmd.StdoutPipe()
		grepCmd.Start()
		errorHandler(err)

		err = lsCmd.Start()
		fmt.Print("run lsCmd")
		errorHandler(err)

		err = lsCmd.Wait()
		errorHandler(err)

		err = grepCmd.Wait()
		fmt.Print("grepCmd")
		errorHandler(err)
	} else {
		lsCmd.Stdout = &output
		err := lsCmd.Run()
		errorHandler(err)
	}

	fmt.Print("output: ")
	fmt.Println(output.String())

}

func printToScreen(content string) {
	fmt.Println(content)
	fmt.Println("over")
}

func main() {
	flag.Parse()

	var output bytes.Buffer
	lsArgs, grepArgs := createBashCommand(l,a,s,i)
	runCommand(lsArgs, grepArgs, output)
	printToScreen(output.String())
}
<commit_msg>Basic functionality is done<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"
	"os/exec"
)

const (
	userBin      = "/usr/bin/"
	userLocalBin = "/usr/local/bin/"
	grep         = "grep"
	LS           = "ls"
)

var l = flag.Bool("l", false, "List files from /usr/local/bin directory")
var a = flag.Bool("a", false, "List files from both /usr/bin and /usr/local/bin directory")
var s = flag.String("s", "", "Applies a grep 'char' filter to the output")
var i = flag.String("i", "", "Apllies a grep 'string' filter to the output")

func createBashCommand(local *bool, all *bool, grepStartsWith *string, grepIncludes *string) ([]string, []string) {
	lsArgs := []string{LS}
	if *all {
		lsArgs = append(lsArgs, userBin)
		lsArgs = append(lsArgs, userLocalBin)
	} else if *local {
		lsArgs = append(lsArgs, userLocalBin)
	} else {
		lsArgs = append(lsArgs, userBin)
	}

	grepArgs := []string{grep}

	if *grepStartsWith != "" || *grepIncludes != "" {
		if *grepStartsWith != "" {
			grepArgs = append(grepArgs, fmt.Sprintf("^%s", *grepStartsWith))
		} else {
			grepArgs = append(grepArgs, fmt.Sprintf("%s", *grepIncludes))
		}
	}
	return lsArgs, grepArgs

}

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

func runCommand(lsArgs []string, grepArgs []string, output bytes.Buffer) string {
	var lsCmd *exec.Cmd
	var grepCmd *exec.Cmd

	numOfArgs := len(lsArgs)

	if numOfArgs == 2 {
		lsCmd = exec.Command(lsArgs[0], lsArgs[1])
	} else if numOfArgs == 3 {
		lsCmd = exec.Command(lsArgs[0], lsArgs[1], lsArgs[2])
	}

	if len(grepArgs) == 2 {
		grepCmd = exec.Command(grepArgs[0], grepArgs[1])
		var err error

		grepCmd.Stdout = &output

		grepCmd.Stdin, err = lsCmd.StdoutPipe()
		grepCmd.Start()
		errorHandler(err)

		err = lsCmd.Start()
		errorHandler(err)

		err = lsCmd.Wait()
		errorHandler(err)

		// There is an error when the output is empty
		//So... ignore it?
		_ = grepCmd.Wait()
	} else {
		lsCmd.Stdout = &output
		err := lsCmd.Run()
		errorHandler(err)
	}

	return output.String()
}

func printToScreen(content string) {
	fmt.Println("See Results Below: ")
	if content == "" {
		fmt.Println("None")
	} else {
		fmt.Println(content)
	}
}

func main() {
	flag.Parse()

	var output bytes.Buffer
	lsArgs, grepArgs := createBashCommand(l, a, s, i)
	result := runCommand(lsArgs, grepArgs, output)
	printToScreen(result)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"regexp"
	"runtime"
)

type Page struct {
}

// Command-line flags
var httpPort = flag.String("port", "8080", "HTTP port the web server listens to.")

// RegEx patterns
var assetUrlPattern = regexp.MustCompile("^/(?:css|js)/")
var whitespacePattern = regexp.MustCompile(">[ \f\n\r\t]+<")

func main() {
	// Set maximum number of processes to number of CPUs
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Parse command-line into defined flags
	flag.Parse()

	http.HandleFunc("/", handleRequest)

	fmt.Println("Started web server at 127.0.0.1:" + *httpPort + ".")
	error := http.ListenAndServe(":"+*httpPort, nil)

	if error != nil {
		log.Fatal("ListenAndServe: ", error)
	}
}

func handleRequest(responseWriter http.ResponseWriter, request *http.Request) {
	if request.URL.Path == "/" {
		fileContent, error := ioutil.ReadFile("views/layouts/default.html")

		if error != nil {
			fmt.Println("Error:", error)
			http.NotFound(responseWriter, request)
			return
		}

		cleanedFileContent := whitespacePattern.ReplaceAllString(string(fileContent), "><")
		parsedTemplate, error := template.New("default").Parse(cleanedFileContent)

		error = parsedTemplate.Execute(responseWriter, &Page{})

		if error != nil {
			http.Error(responseWriter, error.Error(), http.StatusInternalServerError)
			fmt.Println(error)
			return
		}

		return
	}

	if assetUrlPattern.MatchString(request.URL.Path) {
		file, error := os.Open("webroot" + request.URL.Path)

		if error != nil {
			http.NotFound(responseWriter, request)
			return
		}

		fileInfo, error := file.Stat()

		if error != nil {
			fmt.Println("Error:", error)
			return
		}

		http.ServeContent(responseWriter, request, "webroot"+request.URL.Path, fileInfo.ModTime(), file)
		return
	}

	http.NotFound(responseWriter, request)
}
<commit_msg>Replaced fmt.Println() with log.Println().<commit_after>package main

import (
	"flag"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"regexp"
	"runtime"
)

type Page struct {
}

// Command-line flags
var httpPort = flag.String("port", "8080", "HTTP port the web server listens to.")

// RegEx patterns
var assetUrlPattern = regexp.MustCompile("^/(?:css|js)/")
var whitespacePattern = regexp.MustCompile(">[ \f\n\r\t]+<")

func main() {
	// Set maximum number of processes to number of CPUs
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Parse command-line into defined flags
	flag.Parse()

	http.HandleFunc("/", handleRequest)

	log.Println("Started web server at 127.0.0.1:" + *httpPort + ".")
	error := http.ListenAndServe(":"+*httpPort, nil)

	if error != nil {
		log.Fatal("ListenAndServe: ", error)
	}
}

func handleRequest(responseWriter http.ResponseWriter, request *http.Request) {
	if request.URL.Path == "/" {
		fileContent, error := ioutil.ReadFile("views/layouts/default.html")

		if error != nil {
			http.NotFound(responseWriter, request)
			log.Println("Error:", error)
			return
		}

		cleanedFileContent := whitespacePattern.ReplaceAllString(string(fileContent), "><")
		parsedTemplate, error := template.New("default").Parse(cleanedFileContent)

		error = parsedTemplate.Execute(responseWriter, &Page{})

		if error != nil {
			http.Error(responseWriter, error.Error(), http.StatusInternalServerError)
			log.Println("Error:", error)
			return
		}

		return
	}

	if assetUrlPattern.MatchString(request.URL.Path) {
		file, error := os.Open("webroot" + request.URL.Path)

		if error != nil {
			http.NotFound(responseWriter, request)
			log.Println("Error:", error)
			return
		}

		fileInfo, error := file.Stat()

		if error != nil {
			http.NotFound(responseWriter, request)
			log.Println("Error:", error)
			return
		}

		http.ServeContent(responseWriter, request, "webroot"+request.URL.Path, fileInfo.ModTime(), file)
		return
	}

	http.NotFound(responseWriter, request)
}
<|endoftext|>


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

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"bytes"
	"math/rand"
	"time"

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

var bot *linebot.Client
var locdb = make(map[string]linebot.LocationMessage)

func main() {
	var err error
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)

	translate_init()
	yelp_init()

	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

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

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

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				var outmsg bytes.Buffer

				switch {
					case strings.Compare(message.Text, "溫馨提醒") == 0:
						outmsg.WriteString("<<<溫馨提醒>>>\r\n因為這個群很吵 -->\r\n右上角 可以 關閉提醒\r\n\r\n[同學會] 投票進行中 -->\r\n右上角 筆記本 可以進行投票\r\n\r\n[通訊錄] 需要大家的協助 -->\r\n右上角 筆記本 請更新自己的聯絡方式")

					case strings.HasSuffix(message.Text, "麼帥"):
						outmsg.WriteString(GetHandsonText(message.Text))

					case strings.Compare(message.Text, "PPAP") == 0:
						outmsg.WriteString(GetPPAPText())

					case strings.HasPrefix(message.Text, "翻翻"):
						outmsg.WriteString(GetTransText(strings.TrimLeft(message.Text, "翻翻")))

					case strings.HasPrefix(message.Text, "吃吃"):
						yelp_parse(bot, event.ReplyToken, strings.TrimLeft(message.Text, "吃吃"))
						continue
					default:
						continue
				}

				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(outmsg.String())).Do(); err != nil {
					log.Print(err)
				}
			case *linebot.LocationMessage:
				locdb[event.ReplyToken] = message
			}
		}
	}
}

func GetHandsonText(inText string) string {
	var outmsg bytes.Buffer
	var outText bytes.Buffer
	rand.Seed(time.Now().UnixNano())
	i := rand.Intn(100)
	outmsg.WriteString("我覺得還是")
	switch i % 20 {
	case 0:
		outmsg.WriteString("我")
	case 1:
		outmsg.WriteString("你")
	default:
		outText.WriteString(inText)
		outText.WriteString("+1")
		return outText.String()
	}
	outmsg.WriteString("比較帥")
	return outmsg.String()
}

func GetPPAPText() string {
	rand.Seed(time.Now().UnixNano())
	i := rand.Intn(100)
	switch i % 5 {
	case 0:
		return "I have a pencil,\r\nI have an Apple,\r\nApple pencil.\r\nI have a watch,\r\nI have an Apple,\r\nApple watch."
	case 1:
		return "順帶一提，請不要把Apple Pencil刺進水果裡，不管是蘋果還是鳳梨。"
	case 2:
		return "我懂了，這是以書寫工具與種類食物為題的饒舌歌。"
	case 3:
		return "我不太清楚PPAP是什麼，但你可以問我AAPL的相關資訊。"
	case 4:
		return "我是不會接著唱的！"
	}
	return "去問 siri 啦"
}
<commit_msg>test location<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"bytes"
	"math/rand"
	"time"

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

var bot *linebot.Client
var locdb = make(map[string]*linebot.LocationMessage)

func main() {
	var err error
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)

	translate_init()
	yelp_init()

	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

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

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

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				var outmsg bytes.Buffer

				switch {
					case strings.Compare(message.Text, "溫馨提醒") == 0:
						outmsg.WriteString("<<<溫馨提醒>>>\r\n因為這個群很吵 -->\r\n右上角 可以 關閉提醒\r\n\r\n[同學會] 投票進行中 -->\r\n右上角 筆記本 可以進行投票\r\n\r\n[通訊錄] 需要大家的協助 -->\r\n右上角 筆記本 請更新自己的聯絡方式")

					case strings.HasSuffix(message.Text, "麼帥"):
						outmsg.WriteString(GetHandsonText(message.Text))

					case strings.Compare(message.Text, "PPAP") == 0:
						outmsg.WriteString(GetPPAPText())

					case strings.HasPrefix(message.Text, "翻翻"):
						outmsg.WriteString(GetTransText(strings.TrimLeft(message.Text, "翻翻")))

					case strings.HasPrefix(message.Text, "吃吃"):
						yelp_parse(bot, event.ReplyToken, strings.TrimLeft(message.Text, "吃吃"))
						continue
					default:
						continue
				}

				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(outmsg.String())).Do(); err != nil {
					log.Print(err)
				}
			case *linebot.LocationMessage:
				locdb[event.ReplyToken] = message
			}
		}
	}
}

func GetHandsonText(inText string) string {
	var outmsg bytes.Buffer
	var outText bytes.Buffer
	rand.Seed(time.Now().UnixNano())
	i := rand.Intn(100)
	outmsg.WriteString("我覺得還是")
	switch i % 20 {
	case 0:
		outmsg.WriteString("我")
	case 1:
		outmsg.WriteString("你")
	default:
		outText.WriteString(inText)
		outText.WriteString("+1")
		return outText.String()
	}
	outmsg.WriteString("比較帥")
	return outmsg.String()
}

func GetPPAPText() string {
	rand.Seed(time.Now().UnixNano())
	i := rand.Intn(100)
	switch i % 5 {
	case 0:
		return "I have a pencil,\r\nI have an Apple,\r\nApple pencil.\r\nI have a watch,\r\nI have an Apple,\r\nApple watch."
	case 1:
		return "順帶一提，請不要把Apple Pencil刺進水果裡，不管是蘋果還是鳳梨。"
	case 2:
		return "我懂了，這是以書寫工具與種類食物為題的饒舌歌。"
	case 3:
		return "我不太清楚PPAP是什麼，但你可以問我AAPL的相關資訊。"
	case 4:
		return "我是不會接著唱的！"
	}
	return "去問 siri 啦"
}
<|endoftext|>


<commit_before>/**
 * @file main.go
 * @author Mikhail Klementyev jollheef<AT>riseup.net
 * @license GNU AGPLv3
 * @date September, 2015
 * @brief contest checking system daemon
 *
 * Entry point for contest checking system daemon
 */

package main

import (
	"fmt"
	"log"
	"os"
	"syscall"
	"time"

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

import (
	"github.com/jollheef/tin_foil_hat/checker"
	"github.com/jollheef/tin_foil_hat/config"
	"github.com/jollheef/tin_foil_hat/pulse"
	"github.com/jollheef/tin_foil_hat/receiver"
	"github.com/jollheef/tin_foil_hat/scoreboard"
	"github.com/jollheef/tin_foil_hat/steward"
	"github.com/jollheef/tin_foil_hat/vexillary"
)

var (
	configPath = kingpin.Arg("config",
		"Path to configuration file.").String()

	dbReinit = kingpin.Flag("reinit", "Reinit database.").Bool()
)

var (
	commitID  string
	buildDate string
	buildTime string
)

func buildInfo() (str string) {

	if len(commitID) > 7 {
		commitID = commitID[:7] // abbreviated commit hash
	}

	str = fmt.Sprintf("Version: tin_foil_hat %s %s %s\n",
		commitID, buildDate, buildTime)
	str += "Author: Mikhail Klementyev <jollheef@riseup.net>\n"
	return
}

func main() {

	fmt.Println(buildInfo())

	kingpin.Parse()

	if *configPath == "" {
		log.Println("Use default config path")
		*configPath = "/etc/tinfoilhat/tinfoilhat.toml"
	}

	config, err := config.ReadConfig(*configPath)
	if err != nil {
		log.Fatalln("Cannot open config:", err)
	}

	logFile, err := os.OpenFile(config.LogFile,
		os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln("Cannot open file:", err)
	}
	defer logFile.Close()
	log.SetOutput(logFile)

	log.Println(buildInfo())

	var rlim syscall.Rlimit
	err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim)
	if err != nil {
		log.Fatalln("Getrlimit fail:", err)
	}

	log.Println("RLIMIT_NOFILE CUR:", rlim.Cur, "MAX:", rlim.Max)

	db, err := steward.OpenDatabase(config.Database.Connection)
	if err != nil {
		log.Fatalln("Open database fail:", err)
	}

	defer db.Close()

	db.SetMaxOpenConns(config.Database.MaxConnections)

	if *dbReinit {

		if config.Database.SafeReinit {
			if time.Now().After(config.Pulse.Start.Time) {
				log.Fatalln("Reinit after start not allowed")
			}
		}

		log.Println("Reinit database")

		log.Println("Clean database")

		steward.CleanDatabase(db)

		for _, team := range config.Teams {

			log.Println("Add team", team.Name)

			_, err = steward.AddTeam(db, team)
			if err != nil {
				log.Fatalln("Add team failed:", err)
			}
		}

		for _, svc := range config.Services {

			var network string
			if svc.UDP {
				network = "udp"
			} else {
				network = "tcp"
			}

			log.Printf("Add service %s (%s)\n", svc.Name, network)

			err = steward.AddService(db, svc)
			if err != nil {
				log.Fatalln("Add service failed:", err)
			}
		}
	}

	checker.SetTimeout(config.CheckerTimeout.Duration)

	if config.AdvisoryReceiver.Disabled {
		scoreboard.DisableAdvisory()
	}

	priv, err := vexillary.GenerateKey()
	if err != nil {
		log.Fatalln("Generate key fail:", err)
	}

	go receiver.FlagReceiver(db, priv, config.FlagReceiver.Addr,
		config.FlagReceiver.ReceiveTimeout.Duration,
		config.FlagReceiver.SocketTimeout.Duration)

	go receiver.AdvisoryReceiver(db, config.AdvisoryReceiver.Addr,
		config.AdvisoryReceiver.ReceiveTimeout.Duration,
		config.AdvisoryReceiver.SocketTimeout.Duration)

	go scoreboard.Scoreboard(db, config.Scoreboard.WwwPath,
		config.Scoreboard.Addr,
		config.Scoreboard.UpdateTimeout.Duration,
		config.Pulse.Start.Time,
		config.Pulse.Half.Duration,
		config.Pulse.Lunch.Duration,
		config.Pulse.DarkestTime.Duration)

	err = pulse.Pulse(db, priv,
		config.Pulse.Start.Time,
		config.Pulse.Half.Duration,
		config.Pulse.Lunch.Duration,
		config.Pulse.RoundLen.Duration,
		config.Pulse.CheckTimeout.Duration)
	if err != nil {
		log.Fatalln("Game error:", err)
	}

	log.Println("It's now safe to turn off you computer")
	for {
		time.Sleep(time.Hour)
	}
}
<commit_msg>Move reinit database to separate function<commit_after>/**
 * @file main.go
 * @author Mikhail Klementyev jollheef<AT>riseup.net
 * @license GNU AGPLv3
 * @date September, 2015
 * @brief contest checking system daemon
 *
 * Entry point for contest checking system daemon
 */

package main

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"syscall"
	"time"

	"github.com/jollheef/tin_foil_hat/checker"
	"github.com/jollheef/tin_foil_hat/config"
	"github.com/jollheef/tin_foil_hat/pulse"
	"github.com/jollheef/tin_foil_hat/receiver"
	"github.com/jollheef/tin_foil_hat/scoreboard"
	"github.com/jollheef/tin_foil_hat/steward"
	"github.com/jollheef/tin_foil_hat/vexillary"
	kingpin "gopkg.in/alecthomas/kingpin.v2"
)

var (
	configPath = kingpin.Arg("config",
		"Path to configuration file.").String()

	dbReinit = kingpin.Flag("reinit", "Reinit database.").Bool()
)

var (
	commitID  string
	buildDate string
	buildTime string
)

func buildInfo() (str string) {

	if len(commitID) > 7 {
		commitID = commitID[:7] // abbreviated commit hash
	}

	str = fmt.Sprintf("Version: tin_foil_hat %s %s %s\n",
		commitID, buildDate, buildTime)
	str += "Author: Mikhail Klementyev <jollheef@riseup.net>\n"
	return
}

func reinitDatabase(db *sql.DB, config config.Config) {

	var err error

	if config.Database.SafeReinit {
		if time.Now().After(config.Pulse.Start.Time) {
			log.Fatalln("Reinit after start not allowed")
		}
	}

	log.Println("Reinit database")

	log.Println("Clean database")

	steward.CleanDatabase(db)

	for _, team := range config.Teams {

		log.Println("Add team", team.Name)

		_, err = steward.AddTeam(db, team)
		if err != nil {
			log.Fatalln("Add team failed:", err)
		}
	}

	for _, svc := range config.Services {

		var network string
		if svc.UDP {
			network = "udp"
		} else {
			network = "tcp"
		}

		log.Printf("Add service %s (%s)\n", svc.Name, network)

		err = steward.AddService(db, svc)
		if err != nil {
			log.Fatalln("Add service failed:", err)
		}
	}
}

func main() {

	fmt.Println(buildInfo())

	kingpin.Parse()

	if *configPath == "" {
		log.Println("Use default config path")
		*configPath = "/etc/tinfoilhat/tinfoilhat.toml"
	}

	config, err := config.ReadConfig(*configPath)
	if err != nil {
		log.Fatalln("Cannot open config:", err)
	}

	logFile, err := os.OpenFile(config.LogFile,
		os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln("Cannot open file:", err)
	}
	defer logFile.Close()
	log.SetOutput(logFile)

	log.Println(buildInfo())

	var rlim syscall.Rlimit
	err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim)
	if err != nil {
		log.Fatalln("Getrlimit fail:", err)
	}

	log.Println("RLIMIT_NOFILE CUR:", rlim.Cur, "MAX:", rlim.Max)

	db, err := steward.OpenDatabase(config.Database.Connection)
	if err != nil {
		log.Fatalln("Open database fail:", err)
	}

	defer db.Close()

	db.SetMaxOpenConns(config.Database.MaxConnections)

	if *dbReinit {
		reinitDatabase(db, config)
	}

	checker.SetTimeout(config.CheckerTimeout.Duration)

	if config.AdvisoryReceiver.Disabled {
		scoreboard.DisableAdvisory()
	}

	priv, err := vexillary.GenerateKey()
	if err != nil {
		log.Fatalln("Generate key fail:", err)
	}

	go receiver.FlagReceiver(db, priv, config.FlagReceiver.Addr,
		config.FlagReceiver.ReceiveTimeout.Duration,
		config.FlagReceiver.SocketTimeout.Duration)

	go receiver.AdvisoryReceiver(db, config.AdvisoryReceiver.Addr,
		config.AdvisoryReceiver.ReceiveTimeout.Duration,
		config.AdvisoryReceiver.SocketTimeout.Duration)

	go scoreboard.Scoreboard(db, config.Scoreboard.WwwPath,
		config.Scoreboard.Addr,
		config.Scoreboard.UpdateTimeout.Duration,
		config.Pulse.Start.Time,
		config.Pulse.Half.Duration,
		config.Pulse.Lunch.Duration,
		config.Pulse.DarkestTime.Duration)

	err = pulse.Pulse(db, priv,
		config.Pulse.Start.Time,
		config.Pulse.Half.Duration,
		config.Pulse.Lunch.Duration,
		config.Pulse.RoundLen.Duration,
		config.Pulse.CheckTimeout.Duration)
	if err != nil {
		log.Fatalln("Game error:", err)
	}

	log.Println("It's now safe to turn off you computer")
	for {
		time.Sleep(time.Hour)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"log"
	"log/syslog"
	"os"
	"os/signal"
	"syscall"

	libdebug "runtime/debug"

	"sync"

	"github.com/gallir/smart-relayer/custom/redis2kvstore"
	"github.com/gallir/smart-relayer/httpproxy"
	"github.com/gallir/smart-relayer/lib"
	"github.com/gallir/smart-relayer/redis/cluster"
	"github.com/gallir/smart-relayer/redis/fh"
	"github.com/gallir/smart-relayer/redis/fs"
	"github.com/gallir/smart-relayer/redis/kinesis"
	"github.com/gallir/smart-relayer/redis/radix"
	"github.com/gallir/smart-relayer/redis/radix.improved/redis"
	"github.com/gallir/smart-relayer/redis/rsqs"
)

const (
	version = "8.6.2"
)

var (
	mutex          sync.Mutex
	relayers       = make(map[string]lib.Relayer)
	totalRelayers  = 0
	relayersConfig *lib.Config
	done           = make(chan bool)
	reloadSig      = make(chan os.Signal, 1)
	exitSig        = make(chan os.Signal, 1)
)

func getNewServer(conf lib.RelayerConfig) (srv lib.Relayer, err error) {
	switch conf.Protocol {
	case "redis", "redis2":
		srv, err = redis2.New(conf, done)
	case "redis-cluster", "redis-plus":
		srv, err = cluster.New(conf, done)
	case "firehose":
		srv, err = fh.New(conf, done)
	case "kinesis":
		srv, err = kinesis.New(conf, done)
	case "sqs":
		srv, err = rsqs.New(conf, done)
	case "fs":
		srv, err = fs.New(conf, done)
	case "http":
		srv, err = httpproxy.New(conf, done)
	case "redis2kvstore":
		srv, err = redis2kvstore.New(conf, done)
	default:
		err = errors.New("no valid option")
	}
	return
}

func startOrReload() bool {
	mutex.Lock()
	defer mutex.Unlock()

	// Check config is OK
	newConf, err := lib.ReadConfig(lib.GlobalConfig.ConfigFileName)
	if err != nil {
		log.Println("Bad configuration", err)
		return false
	}

	if newConf.GOGC > 100 {
		libdebug.SetGCPercent(newConf.GOGC)
		log.Println("Set GCPercent to", newConf.GOGC)
	} else {
		libdebug.SetGCPercent(100)
	}

	redis.UsePool = newConf.BufferPoolSize
	if redis.UsePool > 0 {
		log.Println("Set UsePool to", redis.UsePool)
	}

	lib.Debugf("%#v", newConf.Relayer)

	newEndpoints := make(map[string]bool)

	for _, conf := range newConf.Relayer {
		endpoint, ok := relayers[conf.Listen]
		newEndpoints[conf.Listen] = true
		if !ok {
			// Start a new relayer
			r, err := getNewServer(conf)
			if err != nil {
				log.Println("E: Error starting relayer", conf.Protocol, conf.URL, err)
			}
			lib.Debugf("Starting new relayer from %s to %s", conf.Listen, conf.URL)
			totalRelayers++
			if e := r.Start(); e == nil {
				relayers[conf.Listen] = r
			}
		} else {
			// The relayer exists, reload it
			err := endpoint.Reload(&conf)
			if err != nil {
				log.Println("E: Error reloading", conf.Protocol, conf.URL, err)
			}
		}
	}

	for endpoint, r := range relayers {
		_, ok := newEndpoints[endpoint]
		if !ok {
			log.Printf("Deleting old endpoint %s", endpoint)
			delete(relayers, endpoint)
			r.Exit()
		}
	}

	return true
}

func main() {

	// Force a high number of file descriptoir, if possible
	var rLimit syscall.Rlimit
	e := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
	if e == nil {
		rLimit.Cur = 65536
		syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
	}

	// Show version and exit
	if lib.GlobalConfig.ShowVersion {
		fmt.Println("smart-relayer version", version)
		fmt.Printf("Max files %d/%d\n", rLimit.Cur, rLimit.Max)
		os.Exit(0)
	}

	if !lib.GlobalConfig.Debug {
		logwriter, e := syslog.New(syslog.LOG_INFO|syslog.LOG_USER, "smart-relayer")
		if e == nil {
			log.SetFlags(0)
			log.SetOutput(logwriter)
		}
	}

	// Listen for reload signals
	signal.Notify(reloadSig, syscall.SIGHUP, syscall.SIGUSR1, syscall.SIGUSR2)
	signal.Notify(exitSig, syscall.SIGINT, syscall.SIGKILL, os.Interrupt, syscall.SIGTERM)

	// Reload config
	go func() {
		for {
			_ = <-reloadSig
			startOrReload()
		}
	}()

	// Exit
	go func() {
		for {
			s := <-exitSig
			log.Printf("Signal %d received, exiting", s)
			for _, r := range relayers {
				r.Exit()
			}
		}
	}()

	if !startOrReload() {
		os.Exit(1)
	}

	for i := 0; i < totalRelayers; i++ {
		<-done
	}
	os.Exit(0)
}
<commit_msg>Version 8.7.0<commit_after>package main

import (
	"errors"
	"fmt"
	"log"
	"log/syslog"
	"os"
	"os/signal"
	"syscall"

	libdebug "runtime/debug"

	"sync"

	"github.com/gallir/smart-relayer/custom/redis2kvstore"
	"github.com/gallir/smart-relayer/httpproxy"
	"github.com/gallir/smart-relayer/lib"
	"github.com/gallir/smart-relayer/redis/cluster"
	"github.com/gallir/smart-relayer/redis/fh"
	"github.com/gallir/smart-relayer/redis/fs"
	"github.com/gallir/smart-relayer/redis/kinesis"
	"github.com/gallir/smart-relayer/redis/radix"
	"github.com/gallir/smart-relayer/redis/radix.improved/redis"
	"github.com/gallir/smart-relayer/redis/rsqs"
)

const (
	version = "8.7.0"
)

var (
	mutex          sync.Mutex
	relayers       = make(map[string]lib.Relayer)
	totalRelayers  = 0
	relayersConfig *lib.Config
	done           = make(chan bool)
	reloadSig      = make(chan os.Signal, 1)
	exitSig        = make(chan os.Signal, 1)
)

func getNewServer(conf lib.RelayerConfig) (srv lib.Relayer, err error) {
	switch conf.Protocol {
	case "redis", "redis2":
		srv, err = redis2.New(conf, done)
	case "redis-cluster", "redis-plus":
		srv, err = cluster.New(conf, done)
	case "firehose":
		srv, err = fh.New(conf, done)
	case "kinesis":
		srv, err = kinesis.New(conf, done)
	case "sqs":
		srv, err = rsqs.New(conf, done)
	case "fs":
		srv, err = fs.New(conf, done)
	case "http":
		srv, err = httpproxy.New(conf, done)
	case "redis2kvstore":
		srv, err = redis2kvstore.New(conf, done)
	default:
		err = errors.New("no valid option")
	}
	return
}

func startOrReload() bool {
	mutex.Lock()
	defer mutex.Unlock()

	// Check config is OK
	newConf, err := lib.ReadConfig(lib.GlobalConfig.ConfigFileName)
	if err != nil {
		log.Println("Bad configuration", err)
		return false
	}

	if newConf.GOGC > 100 {
		libdebug.SetGCPercent(newConf.GOGC)
		log.Println("Set GCPercent to", newConf.GOGC)
	} else {
		libdebug.SetGCPercent(100)
	}

	redis.UsePool = newConf.BufferPoolSize
	if redis.UsePool > 0 {
		log.Println("Set UsePool to", redis.UsePool)
	}

	lib.Debugf("%#v", newConf.Relayer)

	newEndpoints := make(map[string]bool)

	for _, conf := range newConf.Relayer {
		endpoint, ok := relayers[conf.Listen]
		newEndpoints[conf.Listen] = true
		if !ok {
			// Start a new relayer
			r, err := getNewServer(conf)
			if err != nil {
				log.Println("E: Error starting relayer", conf.Protocol, conf.URL, err)
			}
			lib.Debugf("Starting new relayer from %s to %s", conf.Listen, conf.URL)
			totalRelayers++
			if e := r.Start(); e == nil {
				relayers[conf.Listen] = r
			}
		} else {
			// The relayer exists, reload it
			err := endpoint.Reload(&conf)
			if err != nil {
				log.Println("E: Error reloading", conf.Protocol, conf.URL, err)
			}
		}
	}

	for endpoint, r := range relayers {
		_, ok := newEndpoints[endpoint]
		if !ok {
			log.Printf("Deleting old endpoint %s", endpoint)
			delete(relayers, endpoint)
			r.Exit()
		}
	}

	return true
}

func main() {

	// Force a high number of file descriptoir, if possible
	var rLimit syscall.Rlimit
	e := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
	if e == nil {
		rLimit.Cur = 65536
		syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
	}

	// Show version and exit
	if lib.GlobalConfig.ShowVersion {
		fmt.Println("smart-relayer version", version)
		fmt.Printf("Max files %d/%d\n", rLimit.Cur, rLimit.Max)
		os.Exit(0)
	}

	if !lib.GlobalConfig.Debug {
		logwriter, e := syslog.New(syslog.LOG_INFO|syslog.LOG_USER, "smart-relayer")
		if e == nil {
			log.SetFlags(0)
			log.SetOutput(logwriter)
		}
	}

	// Listen for reload signals
	signal.Notify(reloadSig, syscall.SIGHUP, syscall.SIGUSR1, syscall.SIGUSR2)
	signal.Notify(exitSig, syscall.SIGINT, syscall.SIGKILL, os.Interrupt, syscall.SIGTERM)

	// Reload config
	go func() {
		for {
			_ = <-reloadSig
			startOrReload()
		}
	}()

	// Exit
	go func() {
		for {
			s := <-exitSig
			log.Printf("Signal %d received, exiting", s)
			for _, r := range relayers {
				r.Exit()
			}
		}
	}()

	if !startOrReload() {
		os.Exit(1)
	}

	for i := 0; i < totalRelayers; i++ {
		<-done
	}
	os.Exit(0)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"go/parser"
)

func main() {
	// result, _ := seccomp.Compile("bla.seccomp", true)
	// for _, filter := range result {
	// 	fmt.Println(filter)
	// }

	result, err := parser.ParseFile("profiles/shared.seccomp")
	if err != nil {
		fmt.Printf("Error: %s\n", err)
	} else {
		fmt.Printf("Result: %#v\n", result)
	}
}
<commit_msg>I HATE MY LIFE<commit_after>package main

import (
	"fmt"

	"github.com/twtiger/go-seccomp/parser"
)

func main() {
	// result, _ := seccomp.Compile("bla.seccomp", true)
	// for _, filter := range result {
	// 	fmt.Println(filter)
	// }

	result, err := parser.ParseFile("profiles/shared.seccomp")
	if err != nil {
		fmt.Printf("Error: %s\n", err)
	} else {
		fmt.Printf("Result: %#v\n", result)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"regexp"

	"github.com/PuerkitoBio/goquery"
)

var teaSites = []string{
	"https://verdanttea.com/",
}

var teaTypes = []string{
	`(?i)\bpu'er\b`,
	`(?i)\bpuer\b`,
	`(?i)\bpu 'er\b`,
	`(?i)\bpu er\b`,
	`(?i)\boolong\b`,
	`(?i)\bblack\b`,
	`(?i)\bwhite\b`,
	`(?i)\bgrean\b`,
	`(?i)\bherbal\b`,
	`(?i)\byellow\b`,
	`(?i)\bfermented\b`,
}

func Match(pattern string, in string) bool {
	matches := regexp.MustCompile(pattern).MatchString(in)
	return matches
}

var tags = []string{
	//	"span",
	//	"div",
	//	"p",
	//	"text",
	//	"li",
	//	"button",
	"a",
	//	"select",
	//	"option",
	//	"h1",
	//	"h2",
	//	"h3",
	//	"h4",
	//	"article",
}

type Tea struct {
	name string
	link string
	data string
}

type MaybeTea struct {
	Tea
}

func (t *MaybeTea) ConfirmTeaType() bool {
	doc := t.GetDocument()
	allText := doc.Find("body").Text()

	return MatchString(t.name, allText)
}

func (t *MaybeTea) GetDocument() *goquery.Document {
	doc, err := goquery.NewDocument(t.link)
	if err != nil {
		log.Fatal(err)
	}

	return doc
}

func MatchString(toFind string, in string) bool {
	matched, err := regexp.MatchString(toFind, in)
	if err != nil {
		log.Fatal(err)
	}

	return matched
}

/*
	The crawler must be able to keep track of information about the user flow
	spawn multiple crawlers?
	how to find matching data between pages?
	if a link's labeled as a certain thing which is then found in a header on the page it leads to, that's a tea
	but it's not always that easy, sometimes the descriptor is not a link
	but the link is only near the descriptor
	how to determine that a link and a descriptor go together?
	either descriptor is child to the link or the link and the descriptor have a common parent
	the href and the descriptor will overlap in some way
	confirm that tea type is real by getting next page in flow
	confirm that it's in the page's data
*/
type Crawler struct {
	links       []string
	seen        map[string]bool
	possibleTea []*MaybeTea
	foundTea    []*Tea
	data        []string
}

func (t *Crawler) GetNextLink() string {
	totalLinks := len(t.links)

	if totalLinks > 0 {
		next := t.links[0:1][0]

		if totalLinks > 1 {
			t.links = t.links[1:]
		} else {
			t.links = make([]string, 0)
		}

		if !t.seen[next] {
			t.seen[next] = true
			return next
		}
		return t.GetNextLink()
	}
	return ""
}

func (t *Crawler) ScrapeSites() *Crawler {
	nextLink := t.GetNextLink()
	fmt.Println("nextLink", nextLink)

	if nextLink != "" {
		doc, err := goquery.NewDocument(nextLink)
		if err != nil {
			fmt.Println("There was an error while getting the document for this link: %s", nextLink)
			return t.ScrapeSites()
		}

		t.ScrapePage(doc)
		return t.ScrapeSites()
	} else {
		fmt.Println("done")
		return t
	}
}

func (t *Crawler) ScrapePage(doc *goquery.Document) *Crawler {
	for _, teaType := range teaTypes {
		for _, tag := range tags {
			found := doc.Find(tag).FilterFunction(func(i int, node *goquery.Selection) bool {
				text := node.Text()
				return Match(teaType, text)
			})

			found.Each(func(i int, s *goquery.Selection) {
				if tag == "a" {
					href, exists := s.Attr("href")
					if exists {
						t.links = append(t.links, href)
					}
				}

				text := s.Text()
				t.data = append(t.data, text)
			})

		}
	}

	return t

}

/*
	visit site
	look for teaTypes
	if hyperlink, crawl if not seen
	if not hyperlink, save for language processing
*/

func ScrapeSite() {
	tg := Crawler{
		teaSites,
		make(map[string]bool),
		make([]*MaybeTea, 0),
		make([]*Tea, 0),
		make([]string, 0),
	}

	tg.ScrapeSites()
}

func main() {
	ScrapeSite()
}
<commit_msg>Can find real teas (among false positives)<commit_after>package main

import (
	"fmt"
	"log"
	"regexp"

	"github.com/PuerkitoBio/goquery"
)

var teaSites = []string{
	"https://verdanttea.com/",
}

var teaTypes = []string{
	`(?i)\bpu'er\b`,
	`(?i)\bpuer\b`,
	`(?i)\bpu 'er\b`,
	`(?i)\bpu er\b`,
	`(?i)\bpu-er\b`,
	`(?i)\bchai\b`,
	`(?i)\bmatcha\b`,
	`(?i)\brooibos\b`,
	`(?i)\boolong\b`,
	`(?i)\bblack\b`,
	`(?i)\bwhite\b`,
	`(?i)\bgrean\b`,
	`(?i)\bherbal\b`,
	`(?i)\byellow\b`,
	`(?i)\bfermented\b`,
}

func Match(pattern string, in string) bool {
	return regexp.MustCompile(pattern).MatchString(in)
}

func MatchStart(substring string, in string) bool {
	return regexp.MustCompile(`(?i)^` + substring).MatchString(in)
}

var tags = []string{
	//	"span",
	//	"div",
	//	"p",
	//	"text",
	//	"li",
	//	"button",
	"a",
	//	"select",
	//	"option",
	//	"h1",
	//	"h2",
	//	"h3",
	//	"h4",
	//	"article",
}

type Tea struct {
	MaybeTea
	data string
}

type MaybeTea struct {
	name string
	link string
}

func (t *MaybeTea) Convert(name string, data string) *Tea {
	return &Tea{
		MaybeTea{
			name,
			t.link,
		},
		data,
	}
}

func (t *MaybeTea) ConfirmConvertTeaType() (*Tea, bool) {
	doc := t.GetDocument()
	headers := doc.Find("h1").FilterFunction(func(i int, node *goquery.Selection) bool {
		title := node.Text()
		return MatchStart(title, t.name)
	})

	if headers.Length() == 1 {
		header := headers.First().Text()
		data := doc.Text()

		// in the case that the previously found name has extra stuff on the end
		// and assuming that the header will only contain the name
		return t.Convert(header, data), true
	}

	return &Tea{MaybeTea{"", ""}, ""}, false
}

func (t *MaybeTea) GetDocument() *goquery.Document {
	doc, err := goquery.NewDocument(t.link)
	if err != nil {
		log.Fatal(err)
	}

	return doc
}

func MatchString(toFind string, in string) bool {
	matched, err := regexp.MatchString(toFind, in)
	if err != nil {
		log.Fatal(err)
	}

	return matched
}

/*
	The crawler must be able to keep track of information about the user flow
	spawn multiple crawlers?
	how to find matching data between pages?
	if a link's labeled as a certain thing which is then found in a header on the page it leads to, that's a tea
	but it's not always that easy, sometimes the descriptor is not a link
	but the link is only near the descriptor
	how to determine that a link and a descriptor go together?
	either descriptor is child to the link or the link and the descriptor have a common parent
	the href and the descriptor will overlap in some way
	confirm that tea type is real by getting next page in flow
	confirm that it's in the page's data
*/
type Crawler struct {
	links       []string
	seen        map[string]bool
	seenTeas    map[string]bool
	possibleTea []*MaybeTea
	tea         []*Tea
	data        []string
}

func (t *Crawler) GetNextLink() string {
	totalLinks := len(t.links)

	if totalLinks > 0 {
		next := t.links[0:1][0]

		if totalLinks > 1 {
			t.links = t.links[1:]
		} else {
			t.links = make([]string, 0)
		}

		if !t.seen[next] {
			t.seen[next] = true
			return next
		}
		return t.GetNextLink()
	}
	return ""
}

func (t *Crawler) ScrapeSites() *Crawler {
	nextLink := t.GetNextLink()
	fmt.Println("nextLink", nextLink)

	if nextLink != "" {
		doc, err := goquery.NewDocument(nextLink)
		if err != nil {
			fmt.Println("There was an error while getting the document for this link: %s", nextLink)
			return t.ScrapeSites()
		}

		t.ScrapePage(doc)
		return t.ScrapeSites()
	}

	fmt.Println("done")
	return t
}

func (t *Crawler) AddMaybeTea(link string, name string) *MaybeTea {
	tea := &MaybeTea{
		name,
		link,
	}

	t.possibleTea = append(t.possibleTea, tea)

	return tea
}

func (t *Crawler) ScrapePage(doc *goquery.Document) *Crawler {
	for _, teaType := range teaTypes {
		for _, tag := range tags {
			found := doc.Find(tag).FilterFunction(func(i int, node *goquery.Selection) bool {
				text := node.Text()
				return Match(teaType, text)
			})

			found.Each(func(i int, s *goquery.Selection) {
				href, exists := s.Attr("href")
				if exists {
					t.links = append(t.links, href)
				}

				text := s.Text()

				t.AddMaybeTea(href, text)
				t.ProcessMaybes()
				t.data = append(t.data, text)
			})

		}
	}

	return t

}

func (t *Crawler) ProcessMaybes() {
	fmt.Println("processmaybes")
	total := len(t.possibleTea)

	if total > 0 {
		next := t.possibleTea[0:1][0]
		tea, converted := next.ConfirmConvertTeaType()

		if converted {
			fmt.Println("tea name: %s", tea.name)
			t.tea = append(t.tea, tea)
		}

		if total > 1 {
			t.possibleTea = t.possibleTea[1:]
			t.ProcessMaybes()
		} else {
			t.possibleTea = make([]*MaybeTea, 0)
		}

	}
}

/*
	visit site
	look for teaTypes
	if hyperlink, crawl if not seen
	if not hyperlink, save for language processing
*/

func ScrapeSite() {
	tg := Crawler{
		teaSites,
		make(map[string]bool),
		make(map[string]bool),
		make([]*MaybeTea, 0),
		make([]*Tea, 0),
		make([]string, 0),
	}

	tg.ScrapeSites()
}

func main() {
	ScrapeSite()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"net/http"
	"net/http/httputil"
	"net/url"
)

var (
	scheme        string
	host          string
	port          int
	listeningPort int
	allowExternal bool
)

func init() {
	flag.IntVar(&port, "port", 8000, "Port to reverse proxy")
	flag.StringVar(&host, "host", "localhost", "Host to reverse proxy")
	flag.StringVar(&scheme, "scheme", "http", "Scheme to reverse proxy")
	flag.IntVar(&listeningPort, "listening-port", 80, "Port to listen on")
	flag.BoolVar(&allowExternal, "allow-external-connections", false, "Allow other computers to connect to your HTTP server")
}

func main() {
	flag.Parse()

	url := &url.URL{
		Scheme: scheme,
		Host:   fmt.Sprintf("%s:%d", host, port),
	}

	var listenOn string
	if allowExternal {
		listenOn = fmt.Sprintf(":%d", listeningPort)
	} else {
		listenOn = fmt.Sprintf("[::1]:%d", listeningPort)
	}

	LoggingMiddleware := func(s http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Printf("Proxying %s to %s\n", r.URL.Path, url)
			s.ServeHTTP(w, r)
		})
	}

	proxy := LoggingMiddleware(httputil.NewSingleHostReverseProxy(url))

	fmt.Printf("Starting reverse proxy from %s to %s...\n\n", listenOn, url)

	if err := http.ListenAndServe(listenOn, proxy); err != nil {
		fmt.Fprintf(os.Stderr, "Error: %s\n\n", err)
		os.Exit(1)
	}

}
<commit_msg>Don't use IPv6 by default<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"net/http"
	"net/http/httputil"
	"net/url"
)

var (
	scheme        string
	host          string
	port          int
	listeningPort int
	allowExternal bool
)

func init() {
	flag.IntVar(&port, "port", 8000, "Port to reverse proxy")
	flag.StringVar(&host, "host", "localhost", "Host to reverse proxy")
	flag.StringVar(&scheme, "scheme", "http", "Scheme to reverse proxy")
	flag.IntVar(&listeningPort, "listening-port", 80, "Port to listen on")
	flag.BoolVar(&allowExternal, "allow-external-connections", false, "Allow other computers to connect to your HTTP server")
}

func main() {
	flag.Parse()

	url := &url.URL{
		Scheme: scheme,
		Host:   fmt.Sprintf("%s:%d", host, port),
	}

	var listenOn string
	if allowExternal {
		listenOn = fmt.Sprintf(":%d", listeningPort)
	} else {
		listenOn = fmt.Sprintf("127.0.0.1:%d", listeningPort)
	}

	LoggingMiddleware := func(s http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Printf("Proxying %s to %s\n", r.URL.Path, url)
			s.ServeHTTP(w, r)
		})
	}

	proxy := LoggingMiddleware(httputil.NewSingleHostReverseProxy(url))

	fmt.Printf("Starting reverse proxy from %s to %s...\n\n", listenOn, url)

	if err := http.ListenAndServe(listenOn, proxy); err != nil {
		fmt.Fprintf(os.Stderr, "Error: %s\n\n", err)
		os.Exit(1)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"path"
	"runtime"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/kardianos/osext"
	sdees "github.com/schollz/sdees/src"
	"github.com/urfave/cli"
)

var (
	Version, BuildTime, Build, OS, LastCommit string
	Debug                                     bool
	DontEncrypt, Clean                        bool
	ResetConfig                               bool
	ImportOldFile, ImportFile                 bool
)

func main() {
	// Delete temp files upon exit
	defer sdees.CleanUp()

	// Handle Ctl+C for cleanUp
	// from http://stackoverflow.com/questions/11268943/golang-is-it-possible-to-capture-a-ctrlc-signal-and-run-a-cleanup-function-in
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-c
		sdees.CleanUp()
		os.Exit(1)
	}()

	// App information
	setBuild()
	app := cli.NewApp()
	app.Name = "sdees"
	app.Version = Version + " " + Build + " " + BuildTime + " " + OS
	app.Usage = `SDEES Does Editing, Encryption, and Synchronization

	 https://github.com/schollz/sdees

FOLDERS:
	'` + sdees.CachePath + `' stores all encrypted files and repositories
	'` + sdees.ConfigPath + `' stores all configuration files

EXAMPLE USAGE:
   sdees new.txt # edit a new document, new.txt
	 sdees UglyDuckling # edit a entry in a document
   sdees --summary -n 5 # list a summary of last five entries
   sdees --search "dogs cats" # find entries that mention 'dogs' or 'cats'`

	app.Action = func(c *cli.Context) error {
		// Set the log level
		if Debug {
			sdees.DebugMode()
		}

		CheckIfGitIsInstalled()

		workingFile := c.Args().Get(0)
		if len(workingFile) > 0 {
			sdees.InputDocument = workingFile
		}

		// Check if its Windows
		if runtime.GOOS == "windows" {
			sdees.Extension = ".exe"
		} else {
			sdees.Extension = ""
		}
		sdees.Version = Version

		// Check new Version
		programPath, _ := osext.Executable()
		sdees.CheckNewVersion(programPath, Version, LastCommit, OS)

		// Process some flags
		if ResetConfig {
			sdees.SetupConfig()
		} else if Clean {
			sdees.CleanAll()
		} else {
			sdees.Run()
		}
		return nil
	}
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:        "debug",
			Usage:       "Turn on debug mode",
			Destination: &Debug,
		},
		cli.BoolFlag{
			Name:        "clean",
			Usage:       "Deletes all sdees files",
			Destination: &Clean,
		},
		cli.StringFlag{
			Name:        "search",
			Usage:       "Search for `word`",
			Destination: &sdees.Search,
		},
		cli.BoolFlag{
			Name:        "importold",
			Usage:       "Import `document` (JRNL-format)",
			Destination: &sdees.ImportOldFlag,
		},
		cli.BoolFlag{
			Name:        "import",
			Usage:       "Import `document`",
			Destination: &sdees.ImportFlag,
		},
		cli.BoolFlag{
			Name:        "export",
			Usage:       "Export `document`",
			Destination: &sdees.Export,
		},
		cli.BoolFlag{
			Name:        "config",
			Usage:       "Configure",
			Destination: &ResetConfig,
		},
		cli.BoolFlag{
			Name:        "all, a",
			Usage:       "Edit all of the document",
			Destination: &sdees.All,
		},
		cli.BoolFlag{
			Name:        "delete",
			Usage:       "Delete `X`, where X is a document or entry",
			Destination: &sdees.DeleteFlag,
		},
		cli.BoolFlag{
			Name:        "summary",
			Usage:       "Gets summary",
			Destination: &sdees.Summarize,
		},
	}
	app.Run(os.Args)
}

func CheckIfGitIsInstalled() {
	cmd := exec.Command("git", "--version")
	stdout, err := cmd.Output()
	versionNums := strings.Split(strings.Split(strings.TrimSpace(string(stdout)), " ")[2], ".")
	major, _ := strconv.Atoi(versionNums[0])
	minor, _ := strconv.Atoi(versionNums[1])
	if major < 2 || (major == 2 && minor < 12) {
		fmt.Printf("\n%s detected.\n\nPlease install git version 2.5+ before proceeding. To install, go to \n\n    https://git-scm.com/downloads \n\nand install the version for your operating system.\nPress enter to continue... \n", strings.TrimSpace(string(stdout)))
		var input string
		fmt.Scanln(&input)
		os.Exit(1)
	}
	os.Exit(1)
	if err != nil {
		fmt.Println("\ngit is not detected.\n\nPlease install git version 2.5+ before proceeding. To install, go to \n\n    https://git-scm.com/downloads \n\nand install the version for your operating system.\nPress enter to continue... ")
		var input string
		fmt.Scanln(&input)
		os.Exit(1)
	}
}

func setBuild() {
	if len(Build) == 0 {
		cwd, _ := os.Getwd()
		defer os.Chdir(cwd)
		Build = "dev"
		Version = "dev"
		BuildTime = time.Now().String()
		err := os.Chdir(path.Join(os.Getenv("GOPATH"), "src", "github.com", "schollz", "sdees"))
		if err != nil {
			return
		}
		cmd := exec.Command("git", "log", "-1", "--pretty=format:'%ad'")
		stdout, err := cmd.Output()
		if err != nil {
			return
		}
		LastCommit = strings.Replace(string(stdout), "'", "", -1)
		BuildTime = LastCommit
	} else {
		Build = Build[0:7]
	}
}
<commit_msg>Minimum version of git enforced<commit_after>package main

import (
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"path"
	"runtime"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/kardianos/osext"
	sdees "github.com/schollz/sdees/src"
	"github.com/urfave/cli"
)

var (
	Version, BuildTime, Build, OS, LastCommit string
	Debug                                     bool
	DontEncrypt, Clean                        bool
	ResetConfig                               bool
	ImportOldFile, ImportFile                 bool
)

func main() {
	// Delete temp files upon exit
	defer sdees.CleanUp()

	// Handle Ctl+C for cleanUp
	// from http://stackoverflow.com/questions/11268943/golang-is-it-possible-to-capture-a-ctrlc-signal-and-run-a-cleanup-function-in
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-c
		sdees.CleanUp()
		os.Exit(1)
	}()

	// App information
	setBuild()
	app := cli.NewApp()
	app.Name = "sdees"
	app.Version = Version + " " + Build + " " + BuildTime + " " + OS
	app.Usage = `SDEES Does Editing, Encryption, and Synchronization

	 https://github.com/schollz/sdees

FOLDERS:
	'` + sdees.CachePath + `' stores all encrypted files and repositories
	'` + sdees.ConfigPath + `' stores all configuration files

EXAMPLE USAGE:
   sdees new.txt # edit a new document, new.txt
	 sdees UglyDuckling # edit a entry in a document
   sdees --summary -n 5 # list a summary of last five entries
   sdees --search "dogs cats" # find entries that mention 'dogs' or 'cats'`

	app.Action = func(c *cli.Context) error {
		// Set the log level
		if Debug {
			sdees.DebugMode()
		}

		CheckIfGitIsInstalled()

		workingFile := c.Args().Get(0)
		if len(workingFile) > 0 {
			sdees.InputDocument = workingFile
		}

		// Check if its Windows
		if runtime.GOOS == "windows" {
			sdees.Extension = ".exe"
		} else {
			sdees.Extension = ""
		}
		sdees.Version = Version

		// Check new Version
		programPath, _ := osext.Executable()
		sdees.CheckNewVersion(programPath, Version, LastCommit, OS)

		// Process some flags
		if ResetConfig {
			sdees.SetupConfig()
		} else if Clean {
			sdees.CleanAll()
		} else {
			sdees.Run()
		}
		return nil
	}
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:        "debug",
			Usage:       "Turn on debug mode",
			Destination: &Debug,
		},
		cli.BoolFlag{
			Name:        "clean",
			Usage:       "Deletes all sdees files",
			Destination: &Clean,
		},
		cli.StringFlag{
			Name:        "search",
			Usage:       "Search for `word`",
			Destination: &sdees.Search,
		},
		cli.BoolFlag{
			Name:        "importold",
			Usage:       "Import `document` (JRNL-format)",
			Destination: &sdees.ImportOldFlag,
		},
		cli.BoolFlag{
			Name:        "import",
			Usage:       "Import `document`",
			Destination: &sdees.ImportFlag,
		},
		cli.BoolFlag{
			Name:        "export",
			Usage:       "Export `document`",
			Destination: &sdees.Export,
		},
		cli.BoolFlag{
			Name:        "config",
			Usage:       "Configure",
			Destination: &ResetConfig,
		},
		cli.BoolFlag{
			Name:        "all, a",
			Usage:       "Edit all of the document",
			Destination: &sdees.All,
		},
		cli.BoolFlag{
			Name:        "delete",
			Usage:       "Delete `X`, where X is a document or entry",
			Destination: &sdees.DeleteFlag,
		},
		cli.BoolFlag{
			Name:        "summary",
			Usage:       "Gets summary",
			Destination: &sdees.Summarize,
		},
	}
	app.Run(os.Args)
}

func CheckIfGitIsInstalled() {
	cmd := exec.Command("git", "--version")
	stdout, err := cmd.Output()
	versionNums := strings.Split(strings.Split(strings.TrimSpace(string(stdout)), " ")[2], ".")
	major, _ := strconv.Atoi(versionNums[0])
	minor, _ := strconv.Atoi(versionNums[1])
	if major < 2 || (major == 2 && minor < 5) {
		fmt.Printf("\n%s detected.\n\nPlease install git version 2.5+ before proceeding. To install, go to \n\n    https://git-scm.com/downloads \n\nand install the version for your operating system.\nPress enter to continue... \n", strings.TrimSpace(string(stdout)))
		var input string
		fmt.Scanln(&input)
		os.Exit(1)
	}
	os.Exit(1)
	if err != nil {
		fmt.Println("\ngit is not detected.\n\nPlease install git version 2.5+ before proceeding. To install, go to \n\n    https://git-scm.com/downloads \n\nand install the version for your operating system.\nPress enter to continue... ")
		var input string
		fmt.Scanln(&input)
		os.Exit(1)
	}
}

func setBuild() {
	if len(Build) == 0 {
		cwd, _ := os.Getwd()
		defer os.Chdir(cwd)
		Build = "dev"
		Version = "dev"
		BuildTime = time.Now().String()
		err := os.Chdir(path.Join(os.Getenv("GOPATH"), "src", "github.com", "schollz", "sdees"))
		if err != nil {
			return
		}
		cmd := exec.Command("git", "log", "-1", "--pretty=format:'%ad'")
		stdout, err := cmd.Output()
		if err != nil {
			return
		}
		LastCommit = strings.Replace(string(stdout), "'", "", -1)
		BuildTime = LastCommit
	} else {
		Build = Build[0:7]
	}
}
<|endoftext|>


<commit_before>package main

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

	"github.com/prometheus/alertmanager/notify"
	"github.com/prometheus/common/model"
	"github.com/tucnak/telebot"
)

const (
	commandStart = "/start"
	commandStop  = "/stop"
	commandHelp  = "/help"

	responseStart = "Hey, %s! I will now keep you up to date!\n" + commandHelp
	responseStop  = "Alright, %s! I won't talk to you again.\n" + commandHelp
	responseHelp  = `
I'm a drone.io bot. I can notify you about your builds.

Available commands:
` + commandStart + ` - Start listening for drone.io builds
` + commandStop + `- Stop listening for drone.io builds
`
)

var users map[int]telebot.User

func main() {
	log.Println("starting...")
	bot, err := telebot.NewBot(os.Getenv("TELEGRAM_TOKEN"))
	if err != nil {
		log.Fatalln(err)
	}

	users = make(map[int]telebot.User)
	messages := make(chan telebot.Message, 100)
	bot.Listen(messages, 1*time.Second)

	go HTTPListenAndServe(bot)

	for message := range messages {
		switch message.Text {
		case commandStart:
			bot.SendMessage(message.Chat, fmt.Sprintf(responseStart, message.Sender.FirstName), nil)
			users[message.Sender.ID] = message.Sender
			log.Printf("User %d subscribed", message.Sender.ID)
		case commandStop:
			bot.SendMessage(message.Chat, fmt.Sprintf(responseStop, message.Sender.FirstName), nil)
			delete(users, message.Sender.ID)
			log.Printf("User %d unsubscribed", message.Sender.ID)
		case commandHelp:
			bot.SendMessage(message.Chat, responseHelp, nil)
		}
	}
}

func HTTPListenAndServe(bot *telebot.Bot) {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		var m notify.WebhookMessage

		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&m)
		if err != nil {
			log.Printf("failed to decode webhook message: %v\n", err)
		}
		defer r.Body.Close()

		status := m.Alerts[0].Status
		switch status {
		case string(model.AlertFiring):
			status = "🔥 *" + strings.ToUpper(status) + "* 🔥"
		case string(model.AlertResolved):
			status = "✅ *" + strings.ToUpper(status) + "* ✅"
		}

		message := fmt.Sprintf(
			"%s\n*%s* (%s)\n%s",
			status,
			m.Alerts[0].Labels["alertname"],
			m.Alerts[0].Annotations["summary"],
			m.Alerts[0].Annotations["description"],
		)

		for _, user := range users {
			bot.SendMessage(user, message, &telebot.SendOptions{ParseMode: telebot.ModeMarkdown})
		}

		w.WriteHeader(http.StatusOK)
	})

	log.Fatalln(http.ListenAndServe(":8080", nil))
}
<commit_msg>Log Webhook as json to stdout<commit_after>package main

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

	"github.com/prometheus/alertmanager/notify"
	"github.com/prometheus/common/model"
	"github.com/tucnak/telebot"
)

const (
	commandStart = "/start"
	commandStop  = "/stop"
	commandHelp  = "/help"

	responseStart = "Hey, %s! I will now keep you up to date!\n" + commandHelp
	responseStop  = "Alright, %s! I won't talk to you again.\n" + commandHelp
	responseHelp  = `
I'm a drone.io bot. I can notify you about your builds.

Available commands:
` + commandStart + ` - Start listening for drone.io builds
` + commandStop + `- Stop listening for drone.io builds
`
)

var users map[int]telebot.User

func main() {
	log.Println("starting...")
	bot, err := telebot.NewBot(os.Getenv("TELEGRAM_TOKEN"))
	if err != nil {
		log.Fatalln(err)
	}

	users = make(map[int]telebot.User)
	messages := make(chan telebot.Message, 100)
	bot.Listen(messages, 1*time.Second)

	go HTTPListenAndServe(bot)

	for message := range messages {
		switch message.Text {
		case commandStart:
			bot.SendMessage(message.Chat, fmt.Sprintf(responseStart, message.Sender.FirstName), nil)
			users[message.Sender.ID] = message.Sender
			log.Printf("User %d subscribed", message.Sender.ID)
		case commandStop:
			bot.SendMessage(message.Chat, fmt.Sprintf(responseStop, message.Sender.FirstName), nil)
			delete(users, message.Sender.ID)
			log.Printf("User %d unsubscribed", message.Sender.ID)
		case commandHelp:
			bot.SendMessage(message.Chat, responseHelp, nil)
		}
	}
}

func HTTPListenAndServe(bot *telebot.Bot) {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		var webhook notify.WebhookMessage

		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&webhook)
		if err != nil {
			log.Printf("failed to decode webhook message: %v\n", err)
		}
		defer r.Body.Close()

		jsonWebhook, _ := json.Marshal(webhook)
		log.Println(string(jsonWebhook))

		status := webhook.Alerts[0].Status
		switch status {
		case string(model.AlertFiring):
			status = "🔥 *" + strings.ToUpper(status) + "* 🔥"
		case string(model.AlertResolved):
			status = "✅ *" + strings.ToUpper(status) + "* ✅"
		}

		message := fmt.Sprintf(
			"%s\n*%s* (%s)\n%s",
			status,
			webhook.Alerts[0].Labels["alertname"],
			webhook.Alerts[0].Annotations["summary"],
			webhook.Alerts[0].Annotations["description"],
		)

		for _, user := range users {
			bot.SendMessage(user, message, &telebot.SendOptions{ParseMode: telebot.ModeMarkdown})
		}

		w.WriteHeader(http.StatusOK)
	})

	log.Fatalln(http.ListenAndServe(":8080", nil))
}
<|endoftext|>


<commit_before>package gorequest

import (
	"bytes"
	"encoding/json"
	"fmt"
	_ "io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

type Response *http.Response

type SuperAgent struct {
	Url       string
	Method    string
	Header    map[string]string
	Type      string
	ForceType string
	Data      map[string]interface{}
	FormData  url.Values
	QueryData url.Values
}

func New() *SuperAgent {
	s := SuperAgent{
		Type:   "json",
		Data:   make(map[string]interface{}),
		Header: make(map[string]string)}
	return &s
}

func Get(targetUrl string) *SuperAgent {
	newReq := &SuperAgent{
		Url:       targetUrl,
		Method:    "GET",
		Header:    make(map[string]string),
		Data:      make(map[string]interface{}),
		FormData:  url.Values{},
		QueryData: url.Values{}}
	return newReq
}

func Post(targetUrl string) *SuperAgent {
	newReq := &SuperAgent{
		Url:       targetUrl,
		Method:    "POST",
		Type:      "json",
		Header:    make(map[string]string),
		Data:      make(map[string]interface{}),
		FormData:  url.Values{},
		QueryData: url.Values{}}
	return newReq
}

func (s *SuperAgent) Set(param string, value string) *SuperAgent {
	s.Header[param] = value
	return s
}

var Types = map[string]string{
	"html":       "text/html",
	"json":       "application/json",
	"xml":        "application/xml",
	"urlencoded": "application/x-www-form-urlencoded",
	"form":       "application/x-www-form-urlencoded",
	"form-data":  "application/x-www-form-urlencoded",
}

func (s *SuperAgent) SetType(typeStr string) *SuperAgent {
	if _, ok := Types[typeStr]; ok {
		s.ForceType = typeStr
	}
	return s
}

// TODO: check error
func (s *SuperAgent) Query(content string) *SuperAgent {
	var val map[string]string
	if err := json.Unmarshal([]byte(content), &val); err == nil {
		for k, v := range val {
			s.QueryData.Add(k, v)
		}
	} else {
		queryVal, _ := url.ParseQuery(content)
		for k, _ := range queryVal {
			s.QueryData.Add(k, queryVal.Get(k))
		}
		// TODO: need to check correct format of 'field=val&field=val&...'
	}
	return s
}

func (s *SuperAgent) Send(content string) *SuperAgent {
	var val map[string]interface{}
	// check if it is json format
	if err := json.Unmarshal([]byte(content), &val); err == nil {
		if s.Type == "form" {
			for k, v := range val {
				// TODO: check if cannot convert to string, return error
				// Also, check that this is the right way to do. (Check superagent)
				s.FormData.Add(k, v.(string))
			}
			// in case previously sending json before knowing it's a form style, we need to include previous added data to formData as well
			for k, v := range s.Data {
				s.FormData.Add(k, v.(string))
			}
			// clear data
			s.Data = nil
		} else {
			s.Type = "json"
			for k, v := range val {
				s.Data[k] = v
			}
		}
	} else {
		// not json format (just normal string)
		s.Type = "form"
		formVal, _ := url.ParseQuery(content)
		for k, _ := range formVal {
			s.FormData.Add(k, formVal.Get(k))
		}
		// change all json data to form style
		for k, v := range s.Data {
			s.FormData.Add(k, v.(string))
		}
		// clear data
		s.Data = make(map[string]interface{})
	}

	return s
}

func (s *SuperAgent) End(callback ...func(response Response)) (Response, error) {
	var (
		req  *http.Request
		err  error
		resp Response
	)
	client := &http.Client{}
	if s.Method == "POST" {
		// if force type, change all data to that type
		if s.ForceType == "json" {
			s.Type = "json"
			// change all json data to form style
			for k, v := range s.FormData {
				s.Data[k] = v
			}
			// clear data
			s.FormData = make(url.Values)
		} else if s.ForceType == "form" {
			s.Type = "form"
			// in case previously sending json before knowing it's a form style, we need to include previous added data to formData as well
			for k, v := range s.Data {
				s.FormData.Add(k, v.(string))
			}
			// clear data
			s.Data = make(map[string]interface{})
		}
		if s.Type == "json" {
			contentJson, _ := json.Marshal(s.Data)
			contentReader := bytes.NewReader(contentJson)
			req, err = http.NewRequest(s.Method, s.Url, contentReader)
			req.Header.Set("Content-Type", "application/json")
		} else if s.Type == "form" {
			req, err = http.NewRequest(s.Method, s.Url, strings.NewReader(s.FormData.Encode()))
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		}
	} else if s.Method == "GET" {
		req, err = http.NewRequest(s.Method, s.Url, nil)
	}
	for k, v := range s.Header {
		req.Header.Set(k, v)
	}
	// Add all querystring from Query func
	q := req.URL.Query()
	for k, v := range s.QueryData {
		for _, vv := range v {
			q.Add(k, vv)
		}
	}
	req.URL.RawQuery = q.Encode()
	// Send request
	resp, err = client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// deep copy response to give it to both return and callback func
	respCallback := *resp
	if len(callback) != 0 {
		callback[0](&respCallback)
	}
	return resp, nil
}

func main() {
	/*err, response, body:= Get("http://localhost:1337")
	  if err==nil && response.StatusCode == 200 {
	    fmt.Println(body)
	  }
	  fmt.Println(err, response, body)*/

	//s.post("/api/pet").send(`{"name":"tg"}`).end(
	Post("http://requestb.in/1f7ur5s1").
		Send(`nickname=a`).
		Set("Accept", "application/json").
		End(func(response Response) {
		fmt.Println(response)
	})
	/*client:= &http.Client{}
	  req,_ := http.NewRequest("GET", "http://localhost:1337", nil)
	  req.Header.Add("Content-Type","application/json")
	  fmt.Println("main",req)
	  res, _ :=  client.Do(req)
	  fmt.Println(res.Body)
	  /*const jsonStream =`{"sn":"sn1"}`
	  reader:=strings.NewReader(jsonStream)
	  resp,_ := http.Post("http://localhost:1337", "application/json", reader)
	  defer resp.Body.Close()
	  body,_ :=ioutil.ReadAll(resp.Body)
	  fmt.Println(resp)
	  fmt.Println(string(body))*/
}
<commit_msg>Simplified Send() and make array usable in querystring and json<commit_after>package gorequest

import (
	"bytes"
	"encoding/json"
	"fmt"
	_ "io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

type Response *http.Response

type SuperAgent struct {
	Url       string
	Method    string
	Header    map[string]string
	Type      string
	ForceType string
	Data      map[string]interface{}
	FormData  url.Values
	QueryData url.Values
}

func New() *SuperAgent {
	s := SuperAgent{
		Type:   "json",
		Data:   make(map[string]interface{}),
		Header: make(map[string]string)}
	return &s
}

func Get(targetUrl string) *SuperAgent {
	newReq := &SuperAgent{
		Url:       targetUrl,
		Method:    "GET",
		Header:    make(map[string]string),
		Data:      make(map[string]interface{}),
		FormData:  url.Values{},
		QueryData: url.Values{}}
	return newReq
}

func Post(targetUrl string) *SuperAgent {
	newReq := &SuperAgent{
		Url:       targetUrl,
		Method:    "POST",
		Type:      "json",
		Header:    make(map[string]string),
		Data:      make(map[string]interface{}),
		FormData:  url.Values{},
		QueryData: url.Values{}}
	return newReq
}

func (s *SuperAgent) Set(param string, value string) *SuperAgent {
	s.Header[param] = value
	return s
}

var Types = map[string]string{
	"html":       "text/html",
	"json":       "application/json",
	"xml":        "application/xml",
	"urlencoded": "application/x-www-form-urlencoded",
	"form":       "application/x-www-form-urlencoded",
	"form-data":  "application/x-www-form-urlencoded",
}

func (s *SuperAgent) SetType(typeStr string) *SuperAgent {
	if _, ok := Types[typeStr]; ok {
		s.ForceType = typeStr
	}
	return s
}

// TODO: check error
func (s *SuperAgent) Query(content string) *SuperAgent {
	var val map[string]string
	if err := json.Unmarshal([]byte(content), &val); err == nil {
		for k, v := range val {
			s.QueryData.Add(k, v)
		}
	} else {
		queryVal, _ := url.ParseQuery(content)
		for k, _ := range queryVal {
			s.QueryData.Add(k, queryVal.Get(k))
		}
		// TODO: need to check correct format of 'field=val&field=val&...'
	}
	return s
}

func (s *SuperAgent) Send(content string) *SuperAgent {
	var val map[string]interface{}
	// check if it is json format
	if err := json.Unmarshal([]byte(content), &val); err == nil {
		for k, v := range val {
			s.Data[k] = v
		}
	} else {
		formVal, _ := url.ParseQuery(content)
		for k, _ := range formVal {
			// make it array if already have key
			if val, ok := s.Data[k]; ok {
				var strArray []string
				strArray = append(strArray, formVal.Get(k))
				// check if previous data is one string or array
				switch oldValue := val.(type) {
				case []string:
					strArray = append(strArray, oldValue...)
				case string:
					strArray = append(strArray, oldValue)
				}
				s.Data[k] = strArray
			} else {
				// make it just string if does not already have same key
				s.Data[k] = formVal.Get(k)
			}
		}
		s.Type = "form"
	}
	return s
}

func changeMapToURLValues(data map[string]interface{}) url.Values {
	var newUrlValues = url.Values{}
	for k, v := range data {
		switch val := v.(type) {
		case string:
			newUrlValues.Add(k, string(val))
		case []interface{}:
			for _, element := range val {
				if elementStr, ok := element.(string); ok {
					newUrlValues.Add(k, elementStr)
				}
			}
		case []string:
			for _, element := range val {
				newUrlValues.Add(k, element)
			}
		}
	}
	return newUrlValues
}

func (s *SuperAgent) End(callback ...func(response Response)) (Response, error) {
	var (
		req  *http.Request
		err  error
		resp Response
	)
	client := &http.Client{}
	// check if there is forced type
	if s.ForceType == "json" {
		s.Type = "json"
	} else if s.ForceType == "form" {
		s.Type = "form"
	}
	if s.Method == "POST" {
		if s.Type == "json" {
			contentJson, _ := json.Marshal(s.Data)
			contentReader := bytes.NewReader(contentJson)
			req, err = http.NewRequest(s.Method, s.Url, contentReader)
			req.Header.Set("Content-Type", "application/json")
		} else if s.Type == "form" {
			formData := changeMapToURLValues(s.Data)
			req, err = http.NewRequest(s.Method, s.Url, strings.NewReader(formData.Encode()))
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		}
	} else if s.Method == "GET" {
		req, err = http.NewRequest(s.Method, s.Url, nil)
	}
	for k, v := range s.Header {
		req.Header.Set(k, v)
	}
	// Add all querystring from Query func
	q := req.URL.Query()
	for k, v := range s.QueryData {
		for _, vv := range v {
			q.Add(k, vv)
		}
	}
	req.URL.RawQuery = q.Encode()
	// Send request
	resp, err = client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// deep copy response to give it to both return and callback func
	respCallback := *resp
	if len(callback) != 0 {
		callback[0](&respCallback)
	}
	return resp, nil
}

func main() {
	/*err, response, body:= Get("http://localhost:1337")
	  if err==nil && response.StatusCode == 200 {
	    fmt.Println(body)
	  }
	  fmt.Println(err, response, body)*/

	//s.post("/api/pet").send(`{"name":"tg"}`).end(
	Post("http://requestb.in/1f7ur5s1").
		Send(`nickname=a`).
		Set("Accept", "application/json").
		End(func(response Response) {
		fmt.Println(response)
	})
	/*client:= &http.Client{}
	  req,_ := http.NewRequest("GET", "http://localhost:1337", nil)
	  req.Header.Add("Content-Type","application/json")
	  fmt.Println("main",req)
	  res, _ :=  client.Do(req)
	  fmt.Println(res.Body)
	  /*const jsonStream =`{"sn":"sn1"}`
	  reader:=strings.NewReader(jsonStream)
	  resp,_ := http.Post("http://localhost:1337", "application/json", reader)
	  defer resp.Body.Close()
	  body,_ :=ioutil.ReadAll(resp.Body)
	  fmt.Println(resp)
	  fmt.Println(string(body))*/
}
<|endoftext|>