<commit_before>// Package main defines a command line interface for the sqlboiler package
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/friendsofgo/errors"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"github.com/volatiletech/sqlboiler/v4/boilingcore"
	"github.com/volatiletech/sqlboiler/v4/drivers"
	"github.com/volatiletech/sqlboiler/v4/importers"
)

//go:generate go-bindata -nometadata -pkg templatebin -o templatebin/bindata.go templates templates/singleton templates_test templates_test/singleton

const sqlBoilerVersion = "4.3.0"

var (
	flagConfigFile string
	cmdState       *boilingcore.State
	cmdConfig      *boilingcore.Config
)

func initConfig() {
	if len(flagConfigFile) != 0 {
		viper.SetConfigFile(flagConfigFile)
		if err := viper.ReadInConfig(); err != nil {
			fmt.Println("Can't read config:", err)
			os.Exit(1)
		}
		return
	}

	var err error
	viper.SetConfigName("sqlboiler")

	configHome := os.Getenv("XDG_CONFIG_HOME")
	homePath := os.Getenv("HOME")
	wd, err := os.Getwd()
	if err != nil {
		wd = "."
	}

	configPaths := []string{wd}
	if len(configHome) > 0 {
		configPaths = append(configPaths, filepath.Join(configHome, "sqlboiler"))
	} else {
		configPaths = append(configPaths, filepath.Join(homePath, ".config/sqlboiler"))
	}

	for _, p := range configPaths {
		viper.AddConfigPath(p)
	}

	// Ignore errors here, fallback to other validation methods.
	// Users can use environment variables if a config is not found.
	_ = viper.ReadInConfig()
}

func main() {
	// Too much happens between here and cobra's argument handling, for
	// something so simple just do it immediately.
	for _, arg := range os.Args {
		if arg == "--version" {
			fmt.Println("SQLBoiler v" + sqlBoilerVersion)
			return
		}
	}

	// Set up the cobra root command
	var rootCmd = &cobra.Command{
		Use:   "sqlboiler [flags] <driver>",
		Short: "SQL Boiler generates an ORM tailored to your database schema.",
		Long: "SQL Boiler generates a Go ORM from template files, tailored to your database schema.\n" +
			`Complete documentation is available at http://github.com/volatiletech/sqlboiler`,
		Example:       `sqlboiler psql`,
		PreRunE:       preRun,
		RunE:          run,
		PostRunE:      postRun,
		SilenceErrors: true,
		SilenceUsage:  true,
	}

	cobra.OnInitialize(initConfig)

	// Set up the cobra root command flags
	rootCmd.PersistentFlags().StringVarP(&flagConfigFile, "config", "c", "", "Filename of config file to override default lookup")
	rootCmd.PersistentFlags().StringP("output", "o", "models", "The name of the folder to output to")
	rootCmd.PersistentFlags().StringP("pkgname", "p", "models", "The name you wish to assign to your generated package")
	rootCmd.PersistentFlags().StringSliceP("templates", "", nil, "A templates directory, overrides the bindata'd template folders in sqlboiler")
	rootCmd.PersistentFlags().StringSliceP("tag", "t", nil, "Struct tags to be included on your models in addition to json, yaml, toml")
	rootCmd.PersistentFlags().StringSliceP("replace", "", nil, "Replace templates by directory: relpath/to_file.tpl:relpath/to_replacement.tpl")
	rootCmd.PersistentFlags().BoolP("debug", "d", false, "Debug mode prints stack traces on error")
	rootCmd.PersistentFlags().BoolP("no-context", "", false, "Disable context.Context usage in the generated code")
	rootCmd.PersistentFlags().BoolP("no-tests", "", false, "Disable generated go test files")
	rootCmd.PersistentFlags().BoolP("no-hooks", "", false, "Disable hooks feature for your models")
	rootCmd.PersistentFlags().BoolP("no-rows-affected", "", false, "Disable rows affected in the generated API")
	rootCmd.PersistentFlags().BoolP("no-auto-timestamps", "", false, "Disable automatic timestamps for created_at/updated_at")
	rootCmd.PersistentFlags().BoolP("no-driver-templates", "", false, "Disable parsing of templates defined by the database driver")
	rootCmd.PersistentFlags().BoolP("no-back-referencing", "", false, "Disable back referencing in the loaded relationship structs")
	rootCmd.PersistentFlags().BoolP("add-global-variants", "", false, "Enable generation for global variants")
	rootCmd.PersistentFlags().BoolP("add-panic-variants", "", false, "Enable generation for panic variants")
	rootCmd.PersistentFlags().BoolP("add-soft-deletes", "", false, "Enable soft deletion by updating deleted_at timestamp")
	rootCmd.PersistentFlags().BoolP("version", "", false, "Print the version")
	rootCmd.PersistentFlags().BoolP("wipe", "", false, "Delete the output folder (rm -rf) before generation to ensure sanity")
	rootCmd.PersistentFlags().StringP("struct-tag-casing", "", "snake", "Decides the casing for go structure tag names. camel, title or snake (default snake)")
	rootCmd.PersistentFlags().StringP("relation-tag", "r", "-", "Relationship struct tag name")
	rootCmd.PersistentFlags().StringSliceP("tag-ignore", "", nil, "List of column names that should have tags values set to '-' (ignored during parsing)")

	// hide flags not recommended for use
	rootCmd.PersistentFlags().MarkHidden("replace")

	viper.BindPFlags(rootCmd.PersistentFlags())
	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	viper.AutomaticEnv()

	if err := rootCmd.Execute(); err != nil {
		if e, ok := err.(commandFailure); ok {
			fmt.Printf("Error: %v\n\n", string(e))
			rootCmd.Help()
		} else if !viper.GetBool("debug") {
			fmt.Printf("Error: %v\n", err)
		} else {
			fmt.Printf("Error: %+v\n", err)
		}

		os.Exit(1)
	}
}

type commandFailure string

func (c commandFailure) Error() string {
	return string(c)
}

func preRun(cmd *cobra.Command, args []string) error {
	var err error

	if len(args) == 0 {
		return commandFailure("must provide a driver name")
	}

	driverName := args[0]
	driverPath := args[0]

	if strings.ContainsRune(driverName, os.PathSeparator) {
		driverName = strings.Replace(filepath.Base(driverName), "sqlboiler-", "", 1)
		driverName = strings.Replace(driverName, ".exe", "", 1)
	} else {
		driverPath = "sqlboiler-" + driverPath
		if p, err := exec.LookPath(driverPath); err == nil {
			driverPath = p
		}
	}

	driverPath, err = filepath.Abs(driverPath)
	if err != nil {
		return errors.Wrap(err, "could not find absolute path to driver")
	}
	drivers.RegisterBinary(driverName, driverPath)

	cmdConfig = &boilingcore.Config{
		DriverName:        driverName,
		OutFolder:         viper.GetString("output"),
		PkgName:           viper.GetString("pkgname"),
		Debug:             viper.GetBool("debug"),
		AddGlobal:         viper.GetBool("add-global-variants"),
		AddPanic:          viper.GetBool("add-panic-variants"),
		AddSoftDeletes:    viper.GetBool("add-soft-deletes"),
		NoContext:         viper.GetBool("no-context"),
		NoTests:           viper.GetBool("no-tests"),
		NoHooks:           viper.GetBool("no-hooks"),
		NoRowsAffected:    viper.GetBool("no-rows-affected"),
		NoAutoTimestamps:  viper.GetBool("no-auto-timestamps"),
		NoDriverTemplates: viper.GetBool("no-driver-templates"),
		NoBackReferencing: viper.GetBool("no-back-referencing"),
		Wipe:              viper.GetBool("wipe"),
		StructTagCasing:   strings.ToLower(viper.GetString("struct-tag-casing")), // camel | snake | title
		TagIgnore:         viper.GetStringSlice("tag-ignore"),
		RelationTag:       viper.GetString("relation-tag"),
		TemplateDirs:      viper.GetStringSlice("templates"),
		Tags:              viper.GetStringSlice("tag"),
		Replacements:      viper.GetStringSlice("replace"),
		Aliases:           boilingcore.ConvertAliases(viper.Get("aliases")),
		TypeReplaces:      boilingcore.ConvertTypeReplace(viper.Get("types")),
		Version:           sqlBoilerVersion,
	}

	if cmdConfig.Debug {
		fmt.Fprintln(os.Stderr, "using driver:", driverPath)
	}

	// Configure the driver
	cmdConfig.DriverConfig = map[string]interface{}{
		"whitelist": viper.GetStringSlice(driverName + ".whitelist"),
		"blacklist": viper.GetStringSlice(driverName + ".blacklist"),
	}

	keys := allKeys(driverName)
	for _, key := range keys {
		if key != "blacklist" && key != "whitelist" {
			prefixedKey := fmt.Sprintf("%s.%s", driverName, key)
			cmdConfig.DriverConfig[key] = viper.Get(prefixedKey)
		}
	}

	cmdConfig.Imports = configureImports()

	cmdState, err = boilingcore.New(cmdConfig)
	return err
}

func configureImports() importers.Collection {
	imports := importers.NewDefaultImports()

	mustMap := func(m importers.Map, err error) importers.Map {
		if err != nil {
			panic("failed to change viper interface into importers.Map: " + err.Error())
		}

		return m
	}

	if viper.IsSet("imports.all.standard") {
		imports.All.Standard = viper.GetStringSlice("imports.all.standard")
	}
	if viper.IsSet("imports.all.third_party") {
		imports.All.ThirdParty = viper.GetStringSlice("imports.all.third_party")
	}
	if viper.IsSet("imports.test.standard") {
		imports.Test.Standard = viper.GetStringSlice("imports.test.standard")
	}
	if viper.IsSet("imports.test.third_party") {
		imports.Test.ThirdParty = viper.GetStringSlice("imports.test.third_party")
	}
	if viper.IsSet("imports.singleton") {
		imports.Singleton = mustMap(importers.MapFromInterface(viper.Get("imports.singleton")))
	}
	if viper.IsSet("imports.test_singleton") {
		imports.TestSingleton = mustMap(importers.MapFromInterface(viper.Get("imports.test_singleton")))
	}
	if viper.IsSet("imports.based_on_type") {
		imports.BasedOnType = mustMap(importers.MapFromInterface(viper.Get("imports.based_on_type")))
	}

	return imports
}

func run(cmd *cobra.Command, args []string) error {
	return cmdState.Run()
}

func postRun(cmd *cobra.Command, args []string) error {
	return cmdState.Cleanup()
}

func allKeys(prefix string) []string {
	keys := make(map[string]bool)

	prefix += "."

	for _, e := range os.Environ() {
		splits := strings.SplitN(e, "=", 2)
		key := strings.ReplaceAll(strings.ToLower(splits[0]), "_", ".")

		if strings.HasPrefix(key, prefix) {
			keys[strings.ReplaceAll(key, prefix, "")] = true
		}
	}

	for _, key := range viper.AllKeys() {
		if strings.HasPrefix(key, prefix) {
			keys[strings.ReplaceAll(key, prefix, "")] = true
		}
	}

	keySlice := make([]string, 0, len(keys))
	for k := range keys {
		keySlice = append(keySlice, k)
	}
	return keySlice
}
<commit_msg>Bump version<commit_after>// Package main defines a command line interface for the sqlboiler package
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/friendsofgo/errors"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"github.com/volatiletech/sqlboiler/v4/boilingcore"
	"github.com/volatiletech/sqlboiler/v4/drivers"
	"github.com/volatiletech/sqlboiler/v4/importers"
)

//go:generate go-bindata -nometadata -pkg templatebin -o templatebin/bindata.go templates templates/singleton templates_test templates_test/singleton

const sqlBoilerVersion = "4.3.1"

var (
	flagConfigFile string
	cmdState       *boilingcore.State
	cmdConfig      *boilingcore.Config
)

func initConfig() {
	if len(flagConfigFile) != 0 {
		viper.SetConfigFile(flagConfigFile)
		if err := viper.ReadInConfig(); err != nil {
			fmt.Println("Can't read config:", err)
			os.Exit(1)
		}
		return
	}

	var err error
	viper.SetConfigName("sqlboiler")

	configHome := os.Getenv("XDG_CONFIG_HOME")
	homePath := os.Getenv("HOME")
	wd, err := os.Getwd()
	if err != nil {
		wd = "."
	}

	configPaths := []string{wd}
	if len(configHome) > 0 {
		configPaths = append(configPaths, filepath.Join(configHome, "sqlboiler"))
	} else {
		configPaths = append(configPaths, filepath.Join(homePath, ".config/sqlboiler"))
	}

	for _, p := range configPaths {
		viper.AddConfigPath(p)
	}

	// Ignore errors here, fallback to other validation methods.
	// Users can use environment variables if a config is not found.
	_ = viper.ReadInConfig()
}

func main() {
	// Too much happens between here and cobra's argument handling, for
	// something so simple just do it immediately.
	for _, arg := range os.Args {
		if arg == "--version" {
			fmt.Println("SQLBoiler v" + sqlBoilerVersion)
			return
		}
	}

	// Set up the cobra root command
	var rootCmd = &cobra.Command{
		Use:   "sqlboiler [flags] <driver>",
		Short: "SQL Boiler generates an ORM tailored to your database schema.",
		Long: "SQL Boiler generates a Go ORM from template files, tailored to your database schema.\n" +
			`Complete documentation is available at http://github.com/volatiletech/sqlboiler`,
		Example:       `sqlboiler psql`,
		PreRunE:       preRun,
		RunE:          run,
		PostRunE:      postRun,
		SilenceErrors: true,
		SilenceUsage:  true,
	}

	cobra.OnInitialize(initConfig)

	// Set up the cobra root command flags
	rootCmd.PersistentFlags().StringVarP(&flagConfigFile, "config", "c", "", "Filename of config file to override default lookup")
	rootCmd.PersistentFlags().StringP("output", "o", "models", "The name of the folder to output to")
	rootCmd.PersistentFlags().StringP("pkgname", "p", "models", "The name you wish to assign to your generated package")
	rootCmd.PersistentFlags().StringSliceP("templates", "", nil, "A templates directory, overrides the bindata'd template folders in sqlboiler")
	rootCmd.PersistentFlags().StringSliceP("tag", "t", nil, "Struct tags to be included on your models in addition to json, yaml, toml")
	rootCmd.PersistentFlags().StringSliceP("replace", "", nil, "Replace templates by directory: relpath/to_file.tpl:relpath/to_replacement.tpl")
	rootCmd.PersistentFlags().BoolP("debug", "d", false, "Debug mode prints stack traces on error")
	rootCmd.PersistentFlags().BoolP("no-context", "", false, "Disable context.Context usage in the generated code")
	rootCmd.PersistentFlags().BoolP("no-tests", "", false, "Disable generated go test files")
	rootCmd.PersistentFlags().BoolP("no-hooks", "", false, "Disable hooks feature for your models")
	rootCmd.PersistentFlags().BoolP("no-rows-affected", "", false, "Disable rows affected in the generated API")
	rootCmd.PersistentFlags().BoolP("no-auto-timestamps", "", false, "Disable automatic timestamps for created_at/updated_at")
	rootCmd.PersistentFlags().BoolP("no-driver-templates", "", false, "Disable parsing of templates defined by the database driver")
	rootCmd.PersistentFlags().BoolP("no-back-referencing", "", false, "Disable back referencing in the loaded relationship structs")
	rootCmd.PersistentFlags().BoolP("add-global-variants", "", false, "Enable generation for global variants")
	rootCmd.PersistentFlags().BoolP("add-panic-variants", "", false, "Enable generation for panic variants")
	rootCmd.PersistentFlags().BoolP("add-soft-deletes", "", false, "Enable soft deletion by updating deleted_at timestamp")
	rootCmd.PersistentFlags().BoolP("version", "", false, "Print the version")
	rootCmd.PersistentFlags().BoolP("wipe", "", false, "Delete the output folder (rm -rf) before generation to ensure sanity")
	rootCmd.PersistentFlags().StringP("struct-tag-casing", "", "snake", "Decides the casing for go structure tag names. camel, title or snake (default snake)")
	rootCmd.PersistentFlags().StringP("relation-tag", "r", "-", "Relationship struct tag name")
	rootCmd.PersistentFlags().StringSliceP("tag-ignore", "", nil, "List of column names that should have tags values set to '-' (ignored during parsing)")

	// hide flags not recommended for use
	rootCmd.PersistentFlags().MarkHidden("replace")

	viper.BindPFlags(rootCmd.PersistentFlags())
	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	viper.AutomaticEnv()

	if err := rootCmd.Execute(); err != nil {
		if e, ok := err.(commandFailure); ok {
			fmt.Printf("Error: %v\n\n", string(e))
			rootCmd.Help()
		} else if !viper.GetBool("debug") {
			fmt.Printf("Error: %v\n", err)
		} else {
			fmt.Printf("Error: %+v\n", err)
		}

		os.Exit(1)
	}
}

type commandFailure string

func (c commandFailure) Error() string {
	return string(c)
}

func preRun(cmd *cobra.Command, args []string) error {
	var err error

	if len(args) == 0 {
		return commandFailure("must provide a driver name")
	}

	driverName := args[0]
	driverPath := args[0]

	if strings.ContainsRune(driverName, os.PathSeparator) {
		driverName = strings.Replace(filepath.Base(driverName), "sqlboiler-", "", 1)
		driverName = strings.Replace(driverName, ".exe", "", 1)
	} else {
		driverPath = "sqlboiler-" + driverPath
		if p, err := exec.LookPath(driverPath); err == nil {
			driverPath = p
		}
	}

	driverPath, err = filepath.Abs(driverPath)
	if err != nil {
		return errors.Wrap(err, "could not find absolute path to driver")
	}
	drivers.RegisterBinary(driverName, driverPath)

	cmdConfig = &boilingcore.Config{
		DriverName:        driverName,
		OutFolder:         viper.GetString("output"),
		PkgName:           viper.GetString("pkgname"),
		Debug:             viper.GetBool("debug"),
		AddGlobal:         viper.GetBool("add-global-variants"),
		AddPanic:          viper.GetBool("add-panic-variants"),
		AddSoftDeletes:    viper.GetBool("add-soft-deletes"),
		NoContext:         viper.GetBool("no-context"),
		NoTests:           viper.GetBool("no-tests"),
		NoHooks:           viper.GetBool("no-hooks"),
		NoRowsAffected:    viper.GetBool("no-rows-affected"),
		NoAutoTimestamps:  viper.GetBool("no-auto-timestamps"),
		NoDriverTemplates: viper.GetBool("no-driver-templates"),
		NoBackReferencing: viper.GetBool("no-back-referencing"),
		Wipe:              viper.GetBool("wipe"),
		StructTagCasing:   strings.ToLower(viper.GetString("struct-tag-casing")), // camel | snake | title
		TagIgnore:         viper.GetStringSlice("tag-ignore"),
		RelationTag:       viper.GetString("relation-tag"),
		TemplateDirs:      viper.GetStringSlice("templates"),
		Tags:              viper.GetStringSlice("tag"),
		Replacements:      viper.GetStringSlice("replace"),
		Aliases:           boilingcore.ConvertAliases(viper.Get("aliases")),
		TypeReplaces:      boilingcore.ConvertTypeReplace(viper.Get("types")),
		Version:           sqlBoilerVersion,
	}

	if cmdConfig.Debug {
		fmt.Fprintln(os.Stderr, "using driver:", driverPath)
	}

	// Configure the driver
	cmdConfig.DriverConfig = map[string]interface{}{
		"whitelist": viper.GetStringSlice(driverName + ".whitelist"),
		"blacklist": viper.GetStringSlice(driverName + ".blacklist"),
	}

	keys := allKeys(driverName)
	for _, key := range keys {
		if key != "blacklist" && key != "whitelist" {
			prefixedKey := fmt.Sprintf("%s.%s", driverName, key)
			cmdConfig.DriverConfig[key] = viper.Get(prefixedKey)
		}
	}

	cmdConfig.Imports = configureImports()

	cmdState, err = boilingcore.New(cmdConfig)
	return err
}

func configureImports() importers.Collection {
	imports := importers.NewDefaultImports()

	mustMap := func(m importers.Map, err error) importers.Map {
		if err != nil {
			panic("failed to change viper interface into importers.Map: " + err.Error())
		}

		return m
	}

	if viper.IsSet("imports.all.standard") {
		imports.All.Standard = viper.GetStringSlice("imports.all.standard")
	}
	if viper.IsSet("imports.all.third_party") {
		imports.All.ThirdParty = viper.GetStringSlice("imports.all.third_party")
	}
	if viper.IsSet("imports.test.standard") {
		imports.Test.Standard = viper.GetStringSlice("imports.test.standard")
	}
	if viper.IsSet("imports.test.third_party") {
		imports.Test.ThirdParty = viper.GetStringSlice("imports.test.third_party")
	}
	if viper.IsSet("imports.singleton") {
		imports.Singleton = mustMap(importers.MapFromInterface(viper.Get("imports.singleton")))
	}
	if viper.IsSet("imports.test_singleton") {
		imports.TestSingleton = mustMap(importers.MapFromInterface(viper.Get("imports.test_singleton")))
	}
	if viper.IsSet("imports.based_on_type") {
		imports.BasedOnType = mustMap(importers.MapFromInterface(viper.Get("imports.based_on_type")))
	}

	return imports
}

func run(cmd *cobra.Command, args []string) error {
	return cmdState.Run()
}

func postRun(cmd *cobra.Command, args []string) error {
	return cmdState.Cleanup()
}

func allKeys(prefix string) []string {
	keys := make(map[string]bool)

	prefix += "."

	for _, e := range os.Environ() {
		splits := strings.SplitN(e, "=", 2)
		key := strings.ReplaceAll(strings.ToLower(splits[0]), "_", ".")

		if strings.HasPrefix(key, prefix) {
			keys[strings.ReplaceAll(key, prefix, "")] = true
		}
	}

	for _, key := range viper.AllKeys() {
		if strings.HasPrefix(key, prefix) {
			keys[strings.ReplaceAll(key, prefix, "")] = true
		}
	}

	keySlice := make([]string, 0, len(keys))
	for k := range keys {
		keySlice = append(keySlice, k)
	}
	return keySlice
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	apidisp "github.com/clawio/lib/api/dispatcher"
	apiauth "github.com/clawio/lib/api/providers/auth"
	apiwebdav "github.com/clawio/lib/api/providers/webdav"
	"github.com/clawio/lib/apiserver"
	authdisp "github.com/clawio/lib/auth/dispatcher"
	"github.com/clawio/lib/auth/providers/file"
	"github.com/clawio/lib/config"
	"github.com/clawio/lib/logger"
	"github.com/clawio/lib/pidfile"
	"github.com/clawio/lib/signaler"
	storagedisp "github.com/clawio/lib/storage/dispatcher"
	"github.com/clawio/lib/storage/providers/local"
)

func main() {

	/*********************************************
	 *** 1. Parse CLI flags   ********************
	 *********************************************/
	flags := struct {
		pidFile string // the pidfile that will be used by the daemon
		cfg     string
	}{}
	flag.StringVar(&flags.pidFile, "p", "", "PID file")
	flag.StringVar(&flags.cfg, "c", "", "Configuration file")
	flag.Parse()

	/*********************************************
	 *** 2. Create PID file   ********************
	 *********************************************/
	if flags.pidFile == "" {
		fmt.Println("Set pidfile with -p flag")
		os.Exit(1)
	}
	_, err := pidfile.New(flags.pidFile)
	if err != nil {
		fmt.Println("Cannot create PID file: ", err)
		os.Exit(1)
	}

	/************************************************
	 *** 3. Load configuration   ********************
	 ************************************************/
	if flags.cfg == "" {
		fmt.Println("Set configuration with -c flag")
		os.Exit(1)
	}
	cfg, err := config.New(flags.cfg)
	if err != nil {
		fmt.Println("Cannot load configuration: ", err)
		os.Exit(1)
	}

	/******************************************
	 ** 4. Connect to the syslog daemon *******
	 ******************************************/
	syslogWriter, err := logger.NewSyslogWriter("", "", cfg.GetDirectives().LogLevel)
	if err != nil {
		fmt.Println("Cannot connect to syslog: ", err)
		os.Exit(1)
	}

	/******************************************
	 ** 5. Create auth dispatcher       *******
	 ******************************************/
	fileAuthLog := logger.New(syslogWriter, cfg.GetDirectives().LogLevel, "FILEAUTH")
	fauth, err := file.New("fileauth", cfg, fileAuthLog)
	if err != nil {
		fmt.Println("Cannot create file auth provider: ", err)
		os.Exit(1)
	}
	adispLog := logger.New(syslogWriter, cfg.GetDirectives().LogLevel, "AUTHDISP")
	adisp := authdisp.New(cfg, adispLog)
	err = adisp.AddAuth(fauth) // add file auth strategy
	if err != nil {
		fmt.Println("Cannot add file auth provider to auth dispatcher: ", err)
		os.Exit(1)
	}

	/******************************************
	 ** 6. Create storage dispatcher      *****
	 ******************************************/
	localStorageLog := logger.New(syslogWriter, cfg.GetDirectives().LogLevel, "LOCALSTORAGE")
	localStorage := local.New("local", cfg, localStorageLog)

	sdispLog := logger.New(syslogWriter, cfg.GetDirectives().LogLevel, "STORAGEDISP")
	sdisp := storagedisp.New(cfg, sdispLog)
	err = sdisp.AddStorage(localStorage)
	if err != nil {
		fmt.Println("Cannot add local storage to storage dispatcher: ", err)
		os.Exit(1)
	}

	/******************************************
	 ** 7. Create API dispatcher aka router  **
	 ******************************************/
	authAPI := apiauth.New("auth", cfg, adisp, sdisp)
	webdavAPI := apiwebdav.New("webdav", cfg, adisp, sdisp)
	apdisp := apidisp.New(cfg)
	err = apdisp.AddAPI(authAPI)
	if err != nil {
		fmt.Println("Cannot add auth API to API dispatcher: ", err)
		os.Exit(1)
	}
	err = apdisp.AddAPI(webdavAPI)
	if err != nil {
		fmt.Println("Cannot add WebDAV API to API dispatcher: ", err)
		os.Exit(1)
	}

	/***************************************************
	 *** 8. Start HTTP/HTTPS Server ********************
	 ***************************************************/
	srv := apiserver.New(cfg, syslogWriter, apdisp, adisp, sdisp)
	go func() {
		err = srv.Start()
		if err != nil {
			fmt.Println("Cannot start HTTP/HTTPS API server: ", err)
			os.Exit(1)
		}
	}()

	/***************************************************
	 *** 9. Listen to OS signals to control the daemon *
	 ***************************************************/
	sig := signaler.New(cfg, srv)
	endc := sig.Start()
	<-endc
	os.Exit(0)
}
<commit_msg>Add the flag -pc to print the default configuation format<commit_after>// ClawIO - Scalable Distributed High-Performance Synchronisation and Sharing Service
//
// Copyright (C) 2015  Hugo González Labrador <clawio@hugo.labkode.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. See file COPYNG.

package main

import (
	"flag"
	"fmt"
	"os"

	apidisp "github.com/clawio/lib/api/dispatcher"
	apiauth "github.com/clawio/lib/api/providers/auth"
	apiwebdav "github.com/clawio/lib/api/providers/webdav"
	"github.com/clawio/lib/apiserver"
	authdisp "github.com/clawio/lib/auth/dispatcher"
	"github.com/clawio/lib/auth/providers/file"
	"github.com/clawio/lib/config"
	"github.com/clawio/lib/logger"
	"github.com/clawio/lib/pidfile"
	"github.com/clawio/lib/signaler"
	storagedisp "github.com/clawio/lib/storage/dispatcher"
	"github.com/clawio/lib/storage/providers/local"
)

func main() {

	/*********************************************
	 *** 1. Parse CLI flags   ********************
	 *********************************************/
	flags := struct {
		pidFile string // the pidfile that will be used by the daemon
		cfg     string // the config that will be used by the daemon
		pc      bool   // if true prints the default config file
	}{}
	flag.StringVar(&flags.pidFile, "p", "", "PID file")
	flag.StringVar(&flags.cfg, "c", "", "Configuration file")
	flag.BoolVar(&flags.pc, "pc", false, "Prints the default configuration file")
	flag.Parse()

	if flags.pc == true {
		cfg, err := config.Default()
		if err != nil {
			fmt.Printf("Cannot print default configuration: ", err)
			os.Exit(1)
		}
		fmt.Println(cfg)
		os.Exit(0)
	}
	/*********************************************
	 *** 2. Create PID file   ********************
	 *********************************************/
	if flags.pidFile == "" {
		fmt.Println("Set pidfile with -p flag")
		os.Exit(1)
	}
	_, err := pidfile.New(flags.pidFile)
	if err != nil {
		fmt.Println("Cannot create PID file: ", err)
		os.Exit(1)
	}

	/************************************************
	 *** 3. Load configuration   ********************
	 ************************************************/
	if flags.cfg == "" {
		fmt.Println("Set configuration with -c flag")
		os.Exit(1)
	}
	cfg, err := config.New(flags.cfg)
	if err != nil {
		fmt.Println("Cannot load configuration: ", err)
		os.Exit(1)
	}

	/******************************************
	 ** 4. Connect to the syslog daemon *******
	 ******************************************/
	syslogWriter, err := logger.NewSyslogWriter("", "", cfg.GetDirectives().LogLevel)
	if err != nil {
		fmt.Println("Cannot connect to syslog: ", err)
		os.Exit(1)
	}

	/******************************************
	 ** 5. Create auth dispatcher       *******
	 ******************************************/
	fileAuthLog := logger.New(syslogWriter, cfg.GetDirectives().LogLevel, "FILEAUTH")
	fauth, err := file.New("fileauth", cfg, fileAuthLog)
	if err != nil {
		fmt.Println("Cannot create file auth provider: ", err)
		os.Exit(1)
	}
	adispLog := logger.New(syslogWriter, cfg.GetDirectives().LogLevel, "AUTHDISP")
	adisp := authdisp.New(cfg, adispLog)
	err = adisp.AddAuth(fauth) // add file auth strategy
	if err != nil {
		fmt.Println("Cannot add file auth provider to auth dispatcher: ", err)
		os.Exit(1)
	}

	/******************************************
	 ** 6. Create storage dispatcher      *****
	 ******************************************/
	localStorageLog := logger.New(syslogWriter, cfg.GetDirectives().LogLevel, "LOCALSTORAGE")
	localStorage := local.New("local", cfg, localStorageLog)

	sdispLog := logger.New(syslogWriter, cfg.GetDirectives().LogLevel, "STORAGEDISP")
	sdisp := storagedisp.New(cfg, sdispLog)
	err = sdisp.AddStorage(localStorage)
	if err != nil {
		fmt.Println("Cannot add local storage to storage dispatcher: ", err)
		os.Exit(1)
	}

	/******************************************
	 ** 7. Create API dispatcher aka router  **
	 ******************************************/
	authAPI := apiauth.New("auth", cfg, adisp, sdisp)
	webdavAPI := apiwebdav.New("webdav", cfg, adisp, sdisp)
	apdisp := apidisp.New(cfg)
	err = apdisp.AddAPI(authAPI)
	if err != nil {
		fmt.Println("Cannot add auth API to API dispatcher: ", err)
		os.Exit(1)
	}
	err = apdisp.AddAPI(webdavAPI)
	if err != nil {
		fmt.Println("Cannot add WebDAV API to API dispatcher: ", err)
		os.Exit(1)
	}

	/***************************************************
	 *** 8. Start HTTP/HTTPS Server ********************
	 ***************************************************/
	srv := apiserver.New(cfg, syslogWriter, apdisp, adisp, sdisp)
	go func() {
		err = srv.Start()
		if err != nil {
			fmt.Println("Cannot start HTTP/HTTPS API server: ", err)
			os.Exit(1)
		}
	}()

	/***************************************************
	 *** 9. Listen to OS signals to control the daemon *
	 ***************************************************/
	sig := signaler.New(cfg, srv)
	endc := sig.Start()
	<-endc
	os.Exit(0)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/bitrise-io/go-utils/log"
	"github.com/bitrise-tools/go-steputils/stepconf"
)

// Config ...
type Config struct {
	Debug bool `env:"is_debug_mode,opt[yes,no]"`

	// Message
	WebhookURL       stepconf.Secret `env:"webhook_url"`
	APIToken         stepconf.Secret `env:"api_token"`
	Channel          string          `env:"channel"`
	ChannelOnError   string          `env:"channel_on_error"`
	Text             string          `env:"text"`
	TextOnError      string          `env:"text_on_error"`
	IconEmoji        string          `env:"emoji"`
	IconEmojiOnError string          `env:"emoji_on_error"`
	IconURL          string          `env:"icon_url"`
	IconURLOnError   string          `env:"icon_url_on_error"`
	LinkNames        bool            `env:"link_names,opt[yes,no]"`
	Username         string          `env:"from_username"`
	UsernameOnError  string          `env:"from_username_on_error"`

	// Attachment
	Color           string `env:"color,required"`
	ColorOnError    string `env:"color_on_error"`
	PreText         string `env:"pretext"`
	PreTextOnError  string `env:"pretext_on_error"`
	AuthorName      string `env:"author_name"`
	Title           string `env:"title"`
	TitleOnError    string `env:"title_on_error"`
	TitleLink       string `env:"title_link"`
	Message         string `env:"message"`
	MessageOnError  string `env:"message_on_error"`
	ImageURL        string `env:"image_url"`
	ImageURLOnError string `env:"image_url_on_error"`
	ThumbURL        string `env:"thumb_url"`
	ThumbURLOnError string `env:"thumb_url_on_error"`
	Footer          string `env:"footer"`
	FooterIcon      string `env:"footer_icon"`
	TimeStamp       bool   `env:"timestamp,opt[yes,no]"`
	Fields          string `env:"fields"`
	Buttons         string `env:"buttons"`
}

// success is true if the build is successful, false otherwise.
var success = os.Getenv("BITRISE_BUILD_STATUS") == "0"

// selectValue chooses the right value based on the result of the build.
func selectValue(ifSuccess, ifFailed string) string {
	if success || ifFailed == "" {
		return ifSuccess
	}
	return ifFailed
}

// ensureNewlines replaces all \n substrings with newline characters.
func ensureNewlines(s string) string {
	return strings.Replace(s, "\\n", "\n", -1)
}

func newMessage(c Config) Message {
	msg := Message{
		Channel: selectValue(c.Channel, c.ChannelOnError),
		Text:    selectValue(c.Text, c.TextOnError),
		Attachments: []Attachment{{
			Fallback:   ensureNewlines(selectValue(c.Message, c.MessageOnError)),
			Color:      selectValue(c.Color, c.ColorOnError),
			PreText:    selectValue(c.PreText, c.PreTextOnError),
			AuthorName: c.AuthorName,
			Title:      selectValue(c.Title, c.TitleOnError),
			TitleLink:  c.TitleLink,
			Text:       ensureNewlines(selectValue(c.Message, c.MessageOnError)),
			Fields:     parseFields(c.Fields),
			ImageURL:   selectValue(c.ImageURL, c.ImageURLOnError),
			ThumbURL:   selectValue(c.ThumbURL, c.ThumbURLOnError),
			Footer:     c.Footer,
			FooterIcon: c.FooterIcon,
			Buttons:    parseButtons(c.Buttons),
		}},
		IconEmoji: selectValue(c.IconEmoji, c.IconEmojiOnError),
		IconURL:   selectValue(c.IconURL, c.IconURLOnError),
		LinkNames: c.LinkNames,
		Username:  selectValue(c.Username, c.UsernameOnError),
	}
	if c.TimeStamp {
		msg.Attachments[0].TimeStamp = int(time.Now().Unix())
	}
	return msg
}

// postMessage sends a message to a channel.
func postMessage(conf Config, msg Message) error {
	b, err := json.Marshal(msg)
	if err != nil {
		return err
	}
	log.Debugf("Request to Slack: %s\n", b)

	url := strings.TrimSpace(string(conf.WebhookURL))
	if string(conf.APIToken) != "" {
		url = "https://slack.com/api/chat.postMessage"
	}

	req, err := http.NewRequest("POST", url, bytes.NewReader(b))
	req.Header.Add("Content-Type", "application/json; charset=utf-8")

	if string(conf.APIToken) != "" {
		req.Header.Add("Authorization", "Bearer "+string(conf.APIToken))
	}

	client := &http.Client{}

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("failed to send the request: %s", err)
	}
	defer func() {
		if cerr := resp.Body.Close(); err == nil {
			err = cerr
		}
	}()

	if resp.StatusCode != http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("server error: %s, failed to read response: %s", resp.Status, err)
		}
		return fmt.Errorf("server error: %s, response: %s", resp.Status, body)
	}

	return nil
}

func validate(conf *Config) error {
	if conf.APIToken == "" && conf.WebhookURL == "" {
		return fmt.Errorf("Both API Token and WebhookURL are empty. You need to provide one of them. If you want to use incoming webhooks provide the webhook url. If you want to use a bot to send a message provide the bot API token")
	}

	if conf.APIToken != "" && conf.WebhookURL != "" {
		log.Warnf("Both API Token and WebhookURL are provided. Using the API Token")
		conf.WebhookURL = ""

	}
	return nil
}

func main() {
	var conf Config
	if err := stepconf.Parse(&conf); err != nil {
		log.Errorf("Error: %s\n", err)
		os.Exit(1)
	}
	stepconf.Print(conf)
	log.SetEnableDebugLog(conf.Debug)

	if err := validate(&conf); err != nil {
		log.Errorf("Error: %s\n", err)
		os.Exit(1)
	}

	msg := newMessage(conf)
	if err := postMessage(conf, msg); err != nil {
		log.Errorf("Error: %s", err)
		os.Exit(1)
	}

	log.Donef("\nSlack message successfully sent! 🚀\n")
}
<commit_msg>Fix setting default webhook url (#71)<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/bitrise-io/go-utils/log"
	"github.com/bitrise-tools/go-steputils/stepconf"
)

// Config ...
type Config struct {
	Debug bool `env:"is_debug_mode,opt[yes,no]"`

	// Message
	WebhookURL       stepconf.Secret `env:"webhook_url"`
	APIToken         stepconf.Secret `env:"api_token"`
	Channel          string          `env:"channel"`
	ChannelOnError   string          `env:"channel_on_error"`
	Text             string          `env:"text"`
	TextOnError      string          `env:"text_on_error"`
	IconEmoji        string          `env:"emoji"`
	IconEmojiOnError string          `env:"emoji_on_error"`
	IconURL          string          `env:"icon_url"`
	IconURLOnError   string          `env:"icon_url_on_error"`
	LinkNames        bool            `env:"link_names,opt[yes,no]"`
	Username         string          `env:"from_username"`
	UsernameOnError  string          `env:"from_username_on_error"`

	// Attachment
	Color           string `env:"color,required"`
	ColorOnError    string `env:"color_on_error"`
	PreText         string `env:"pretext"`
	PreTextOnError  string `env:"pretext_on_error"`
	AuthorName      string `env:"author_name"`
	Title           string `env:"title"`
	TitleOnError    string `env:"title_on_error"`
	TitleLink       string `env:"title_link"`
	Message         string `env:"message"`
	MessageOnError  string `env:"message_on_error"`
	ImageURL        string `env:"image_url"`
	ImageURLOnError string `env:"image_url_on_error"`
	ThumbURL        string `env:"thumb_url"`
	ThumbURLOnError string `env:"thumb_url_on_error"`
	Footer          string `env:"footer"`
	FooterIcon      string `env:"footer_icon"`
	TimeStamp       bool   `env:"timestamp,opt[yes,no]"`
	Fields          string `env:"fields"`
	Buttons         string `env:"buttons"`
}

// success is true if the build is successful, false otherwise.
var success = os.Getenv("BITRISE_BUILD_STATUS") == "0"

// selectValue chooses the right value based on the result of the build.
func selectValue(ifSuccess, ifFailed string) string {
	if success || ifFailed == "" {
		return ifSuccess
	}
	return ifFailed
}

// ensureNewlines replaces all \n substrings with newline characters.
func ensureNewlines(s string) string {
	return strings.Replace(s, "\\n", "\n", -1)
}

func newMessage(c Config) Message {
	msg := Message{
		Channel: selectValue(c.Channel, c.ChannelOnError),
		Text:    selectValue(c.Text, c.TextOnError),
		Attachments: []Attachment{{
			Fallback:   ensureNewlines(selectValue(c.Message, c.MessageOnError)),
			Color:      selectValue(c.Color, c.ColorOnError),
			PreText:    selectValue(c.PreText, c.PreTextOnError),
			AuthorName: c.AuthorName,
			Title:      selectValue(c.Title, c.TitleOnError),
			TitleLink:  c.TitleLink,
			Text:       ensureNewlines(selectValue(c.Message, c.MessageOnError)),
			Fields:     parseFields(c.Fields),
			ImageURL:   selectValue(c.ImageURL, c.ImageURLOnError),
			ThumbURL:   selectValue(c.ThumbURL, c.ThumbURLOnError),
			Footer:     c.Footer,
			FooterIcon: c.FooterIcon,
			Buttons:    parseButtons(c.Buttons),
		}},
		IconEmoji: selectValue(c.IconEmoji, c.IconEmojiOnError),
		IconURL:   selectValue(c.IconURL, c.IconURLOnError),
		LinkNames: c.LinkNames,
		Username:  selectValue(c.Username, c.UsernameOnError),
	}
	if c.TimeStamp {
		msg.Attachments[0].TimeStamp = int(time.Now().Unix())
	}
	return msg
}

// postMessage sends a message to a channel.
func postMessage(conf Config, msg Message) error {
	b, err := json.Marshal(msg)
	if err != nil {
		return err
	}
	log.Debugf("Request to Slack: %s\n", b)

	url := strings.TrimSpace(string(conf.WebhookURL))
	if url == "" {
		url = "https://slack.com/api/chat.postMessage"
	}

	req, err := http.NewRequest("POST", url, bytes.NewReader(b))
	req.Header.Add("Content-Type", "application/json; charset=utf-8")

	if string(conf.APIToken) != "" {
		req.Header.Add("Authorization", "Bearer "+string(conf.APIToken))
	}

	client := &http.Client{}

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("failed to send the request: %s", err)
	}
	defer func() {
		if cerr := resp.Body.Close(); err == nil {
			err = cerr
		}
	}()

	if resp.StatusCode != http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("server error: %s, failed to read response: %s", resp.Status, err)
		}
		return fmt.Errorf("server error: %s, response: %s", resp.Status, body)
	}

	return nil
}

func validate(conf *Config) error {
	if conf.APIToken == "" && conf.WebhookURL == "" {
		return fmt.Errorf("Both API Token and WebhookURL are empty. You need to provide one of them. If you want to use incoming webhooks provide the webhook url. If you want to use a bot to send a message provide the bot API token")
	}

	if conf.APIToken != "" && conf.WebhookURL != "" {
		log.Warnf("Both API Token and WebhookURL are provided. Using the API Token")
		conf.WebhookURL = ""

	}
	return nil
}

func main() {
	var conf Config
	if err := stepconf.Parse(&conf); err != nil {
		log.Errorf("Error: %s\n", err)
		os.Exit(1)
	}
	stepconf.Print(conf)
	log.SetEnableDebugLog(conf.Debug)

	if err := validate(&conf); err != nil {
		log.Errorf("Error: %s\n", err)
		os.Exit(1)
	}

	msg := newMessage(conf)
	if err := postMessage(conf, msg); err != nil {
		log.Errorf("Error: %s", err)
		os.Exit(1)
	}

	log.Donef("\nSlack message successfully sent! 🚀\n")
}
<|endoftext|>


<commit_before>package main

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

func executeCmdline(cmdline string, data interface{}) bool {
	fmt.Printf("\nexecute [%v]\n", cmdline)
	return false
}

func main() {
	inst := &Instance{
		prompt: "\033[32m>>\033[0m ",
	}
	inst.Init(os.Stdin, os.Stdout)
	defer inst.Deinit()

	flag.BoolVar(&inst.debug, "d", false, "eanble debug")
	flag.Parse()

	inst.SetExecute(executeCmdline, nil)
	inst.SetCmds(
		Item("ls"),
		Item("lsblk"),
		Item("git",
			Item("clone"),
			Item("clean"),
			Item("log",
				Item("all"),
				Item("verbose"),
			),
		),
		Item("echo"),
		Item("help"),
	)
	inst.PrintTree(os.Stdout)

	inputLoop(inst)
}
<commit_msg>add and hanle 'exit' command<commit_after>package main

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

func executeCmdline(line string, data interface{}) bool {
	cmdline := strings.Fields(line)
	if len(cmdline) == 0 {
		fmt.Printf("invalid command [%s]\n", line)
		return false
	}
	switch cmdline[0] {
	case "exit":
		return true
	default:
		fmt.Printf("\nexecute [%v]\n", cmdline)
	}
	return false
}

func main() {
	inst := &Instance{
		prompt: "\033[32m>>\033[0m ",
	}
	inst.Init(os.Stdin, os.Stdout)
	defer inst.Deinit()

	flag.BoolVar(&inst.debug, "d", false, "eanble debug")
	flag.Parse()

	inst.SetExecute(executeCmdline, nil)
	inst.SetCmds(
		Item("ls"),
		Item("lsblk"),
		Item("git",
			Item("clone"),
			Item("clean"),
			Item("log",
				Item("all"),
				Item("verbose"),
			),
		),
		Item("exit"),
		Item("help"),
	)
	inst.PrintTree(os.Stdout)

	inputLoop(inst)
}
<|endoftext|>


<commit_before>// main.go
//
// Copyright 2015, Evan Prodromou <evan@e14n.com>
// 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"
    "net/http"
    "encoding/json"
)

var users map[string]map[string]string

func userHandler(w http.ResponseWriter, r *http.Request) {
  nick := r.URL.Path[6:]
  fmt.Printf("Request for user %s\n", nick)
  user := users[nick]
  if user == nil {
    http.Error(w, "No such user", 404)
  } else {
    b, err := json.Marshal(user)
    marshalled := string(b)
    fmt.Printf("User: '%s'", marshalled)
    if err != nil {
      http.Error(w, "Error encoding data", 500)
    } else {
      w.Header().Set("Content-Type", "application/activitystreams+json")
      fmt.Fprintf(w, marshalled)
    }
  }
}

func main() {
  http.HandleFunc("/user/", userHandler)
  users = make(map[string]map[string]string)
  users["evan"] = map[string]string {
    "preferredUsername": "evan",
    "displayName": "Evan Prodromou",
    "summary": "A person",
    "icon": "https://e14n.com/uploads/evan/2014/9/24/knyf1g_thumb.jpg",
  }
  http.ListenAndServe(":8080", nil)
}
<commit_msg>remove main.go<commit_after><|endoftext|>


<commit_before>// Declare this file to be part of the main package so it can be compiled into
// an executable.
package main

// Import all Go packages required for this file.
import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/bwmarrin/discordgo"
)

// Version is a constant that stores the Disgord version information.
const Version = "v0.0.0-alpha"

// Session is declared in the global space so it can be easily used
// throughout this program.
// In this use case, there is no error that would be returned.
var Session, _ = discordgo.New()

// Read in all configuration options from both environment variables and
// command line arguments.
func init() {

	// Discord Authentication Token
	Session.Token = os.Getenv("DG_TOKEN")
	if Session.Token == "" {
		flag.StringVar(&Session.Token, "t", "", "Discord Authentication Token")
	}
}

func main() {

	// Declare any variables needed later.
	var err error

	// Print out a fancy logo!
	fmt.Printf(`
	________  .__                               .___
	\______ \ |__| ______ ____   ___________  __| _/
	||    |  \|  |/  ___// ___\ /  _ \_  __ \/ __ |
	||    '   \  |\___ \/ /_/  >  <_> )  | \/ /_/ |
	||______  /__/____  >___  / \____/|__|  \____ |
	\_______\/        \/_____/   %-16s\/`+"\n\n", Version)

	// Parse command line arguments
	flag.Parse()

	// Verify a Token was provided
	if Session.Token == "" {
		log.Println("You must provide a Discord authentication token.")
		return
	}

	// Verify the Token is valid and grab user information
	Session.State.User, err = Session.User("@me")
	if err != nil {
		log.Printf("error fetching user information, %s\n", err)
	}

	// Open a websocket connection to Discord
	err = Session.Open()
	if err != nil {
		log.Printf("error opening connection to Discord, %s\n", err)
		os.Exit(1)
	}

	// Wait for a CTRL-C
	log.Printf(`Now running. Press CTRL-C to exit.`)
	sc := make(chan os.Signal, 1)
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
	<-sc

	// Clean up
	Session.Close()

	// Exit Normally.
}
<commit_msg>Removed block to fetch user information<commit_after>// Declare this file to be part of the main package so it can be compiled into
// an executable.
package main

// Import all Go packages required for this file.
import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/bwmarrin/discordgo"
)

// Version is a constant that stores the Disgord version information.
const Version = "v0.0.0-alpha"

// Session is declared in the global space so it can be easily used
// throughout this program.
// In this use case, there is no error that would be returned.
var Session, _ = discordgo.New()

// Read in all configuration options from both environment variables and
// command line arguments.
func init() {

	// Discord Authentication Token
	Session.Token = os.Getenv("DG_TOKEN")
	if Session.Token == "" {
		flag.StringVar(&Session.Token, "t", "", "Discord Authentication Token")
	}
}

func main() {

	// Declare any variables needed later.
	var err error

	// Print out a fancy logo!
	fmt.Printf(`
	________  .__                               .___
	\______ \ |__| ______ ____   ___________  __| _/
	||    |  \|  |/  ___// ___\ /  _ \_  __ \/ __ |
	||    '   \  |\___ \/ /_/  >  <_> )  | \/ /_/ |
	||______  /__/____  >___  / \____/|__|  \____ |
	\_______\/        \/_____/   %-16s\/`+"\n\n", Version)

	// Parse command line arguments
	flag.Parse()

	// Verify a Token was provided
	if Session.Token == "" {
		log.Println("You must provide a Discord authentication token.")
		return
	}

	// Open a websocket connection to Discord
	err = Session.Open()
	if err != nil {
		log.Printf("error opening connection to Discord, %s\n", err)
		os.Exit(1)
	}

	// Wait for a CTRL-C
	log.Printf(`Now running. Press CTRL-C to exit.`)
	sc := make(chan os.Signal, 1)
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
	<-sc

	// Clean up
	Session.Close()

	// Exit Normally.
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"net/textproto"
	"os"
	"strings"
	"time"
)

// Connection stores messages sent in the last 30 seconds and the connection itself
type Connection struct {
	conn     net.Conn
	messages int
}

// NewConnection initialize a Connection struct
func NewConnection(conn net.Conn) Connection {
	return Connection{
		conn:     conn,
		messages: 0,
	}

}

func (connection *Connection) reduceConnectionMessages() {
	connection.messages--
}

// Message called everytime you send a message
func (connection *Connection) Message(channel string, message string) {
	fmt.Fprintf(connection.conn, "PRIVMSG %s :%s\r\n", channel, message)
	connection.messages++
	time.AfterFunc(30*time.Second, connection.reduceConnectionMessages)
}

func (bot *Bot) reduceJoins() {
	bot.joins--
}

// Bot struct for main config
type Bot struct {
	server      string
	groupserver string
	port        string
	oauth       string
	nick        string
	inconn      net.Conn
	mainconn    net.Conn
	connlist    []Connection
	groupconn   net.Conn
	joins       int
	toJoin      []string
}

// NewBot main config
func NewBot() *Bot {
	return &Bot{
		server:      "irc.twitch.tv",
		groupserver: "group.tmi.twitch.tv",
		port:        "6667",
		oauth:       "",
		nick:        "",
		inconn:      nil,
		mainconn:    nil,
		connlist:    make([]Connection, 0),
		groupconn:   nil,
		joins:       0,
	}
}

func (bot *Bot) join(channel string) {
	if bot.joins < 42 {
		fmt.Fprintf(bot.mainconn, "JOIN %s\r\n", channel)
		bot.joins++
		time.AfterFunc(10*time.Second, bot.reduceJoins)
	}
}

// ListenToConnection listen
func (bot *Bot) ListenToConnection(conn net.Conn) {
	reader := bufio.NewReader(conn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			break // break loop on errors
		}
		if strings.Contains(line, "PING ") {
			fmt.Fprintf(conn, "PONG tmi.twitch.tv\r\n")
			log.Printf("PONG tmi.twitch.tv\r\n")
		}
		bot.inconn.Write([]byte(line + "\r\n"))
	}
}

// CreateConnection Add a new connection
func (bot *Bot) CreateConnection() (conn net.Conn, err error) {
	conn, err = net.Dial("tcp", bot.server+":"+bot.port)
	if err != nil {
		log.Fatal("unable to connect to IRC server ", err)
		return nil, err
	}
	fmt.Fprintf(conn, "PASS %s\r\n", bot.oauth)
	fmt.Fprintf(conn, "USER %s\r\n", bot.nick)
	fmt.Fprintf(conn, "NICK %s\r\n", bot.nick)
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/tags\r\n")     // enable ircv3 tags
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/commands\r\n") // enable roomstate and such
	log.Printf("new Connected to IRC server %s (%s)\n", bot.server, conn.RemoteAddr())

	connnection := NewConnection(conn)
	bot.connlist = append(bot.connlist, connnection)

	if len(bot.connlist) == 1 {
		bot.mainconn = conn
	}

	go bot.ListenToConnection(conn)

	return conn, nil
}

func main() {
	log.SetOutput(os.Stdout)
	ret := TCPServer()
	log.Printf("got ret code %d\n", ret)
	os.Exit(ret)
}

// Message to send a message
func (bot *Bot) Message(channel string, message string) {
	if message == "" {
		return
	}

	for i := 0; i < len(bot.connlist); i++ {
		if bot.connlist[i].messages < 90 {
			bot.connlist[i].Message(channel, message)
			return
		}
	}
	newConn, _ := bot.CreateConnection()
	fmt.Fprintf(newConn, "PRIVMSG %s :%s\r\n", channel, message)
	log.Println(newConn)
}
<commit_msg>logging fatal errors from tcp connection<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"net/textproto"
	"os"
	"strings"
	"time"
)

// Connection stores messages sent in the last 30 seconds and the connection itself
type Connection struct {
	conn     net.Conn
	messages int
}

// NewConnection initialize a Connection struct
func NewConnection(conn net.Conn) Connection {
	return Connection{
		conn:     conn,
		messages: 0,
	}

}

func (connection *Connection) reduceConnectionMessages() {
	connection.messages--
}

// Message called everytime you send a message
func (connection *Connection) Message(channel string, message string) {
	fmt.Fprintf(connection.conn, "PRIVMSG %s :%s\r\n", channel, message)
	connection.messages++
	time.AfterFunc(30*time.Second, connection.reduceConnectionMessages)
}

func (bot *Bot) reduceJoins() {
	bot.joins--
}

// Bot struct for main config
type Bot struct {
	server      string
	groupserver string
	port        string
	oauth       string
	nick        string
	inconn      net.Conn
	mainconn    net.Conn
	connlist    []Connection
	groupconn   net.Conn
	joins       int
	toJoin      []string
}

// NewBot main config
func NewBot() *Bot {
	return &Bot{
		server:      "irc.twitch.tv",
		groupserver: "group.tmi.twitch.tv",
		port:        "6667",
		oauth:       "",
		nick:        "",
		inconn:      nil,
		mainconn:    nil,
		connlist:    make([]Connection, 0),
		groupconn:   nil,
		joins:       0,
	}
}

func (bot *Bot) join(channel string) {
	if bot.joins < 42 {
		fmt.Fprintf(bot.mainconn, "JOIN %s\r\n", channel)
		bot.joins++
		time.AfterFunc(10*time.Second, bot.reduceJoins)
	}
}

// ListenToConnection listen
func (bot *Bot) ListenToConnection(conn net.Conn) {
	reader := bufio.NewReader(conn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			log.Fatal(err)
			break // break loop on errors
		}
		if strings.Contains(line, "PING ") {
			fmt.Fprintf(conn, "PONG tmi.twitch.tv\r\n")
			log.Printf("PONG tmi.twitch.tv\r\n")
		}
		bot.inconn.Write([]byte(line + "\r\n"))
	}
}

// CreateConnection Add a new connection
func (bot *Bot) CreateConnection() (conn net.Conn, err error) {
	conn, err = net.Dial("tcp", bot.server+":"+bot.port)
	if err != nil {
		log.Fatal("unable to connect to IRC server ", err)
		return nil, err
	}
	fmt.Fprintf(conn, "PASS %s\r\n", bot.oauth)
	fmt.Fprintf(conn, "USER %s\r\n", bot.nick)
	fmt.Fprintf(conn, "NICK %s\r\n", bot.nick)
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/tags\r\n")     // enable ircv3 tags
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/commands\r\n") // enable roomstate and such
	log.Printf("new Connected to IRC server %s (%s)\n", bot.server, conn.RemoteAddr())

	connnection := NewConnection(conn)
	bot.connlist = append(bot.connlist, connnection)

	if len(bot.connlist) == 1 {
		bot.mainconn = conn
	}

	go bot.ListenToConnection(conn)

	return conn, nil
}

func main() {
	log.SetOutput(os.Stdout)
	ret := TCPServer()
	log.Printf("got ret code %d\n", ret)
	os.Exit(ret)
}

// Message to send a message
func (bot *Bot) Message(channel string, message string) {
	if message == "" {
		return
	}

	for i := 0; i < len(bot.connlist); i++ {
		if bot.connlist[i].messages < 90 {
			bot.connlist[i].Message(channel, message)
			return
		}
	}
	newConn, _ := bot.CreateConnection()
	fmt.Fprintf(newConn, "PRIVMSG %s :%s\r\n", channel, message)
	log.Println(newConn)
}
<|endoftext|>


<commit_before>/*
 * Minimalist Object Storage, (C) 2015 Minio, Inc.
 *
 * 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"
	"os"
	"os/user"
	"path"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/dustin/go-humanize"
	"github.com/minio-io/cli"
	"github.com/minio-io/minio/pkg/iodine"
	"github.com/minio-io/minio/pkg/server"
	"github.com/minio-io/minio/pkg/server/httpserver"
	"github.com/minio-io/minio/pkg/utils/log"
)

var globalDebugFlag = false

var commands = []cli.Command{
	modeCmd,
}

var modeCommands = []cli.Command{
	memoryCmd,
	donutCmd,
}

var modeCmd = cli.Command{
	Name:        "mode",
	Subcommands: modeCommands,
	Description: "Mode of execution",
}

var memoryCmd = cli.Command{
	Name:        "memory",
	Description: "Limit maximum memory usage to SIZE in [B, KB, MB, GB]",
	Action:      runMemory,
	CustomHelpTemplate: `NAME:
  minio mode {{.Name}} - {{.Description}}

USAGE:
  minio mode {{.Name}} SIZE

EXAMPLES:
  1. Limit maximum memory usage to 64MB
      $ minio mode {{.Name}} 64MB

  2. Limit maximum memory usage to 4GB
      $ minio mode {{.Name}} 4GB
`,
}

var donutCmd = cli.Command{
	Name:        "donut",
	Description: "Specify a path to instantiate donut",
	Action:      runDonut,
	CustomHelpTemplate: `NAME:
  minio mode {{.Name}} - {{.Description}}

USAGE:
  minio mode {{.Name}} PATH

EXAMPLES:
  1. Create a donut volume under "/mnt/backup"
      $ minio mode {{.Name}} /mnt/backup

  2. Create a temporary donut volume under "/tmp"
      $ minio mode {{.Name}} /tmp

  3. Create a donut volume under collection of paths
      $ minio mode {{.Name}} /mnt/backup2014feb /mnt/backup2014feb

`,
}

var flags = []cli.Flag{
	cli.StringFlag{
		Name:  "domain,d",
		Value: "",
		Usage: "domain used for routing incoming API requests",
	},
	cli.StringFlag{
		Name:  "api-address,a",
		Value: ":9000",
		Usage: "address for incoming API requests",
	},
	cli.StringFlag{
		Name:  "web-address,w",
		Value: ":9001",
		Usage: "address for incoming Management UI requests",
	},
	cli.StringFlag{
		Name:  "cert,c",
		Hide:  true,
		Value: "",
		Usage: "cert.pem",
	},
	cli.StringFlag{
		Name:  "key,k",
		Hide:  true,
		Value: "",
		Usage: "key.pem",
	},
	cli.BoolFlag{
		Name:  "debug",
		Usage: "print debug information",
	},
}

func init() {
	// Check for the environment early on and gracefuly report.
	_, err := user.Current()
	if err != nil {
		log.Fatalf("minio: Unable to obtain user's home directory. \nError: %s\n", err)
	}
}

func runMemory(c *cli.Context) {
	if len(c.Args()) < 1 {
		cli.ShowCommandHelpAndExit(c, "memory", 1) // last argument is exit code
	}
	apiServerConfig := getAPIServerConfig(c)
	maxMemory, err := humanize.ParseBytes(c.Args().First())
	if err != nil {
		log.Fatalf("MaxMemory not a numeric value with reason: %s", err)
	}
	memoryDriver := server.MemoryFactory{
		Config:    apiServerConfig,
		MaxMemory: maxMemory,
	}
	apiServer := memoryDriver.GetStartServerFunc()
	webServer := getWebServerConfigFunc(c)
	servers := []server.StartServerFunc{apiServer, webServer}
	server.StartMinio(servers)
}

func runDonut(c *cli.Context) {
	u, err := user.Current()
	if err != nil {
		log.Fatalln(err)
	}
	if len(c.Args()) < 1 {
		cli.ShowCommandHelpAndExit(c, "donut", 1) // last argument is exit code
	}

	// supporting multiple paths
	var paths []string
	if strings.TrimSpace(c.Args().First()) == "" {
		p := path.Join(u.HomeDir, "minio-storage", "donut")
		paths = append(paths, p)
	} else {
		for _, arg := range c.Args() {
			paths = append(paths, strings.TrimSpace(arg))
		}
	}
	apiServerConfig := getAPIServerConfig(c)
	donutDriver := server.DonutFactory{
		Config: apiServerConfig,
		Paths:  paths,
	}
	apiServer := donutDriver.GetStartServerFunc()
	webServer := getWebServerConfigFunc(c)
	servers := []server.StartServerFunc{apiServer, webServer}
	server.StartMinio(servers)
}

func getAPIServerConfig(c *cli.Context) httpserver.Config {
	certFile := c.String("cert")
	keyFile := c.String("key")
	if (certFile != "" && keyFile == "") || (certFile == "" && keyFile != "") {
		log.Fatalln("Both certificate and key must be provided to enable https")
	}
	tls := (certFile != "" && keyFile != "")
	return httpserver.Config{
		Domain:   c.GlobalString("domain"),
		Address:  c.GlobalString("api-address"),
		TLS:      tls,
		CertFile: certFile,
		KeyFile:  keyFile,
	}
}

func getWebServerConfigFunc(c *cli.Context) server.StartServerFunc {
	config := httpserver.Config{
		Domain:   c.GlobalString("domain"),
		Address:  c.GlobalString("web-address"),
		TLS:      false,
		CertFile: "",
		KeyFile:  "",
	}
	webDrivers := server.WebFactory{
		Config: config,
	}
	return webDrivers.GetStartServerFunc()
}

// Tries to get os/arch/platform specific information
// Returns a map of current os/arch/platform/memstats
func getSystemData() map[string]string {
	host, err := os.Hostname()
	if err != nil {
		host = ""
	}
	memstats := &runtime.MemStats{}
	runtime.ReadMemStats(memstats)
	mem := fmt.Sprintf("Used: %s | Allocated: %s | Used-Heap: %s | Allocated-Heap: %s",
		humanize.Bytes(memstats.Alloc),
		humanize.Bytes(memstats.TotalAlloc),
		humanize.Bytes(memstats.HeapAlloc),
		humanize.Bytes(memstats.HeapSys))
	platform := fmt.Sprintf("Host: %s | OS: %s | Arch: %s",
		host,
		runtime.GOOS,
		runtime.GOARCH)
	goruntime := fmt.Sprintf("Version: %s | CPUs: %s", runtime.Version(), strconv.Itoa(runtime.NumCPU()))
	return map[string]string{
		"PLATFORM": platform,
		"RUNTIME":  goruntime,
		"MEM":      mem,
	}
}

// Version is based on MD5SUM of its binary
var Version = mustHashBinarySelf()

// BuildDate - build time
var BuildDate string

func main() {
	// set up iodine
	iodine.SetGlobalState("minio.version", Version)
	iodine.SetGlobalState("minio.starttime", time.Now().Format(time.RFC3339))

	// set up app
	app := cli.NewApp()
	app.Name = "minio"
	app.Version = Version
	app.Compiled, _ = time.Parse(time.RFC3339Nano, BuildDate)
	app.Author = "Minio.io"
	app.Usage = "Minimalist Object Storage"
	app.Flags = flags
	app.Commands = commands
	app.Before = func(c *cli.Context) error {
		globalDebugFlag = c.GlobalBool("debug")
		if globalDebugFlag {
			app.ExtraInfo = getSystemData()
		}
		return nil
	}
	app.RunAndExitOnError()
}
<commit_msg>remove single char args<commit_after>/*
 * Minimalist Object Storage, (C) 2015 Minio, Inc.
 *
 * 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"
	"os"
	"os/user"
	"path"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/dustin/go-humanize"
	"github.com/minio-io/cli"
	"github.com/minio-io/minio/pkg/iodine"
	"github.com/minio-io/minio/pkg/server"
	"github.com/minio-io/minio/pkg/server/httpserver"
	"github.com/minio-io/minio/pkg/utils/log"
)

var globalDebugFlag = false

var commands = []cli.Command{
	modeCmd,
}

var modeCommands = []cli.Command{
	memoryCmd,
	donutCmd,
}

var modeCmd = cli.Command{
	Name:        "mode",
	Subcommands: modeCommands,
	Description: "Mode of execution",
}

var memoryCmd = cli.Command{
	Name:        "memory",
	Description: "Limit maximum memory usage to SIZE in [B, KB, MB, GB]",
	Action:      runMemory,
	CustomHelpTemplate: `NAME:
  minio mode {{.Name}} - {{.Description}}

USAGE:
  minio mode {{.Name}} SIZE

EXAMPLES:
  1. Limit maximum memory usage to 64MB
      $ minio mode {{.Name}} 64MB

  2. Limit maximum memory usage to 4GB
      $ minio mode {{.Name}} 4GB
`,
}

var donutCmd = cli.Command{
	Name:        "donut",
	Description: "Specify a path to instantiate donut",
	Action:      runDonut,
	CustomHelpTemplate: `NAME:
  minio mode {{.Name}} - {{.Description}}

USAGE:
  minio mode {{.Name}} PATH

EXAMPLES:
  1. Create a donut volume under "/mnt/backup"
      $ minio mode {{.Name}} /mnt/backup

  2. Create a temporary donut volume under "/tmp"
      $ minio mode {{.Name}} /tmp

  3. Create a donut volume under collection of paths
      $ minio mode {{.Name}} /mnt/backup2014feb /mnt/backup2014feb

`,
}

var flags = []cli.Flag{
	cli.StringFlag{
		Name:  "domain",
		Value: "",
		Usage: "domain used for routing incoming API requests",
	},
	cli.StringFlag{
		Name:  "port-api",
		Value: ":9000",
		Usage: "address for incoming API requests",
	},
	cli.StringFlag{
		Name:  "port-mgmt",
		Value: ":9001",
		Usage: "address for incoming Management UI requests",
	},
	cli.StringFlag{
		Name:  "cert",
		Hide:  true,
		Value: "",
		Usage: "cert.pem",
	},
	cli.StringFlag{
		Name:  "key",
		Hide:  true,
		Value: "",
		Usage: "key.pem",
	},
	cli.BoolFlag{
		Name:  "debug",
		Usage: "print debug information",
	},
}

func init() {
	// Check for the environment early on and gracefuly report.
	_, err := user.Current()
	if err != nil {
		log.Fatalf("minio: Unable to obtain user's home directory. \nError: %s\n", err)
	}
}

func runMemory(c *cli.Context) {
	if len(c.Args()) < 1 {
		cli.ShowCommandHelpAndExit(c, "memory", 1) // last argument is exit code
	}
	apiServerConfig := getAPIServerConfig(c)
	maxMemory, err := humanize.ParseBytes(c.Args().First())
	if err != nil {
		log.Fatalf("MaxMemory not a numeric value with reason: %s", err)
	}
	memoryDriver := server.MemoryFactory{
		Config:    apiServerConfig,
		MaxMemory: maxMemory,
	}
	apiServer := memoryDriver.GetStartServerFunc()
	webServer := getWebServerConfigFunc(c)
	servers := []server.StartServerFunc{apiServer, webServer}
	server.StartMinio(servers)
}

func runDonut(c *cli.Context) {
	u, err := user.Current()
	if err != nil {
		log.Fatalln(err)
	}
	if len(c.Args()) < 1 {
		cli.ShowCommandHelpAndExit(c, "donut", 1) // last argument is exit code
	}

	// supporting multiple paths
	var paths []string
	if strings.TrimSpace(c.Args().First()) == "" {
		p := path.Join(u.HomeDir, "minio-storage", "donut")
		paths = append(paths, p)
	} else {
		for _, arg := range c.Args() {
			paths = append(paths, strings.TrimSpace(arg))
		}
	}
	apiServerConfig := getAPIServerConfig(c)
	donutDriver := server.DonutFactory{
		Config: apiServerConfig,
		Paths:  paths,
	}
	apiServer := donutDriver.GetStartServerFunc()
	webServer := getWebServerConfigFunc(c)
	servers := []server.StartServerFunc{apiServer, webServer}
	server.StartMinio(servers)
}

func getAPIServerConfig(c *cli.Context) httpserver.Config {
	certFile := c.String("cert")
	keyFile := c.String("key")
	if (certFile != "" && keyFile == "") || (certFile == "" && keyFile != "") {
		log.Fatalln("Both certificate and key must be provided to enable https")
	}
	tls := (certFile != "" && keyFile != "")
	return httpserver.Config{
		Domain:   c.GlobalString("domain"),
		Address:  c.GlobalString("api-address"),
		TLS:      tls,
		CertFile: certFile,
		KeyFile:  keyFile,
	}
}

func getWebServerConfigFunc(c *cli.Context) server.StartServerFunc {
	config := httpserver.Config{
		Domain:   c.GlobalString("domain"),
		Address:  c.GlobalString("web-address"),
		TLS:      false,
		CertFile: "",
		KeyFile:  "",
	}
	webDrivers := server.WebFactory{
		Config: config,
	}
	return webDrivers.GetStartServerFunc()
}

// Tries to get os/arch/platform specific information
// Returns a map of current os/arch/platform/memstats
func getSystemData() map[string]string {
	host, err := os.Hostname()
	if err != nil {
		host = ""
	}
	memstats := &runtime.MemStats{}
	runtime.ReadMemStats(memstats)
	mem := fmt.Sprintf("Used: %s | Allocated: %s | Used-Heap: %s | Allocated-Heap: %s",
		humanize.Bytes(memstats.Alloc),
		humanize.Bytes(memstats.TotalAlloc),
		humanize.Bytes(memstats.HeapAlloc),
		humanize.Bytes(memstats.HeapSys))
	platform := fmt.Sprintf("Host: %s | OS: %s | Arch: %s",
		host,
		runtime.GOOS,
		runtime.GOARCH)
	goruntime := fmt.Sprintf("Version: %s | CPUs: %s", runtime.Version(), strconv.Itoa(runtime.NumCPU()))
	return map[string]string{
		"PLATFORM": platform,
		"RUNTIME":  goruntime,
		"MEM":      mem,
	}
}

// Version is based on MD5SUM of its binary
var Version = mustHashBinarySelf()

// BuildDate - build time
var BuildDate string

func main() {
	// set up iodine
	iodine.SetGlobalState("minio.version", Version)
	iodine.SetGlobalState("minio.starttime", time.Now().Format(time.RFC3339))

	// set up app
	app := cli.NewApp()
	app.Name = "minio"
	app.Version = Version
	app.Compiled, _ = time.Parse(time.RFC3339Nano, BuildDate)
	app.Author = "Minio.io"
	app.Usage = "Minimalist Object Storage"
	app.Flags = flags
	app.Commands = commands
	app.Before = func(c *cli.Context) error {
		globalDebugFlag = c.GlobalBool("debug")
		if globalDebugFlag {
			app.ExtraInfo = getSystemData()
		}
		return nil
	}
	app.RunAndExitOnError()
}
<|endoftext|>


<commit_before>// cosgo is an easy to use contact form *server*, able to be iframed on a static web site.
package main

/*
                           _
  ___ ___  ___  __ _  ___ | |
 / __/ _ \/ __|/ _` |/ _ \| |
| (_| (_) \__ \ (_| | (_) |_|
 \___\___/|___/\__, |\___/(_)
               |___/

https://github.com/aerth/cosgo

*/

// The MIT License (MIT)
//
// Copyright (c) 2016 aerth
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import (
	"flag"
	"fmt"
	"html/template"
	"log"
	"math/rand"
	"net"
	"net/http"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/aerth/mbox"

	"github.com/gorilla/csrf"
	sl "github.com/hydrogen18/stoppableListener"
)

var (
	version          = "0.9.G" // Use makefile for version hash
	destinationEmail = "cosgo@localhost"
	antiCSRFkey      = []byte("LI80PNK1xcT01jmQBsEyxyrNCrbyyFPjPU8CKnxwmCruxNijgnyb3hXXD3p1RBc0+LIRQUUbTtis6hc6LD4I/A==")
	cosgoRefresh     = 42 * time.Minute
	err              error
	hitcounter       int
	timeboot         = time.Now()
	templateDir      = "./templates/"
	cwd              string
	publicKey        []byte
	cosgo            = new(Cosgo)
	// flags
	port            = flag.String("port", "8080", "Port to listen on")
	bind            = flag.String("bind", "0.0.0.0", "Default: 0.0.0.0 (all interfaces)...\n\tTry -bind=127.0.0.1")
	debug           = flag.Bool("debug", false, "More verbose.")
	quiet           = flag.Bool("quiet", false, "Less output. Can be combined with -nolog for absolute silence.")
	nolog           = flag.Bool("nolog", false, "Logs to /dev/null")
	gpg             = flag.String("gpg", "", "Path to ascii-armored GPG public key (for encrypting messages.)")
	customExtension = flag.String("ext", "", "Serve extra static files. Uses regex. \n\tExample: -ext \"pdf|txt|html\"")
	sendgridKey     = flag.String("sg", "", "Sendgrid API key (disables mbox)")
	digest          = flag.String("digest", "", "Set to a time of day (or night) to consolidate messages into one big one)")
	logfile         = flag.String("log", "", "Use a log file instead of stdout\n\tExample: -log cosgo.log -debug")
	mboxfile        = flag.String("mbox", "cosgo.mbox", "Custom mbox file name\n\tExample: -mbox custom.mbox")
)

// Cosgo struct holds the Boottime and
type Cosgo struct {
	URLKey   string
	Visitors int
}

func main() {
	if !*quiet {
		fmt.Println(logo)
		fmt.Printf("\n\tcosgo v" + version + "\n")
		fmt.Printf("\tCopyright 2016 aerth\n\tSource code at https://github.com/aerth/cosgo\n")
	}
	timeboot, cwd, staticDir, templatesDir := initialize()
	r := route(cwd, staticDir)
	//	http.Handle("/", r)

	if *debug && !*quiet {
		log.Println("booted:", timeboot)
		log.Println("working dir:", cwd)
		log.Println("css/js/img dir:", staticDir)
		log.Println("cosgo templates dir:", templatesDir)
	}
	// Fire up the cosgo engine
	go func() {
		for {
			if *debug && !*quiet {
				log.Println("Info: Generating Random 40 URL Key...")
			}
			// set a random URL key (40 char length)
			cosgo.URLKey = generateURLKey(40)
			if *debug && !*quiet {
				log.Printf("Info: URL Key is " + cosgo.URLKey + "\n")
			}
			// every X minutes
			time.Sleep(cosgoRefresh)
		}
	}()

	if *sendgridKey != "" {
		*mboxfile = os.DevNull
	}
	f, err := os.OpenFile(*mboxfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
	if err != nil {
		log.Printf("error opening file: %v", err)
		log.Fatal("Hint: touch ./cosgo.mbox, or chown/chmod it so that the cosgo process can access it.")
		os.Exit(1)
	}
	mbox.Destination = destinationEmail
	mbox.Mail = log.New(f, "", 0)
	if *nolog {
		*logfile = os.DevNull
	}
	// Switch to cosgo.log if not debug
	if *logfile != "" {
		openLogFile()
	}

	// Start serving
	oglistener, binderr := net.Listen("tcp", *bind+":"+*port)
	if binderr != nil {
		log.Println(binderr)
		os.Exit(1)
	}
	listener, stoperr := sl.New(oglistener)
	if stoperr != nil {
		log.Println(stoperr)
		os.Exit(1)
	}
	if *debug && !*quiet {
		log.Printf("Info: Got listener %s %s", listener.Addr().String(), listener.Addr().Network())
	}
	// Start Serving Loop
	for {
		listener, err = sl.New(oglistener)
		if err != nil {
			log.Fatalln(err)
		}
		go func() {
			if listener != nil {
				go http.Serve(listener,
					csrf.Protect(antiCSRFkey,
						csrf.HttpOnly(true),
						csrf.FieldName("cosgo"),
						csrf.CookieName("cosgo"),
						csrf.Secure(false))(r))
			} else {
				log.Fatalln("nil listener")
			}

		}()
		// End the for-loop with a timer/hit counter
		select {
		default:
			if !*quiet {
				log.Printf("Uptime: %s", time.Since(timeboot))
				log.Printf("Hits: %s", strconv.Itoa(hitcounter))
			}
			time.Sleep(time.Minute * 30)
		}

	}
}

var logo = `
                           _
  ___ ___  ___  __ _  ___ | |
 / __/ _ \/ __|/ _  |/ _ \| |
| (_| (_) \__ \ (_| | (_) |_|
 \___\___/|___/\__, |\___/(_)
               |___/
`

func init() {

	// Key Generator
	rand.Seed(time.Now().UnixNano())

	// Hopefully a clean exit
	interrupt := make(chan os.Signal, 1)
	stop := make(chan os.Signal, 1)
	reload := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)
	signal.Notify(stop, syscall.SIGINT)
	signal.Notify(reload, syscall.SIGHUP)
	go func() {
		select {
		case signal := <-interrupt:
			fmt.Println("Got signal:", signal)
			fmt.Println("Dying")
			os.Exit(0)
		case signal := <-reload:
			fmt.Println("Got signal:", signal)
			fmt.Println("Dying")
			os.Exit(0)
		case signal := <-stop:
			fmt.Printf("Got signal:%v\n", signal)
			fmt.Println("Dying")
			os.Exit(0)
		}
	}()
	flag.Parse()

}

//openLogFile switches the log engine to a file, rather than stdout.
func openLogFile() {
	if *logfile == "" {
		return
	}
	f, err := os.OpenFile(*logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
	if err != nil {
		log.Printf("error opening file: %v", err)
		log.Fatal("Hint: touch " + *logfile + ", or chown/chmod it so that the cosgo process can access it.")
		os.Exit(1)
	}
	log.SetOutput(f)
}

func initialize() (time.Time, string, string, string) {

	// Load environmental variables as flags
	if os.Getenv("COSGO_PORT") == "" {
		*port = os.Getenv("COSGO_PORT")
	}

	if os.Getenv("COSGO_BIND") == "" {
		*bind = os.Getenv("COSGO_BIND")
	}

	if os.Getenv("COSGO_REFRESH") == "" {
		cosgoRefresh = os.Getenv("COSGO_REFRESH")
	}

	if os.Getenv("COSGO_GPG") == "" {
		*gpg = os.Getenv("COSGO_GPG")
	}
	if *gpg != "" {
		log.Println("\t[gpg pubkey: " + *gpg + "]")
		publicKey = read2mem(rel2real(*gpg))
	}
	timeboot := time.Now()
	cwd, _ := os.Getwd()
	staticDir := staticFinder(cwd)
	templatesDir := templateFinder()

	if *digest != "" && *sendgridKey == "" {
		log.Fatalln("Check flags. Can't use -digest without -sg. Show usage with cosgo -h")
	}

	return timeboot, cwd, staticDir, templatesDir

}

// templateFinder returns the template directory we will use, if one isn't found, the error is fatal.
func templateFinder() string {
	templateDir := "./templates/"
	if *debug && !*quiet {
		log.Printf("Trying ./templates/")
	}
	_, notlocal := template.New("Index").ParseFiles(templateDir + "index.html")
	if notlocal != nil {
		if *debug && !*quiet {
			log.Println(notlocal)
			log.Printf("...Trying /usr/local/share/cosgo/templates/")
		}
		_, notglobal := template.New("Index").ParseFiles("/usr/local/share/cosgo/templates/index.html")
		if notglobal != nil {
			if *debug && !*quiet {
				log.Printf("...No templatesDir found, creating one.")
			}
			RestoreAssets(".", "templates")
		} else {
			if *debug && !*quiet {
				log.Println("Using /usr/local/share/cosgo/templates directory")
			}
			return "/usr/local/share/cosgo/templates/"
		}
	}
	if *debug && !*quiet {
		log.Printf("Using %s directory\n", templateDir)
	}
	return templateDir
}

// staticFinder returns the static directory. If none is found, static files are disabled.
func staticFinder(cwd string) string {
	staticDir := "./static/"
	_, err = os.Open(staticDir)
	if err != nil {
		if os.IsNotExist(err) {
			staticDir = "/usr/local/share/cosgo/static/"
			_, err = os.Open(staticDir)
			if err != nil {
				if os.IsNotExist(err) {
					if *debug {
						log.Printf("No staticDir. Creating one.")
					}
					RestoreAssets(".", "static")
					staticDir = "./static/"
				}
			}
		}
	}

	return staticDir
}

func getKey() string {
	return cosgo.URLKey
}
func getDestination() string {
	return destinationEmail
}

func read2mem(abspath string) []byte {
	file, err := os.Open(abspath) // For read access.
	if err != nil {
		log.Fatal(err)
	}

	data := make([]byte, 4096)
	_, err = file.Read(data)
	if err != nil {
		log.Fatal(err)
	}

	return data

}
func rel2real(file string) (realpath string) {
	pathdir, _ := path.Split(file)

	if pathdir == "" {
		realpath, _ = filepath.Abs(file)
	} else {
		realpath = file
	}
	return realpath
}

// getDomain returns the domain name (without port) of a request.
func getDomain(r *http.Request) string {
	type Domains map[string]http.Handler
	hostparts := strings.Split(r.Host, ":")
	requesthost := hostparts[0]
	return requesthost
}

// getSubdomain returns the subdomain (if any)
func getSubdomain(r *http.Request) string {
	type Subdomains map[string]http.Handler
	hostparts := strings.Split(r.Host, ":")
	requesthost := hostparts[0]
	if net.ParseIP(requesthost) == nil {
		//log.Println("Info: " + requesthost)
		domainParts := strings.Split(requesthost, ".")
		if len(domainParts) > 2 {
			if domainParts[0] != "127" {
				return domainParts[0]
			}
		}
	}
	return ""
}

//generateURLKey creates a new key, with the given runes, n length.
func generateURLKey(n int) string {
	runes := []rune("____ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890123456789012345678901234567890")
	b := make([]rune, n)
	for i := range b {
		b[i] = runes[rand.Intn(len(runes))]
	}
	return strings.TrimSpace(string(b))
}
<commit_msg>parse time<commit_after>// cosgo is an easy to use contact form *server*, able to be iframed on a static web site.
package main

/*
                           _
  ___ ___  ___  __ _  ___ | |
 / __/ _ \/ __|/ _` |/ _ \| |
| (_| (_) \__ \ (_| | (_) |_|
 \___\___/|___/\__, |\___/(_)
               |___/

https://github.com/aerth/cosgo

*/

// The MIT License (MIT)
//
// Copyright (c) 2016 aerth
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import (
	"flag"
	"fmt"
	"html/template"
	"log"
	"math/rand"
	"net"
	"net/http"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/aerth/mbox"

	"github.com/gorilla/csrf"
	sl "github.com/hydrogen18/stoppableListener"
)

var (
	version          = "0.9.G" // Use makefile for version hash
	destinationEmail = "cosgo@localhost"
	antiCSRFkey      = []byte("LI80PNK1xcT01jmQBsEyxyrNCrbyyFPjPU8CKnxwmCruxNijgnyb3hXXD3p1RBc0+LIRQUUbTtis6hc6LD4I/A==")
	cosgoRefresh     = 42 * time.Minute
	err              error
	hitcounter       int
	timeboot         = time.Now()
	templateDir      = "./templates/"
	cwd              string
	publicKey        []byte
	cosgo            = new(Cosgo)
	// flags
	port            = flag.String("port", "8080", "Port to listen on")
	bind            = flag.String("bind", "0.0.0.0", "Default: 0.0.0.0 (all interfaces)...\n\tTry -bind=127.0.0.1")
	debug           = flag.Bool("debug", false, "More verbose.")
	quiet           = flag.Bool("quiet", false, "Less output. Can be combined with -nolog for absolute silence.")
	nolog           = flag.Bool("nolog", false, "Logs to /dev/null")
	gpg             = flag.String("gpg", "", "Path to ascii-armored GPG public key (for encrypting messages.)")
	customExtension = flag.String("ext", "", "Serve extra static files. Uses regex. \n\tExample: -ext \"pdf|txt|html\"")
	sendgridKey     = flag.String("sg", "", "Sendgrid API key (disables mbox)")
	digest          = flag.String("digest", "", "Set to a time of day (or night) to consolidate messages into one big one)")
	logfile         = flag.String("log", "", "Use a log file instead of stdout\n\tExample: -log cosgo.log -debug")
	mboxfile        = flag.String("mbox", "cosgo.mbox", "Custom mbox file name\n\tExample: -mbox custom.mbox")
)

// Cosgo struct holds the Boottime and
type Cosgo struct {
	URLKey   string
	Visitors int
}

func main() {
	if !*quiet {
		fmt.Println(logo)
		fmt.Printf("\n\tcosgo v" + version + "\n")
		fmt.Printf("\tCopyright 2016 aerth\n\tSource code at https://github.com/aerth/cosgo\n")
	}
	timeboot, cwd, staticDir, templatesDir := initialize()
	r := route(cwd, staticDir)
	//	http.Handle("/", r)

	if *debug && !*quiet {
		log.Println("booted:", timeboot)
		log.Println("working dir:", cwd)
		log.Println("css/js/img dir:", staticDir)
		log.Println("cosgo templates dir:", templatesDir)
	}
	// Fire up the cosgo engine
	go func() {
		for {
			if *debug && !*quiet {
				log.Println("Info: Generating Random 40 URL Key...")
			}
			// set a random URL key (40 char length)
			cosgo.URLKey = generateURLKey(40)
			if *debug && !*quiet {
				log.Printf("Info: URL Key is " + cosgo.URLKey + "\n")
			}
			// every X minutes
			time.Sleep(cosgoRefresh)
		}
	}()

	if *sendgridKey != "" {
		*mboxfile = os.DevNull
	}
	f, err := os.OpenFile(*mboxfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
	if err != nil {
		log.Printf("error opening file: %v", err)
		log.Fatal("Hint: touch ./cosgo.mbox, or chown/chmod it so that the cosgo process can access it.")
		os.Exit(1)
	}
	mbox.Destination = destinationEmail
	mbox.Mail = log.New(f, "", 0)
	if *nolog {
		*logfile = os.DevNull
	}
	// Switch to cosgo.log if not debug
	if *logfile != "" {
		openLogFile()
	}

	// Start serving
	oglistener, binderr := net.Listen("tcp", *bind+":"+*port)
	if binderr != nil {
		log.Println(binderr)
		os.Exit(1)
	}
	listener, stoperr := sl.New(oglistener)
	if stoperr != nil {
		log.Println(stoperr)
		os.Exit(1)
	}
	if *debug && !*quiet {
		log.Printf("Info: Got listener %s %s", listener.Addr().String(), listener.Addr().Network())
	}
	// Start Serving Loop
	for {
		listener, err = sl.New(oglistener)
		if err != nil {
			log.Fatalln(err)
		}
		go func() {
			if listener != nil {
				go http.Serve(listener,
					csrf.Protect(antiCSRFkey,
						csrf.HttpOnly(true),
						csrf.FieldName("cosgo"),
						csrf.CookieName("cosgo"),
						csrf.Secure(false))(r))
			} else {
				log.Fatalln("nil listener")
			}

		}()
		// End the for-loop with a timer/hit counter
		select {
		default:
			if !*quiet {
				log.Printf("Uptime: %s", time.Since(timeboot))
				log.Printf("Hits: %s", strconv.Itoa(hitcounter))
			}
			time.Sleep(time.Minute * 30)
		}

	}
}

var logo = `
                           _
  ___ ___  ___  __ _  ___ | |
 / __/ _ \/ __|/ _  |/ _ \| |
| (_| (_) \__ \ (_| | (_) |_|
 \___\___/|___/\__, |\___/(_)
               |___/
`

func init() {

	// Key Generator
	rand.Seed(time.Now().UnixNano())

	// Hopefully a clean exit
	interrupt := make(chan os.Signal, 1)
	stop := make(chan os.Signal, 1)
	reload := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)
	signal.Notify(stop, syscall.SIGINT)
	signal.Notify(reload, syscall.SIGHUP)
	go func() {
		select {
		case signal := <-interrupt:
			fmt.Println("Got signal:", signal)
			fmt.Println("Dying")
			os.Exit(0)
		case signal := <-reload:
			fmt.Println("Got signal:", signal)
			fmt.Println("Dying")
			os.Exit(0)
		case signal := <-stop:
			fmt.Printf("Got signal:%v\n", signal)
			fmt.Println("Dying")
			os.Exit(0)
		}
	}()
	flag.Parse()

}

//openLogFile switches the log engine to a file, rather than stdout.
func openLogFile() {
	if *logfile == "" {
		return
	}
	f, err := os.OpenFile(*logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
	if err != nil {
		log.Printf("error opening file: %v", err)
		log.Fatal("Hint: touch " + *logfile + ", or chown/chmod it so that the cosgo process can access it.")
		os.Exit(1)
	}
	log.SetOutput(f)
}

func initialize() (time.Time, string, string, string) {

	// Load environmental variables as flags
	if os.Getenv("COSGO_PORT") == "" {
		*port = os.Getenv("COSGO_PORT")
	}

	if os.Getenv("COSGO_BIND") == "" {
		*bind = os.Getenv("COSGO_BIND")
	}

	if os.Getenv("COSGO_REFRESH") == "" {
		cosgoRefresh, err = time.ParseDuration(os.Getenv("COSGO_REFRESH"))
		if err != nil {
			log.Fatalln(err)
		}
	}

	if os.Getenv("COSGO_GPG") == "" {
		*gpg = os.Getenv("COSGO_GPG")
	}
	if *gpg != "" {
		log.Println("\t[gpg pubkey: " + *gpg + "]")
		publicKey = read2mem(rel2real(*gpg))
	}
	timeboot := time.Now()
	cwd, _ := os.Getwd()
	staticDir := staticFinder(cwd)
	templatesDir := templateFinder()

	if *digest != "" && *sendgridKey == "" {
		log.Fatalln("Check flags. Can't use -digest without -sg. Show usage with cosgo -h")
	}

	return timeboot, cwd, staticDir, templatesDir

}

// templateFinder returns the template directory we will use, if one isn't found, the error is fatal.
func templateFinder() string {
	templateDir := "./templates/"
	if *debug && !*quiet {
		log.Printf("Trying ./templates/")
	}
	_, notlocal := template.New("Index").ParseFiles(templateDir + "index.html")
	if notlocal != nil {
		if *debug && !*quiet {
			log.Println(notlocal)
			log.Printf("...Trying /usr/local/share/cosgo/templates/")
		}
		_, notglobal := template.New("Index").ParseFiles("/usr/local/share/cosgo/templates/index.html")
		if notglobal != nil {
			if *debug && !*quiet {
				log.Printf("...No templatesDir found, creating one.")
			}
			RestoreAssets(".", "templates")
		} else {
			if *debug && !*quiet {
				log.Println("Using /usr/local/share/cosgo/templates directory")
			}
			return "/usr/local/share/cosgo/templates/"
		}
	}
	if *debug && !*quiet {
		log.Printf("Using %s directory\n", templateDir)
	}
	return templateDir
}

// staticFinder returns the static directory. If none is found, static files are disabled.
func staticFinder(cwd string) string {
	staticDir := "./static/"
	_, err = os.Open(staticDir)
	if err != nil {
		if os.IsNotExist(err) {
			staticDir = "/usr/local/share/cosgo/static/"
			_, err = os.Open(staticDir)
			if err != nil {
				if os.IsNotExist(err) {
					if *debug {
						log.Printf("No staticDir. Creating one.")
					}
					RestoreAssets(".", "static")
					staticDir = "./static/"
				}
			}
		}
	}

	return staticDir
}

func getKey() string {
	return cosgo.URLKey
}
func getDestination() string {
	return destinationEmail
}

func read2mem(abspath string) []byte {
	file, err := os.Open(abspath) // For read access.
	if err != nil {
		log.Fatal(err)
	}

	data := make([]byte, 4096)
	_, err = file.Read(data)
	if err != nil {
		log.Fatal(err)
	}

	return data

}
func rel2real(file string) (realpath string) {
	pathdir, _ := path.Split(file)

	if pathdir == "" {
		realpath, _ = filepath.Abs(file)
	} else {
		realpath = file
	}
	return realpath
}

// getDomain returns the domain name (without port) of a request.
func getDomain(r *http.Request) string {
	type Domains map[string]http.Handler
	hostparts := strings.Split(r.Host, ":")
	requesthost := hostparts[0]
	return requesthost
}

// getSubdomain returns the subdomain (if any)
func getSubdomain(r *http.Request) string {
	type Subdomains map[string]http.Handler
	hostparts := strings.Split(r.Host, ":")
	requesthost := hostparts[0]
	if net.ParseIP(requesthost) == nil {
		//log.Println("Info: " + requesthost)
		domainParts := strings.Split(requesthost, ".")
		if len(domainParts) > 2 {
			if domainParts[0] != "127" {
				return domainParts[0]
			}
		}
	}
	return ""
}

//generateURLKey creates a new key, with the given runes, n length.
func generateURLKey(n int) string {
	runes := []rune("____ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890123456789012345678901234567890")
	b := make([]rune, n)
	for i := range b {
		b[i] = runes[rand.Intn(len(runes))]
	}
	return strings.TrimSpace(string(b))
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"os/exec"

	"github.com/nu7hatch/gouuid"
)

type check struct {
	Id  string `json:"id"`
	Url string `json:"url"`
}

// {"url": "http://github.com", "connect_time": 0.031178999999999998, "exit_status": 0, "starttransfer_time": 0.031178999999999998, "t": 1397688864, "local_ip": "107.170.123.131", "primary_ip": "192.30.252.128", "total_time": 0.037648000000000001, "http_status": 301, "namelookup_time": 0.024646000000000001, "local_port": 53858}
type measurement struct {
	Id                string  `json:"id"`
	CheckId           string  `json:"check_id"`
	Location          string  `json:"location"`
	Url               string  `json:"url"`
	ConnectTime       float64 `json:"connect_time"`
	ExitStatus        int     `json:"exit_status"`
	StartTransferTime float64 `json:"starttransfer_time"`
	T                 int     `json:"t"`
	LocalIp           string  `json:"local_ip"`
	PrimaryIp         string  `json:"primary_ip"`
	TotalTime         float64 `json:"total_time"`
	HttpStatus        int     `json:"http_status"`
	NameLookupTime    float64 `json:"namelookup_time"`
}

func curly(url string) []byte {
	cmd := exec.Command("curly", url)
	out, err := cmd.Output()
	if err != nil {
		panic(err)
	}

	return out
}

func measure(c check) measurement {
	s := curly(c.Url)

	var m measurement
	if err := json.Unmarshal(s, &m); err != nil {
		panic(err)
	}

	id, _ := uuid.NewV4()
	m.Id = id.String()
	m.CheckId = c.Id

	return m
}

func main() {
	var c check
	c.Id = "1"
	c.Url = "http://github.com"

	foo := measure(c)

	s, err := json.Marshal(foo)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s\n", s)
}
<commit_msg>measure and send the result on to redis<commit_after>package main

import (
	"encoding/json"
	"os/exec"

	"github.com/nu7hatch/gouuid"
	"github.com/vmihailenco/redis/v2"
)

type check struct {
	Id  string `json:"id"`
	Url string `json:"url"`
}

// {"url": "http://github.com", "connect_time": 0.031178999999999998, "exit_status": 0, "starttransfer_time": 0.031178999999999998, "t": 1397688864, "local_ip": "107.170.123.131", "primary_ip": "192.30.252.128", "total_time": 0.037648000000000001, "http_status": 301, "namelookup_time": 0.024646000000000001, "local_port": 53858}
type measurement struct {
	Id                string  `json:"id"`
	CheckId           string  `json:"check_id"`
	Location          string  `json:"location"`
	Url               string  `json:"url"`
	ConnectTime       float64 `json:"connect_time"`
	ExitStatus        int     `json:"exit_status"`
	StartTransferTime float64 `json:"starttransfer_time"`
	T                 int     `json:"t"`
	LocalIp           string  `json:"local_ip"`
	PrimaryIp         string  `json:"primary_ip"`
	TotalTime         float64 `json:"total_time"`
	HttpStatus        int     `json:"http_status"`
	NameLookupTime    float64 `json:"namelookup_time"`
}

func curly(url string) []byte {
	cmd := exec.Command("curly", url)
	out, err := cmd.Output()
	if err != nil {
		panic(err)
	}

	return out
}

func measure(c check) measurement {
	s := curly(c.Url)

	var m measurement
	if err := json.Unmarshal(s, &m); err != nil {
		panic(err)
	}

	id, _ := uuid.NewV4()
	m.Id = id.String()
	m.CheckId = c.Id

	return m
}

func main() {
	client := redis.NewTCPClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})
	defer client.Close()

	var c check
	c.Id = "1"
	c.Url = "http://github.com"

	foo := measure(c)

	s, err := json.Marshal(foo)
	if err != nil {
		panic(err)
	}

	client.LPush("measurements", string(s))
}
<|endoftext|>


<commit_before>// vim: ts=4 sts=4 sw=4
package main

import (
	"fmt"
	"time"
	"github.com/ofavre/calcgraph/executor"
	"github.com/ofavre/calcgraph/nodes"
)

//////////
// Main //
//////////

func main() {
	executor := executor.New()

	obsChan := nodes.GoPrintObs(executor)

	var v1 nodes.Node = nodes.LoopNode(executor, nodes.NewConstantNode(int(1)))
	fmt.Printf("%v\n", v1)
	var o1 nodes.Node = nodes.LoopNode(executor, nodes.NewObserverNode(obsChan, v1))
	fmt.Printf("%v\n", o1)
	var v2 nodes.Node = nodes.LoopNode(executor, nodes.NewConstantNode(int(2)))
	fmt.Printf("%v\n", v2)
	var o2 nodes.Node = nodes.LoopNode(executor, nodes.NewObserverNode(obsChan, v2))
	fmt.Printf("%v\n", o2)
	var c1 nodes.Node = nodes.LoopNode(executor, nodes.NewAddNode(nil, o1, o2))
	fmt.Printf("%v\n", c1)
	var o3 nodes.Node = nodes.LoopNode(executor, nodes.NewObserverNode(obsChan, c1))
	fmt.Printf("%v\n", o3)
	var c2 nodes.Node = nodes.LoopNode(executor, nodes.NewSubNode(nil, o1, o3))
	fmt.Printf("%v\n", c2)
	var o4 nodes.Node = nodes.LoopNode(executor, nodes.NewObserverNode(obsChan, c2))
	fmt.Printf("%v\n", o4)
	var c3 nodes.Node = nodes.LoopNode(executor, nodes.NewMulNode(nil, o3, o4))
	fmt.Printf("%v\n", c2)
	var o5 nodes.Node = nodes.LoopNode(executor, nodes.NewObserverNode(obsChan, c3))
	fmt.Printf("%v\n", o4)
	var c4 nodes.Node = nodes.LoopNode(executor, nodes.NewFanInNode(o3, o4, o5))
	fmt.Printf("%v\n", c4)
	var o6 nodes.Node = nodes.LoopNode(executor, nodes.NewObserverNode(obsChan, c4))
	fmt.Printf("%v\n", o6)
	var s1 nodes.Node = nodes.LoopNode(executor, nodes.NewSinkNode(o6))
	fmt.Printf("%v\n", s1)

	time.Sleep(2 * time.Millisecond)
	executor.Interrupt()
	fmt.Println("Quitting")
}
<commit_msg>Keep only one Observer for more clarity in the output<commit_after>// vim: ts=4 sts=4 sw=4
package main

import (
	"fmt"
	"time"
	"github.com/ofavre/calcgraph/executor"
	"github.com/ofavre/calcgraph/nodes"
)

//////////
// Main //
//////////

func main() {
	executor := executor.New()

	obsChan := nodes.GoPrintObs(executor)

	var v1 nodes.Node = nodes.LoopNode(executor, nodes.NewConstantNode(int(1)))
	fmt.Printf("%v\n", v1)
	var v2 nodes.Node = nodes.LoopNode(executor, nodes.NewConstantNode(int(2)))
	fmt.Printf("%v\n", v2)
	var c1 nodes.Node = nodes.LoopNode(executor, nodes.NewAddNode(nil, v1, v2))
	fmt.Printf("%v\n", c1)
	var c2 nodes.Node = nodes.LoopNode(executor, nodes.NewSubNode(nil, v1, c1))
	fmt.Printf("%v\n", c2)
	var c3 nodes.Node = nodes.LoopNode(executor, nodes.NewMulNode(nil, c1, c2))
	fmt.Printf("%v\n", c2)
	var c4 nodes.Node = nodes.LoopNode(executor, nodes.NewFanInNode(c1, c2, c3))
	fmt.Printf("%v\n", c4)
	var o nodes.Node = nodes.LoopNode(executor, nodes.NewObserverNode(obsChan, c4))
	fmt.Printf("%v\n", o)
	var s1 nodes.Node = nodes.LoopNode(executor, nodes.NewSinkNode(o))
	fmt.Printf("%v\n", s1)

	time.Sleep(2 * time.Millisecond)
	executor.Interrupt()
	fmt.Println("Quitting")
}
<|endoftext|>