<commit_before>package mplinux

import (
	"os"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestCollectWho(t *testing.T) {
	_, err := os.Stat("/usr/bin/who")
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectWho(&p))
}

func TestParseWho(t *testing.T) {
	stub := `test0  pts/48       2014-09-30 08:00 (192.168.24.123)
test1  pts/48       2014-09-30 08:59 (192.168.24.123)
test2  pts/48       2014-09-30 09:00 (192.168.24.123)`
	stat := make(map[string]interface{})

	err := parseWho(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["users"], 3)
}

func TestParseWho2(t *testing.T) {
	stub := ""
	stat := make(map[string]interface{})

	err := parseWho(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["users"], 0)
}

func TestGetWho(t *testing.T) {
	_, err := os.Stat("/usr/sbin/who")
	if err != nil {
		return
	}

	ret, err := getWho()
	assert.Nil(t, err)
	assert.NotNil(t, ret)
}

func TestCollectStat(t *testing.T) {
	path := "/proc/stat"
	_, err := os.Stat(path)
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectProcStat(path, &p))
}

func TestParseProcStat(t *testing.T) {
	stub := `intr 614818624 122 8 0 0 1 0 0 0 1 0 0 0 123 0 0 0 0 0 0 0 0 0 0 0 4846888 0 44650320 253 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 ctxt 879305394
 btime 1409212617
 processes 1959410`
	stat := make(map[string]interface{})

	err := parseProcStat(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["interrupts"], 614818624)
	assert.EqualValues(t, stat["context_switches"], 879305394)
	assert.EqualValues(t, stat["forks"], 1959410)
}

func TestCollectProcDiskstats(t *testing.T) {
	path := "/proc/diskstats"
	_, err := os.Stat(path)
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectProcDiskstats(path, &p))
}

func TestParseProcDiskstats(t *testing.T) {
	stub := `   1       0 ram0 0 0 0 0 0 0 0 0 0 0 0
   8       0 sda 324351 303093 35032074 12441261 4456146 5387174 68639686 423711425 0 23865772 436201338
   8       1 sda1 678 405 10970 4696 276 22946 46462 1217036 0 53528 1221732
 253       2 dm-2 83 0 664 94 0 0 0 0 0 94 94`
	stat := make(map[string]interface{})

	err := parseProcDiskstats(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["iotime_sda"], 23865772)
	assert.EqualValues(t, stat["iotime_weighted_sda"], 436201338)
	assert.EqualValues(t, stat["tsreading_sda"], 12441261)
	assert.EqualValues(t, stat["tswriting_sda"], 423711425)
}

func TestCollectSs(t *testing.T) {
	_, err := os.Stat("/usr/sbin/ss")
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectSs(&p))
}

func TestParseSs(t *testing.T) {
	stub := `State      Recv-Q Send-Q                       Local Address:Port                         Peer Address:Port
LISTEN     0      128                                     :::45103                                  :::*
LISTEN     0      128                                     :::111                                    :::*
TIME-WAIT  0      0                         ::ffff:127.0.0.1:80                       ::ffff:127.0.0.1:50082
ESTAB      0      0                              10.0.25.101:60826                         10.0.25.104:5672  `
	stat := make(map[string]interface{})

	err := parseSs(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["LISTEN"], 2)
	assert.EqualValues(t, stat["TIME-WAIT"], 1)
	assert.EqualValues(t, stat["ESTAB"], 1)
}

func TestParseSs2(t *testing.T) {
	stub := `Netid State      Recv-Q Send-Q                                      Local Address:Port                                        Peer Address:Port
nl    UNCONN     0      0                                                      18:0                                                       *
p_raw UNCONN     0      0                                                       *:em2                                                     *
u_dgr UNCONN     0      0                                                /dev/log 10549                                                  * 0
u_dgr LISTEN     0      0                                       /run/udev/control 8552                                                   * 0
u_str LISTEN     0      10                                  /var/run/acpid.socket 9649                                                   * 0
u_str ESTAB      0      0                                    @/com/ubuntu/upstart 10582                                                  * 1887`
	stat := make(map[string]interface{})

	err := parseSs(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["LISTEN"], 2)
	assert.EqualValues(t, stat["UNCONN"], 3)
	assert.EqualValues(t, stat["ESTAB"], 1)
}

func TestGetSs(t *testing.T) {
	_, err := os.Stat("/usr/sbin/ss")
	if err != nil {
		return
	}

	ret, err := getSs()
	assert.Nil(t, err)
	assert.NotNil(t, ret)
	assert.Contains(t, ret, "State")
}

func TestCollectProcVmstat(t *testing.T) {
	path := "/proc/vmstat"
	_, err := os.Stat(path)
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectProcVmstat(path, &p))
}

func TestParseProcVmstat(t *testing.T) {
	stub := `pgpgin 770294
pgpgout 31351354
pswpin 0
pswpout 113`
	stat := make(map[string]interface{})

	err := parseProcVmstat(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["pgpgin"], 770294)
	assert.EqualValues(t, stat["pgpgout"], 31351354)
	assert.EqualValues(t, stat["pswpin"], 0)
	assert.EqualValues(t, stat["pswpout"], 113)
}

func TestGetProc(t *testing.T) {
	stub := "/proc/diskstats"
	_, err := os.Stat(stub)
	if err != nil {
		return
	}

	ret, err := getProc(stub)
	assert.Nil(t, err)
	assert.NotNil(t, ret)
	assert.Contains(t, ret, "ram0")
}
<commit_msg>Remove a test which is not necessary and may fall sometimes<commit_after>package mplinux

import (
	"os"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestCollectWho(t *testing.T) {
	_, err := os.Stat("/usr/bin/who")
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectWho(&p))
}

func TestParseWho(t *testing.T) {
	stub := `test0  pts/48       2014-09-30 08:00 (192.168.24.123)
test1  pts/48       2014-09-30 08:59 (192.168.24.123)
test2  pts/48       2014-09-30 09:00 (192.168.24.123)`
	stat := make(map[string]interface{})

	err := parseWho(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["users"], 3)
}

func TestParseWho2(t *testing.T) {
	stub := ""
	stat := make(map[string]interface{})

	err := parseWho(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["users"], 0)
}

func TestGetWho(t *testing.T) {
	_, err := os.Stat("/usr/sbin/who")
	if err != nil {
		return
	}

	ret, err := getWho()
	assert.Nil(t, err)
	assert.NotNil(t, ret)
}

func TestCollectStat(t *testing.T) {
	path := "/proc/stat"
	_, err := os.Stat(path)
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectProcStat(path, &p))
}

func TestParseProcStat(t *testing.T) {
	stub := `intr 614818624 122 8 0 0 1 0 0 0 1 0 0 0 123 0 0 0 0 0 0 0 0 0 0 0 4846888 0 44650320 253 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 ctxt 879305394
 btime 1409212617
 processes 1959410`
	stat := make(map[string]interface{})

	err := parseProcStat(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["interrupts"], 614818624)
	assert.EqualValues(t, stat["context_switches"], 879305394)
	assert.EqualValues(t, stat["forks"], 1959410)
}

func TestCollectProcDiskstats(t *testing.T) {
	path := "/proc/diskstats"
	_, err := os.Stat(path)
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectProcDiskstats(path, &p))
}

func TestParseProcDiskstats(t *testing.T) {
	stub := `   1       0 ram0 0 0 0 0 0 0 0 0 0 0 0
   8       0 sda 324351 303093 35032074 12441261 4456146 5387174 68639686 423711425 0 23865772 436201338
   8       1 sda1 678 405 10970 4696 276 22946 46462 1217036 0 53528 1221732
 253       2 dm-2 83 0 664 94 0 0 0 0 0 94 94`
	stat := make(map[string]interface{})

	err := parseProcDiskstats(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["iotime_sda"], 23865772)
	assert.EqualValues(t, stat["iotime_weighted_sda"], 436201338)
	assert.EqualValues(t, stat["tsreading_sda"], 12441261)
	assert.EqualValues(t, stat["tswriting_sda"], 423711425)
}

func TestCollectSs(t *testing.T) {
	_, err := os.Stat("/usr/sbin/ss")
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectSs(&p))
}

func TestParseSs(t *testing.T) {
	stub := `State      Recv-Q Send-Q                       Local Address:Port                         Peer Address:Port
LISTEN     0      128                                     :::45103                                  :::*
LISTEN     0      128                                     :::111                                    :::*
TIME-WAIT  0      0                         ::ffff:127.0.0.1:80                       ::ffff:127.0.0.1:50082
ESTAB      0      0                              10.0.25.101:60826                         10.0.25.104:5672  `
	stat := make(map[string]interface{})

	err := parseSs(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["LISTEN"], 2)
	assert.EqualValues(t, stat["TIME-WAIT"], 1)
	assert.EqualValues(t, stat["ESTAB"], 1)
}

func TestParseSs2(t *testing.T) {
	stub := `Netid State      Recv-Q Send-Q                                      Local Address:Port                                        Peer Address:Port
nl    UNCONN     0      0                                                      18:0                                                       *
p_raw UNCONN     0      0                                                       *:em2                                                     *
u_dgr UNCONN     0      0                                                /dev/log 10549                                                  * 0
u_dgr LISTEN     0      0                                       /run/udev/control 8552                                                   * 0
u_str LISTEN     0      10                                  /var/run/acpid.socket 9649                                                   * 0
u_str ESTAB      0      0                                    @/com/ubuntu/upstart 10582                                                  * 1887`
	stat := make(map[string]interface{})

	err := parseSs(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["LISTEN"], 2)
	assert.EqualValues(t, stat["UNCONN"], 3)
	assert.EqualValues(t, stat["ESTAB"], 1)
}

func TestGetSs(t *testing.T) {
	_, err := os.Stat("/usr/sbin/ss")
	if err != nil {
		return
	}

	ret, err := getSs()
	assert.Nil(t, err)
	assert.NotNil(t, ret)
	assert.Contains(t, ret, "State")
}

func TestCollectProcVmstat(t *testing.T) {
	path := "/proc/vmstat"
	_, err := os.Stat(path)
	if err != nil {
		return
	}
	p := make(map[string]interface{})

	assert.Nil(t, collectProcVmstat(path, &p))
}

func TestParseProcVmstat(t *testing.T) {
	stub := `pgpgin 770294
pgpgout 31351354
pswpin 0
pswpout 113`
	stat := make(map[string]interface{})

	err := parseProcVmstat(stub, &stat)
	assert.Nil(t, err)
	assert.EqualValues(t, stat["pgpgin"], 770294)
	assert.EqualValues(t, stat["pgpgout"], 31351354)
	assert.EqualValues(t, stat["pswpin"], 0)
	assert.EqualValues(t, stat["pswpout"], 113)
}

func TestGetProc(t *testing.T) {
	stub := "/proc/diskstats"
	_, err := os.Stat(stub)
	if err != nil {
		return
	}

	ret, err := getProc(stub)
	assert.Nil(t, err)
	assert.NotNil(t, ret)
}
<|endoftext|>


<commit_before>package v7

import (
	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
	"code.cloudfoundry.org/cli/command"
	"code.cloudfoundry.org/cli/command/flag"
	"code.cloudfoundry.org/cli/command/v7/shared"
	"code.cloudfoundry.org/cli/resources"
)

type RestartCommand struct {
	BaseCommand

	RequiredArgs        flag.AppName            `positional-args:"yes"`
	Strategy            flag.DeploymentStrategy `long:"strategy" description:"Deployment strategy, either rolling or null."`
	NoWait              bool                    `long:"no-wait" description:"Exit when the first instance of the web process is healthy"`
	usage               interface{}             `usage:"CF_NAME restart APP_NAME\n\n   This command will cause downtime unless you use '--strategy rolling'.\n\n   If the app's most recent package is unstaged, restarting the app will stage and run that package.\n   Otherwise, the app's current droplet will be run."`
	relatedCommands     interface{}             `related_commands:"restage, restart-app-instance"`
	envCFStagingTimeout interface{}             `environmentName:"CF_STAGING_TIMEOUT" environmentDescription:"Max wait time for staging, in minutes" environmentDefault:"15"`
	envCFStartupTimeout interface{}             `environmentName:"CF_STARTUP_TIMEOUT" environmentDescription:"Max wait time for app instance startup, in minutes" environmentDefault:"5"`

	Stager shared.AppStager
}

func (cmd *RestartCommand) Setup(config command.Config, ui command.UI) error {
	err := cmd.BaseCommand.Setup(config, ui)
	if err != nil {
		return err
	}
	logCacheEndpoint, _, err := cmd.Actor.GetLogCacheEndpoint()
	if err != nil {
		ui.DisplayText("here3")
		return err
	}
	logCacheClient := command.NewLogCacheClient(logCacheEndpoint, config, ui)
	cmd.Stager = shared.NewAppStager(cmd.Actor, cmd.UI, cmd.Config, logCacheClient)

	return nil
}

func (cmd RestartCommand) Execute(args []string) error {
	err := cmd.SharedActor.CheckTarget(true, true)
	if err != nil {
		return err
	}

	user, err := cmd.Config.CurrentUser()
	if err != nil {
		return err
	}

	app, warnings, err := cmd.Actor.GetApplicationByNameAndSpace(cmd.RequiredArgs.AppName, cmd.Config.TargetedSpace().GUID)
	cmd.UI.DisplayWarnings(warnings)
	if err != nil {
		return err
	}

	packageGUID, warnings, err := cmd.Actor.GetUnstagedNewestPackageGUID(app.GUID)
	cmd.UI.DisplayWarnings(warnings)
	if err != nil {
		return err
	}

	if packageGUID != "" || cmd.Strategy.Name == constant.DeploymentStrategyRolling {
		cmd.UI.DisplayTextWithFlavor("Restarting app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{
			"AppName":   cmd.RequiredArgs.AppName,
			"OrgName":   cmd.Config.TargetedOrganization().Name,
			"SpaceName": cmd.Config.TargetedSpace().Name,
			"Username":  user.Name,
		})
		cmd.UI.DisplayNewline()
	}

	if packageGUID != "" {
		err = cmd.Stager.StageAndStart(app, cmd.Config.TargetedSpace(), cmd.Config.TargetedOrganization(), packageGUID, cmd.Strategy.Name, cmd.NoWait, constant.ApplicationRestarting)
		if err != nil {
			return err
		}
	} else {
		err = cmd.Stager.StartApp(app, resources.Droplet{}, cmd.Strategy.Name, cmd.NoWait, cmd.Config.TargetedSpace(), cmd.Config.TargetedOrganization(), constant.ApplicationRestarting)
		if err != nil {
			return err
		}
	}

	return nil
}
<commit_msg>Remove residual debugging log<commit_after>package v7

import (
	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
	"code.cloudfoundry.org/cli/command"
	"code.cloudfoundry.org/cli/command/flag"
	"code.cloudfoundry.org/cli/command/v7/shared"
	"code.cloudfoundry.org/cli/resources"
)

type RestartCommand struct {
	BaseCommand

	RequiredArgs        flag.AppName            `positional-args:"yes"`
	Strategy            flag.DeploymentStrategy `long:"strategy" description:"Deployment strategy, either rolling or null."`
	NoWait              bool                    `long:"no-wait" description:"Exit when the first instance of the web process is healthy"`
	usage               interface{}             `usage:"CF_NAME restart APP_NAME\n\n   This command will cause downtime unless you use '--strategy rolling'.\n\n   If the app's most recent package is unstaged, restarting the app will stage and run that package.\n   Otherwise, the app's current droplet will be run."`
	relatedCommands     interface{}             `related_commands:"restage, restart-app-instance"`
	envCFStagingTimeout interface{}             `environmentName:"CF_STAGING_TIMEOUT" environmentDescription:"Max wait time for staging, in minutes" environmentDefault:"15"`
	envCFStartupTimeout interface{}             `environmentName:"CF_STARTUP_TIMEOUT" environmentDescription:"Max wait time for app instance startup, in minutes" environmentDefault:"5"`

	Stager shared.AppStager
}

func (cmd *RestartCommand) Setup(config command.Config, ui command.UI) error {
	err := cmd.BaseCommand.Setup(config, ui)
	if err != nil {
		return err
	}
	logCacheEndpoint, _, err := cmd.Actor.GetLogCacheEndpoint()
	if err != nil {
		return err
	}
	logCacheClient := command.NewLogCacheClient(logCacheEndpoint, config, ui)
	cmd.Stager = shared.NewAppStager(cmd.Actor, cmd.UI, cmd.Config, logCacheClient)

	return nil
}

func (cmd RestartCommand) Execute(args []string) error {
	err := cmd.SharedActor.CheckTarget(true, true)
	if err != nil {
		return err
	}

	user, err := cmd.Config.CurrentUser()
	if err != nil {
		return err
	}

	app, warnings, err := cmd.Actor.GetApplicationByNameAndSpace(cmd.RequiredArgs.AppName, cmd.Config.TargetedSpace().GUID)
	cmd.UI.DisplayWarnings(warnings)
	if err != nil {
		return err
	}

	packageGUID, warnings, err := cmd.Actor.GetUnstagedNewestPackageGUID(app.GUID)
	cmd.UI.DisplayWarnings(warnings)
	if err != nil {
		return err
	}

	if packageGUID != "" || cmd.Strategy.Name == constant.DeploymentStrategyRolling {
		cmd.UI.DisplayTextWithFlavor("Restarting app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{
			"AppName":   cmd.RequiredArgs.AppName,
			"OrgName":   cmd.Config.TargetedOrganization().Name,
			"SpaceName": cmd.Config.TargetedSpace().Name,
			"Username":  user.Name,
		})
		cmd.UI.DisplayNewline()
	}

	if packageGUID != "" {
		err = cmd.Stager.StageAndStart(app, cmd.Config.TargetedSpace(), cmd.Config.TargetedOrganization(), packageGUID, cmd.Strategy.Name, cmd.NoWait, constant.ApplicationRestarting)
		if err != nil {
			return err
		}
	} else {
		err = cmd.Stager.StartApp(app, resources.Droplet{}, cmd.Strategy.Name, cmd.NoWait, cmd.Config.TargetedSpace(), cmd.Config.TargetedOrganization(), constant.ApplicationRestarting)
		if err != nil {
			return err
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package bitfinex

import (
	// "github.com/davecgh/go-spew/spew"
	"bitfx2/exchange"
	"math"
	"os"
	"testing"
)

var book exchange.Book
var bf = New(os.Getenv("BITFINEX_KEY"), os.Getenv("BITFINEX_SECRET"), "ltc", "usd", 2, 0.001, .1)

func TestPriority(t *testing.T) {
	if bf.Priority() != 2 {
		t.Fatal("Priority should be 2")
	}
}

func TestFee(t *testing.T) {
	if bf.Fee()-0.002 > 0.000001 {
		t.Fatal("Fee should be 0.002")
	}
}

func TestUpdatePositon(t *testing.T) {
	if bf.Position() != 0 {
		t.Fatal("Should start with zero position")
	}
	bf.SetPosition(10)
	t.Logf("Set position to 10")
	if bf.Position() != 10 {
		t.Fatal("Position should have updated to 10")
	}
}

func TestCurrencyCode(t *testing.T) {
	if bf.CurrencyCode() != 0 {
		t.Fatal("Currency code should be 0")
	}
}

func TestMaxPos(t *testing.T) {
	if math.Abs(bf.MaxPos()-.1) > .000001 {
		t.Fatal("MaxPos should be .1")
	}
}

func TestCommunicateBook(t *testing.T) {
	bookChan := make(chan exchange.Book)
	doneChan := make(chan bool)
	if book = bf.CommunicateBook(bookChan, doneChan); book.Error != nil {
		t.Fatal(book.Error)
	}

	book = <-bookChan
	t.Logf("Received book data")
	// spew.Dump(book)
	if len(book.Bids) != 20 || len(book.Asks) != 20 {
		t.Fatal("Expected 20 book entries")
	}
	if book.Bids[0].Price < book.Bids[1].Price {
		t.Fatal("Bids not sorted correctly")
	}
	if book.Asks[0].Price > book.Asks[1].Price {
		t.Fatal("Asks not sorted correctly")
	}
	doneChan <- true
}

func TestNewOrder(t *testing.T) {
	action := "sell"
	otype := "limit"
	amount := 0.1
	price := book.Asks[0].Price + 0.10

	// Test submitting a new order
	id, err := bf.SendOrder(action, otype, amount, price)
	if err != nil || id == 0 {
		t.Fatal(err)
	}
	t.Logf("Placed a new sell order of 0.1 ltcusd @ %v limit with ID: %d", price, id)

	// Check status
	order, err := bf.GetOrderStatus(id)
	if err != nil {
		t.Fatal(err)
	}
	if order.Status != "live" {
		t.Fatal("Order should be live")
	}
	t.Logf("Order confirmed live")
	if order.FilledAmount != 0 {
		t.Fatal("Order should not be filled")
	}
	t.Logf("Order confirmed unfilled")

	// Test cancelling the order
	success, err := bf.CancelOrder(id)
	if err != nil {
		t.Fatal(err)
	}
	if !success {
		t.Fatal("Order not cancelled")
	}
	t.Logf("Sent cancellation")

	// Check status
	tryAgain := true
	for tryAgain {
		t.Logf("checking status...")
		order, err = bf.GetOrderStatus(id)
		tryAgain = order.Status == ""
	}
	if err != nil {
		t.Fatal(err)
	}
	if order.Status != "dead" {
		t.Fatal("Order should be dead after cancel")
	}
	t.Logf("Order confirmed dead")
	if order.FilledAmount != 0 {
		t.Fatal("Order should not be filled")
	}
	t.Logf("Order confirmed unfilled")

	// Test bad order
	id, err = bf.SendOrder("kill", otype, amount, price)
	if id != 0 {
		t.Fatal("Expected id = 0")
	}
	if err.Error() != "Bitfinex SendOrder error: Order side must be either 'buy' or 'sell'." {
		t.Fatal("Expected error 'Bitfinex SendOrder error: Order side must be either 'buy' or 'sell'.' on bad order")
	}
}
<commit_msg>remove broken error message test<commit_after>package bitfinex

import (
	// "github.com/davecgh/go-spew/spew"
	"bitfx2/exchange"
	"math"
	"os"
	"testing"
)

var book exchange.Book
var bf = New(os.Getenv("BITFINEX_KEY"), os.Getenv("BITFINEX_SECRET"), "ltc", "usd", 2, 0.001, .1)

func TestPriority(t *testing.T) {
	if bf.Priority() != 2 {
		t.Fatal("Priority should be 2")
	}
}

func TestFee(t *testing.T) {
	if bf.Fee()-0.002 > 0.000001 {
		t.Fatal("Fee should be 0.002")
	}
}

func TestUpdatePositon(t *testing.T) {
	if bf.Position() != 0 {
		t.Fatal("Should start with zero position")
	}
	bf.SetPosition(10)
	t.Logf("Set position to 10")
	if bf.Position() != 10 {
		t.Fatal("Position should have updated to 10")
	}
}

func TestCurrencyCode(t *testing.T) {
	if bf.CurrencyCode() != 0 {
		t.Fatal("Currency code should be 0")
	}
}

func TestMaxPos(t *testing.T) {
	if math.Abs(bf.MaxPos()-.1) > .000001 {
		t.Fatal("MaxPos should be .1")
	}
}

func TestCommunicateBook(t *testing.T) {
	bookChan := make(chan exchange.Book)
	doneChan := make(chan bool)
	if book = bf.CommunicateBook(bookChan, doneChan); book.Error != nil {
		t.Fatal(book.Error)
	}

	book = <-bookChan
	t.Logf("Received book data")
	// spew.Dump(book)
	if len(book.Bids) != 20 || len(book.Asks) != 20 {
		t.Fatal("Expected 20 book entries")
	}
	if book.Bids[0].Price < book.Bids[1].Price {
		t.Fatal("Bids not sorted correctly")
	}
	if book.Asks[0].Price > book.Asks[1].Price {
		t.Fatal("Asks not sorted correctly")
	}
	doneChan <- true
}

func TestNewOrder(t *testing.T) {
	action := "sell"
	otype := "limit"
	amount := 0.1
	price := book.Asks[0].Price + 0.10

	// Test submitting a new order
	id, err := bf.SendOrder(action, otype, amount, price)
	if err != nil || id == 0 {
		t.Fatal(err)
	}
	t.Logf("Placed a new sell order of 0.1 ltcusd @ %v limit with ID: %d", price, id)

	// Check status
	order, err := bf.GetOrderStatus(id)
	if err != nil {
		t.Fatal(err)
	}
	if order.Status != "live" {
		t.Fatal("Order should be live")
	}
	t.Logf("Order confirmed live")
	if order.FilledAmount != 0 {
		t.Fatal("Order should not be filled")
	}
	t.Logf("Order confirmed unfilled")

	// Test cancelling the order
	success, err := bf.CancelOrder(id)
	if err != nil {
		t.Fatal(err)
	}
	if !success {
		t.Fatal("Order not cancelled")
	}
	t.Logf("Sent cancellation")

	// Check status
	tryAgain := true
	for tryAgain {
		t.Logf("checking status...")
		order, err = bf.GetOrderStatus(id)
		tryAgain = order.Status == ""
	}
	if err != nil {
		t.Fatal(err)
	}
	if order.Status != "dead" {
		t.Fatal("Order should be dead after cancel")
	}
	t.Logf("Order confirmed dead")
	if order.FilledAmount != 0 {
		t.Fatal("Order should not be filled")
	}
	t.Logf("Order confirmed unfilled")

	// Test bad order
	id, err = bf.SendOrder("kill", otype, amount, price)
	if id != 0 {
		t.Fatal("Expected id = 0")
	}
}
<|endoftext|>


<commit_before>package k8s

import (
	"strings"

	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/pkg/api/v1"
	"k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"k8s.io/client-go/pkg/labels"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

// Client defines a subset of a Kubernetes API server
// client providing functionality we need.
type Client struct {
	Clientset *kubernetes.Clientset
}

// NewInClusterClient deals with creating a new
// instance of a Kubernetes client.
func NewInClusterClient() (*Client, error) {
	// Let's create an in cluster config.
	config, err := rest.InClusterConfig()
	if err != nil {
		return nil, err
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return &Client{Clientset: clientset}, nil
}

// NewClient deals with creating
// a new kubernetes client instance from provided configuration.
func NewClient(configFile string) (*Client, error) {
	// Create our configuration from the provided file.
	config, err := clientcmd.BuildConfigFromFlags("", configFile)
	if err != nil {
		return nil, err
	}
	// creates the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return &Client{Clientset: clientset}, nil
}

// Deployments retrieves the deployments matching the provided label selector
// and filtered down for those with container specs with the provided image.
// TODO: Implement a way to distinguish between containers in different registries with the same name for completely
// different projects.
// TODO: Add caching layer for deployments.
func (c *Client) Deployments(
	namespace string,
	containerImage string,
	selector labels.Selector,
) (*v1beta1.DeploymentList, error) {
	opts := v1.ListOptions{
		LabelSelector: selector.String(),
	}
	deployments, err := c.Clientset.ExtensionsV1beta1().Deployments(namespace).List(opts)
	if err != nil {
		return nil, err
	}
	c.filterDeploymentsByImage(containerImage, deployments)
	return deployments, nil
}

// Gets all deployments that have atleast a single container that ends with
// or is equal to the provided container image.
// The provided container image is expected to be of the form vendor/repo:tag.
func (c *Client) filterDeploymentsByImage(containerImage string, deployments *v1beta1.DeploymentList) {
	filtered := []v1beta1.Deployment{}
	for _, deployment := range deployments.Items {
		containers := deployment.Spec.Template.Spec.Containers
		if c.hasContainerWithImage(containerImage, containers) {
			filtered = append(filtered, deployment)
		}
	}
	deployments.Items = filtered
}

// Determines whether at least one of the provided set of containers have the specified
// image.
func (c *Client) hasContainerWithImage(image string, containers []v1.Container) bool {
	hasContainerImage := false
	i := 0
	for !hasContainerImage && i < len(containers) {
		if strings.HasSuffix(containers[i].Image, image) || containers[i].Image == image {
			hasContainerImage = true
		} else {
			i++
		}
	}
	return hasContainerImage
}

// ReplicationControllers retrieves the replication controllers matching the provided label selector
// and filters to rcs with containers which use the provided container image.
// TODO: Add caching layer for replication controllers.
func (c *Client) ReplicationControllers(
	namespace string,
	containerImage string,
	selector labels.Selector,
) (*v1.ReplicationControllerList, error) {
	opts := v1.ListOptions{
		LabelSelector: selector.String(),
	}
	replicationControllers, err := c.Clientset.CoreV1().ReplicationControllers(namespace).List(opts)
	if err != nil {
		return nil, err
	}
	c.filterRCsByImage(containerImage, replicationControllers)
	return replicationControllers, nil
}

// Deals with filtering a set of Replication Controllers down to those which use the provided image in
// at least one container.
func (c *Client) filterRCsByImage(image string, replicationControllers *v1.ReplicationControllerList) {
	filtered := []v1.ReplicationController{}
	for _, rc := range replicationControllers.Items {
		containers := rc.Spec.Template.Spec.Containers
		if c.hasContainerWithImage(image, containers) {
			filtered = append(filtered, rc)
		}
	}
	replicationControllers.Items = filtered
}

// RedeployDeployment deals with deleting and then creating the provided deployment
// in the given namespace.
func (c *Client) RedeployDeployment(namespace string, deployment *v1beta1.Deployment) error {
	opts := &v1.DeleteOptions{}
	err := c.Clientset.ExtensionsV1beta1().
		Deployments(namespace).
		Delete(deployment.GetName(), opts)
	if err != nil {
		return err
	}
	_, err = c.Clientset.ExtensionsV1beta1().
		Deployments(namespace).
		Create(deployment)
	if err != nil {
		return err
	}
	return nil
}

// RedeployRC deals with deleting and then creating the provided replication controller
// in the given namespace.
func (c *Client) RedeployRC(namespace string, rc *v1.ReplicationController) error {
	opts := &v1.DeleteOptions{}
	err := c.Clientset.CoreV1().
		ReplicationControllers(namespace).
		Delete(rc.GetName(), opts)
	if err != nil {
		return err
	}
	_, err = c.Clientset.CoreV1().
		ReplicationControllers(namespace).
		Create(rc)
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>Made the resource version empty so system can populate it as resource creation was failing because an old resource version was already set.<commit_after>package k8s

import (
	"strings"

	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/pkg/api/v1"
	"k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"k8s.io/client-go/pkg/labels"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

// Client defines a subset of a Kubernetes API server
// client providing functionality we need.
type Client struct {
	Clientset *kubernetes.Clientset
}

// NewInClusterClient deals with creating a new
// instance of a Kubernetes client.
func NewInClusterClient() (*Client, error) {
	// Let's create an in cluster config.
	config, err := rest.InClusterConfig()
	if err != nil {
		return nil, err
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return &Client{Clientset: clientset}, nil
}

// NewClient deals with creating
// a new kubernetes client instance from provided configuration.
func NewClient(configFile string) (*Client, error) {
	// Create our configuration from the provided file.
	config, err := clientcmd.BuildConfigFromFlags("", configFile)
	if err != nil {
		return nil, err
	}
	// creates the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return &Client{Clientset: clientset}, nil
}

// Deployments retrieves the deployments matching the provided label selector
// and filtered down for those with container specs with the provided image.
// TODO: Implement a way to distinguish between containers in different registries with the same name for completely
// different projects.
// TODO: Add caching layer for deployments.
func (c *Client) Deployments(
	namespace string,
	containerImage string,
	selector labels.Selector,
) (*v1beta1.DeploymentList, error) {
	opts := v1.ListOptions{
		LabelSelector: selector.String(),
	}
	deployments, err := c.Clientset.ExtensionsV1beta1().Deployments(namespace).List(opts)
	if err != nil {
		return nil, err
	}
	c.filterDeploymentsByImage(containerImage, deployments)
	return deployments, nil
}

// Gets all deployments that have atleast a single container that ends with
// or is equal to the provided container image.
// The provided container image is expected to be of the form vendor/repo:tag.
func (c *Client) filterDeploymentsByImage(containerImage string, deployments *v1beta1.DeploymentList) {
	filtered := []v1beta1.Deployment{}
	for _, deployment := range deployments.Items {
		containers := deployment.Spec.Template.Spec.Containers
		if c.hasContainerWithImage(containerImage, containers) {
			filtered = append(filtered, deployment)
		}
	}
	deployments.Items = filtered
}

// Determines whether at least one of the provided set of containers have the specified
// image.
func (c *Client) hasContainerWithImage(image string, containers []v1.Container) bool {
	hasContainerImage := false
	i := 0
	for !hasContainerImage && i < len(containers) {
		if strings.HasSuffix(containers[i].Image, image) || containers[i].Image == image {
			hasContainerImage = true
		} else {
			i++
		}
	}
	return hasContainerImage
}

// ReplicationControllers retrieves the replication controllers matching the provided label selector
// and filters to rcs with containers which use the provided container image.
// TODO: Add caching layer for replication controllers.
func (c *Client) ReplicationControllers(
	namespace string,
	containerImage string,
	selector labels.Selector,
) (*v1.ReplicationControllerList, error) {
	opts := v1.ListOptions{
		LabelSelector: selector.String(),
	}
	replicationControllers, err := c.Clientset.CoreV1().ReplicationControllers(namespace).List(opts)
	if err != nil {
		return nil, err
	}
	c.filterRCsByImage(containerImage, replicationControllers)
	return replicationControllers, nil
}

// Deals with filtering a set of Replication Controllers down to those which use the provided image in
// at least one container.
func (c *Client) filterRCsByImage(image string, replicationControllers *v1.ReplicationControllerList) {
	filtered := []v1.ReplicationController{}
	for _, rc := range replicationControllers.Items {
		containers := rc.Spec.Template.Spec.Containers
		if c.hasContainerWithImage(image, containers) {
			filtered = append(filtered, rc)
		}
	}
	replicationControllers.Items = filtered
}

// RedeployDeployment deals with deleting and then creating the provided deployment
// in the given namespace.
func (c *Client) RedeployDeployment(namespace string, deployment *v1beta1.Deployment) error {
	opts := &v1.DeleteOptions{}
	err := c.Clientset.ExtensionsV1beta1().
		Deployments(namespace).
		Delete(deployment.GetName(), opts)
	if err != nil {
		return err
	}
	// Make sure the resource version is empty so the system can set it.
	deployment.ResourceVersion = ""
	_, err = c.Clientset.ExtensionsV1beta1().
		Deployments(namespace).
		Create(deployment)
	if err != nil {
		return err
	}
	return nil
}

// RedeployRC deals with deleting and then creating the provided replication controller
// in the given namespace.
func (c *Client) RedeployRC(namespace string, rc *v1.ReplicationController) error {
	opts := &v1.DeleteOptions{}
	err := c.Clientset.CoreV1().
		ReplicationControllers(namespace).
		Delete(rc.GetName(), opts)
	if err != nil {
		return err
	}
	// Make sure the resource version is empty so the system can set it.
	rc.ResourceVersion = ""
	_, err = c.Clientset.CoreV1().
		ReplicationControllers(namespace).
		Create(rc)
	if err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package kitsu

import (
	"fmt"
)

// Possible values for User.RatingSystem.
const (
	UserRatingSystemAdvanced = "advanced"
	UserRatingSystemRegular  = "regular"
	UserRatingSystemSimple   = "simple"
)

// Possible values for User.Theme.
const (
	UserThemeLight = "light"
	UserThemeDark  = "dark"
)

// UserService handles communication with the user related methods of the
// Kitsu API.
//
// Kitsu API docs:
// http://docs.kitsu.apiary.io/#reference/users/users
type UserService service

// User represents a Kitsu user.
type User struct {
	ID string `jsonapi:"primary,users"`

	// --- Attributes ---

	// ISO 8601 date and time, e.g. 2017-07-27T22:21:26.824Z
	CreatedAt string `jsonapi:"attr,createdAt,omitempty"`

	// ISO 8601 of last modification, e.g. 2017-07-27T22:47:45.129Z
	UpdatedAt string `jsonapi:"attr,updatedAt,omitempty"`

	// e.g. vikhyat
	Name string `jsonapi:"attr,name,omitempty"`

	PastNames []string `jsonapi:"attr,pastNames,omitempty"`

	// Unique slug used for page URLs, e.g. vikhyat
	Slug string `jsonapi:"attr,slug,omitempty"`

	// Max length of 500 characters, e.g.
	//
	// Co-founder of Hummingbird. Obsessed with Gumi.
	About string `jsonapi:"attr,about,omitempty"`

	// e.g. Seattle, WA
	Location string `jsonapi:"attr,location,omitempty"`

	// e.g. Waifu
	WaifuOrHusbando string `jsonapi:"attr,waifuOrHusbando,omitempty"`

	// e.g. 1716
	followersCount int `jsonapi:"attr,followersCount,omitempty"`

	// e.g. 2031
	followingCount int `jsonapi:"attr,followingCount,omitempty"`

	Birthday string `jsonapi:"attr,birthday,omitempty"`
	Gender   string `jsonapi:"attr,gender,omitempty"`

	CommentsCount       int `jsonapi:"attr,commentsCount,omitempty"`
	FavoritesCount      int `jsonapi:"attr,favoritesCount,omitempty"`
	LikesGivenCount     int `jsonapi:"attr,likesGivenCount,omitempty"`
	ReviewsCount        int `jsonapi:"attr,reviewsCount,omitempty"`
	LikesReceivedCount  int `jsonapi:"attr,likesReceivedCount,omitempty"`
	PostsCount          int `jsonapi:"attr,postsCount,omitempty"`
	RatingsCount        int `jsonapi:"attr,ratingsCount,omitempty"`
	MediaReactionsCount int `jsonapi:"attr,mediaReactionsCount,omitempty"`

	// e.g. 2015-01-30T16:49:35.173Z
	ProExpiresAt string `jsonapi:"attr,proExpiresAt,omitempty"`

	Title string `jsonapi:"attr,title,omitempty"`

	ProfileCompleted bool `jsonapi:"attr,profileCompleted,omitempty"`
	FeedCompleted    bool `jsonapi:"attr,feedCompleted,omitempty"`

	// e.g.
	//
	// "tiny": "https://media.kitsu.io/users/avatars/1/tiny.jpg?1434087646"
	//
	// "small": "https://media.kitsu.io/users/avatars/1/small.jpg?1434087646"
	//
	// "medium": "https://media.kitsu.io/users/avatars/1/medium.jpg?1434087646"
	//
	// "large": "https://media.kitsu.io/users/avatars/1/large.jpg?1434087646"
	//
	// "original": "https://media.kitsu.io/users/avatars/1/original.jpg?1434087646"
	//
	// It may also contain a meta object with additional dimentions objects for
	// each previous Avatar type.
	Avatar     map[string]interface{} `jsonapi:"attr,avatar,omitempty"`
	CoverImage map[string]interface{} `jsonapi:"attr,coverImage,omitempty"`

	// Possible valued described by UserRatingSystem constants.
	RatingSystem string `jsonapi:"attr,ratingSystem,omitempty"`

	// Possible valued described by UserTheme constants.
	Theme string `jsonapi:"attr,theme,omitempty"`

	FacebookId string `jsonapi:"attr,facebookId,omitempty"`

	// --- Relationships ---

	Waifu          *Character      `jsonapi:"relation,waifu,omitempty"`
	LibraryEntries []*LibraryEntry `jsonapi:"relation,libraryEntries,omitempty"`
}

// Show returns details for a specific User by providing the ID of the user
// e.g. 29745.
func (s *UserService) Show(userID string, opts ...URLOption) (*User, *Response, error) {
	u := fmt.Sprintf(defaultAPIVersion+"users/%s", userID)

	req, err := s.client.NewRequest("GET", u, nil, opts...)
	if err != nil {
		return nil, nil, err
	}

	user := new(User)
	resp, err := s.client.Do(req, user)
	if err != nil {
		return nil, resp, err
	}

	return user, resp, nil
}

// List returns a list of Users. Optional parameters can be specified to filter
// the search results and control pagination, sorting etc.
func (s *UserService) List(opts ...URLOption) ([]*User, *Response, error) {
	u := defaultAPIVersion + "users"

	req, err := s.client.NewRequest("GET", u, nil, opts...)
	if err != nil {
		return nil, nil, err
	}

	var users []*User
	resp, err := s.client.Do(req, &users)
	if err != nil {
		return nil, resp, err
	}

	return users, resp, nil
}
<commit_msg>Change to User.FacebookID and fix typo in doc<commit_after>package kitsu

import (
	"fmt"
)

// Possible values for User.RatingSystem.
const (
	UserRatingSystemAdvanced = "advanced"
	UserRatingSystemRegular  = "regular"
	UserRatingSystemSimple   = "simple"
)

// Possible values for User.Theme.
const (
	UserThemeLight = "light"
	UserThemeDark  = "dark"
)

// UserService handles communication with the user related methods of the
// Kitsu API.
//
// Kitsu API docs:
// http://docs.kitsu.apiary.io/#reference/users/users
type UserService service

// User represents a Kitsu user.
type User struct {
	ID string `jsonapi:"primary,users"`

	// --- Attributes ---

	// ISO 8601 date and time, e.g. 2017-07-27T22:21:26.824Z
	CreatedAt string `jsonapi:"attr,createdAt,omitempty"`

	// ISO 8601 of last modification, e.g. 2017-07-27T22:47:45.129Z
	UpdatedAt string `jsonapi:"attr,updatedAt,omitempty"`

	// e.g. vikhyat
	Name string `jsonapi:"attr,name,omitempty"`

	PastNames []string `jsonapi:"attr,pastNames,omitempty"`

	// Unique slug used for page URLs, e.g. vikhyat
	Slug string `jsonapi:"attr,slug,omitempty"`

	// Max length of 500 characters, e.g.
	//
	// Co-founder of Hummingbird. Obsessed with Gumi.
	About string `jsonapi:"attr,about,omitempty"`

	// e.g. Seattle, WA
	Location string `jsonapi:"attr,location,omitempty"`

	// e.g. Waifu
	WaifuOrHusbando string `jsonapi:"attr,waifuOrHusbando,omitempty"`

	// e.g. 1716
	followersCount int `jsonapi:"attr,followersCount,omitempty"`

	// e.g. 2031
	followingCount int `jsonapi:"attr,followingCount,omitempty"`

	Birthday string `jsonapi:"attr,birthday,omitempty"`
	Gender   string `jsonapi:"attr,gender,omitempty"`

	CommentsCount       int `jsonapi:"attr,commentsCount,omitempty"`
	FavoritesCount      int `jsonapi:"attr,favoritesCount,omitempty"`
	LikesGivenCount     int `jsonapi:"attr,likesGivenCount,omitempty"`
	ReviewsCount        int `jsonapi:"attr,reviewsCount,omitempty"`
	LikesReceivedCount  int `jsonapi:"attr,likesReceivedCount,omitempty"`
	PostsCount          int `jsonapi:"attr,postsCount,omitempty"`
	RatingsCount        int `jsonapi:"attr,ratingsCount,omitempty"`
	MediaReactionsCount int `jsonapi:"attr,mediaReactionsCount,omitempty"`

	// e.g. 2015-01-30T16:49:35.173Z
	ProExpiresAt string `jsonapi:"attr,proExpiresAt,omitempty"`

	Title string `jsonapi:"attr,title,omitempty"`

	ProfileCompleted bool `jsonapi:"attr,profileCompleted,omitempty"`
	FeedCompleted    bool `jsonapi:"attr,feedCompleted,omitempty"`

	// e.g.
	//
	// "tiny": "https://media.kitsu.io/users/avatars/1/tiny.jpg?1434087646"
	//
	// "small": "https://media.kitsu.io/users/avatars/1/small.jpg?1434087646"
	//
	// "medium": "https://media.kitsu.io/users/avatars/1/medium.jpg?1434087646"
	//
	// "large": "https://media.kitsu.io/users/avatars/1/large.jpg?1434087646"
	//
	// "original": "https://media.kitsu.io/users/avatars/1/original.jpg?1434087646"
	//
	// It may also contain a meta object with additional dimensions objects for
	// each previous Avatar type.
	Avatar     map[string]interface{} `jsonapi:"attr,avatar,omitempty"`
	CoverImage map[string]interface{} `jsonapi:"attr,coverImage,omitempty"`

	// Possible valued described by UserRatingSystem constants.
	RatingSystem string `jsonapi:"attr,ratingSystem,omitempty"`

	// Possible valued described by UserTheme constants.
	Theme string `jsonapi:"attr,theme,omitempty"`

	FacebookID string `jsonapi:"attr,facebookId,omitempty"`

	// --- Relationships ---

	Waifu          *Character      `jsonapi:"relation,waifu,omitempty"`
	LibraryEntries []*LibraryEntry `jsonapi:"relation,libraryEntries,omitempty"`
}

// Show returns details for a specific User by providing the ID of the user
// e.g. 29745.
func (s *UserService) Show(userID string, opts ...URLOption) (*User, *Response, error) {
	u := fmt.Sprintf(defaultAPIVersion+"users/%s", userID)

	req, err := s.client.NewRequest("GET", u, nil, opts...)
	if err != nil {
		return nil, nil, err
	}

	user := new(User)
	resp, err := s.client.Do(req, user)
	if err != nil {
		return nil, resp, err
	}

	return user, resp, nil
}

// List returns a list of Users. Optional parameters can be specified to filter
// the search results and control pagination, sorting etc.
func (s *UserService) List(opts ...URLOption) ([]*User, *Response, error) {
	u := defaultAPIVersion + "users"

	req, err := s.client.NewRequest("GET", u, nil, opts...)
	if err != nil {
		return nil, nil, err
	}

	var users []*User
	resp, err := s.client.Do(req, &users)
	if err != nil {
		return nil, resp, err
	}

	return users, resp, nil
}
<|endoftext|>


<commit_before>package knx

import (
	"bytes"
	"net"
	"time"
)

// UDP socket for KNXnet/IP packet exchange
type Socket struct {
	conn *net.UDPConn

	// Inbound relays incoming KNXnet/IP packets.
	// The types of these packets are limited to those returned by ReadPacket.
	Inbound <-chan interface{}

	// Outbound relays outgoing KNXnet/IP packets to the gateway or router.
	Outbound chan<- OutgoingPayload
}

// NewClientSocket creates a new Socket which can used to exchange KNXnet/IP packets with a gateway.
func NewClientSocket(gatewayAddress string) (*Socket, error) {
	addr, err := net.ResolveUDPAddr("udp4", gatewayAddress)
	if err != nil { return nil, err }

	conn, err := net.DialUDP("udp4", nil, addr)
	if err != nil { return nil, err }

	return makeSocket(conn, addr)
}

// NewRoutingSocket creates a new Socket which can be used to exchange KNXnet/IP packets with a
// router.
func NewRoutingSocket(multicastAddress string) (*Socket, error) {
	addr, err := net.ResolveUDPAddr("udp4", multicastAddress)
	if err != nil { return nil, err }

	conn, err := net.ListenMulticastUDP("udp4", nil, addr)
	if err != nil { return nil, err }

	return makeSocket(conn, addr)
}

// Close shuts the socket down. This will indirectly terminate the associated workers.
func (sock *Socket) Close() error {
	return sock.conn.Close()
}

// makeSocket configures the UDPConn and launches the receiver and sender workers.
func makeSocket(conn *net.UDPConn, addr *net.UDPAddr) (*Socket, error) {
	conn.SetDeadline(time.Time{})

	inbound := make(chan interface{})
	go socketReceiver(conn, addr, inbound)

	outbound := make(chan OutgoingPayload)
	go socketSender(conn, addr, outbound)

	return &Socket{conn, inbound, outbound}, nil
}

// isSameUDPAddr tests the given UDPAddrs for equality.
func isSameUDPAddr(a, b *net.UDPAddr) bool {
	return bytes.Equal(a.IP, b.IP) && a.Port == b.Port
}

// socketReceiver is the receiver worker for Socket.
func socketReceiver(conn *net.UDPConn, addr *net.UDPAddr, inbound chan<- interface{}) {
	Logger.Printf("socket[%v]: Started receiver", conn.RemoteAddr())

	buffer := [1024]byte{}
	reader := bytes.NewReader(buffer[:])

	for {
		len, sender, err := conn.ReadFromUDP(buffer[:])
		if err != nil {
			Logger.Printf("socket[%v]: Error during read: %v", conn.RemoteAddr(), err)
			break
		} else if !isSameUDPAddr(sender, addr) {
			Logger.Printf("socket[%v]: Packet from invalid sender: %+v", conn.RemoteAddr(), sender)
			continue
		}

		reader.Reset(buffer[:len])

		payload, err := ReadPacket(reader)
		if err != nil {
			Logger.Printf("socket[%v]: Error during packet parsing: %v\n" +
			              "            Buffer was: %v",
			              conn.RemoteAddr(), err, buffer[:len])
			continue
		}

		Logger.Printf("socket[%v]: Received: %+v", conn.RemoteAddr(), payload)

		inbound <- payload
	}

	close(inbound)
	Logger.Printf("socket[%v]: Stopped receiver", conn.RemoteAddr())
}

// socketSender is the sender worker for Socket.
func socketSender(conn *net.UDPConn, addr *net.UDPAddr, outbound <-chan OutgoingPayload) {
	Logger.Printf("socket[%v]: Started sender", conn.RemoteAddr())

	buffer := &bytes.Buffer{}

	for payload := range outbound {
		buffer.Reset()

		err := WritePacket(buffer, payload)
		if err != nil {
			Logger.Printf("socket[%v]: Error during packet generation: %v", conn.RemoteAddr(), err)
			continue
		}

		Logger.Printf("socket[%v]: Sending: %+v", conn.RemoteAddr(), payload)

		_, err = conn.WriteToUDP(buffer.Bytes(), addr)
		if err != nil {
			Logger.Printf("socket[%v]: Error during write: %v", conn.RemoteAddr(), err)
			break
		}
	}

	Logger.Printf("socket[%v]: Stopped sender", conn.RemoteAddr())
}
<commit_msg>Make 'makeSocket' return a single value<commit_after>package knx

import (
	"bytes"
	"net"
	"time"
)

// UDP socket for KNXnet/IP packet exchange
type Socket struct {
	conn *net.UDPConn

	// Inbound relays incoming KNXnet/IP packets.
	// The types of these packets are limited to those returned by ReadPacket.
	Inbound <-chan interface{}

	// Outbound relays outgoing KNXnet/IP packets to the gateway or router.
	Outbound chan<- OutgoingPayload
}

// NewClientSocket creates a new Socket which can used to exchange KNXnet/IP packets with a gateway.
func NewClientSocket(gatewayAddress string) (*Socket, error) {
	addr, err := net.ResolveUDPAddr("udp4", gatewayAddress)
	if err != nil { return nil, err }

	conn, err := net.DialUDP("udp4", nil, addr)
	if err != nil { return nil, err }

	return makeSocket(conn, addr), nil
}

// NewRoutingSocket creates a new Socket which can be used to exchange KNXnet/IP packets with a
// router.
func NewRoutingSocket(multicastAddress string) (*Socket, error) {
	addr, err := net.ResolveUDPAddr("udp4", multicastAddress)
	if err != nil { return nil, err }

	conn, err := net.ListenMulticastUDP("udp4", nil, addr)
	if err != nil { return nil, err }

	return makeSocket(conn, addr), nil
}

// Close shuts the socket down. This will indirectly terminate the associated workers.
func (sock *Socket) Close() error {
	return sock.conn.Close()
}

// makeSocket configures the UDPConn and launches the receiver and sender workers.
func makeSocket(conn *net.UDPConn, addr *net.UDPAddr) *Socket {
	conn.SetDeadline(time.Time{})

	inbound := make(chan interface{})
	go socketReceiver(conn, addr, inbound)

	outbound := make(chan OutgoingPayload)
	go socketSender(conn, addr, outbound)

	return &Socket{conn, inbound, outbound}
}

// isSameUDPAddr tests the given UDPAddrs for equality.
func isSameUDPAddr(a, b *net.UDPAddr) bool {
	return bytes.Equal(a.IP, b.IP) && a.Port == b.Port
}

// socketReceiver is the receiver worker for Socket.
func socketReceiver(conn *net.UDPConn, addr *net.UDPAddr, inbound chan<- interface{}) {
	Logger.Printf("socket[%v]: Started receiver", conn.RemoteAddr())

	buffer := [1024]byte{}
	reader := bytes.NewReader(buffer[:])

	for {
		len, sender, err := conn.ReadFromUDP(buffer[:])
		if err != nil {
			Logger.Printf("socket[%v]: Error during read: %v", conn.RemoteAddr(), err)
			break
		} else if !isSameUDPAddr(sender, addr) {
			Logger.Printf("socket[%v]: Packet from invalid sender: %+v", conn.RemoteAddr(), sender)
			continue
		}

		reader.Reset(buffer[:len])

		payload, err := ReadPacket(reader)
		if err != nil {
			Logger.Printf("socket[%v]: Error during packet parsing: %v\n" +
			              "            Buffer was: %v",
			              conn.RemoteAddr(), err, buffer[:len])
			continue
		}

		Logger.Printf("socket[%v]: Received: %+v", conn.RemoteAddr(), payload)

		inbound <- payload
	}

	close(inbound)
	Logger.Printf("socket[%v]: Stopped receiver", conn.RemoteAddr())
}

// socketSender is the sender worker for Socket.
func socketSender(conn *net.UDPConn, addr *net.UDPAddr, outbound <-chan OutgoingPayload) {
	Logger.Printf("socket[%v]: Started sender", conn.RemoteAddr())

	buffer := &bytes.Buffer{}

	for payload := range outbound {
		buffer.Reset()

		err := WritePacket(buffer, payload)
		if err != nil {
			Logger.Printf("socket[%v]: Error during packet generation: %v", conn.RemoteAddr(), err)
			continue
		}

		Logger.Printf("socket[%v]: Sending: %+v", conn.RemoteAddr(), payload)

		_, err = conn.WriteToUDP(buffer.Bytes(), addr)
		if err != nil {
			Logger.Printf("socket[%v]: Error during write: %v", conn.RemoteAddr(), err)
			break
		}
	}

	Logger.Printf("socket[%v]: Stopped sender", conn.RemoteAddr())
}
<|endoftext|>


<commit_before>package geom

import (
	"math"
)

// A Bounds represents a multi-dimensional bounding box.
type Bounds struct {
	layout Layout
	min    Coord
	max    Coord
}

// NewBounds creates a new Bounds.
func NewBounds(layout Layout) *Bounds {
	stride := layout.Stride()
	min, max := make(Coord, stride), make(Coord, stride)
	for i := 0; i < stride; i++ {
		min[i], max[i] = math.Inf(1), math.Inf(-1)
	}
	return &Bounds{
		layout: layout,
		min:    min,
		max:    max,
	}
}

// Clone returns a deep copy of b.
func (b *Bounds) Clone() *Bounds {
	return deriveCloneBounds(b)
}

// Extend extends b to include geometry g.
func (b *Bounds) Extend(g T) *Bounds {
	b.extendLayout(g.Layout())
	if b.layout == XYZM && g.Layout() == XYM {
		return b.extendXYZMFlatCoordsWithXYM(g.FlatCoords(), 0, len(g.FlatCoords()))
	}
	return b.extendFlatCoords(g.FlatCoords(), 0, len(g.FlatCoords()), g.Stride())
}

// IsEmpty returns true if b is empty.
func (b *Bounds) IsEmpty() bool {
	for i, stride := 0, b.layout.Stride(); i < stride; i++ {
		if b.max[i] < b.min[i] {
			return true
		}
	}
	return false
}

// Layout returns b's layout.
func (b *Bounds) Layout() Layout {
	return b.layout
}

// Max returns the maximum value in dimension dim.
func (b *Bounds) Max(dim int) float64 {
	return b.max[dim]
}

// Min returns the minimum value in dimension dim.
func (b *Bounds) Min(dim int) float64 {
	return b.min[dim]
}

// Overlaps returns true if b overlaps b2 in layout.
func (b *Bounds) Overlaps(layout Layout, b2 *Bounds) bool {
	for i, stride := 0, layout.Stride(); i < stride; i++ {
		if b.min[i] > b2.max[i] || b.max[i] < b2.min[i] {
			return false
		}
	}
	return true
}

// Set sets the minimum and maximum values. args must be an even number of
// values: the first half are the minimum values for each dimension and the
// second half are the maximum values for each dimension.
func (b *Bounds) Set(args ...float64) *Bounds {
	if len(args)&1 != 0 {
		panic("geom: even number of arguments required")
	}
	stride := len(args) / 2
	b.extendStride(stride)
	for i := 0; i < stride; i++ {
		b.min[i], b.max[i] = args[i], args[i+stride]
	}
	return b
}

// SetCoords sets the minimum and maximum values of the Bounds.
func (b *Bounds) SetCoords(min, max Coord) *Bounds {
	b.min = Coord(make([]float64, b.layout.Stride()))
	b.max = Coord(make([]float64, b.layout.Stride()))
	for i := 0; i < b.layout.Stride(); i++ {
		b.min[i] = math.Min(min[i], max[i])
		b.max[i] = math.Max(min[i], max[i])
	}
	return b
}

// OverlapsPoint determines if the bounding box overlaps the point (point is within or on the border of the bounds)
func (b *Bounds) OverlapsPoint(layout Layout, point Coord) bool {
	for i, stride := 0, layout.Stride(); i < stride; i++ {
		if b.min[i] > point[i] || b.max[i] < point[i] {
			return false
		}
	}
	return true
}

func (b *Bounds) extendFlatCoords(flatCoords []float64, offset, end, stride int) *Bounds {
	b.extendStride(stride)
	for i := offset; i < end; i += stride {
		for j := 0; j < stride; j++ {
			b.min[j] = math.Min(b.min[j], flatCoords[i+j])
			b.max[j] = math.Max(b.max[j], flatCoords[i+j])
		}
	}
	return b
}

func (b *Bounds) extendLayout(layout Layout) {
	switch {
	case b.layout == XYZ && layout == XYM:
		b.min = append(b.min, math.Inf(1))
		b.max = append(b.max, math.Inf(-1))
		b.layout = XYZM
	case b.layout == XYM && (layout == XYZ || layout == XYZM):
		b.min = append(b.min[:2], math.Inf(1), b.min[2])
		b.max = append(b.max[:2], math.Inf(-1), b.max[2])
		b.layout = XYZM
	case b.layout < layout:
		b.extendStride(layout.Stride())
		b.layout = layout
	}
}

func (b *Bounds) extendStride(stride int) {
	for s := b.layout.Stride(); s < stride; s++ {
		b.min = append(b.min, math.Inf(1))
		b.max = append(b.max, math.Inf(-1))
	}
}

func (b *Bounds) extendXYZMFlatCoordsWithXYM(flatCoords []float64, offset, end int) *Bounds {
	for i := offset; i < end; i += 3 {
		b.min[0] = math.Min(b.min[0], flatCoords[i+0])
		b.max[0] = math.Max(b.max[0], flatCoords[i+0])
		b.min[1] = math.Min(b.min[1], flatCoords[i+1])
		b.max[1] = math.Max(b.max[1], flatCoords[i+1])
		b.min[3] = math.Min(b.min[3], flatCoords[i+2])
		b.max[3] = math.Max(b.max[3], flatCoords[i+2])
	}
	return b
}
<commit_msg>Add note about dimension extension<commit_after>package geom

import (
	"math"
)

// A Bounds represents a multi-dimensional bounding box.
type Bounds struct {
	layout Layout
	min    Coord
	max    Coord
}

// NewBounds creates a new Bounds.
func NewBounds(layout Layout) *Bounds {
	stride := layout.Stride()
	min, max := make(Coord, stride), make(Coord, stride)
	for i := 0; i < stride; i++ {
		min[i], max[i] = math.Inf(1), math.Inf(-1)
	}
	return &Bounds{
		layout: layout,
		min:    min,
		max:    max,
	}
}

// Clone returns a deep copy of b.
func (b *Bounds) Clone() *Bounds {
	return deriveCloneBounds(b)
}

// Extend extends b to include geometry g.
func (b *Bounds) Extend(g T) *Bounds {
	b.extendLayout(g.Layout())
	if b.layout == XYZM && g.Layout() == XYM {
		return b.extendXYZMFlatCoordsWithXYM(g.FlatCoords(), 0, len(g.FlatCoords()))
	}
	return b.extendFlatCoords(g.FlatCoords(), 0, len(g.FlatCoords()), g.Stride())
}

// IsEmpty returns true if b is empty.
func (b *Bounds) IsEmpty() bool {
	for i, stride := 0, b.layout.Stride(); i < stride; i++ {
		if b.max[i] < b.min[i] {
			return true
		}
	}
	return false
}

// Layout returns b's layout.
func (b *Bounds) Layout() Layout {
	return b.layout
}

// Max returns the maximum value in dimension dim.
func (b *Bounds) Max(dim int) float64 {
	return b.max[dim]
}

// Min returns the minimum value in dimension dim.
func (b *Bounds) Min(dim int) float64 {
	return b.min[dim]
}

// Overlaps returns true if b overlaps b2 in layout.
func (b *Bounds) Overlaps(layout Layout, b2 *Bounds) bool {
	for i, stride := 0, layout.Stride(); i < stride; i++ {
		if b.min[i] > b2.max[i] || b.max[i] < b2.min[i] {
			return false
		}
	}
	return true
}

// Set sets the minimum and maximum values. args must be an even number of
// values: the first half are the minimum values for each dimension and the
// second half are the maximum values for each dimension. If necessary, the
// layout of b will be extended to cover all the supplied dimensions implied by
// args.
func (b *Bounds) Set(args ...float64) *Bounds {
	if len(args)&1 != 0 {
		panic("geom: even number of arguments required")
	}
	stride := len(args) / 2
	b.extendStride(stride)
	for i := 0; i < stride; i++ {
		b.min[i], b.max[i] = args[i], args[i+stride]
	}
	return b
}

// SetCoords sets the minimum and maximum values of the Bounds.
func (b *Bounds) SetCoords(min, max Coord) *Bounds {
	b.min = Coord(make([]float64, b.layout.Stride()))
	b.max = Coord(make([]float64, b.layout.Stride()))
	for i := 0; i < b.layout.Stride(); i++ {
		b.min[i] = math.Min(min[i], max[i])
		b.max[i] = math.Max(min[i], max[i])
	}
	return b
}

// OverlapsPoint determines if the bounding box overlaps the point (point is within or on the border of the bounds)
func (b *Bounds) OverlapsPoint(layout Layout, point Coord) bool {
	for i, stride := 0, layout.Stride(); i < stride; i++ {
		if b.min[i] > point[i] || b.max[i] < point[i] {
			return false
		}
	}
	return true
}

func (b *Bounds) extendFlatCoords(flatCoords []float64, offset, end, stride int) *Bounds {
	b.extendStride(stride)
	for i := offset; i < end; i += stride {
		for j := 0; j < stride; j++ {
			b.min[j] = math.Min(b.min[j], flatCoords[i+j])
			b.max[j] = math.Max(b.max[j], flatCoords[i+j])
		}
	}
	return b
}

func (b *Bounds) extendLayout(layout Layout) {
	switch {
	case b.layout == XYZ && layout == XYM:
		b.min = append(b.min, math.Inf(1))
		b.max = append(b.max, math.Inf(-1))
		b.layout = XYZM
	case b.layout == XYM && (layout == XYZ || layout == XYZM):
		b.min = append(b.min[:2], math.Inf(1), b.min[2])
		b.max = append(b.max[:2], math.Inf(-1), b.max[2])
		b.layout = XYZM
	case b.layout < layout:
		b.extendStride(layout.Stride())
		b.layout = layout
	}
}

func (b *Bounds) extendStride(stride int) {
	for s := b.layout.Stride(); s < stride; s++ {
		b.min = append(b.min, math.Inf(1))
		b.max = append(b.max, math.Inf(-1))
	}
}

func (b *Bounds) extendXYZMFlatCoordsWithXYM(flatCoords []float64, offset, end int) *Bounds {
	for i := offset; i < end; i += 3 {
		b.min[0] = math.Min(b.min[0], flatCoords[i+0])
		b.max[0] = math.Max(b.max[0], flatCoords[i+0])
		b.min[1] = math.Min(b.min[1], flatCoords[i+1])
		b.max[1] = math.Max(b.max[1], flatCoords[i+1])
		b.min[3] = math.Min(b.min[3], flatCoords[i+2])
		b.max[3] = math.Max(b.max[3], flatCoords[i+2])
	}
	return b
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"

	"github.com/pilu/traffic"
	"github.com/tealeg/xlsx"
)

type Col struct {
	ColID int
	Value string
}

type Row struct {
	RowID int
	Cols []Col
}

type Sheet struct {
	SheetID int
	MaxCols int
	MaxRows int
	Rows []Row
}

type ExcelData struct {
	DocumentName string
	Sheets []Sheet
}

func excelResponse(w traffic.ResponseWriter, r *traffic.Request) {
	file, handler, err := r.FormFile("file")
        if err != nil {
                fmt.Println(err)
        }
        data, err := ioutil.ReadAll(file)
        if err != nil {
                fmt.Println(err)
        }
	fmt.Print("Filename: ")
	fmt.Println(handler.Filename)

	xlFile, err := xlsx.OpenBinary(data)
	if err != nil {
		fmt.Println(err)
	}

	excelData := ExcelData{DocumentName: handler.Filename}

	excelData.Sheets = []Sheet{}
	for sheetIndex, sheet := range xlFile.Sheets {
		jSheet := Sheet{MaxCols: sheet.MaxCol, MaxRows: sheet.MaxRow, SheetID: sheetIndex}
		jSheet.Rows = []Row{}
		for rowIndex, row := range sheet.Rows {
			jRow := Row{RowID: rowIndex}
			jRow.Cols = []Col{}
			for cellIndex, cell := range row.Cells {
				jCol := Col{ColID: cellIndex}
				value, err := cell.FormattedValue()
				if err != nil {
					value = err.Error()
				}
				jCol.Value = value
				jRow.Cols = append(jRow.Cols, jCol)
			}
			jSheet.Rows = append(jSheet.Rows, jRow)
		}
		excelData.Sheets = append(excelData.Sheets, jSheet)
	}
	fmt.Println(excelData)
	enc := json.NewEncoder(w)
	enc.Encode(excelData)
}

func APIHandler(w traffic.ResponseWriter, r *traffic.Request) {
	params := r.URL.Query()
	call := params.Get("call")
	if call == "conversion" {
		excelResponse(w, r);
	}
}
<commit_msg>Return more structured representations of the spreadsheet.<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"

	"github.com/pilu/traffic"
	"github.com/tealeg/xlsx"
)

type Col struct {
	ColID string
	Value string
}

type Row struct {
	RowID string
	Cols []Col
}

type Sheet struct {
	SheetID string
	MaxCols int
	MaxRows int
	Rows []Row
}

type ExcelData struct {
	DocumentName string
	Sheets []Sheet
}

func excelResponse(w traffic.ResponseWriter, r *traffic.Request) {
	file, handler, err := r.FormFile("file")
        if err != nil {
                fmt.Println(err)
        }
        data, err := ioutil.ReadAll(file)
        if err != nil {
                fmt.Println(err)
        }
	fmt.Print("Filename: ")
	fmt.Println(handler.Filename)

	xlFile, err := xlsx.OpenBinary(data)
	if err != nil {
		fmt.Println(err)
	}

	excelData := ExcelData{DocumentName: handler.Filename}

	excelData.Sheets = []Sheet{}
	for sheetIndex, sheet := range xlFile.Sheets {
		sheetID := fmt.Sprintf("%d", sheetIndex)
		jSheet := Sheet{MaxCols: sheet.MaxCol, MaxRows: sheet.MaxRow, SheetID: sheetID}
		jSheet.Rows = []Row{}
		for rowIndex, row := range sheet.Rows {
			rowID := fmt.Sprintf("%d-%d", sheetIndex, rowIndex)
			jRow := Row{RowID: rowID}
			jRow.Cols = []Col{}
			for cellIndex, cell := range row.Cells {
				colID := fmt.Sprintf("%d-%d-%d", sheetIndex, rowIndex, cellIndex)
				jCol := Col{ColID: colID}
				value, err := cell.FormattedValue()
				if err != nil {
					value = err.Error()
				}
				jCol.Value = value
				jRow.Cols = append(jRow.Cols, jCol)
			}
			jSheet.Rows = append(jSheet.Rows, jRow)
		}
		excelData.Sheets = append(excelData.Sheets, jSheet)
	}
	fmt.Println(excelData)
	enc := json.NewEncoder(w)
	enc.Encode(excelData)
}

func APIHandler(w traffic.ResponseWriter, r *traffic.Request) {
	params := r.URL.Query()
	call := params.Get("call")
	if call == "conversion" {
		excelResponse(w, r);
	}
}
<|endoftext|>


<commit_before>package termbox

import (
	"syscall"
)

// public API

// Initializes termbox library. This function should be called before any other functions.
// After successful initialization, the library must be finalized using 'Close' function.
//
// Example usage:
//      err := termbox.Init()
//      if err != nil {
//              panic(err)
//      }
//      defer termbox.Close()
func Init() error {
	var err error

	interrupt, err = create_event()
	if err != nil {
		return err
	}

	in, err = syscall.Open("CONIN$", syscall.O_RDWR, 0)
	if err != nil {
		return err
	}
	out, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0)
	if err != nil {
		return err
	}

	err = get_console_mode(in, &orig_mode)
	if err != nil {
		return err
	}

	err = set_console_mode(in, enable_window_input)
	if err != nil {
		return err
	}

	orig_size = get_term_size(out)
	win_size := get_win_size(out)

	err = set_console_screen_buffer_size(out, win_size)
	if err != nil {
		return err
	}

	err = get_console_cursor_info(out, &orig_cursor_info)
	if err != nil {
		return err
	}

	show_cursor(false)
	term_size = get_term_size(out)
	back_buffer.init(int(term_size.x), int(term_size.y))
	front_buffer.init(int(term_size.x), int(term_size.y))
	back_buffer.clear()
	front_buffer.clear()
	clear()

	diffbuf = make([]diff_msg, 0, 32)

	go input_event_producer()
	IsInit = true
	return nil
}

// Finalizes termbox library, should be called after successful initialization
// when termbox's functionality isn't required anymore.
func Close() {
	// we ignore errors here, because we can't really do anything about them
	Clear(0, 0)
	Flush()

	// stop event producer
	cancel_comm <- true
	set_event(interrupt)
	<-cancel_done_comm

	set_console_cursor_info(out, &orig_cursor_info)
	set_console_cursor_position(out, coord{})
	set_console_screen_buffer_size(out, orig_size)
	set_console_mode(in, orig_mode)
	syscall.Close(in)
	syscall.Close(out)
	syscall.Close(interrupt)
	IsInit = false
}

// Interrupt an in-progress call to PollEvent by causing it to return
// EventInterrupt.  Note that this function will block until the PollEvent
// function has successfully been interrupted.
func Interrupt() {
	interrupt_comm <- struct{}{}
}

// Synchronizes the internal back buffer with the terminal.
func Flush() error {
	update_size_maybe()
	prepare_diff_messages()
	for _, diff := range diffbuf {
		r := small_rect{
			left:   0,
			top:    diff.pos,
			right:  term_size.x - 1,
			bottom: diff.pos + diff.lines - 1,
		}
		write_console_output(out, diff.chars, r)
	}
	if !is_cursor_hidden(cursor_x, cursor_y) {
		move_cursor(cursor_x, cursor_y)
	}
	return nil
}

// Sets the position of the cursor. See also HideCursor().
func SetCursor(x, y int) {
	if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
		show_cursor(true)
	}

	if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
		show_cursor(false)
	}

	cursor_x, cursor_y = x, y
	if !is_cursor_hidden(cursor_x, cursor_y) {
		move_cursor(cursor_x, cursor_y)
	}
}

// The shortcut for SetCursor(-1, -1).
func HideCursor() {
	SetCursor(cursor_hidden, cursor_hidden)
}

// Changes cell's parameters in the internal back buffer at the specified
// position.
func SetCell(x, y int, ch rune, fg, bg Attribute) {
	if x < 0 || x >= back_buffer.width {
		return
	}
	if y < 0 || y >= back_buffer.height {
		return
	}

	back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
}

// Returns a slice into the termbox's back buffer. You can get its dimensions
// using 'Size' function. The slice remains valid as long as no 'Clear' or
// 'Flush' function calls were made after call to this function.
func CellBuffer() []Cell {
	return back_buffer.cells
}

// Wait for an event and return it. This is a blocking function call.
func PollEvent() Event {
	select {
	case ev := <-input_comm:
		return ev
	case <-interrupt_comm:
		return Event{Type: EventInterrupt}
	}
}

// Returns the size of the internal back buffer (which is mostly the same as
// console's window size in characters). But it doesn't always match the size
// of the console window, after the console size has changed, the internal back
// buffer will get in sync only after Clear or Flush function calls.
func Size() (int, int) {
	return int(term_size.x), int(term_size.y)
}

// Clears the internal back buffer.
func Clear(fg, bg Attribute) error {
	foreground, background = fg, bg
	update_size_maybe()
	back_buffer.clear()
	return nil
}

// Sets termbox input mode. Termbox has two input modes:
//
// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC means KeyEsc. This is the default input mode.
//
// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
//
// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
// enable mouse button click events.
//
// If 'mode' is InputCurrent, returns the current input mode. See also Input*
// constants.
func SetInputMode(mode InputMode) InputMode {
	if mode == InputCurrent {
		return input_mode
	}
	if mode&InputMouse != 0 {
		err := set_console_mode(in, enable_window_input|enable_mouse_input|enable_extended_flags)
		if err != nil {
			panic(err)
		}
	} else {
		err := set_console_mode(in, enable_window_input)
		if err != nil {
			panic(err)
		}
	}

	input_mode = mode
	return input_mode
}

// Sets the termbox output mode.
//
// Windows console does not support extra colour modes,
// so this will always set and return OutputNormal.
func SetOutputMode(mode OutputMode) OutputMode {
	return OutputNormal
}

// Sync comes handy when something causes desync between termbox's understanding
// of a terminal buffer and the reality. Such as a third party process. Sync
// forces a complete resync between the termbox and a terminal, it may not be
// visually pretty though. At the moment on Windows it does nothing.
func Sync() error {
	return nil
}
<commit_msg>Fix hang with termbox.Close() on Windows<commit_after>package termbox

import (
	"syscall"
)

// public API

// Initializes termbox library. This function should be called before any other functions.
// After successful initialization, the library must be finalized using 'Close' function.
//
// Example usage:
//      err := termbox.Init()
//      if err != nil {
//              panic(err)
//      }
//      defer termbox.Close()
func Init() error {
	var err error

	interrupt, err = create_event()
	if err != nil {
		return err
	}

	in, err = syscall.Open("CONIN$", syscall.O_RDWR, 0)
	if err != nil {
		return err
	}
	out, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0)
	if err != nil {
		return err
	}

	err = get_console_mode(in, &orig_mode)
	if err != nil {
		return err
	}

	err = set_console_mode(in, enable_window_input)
	if err != nil {
		return err
	}

	orig_size = get_term_size(out)
	win_size := get_win_size(out)

	err = set_console_screen_buffer_size(out, win_size)
	if err != nil {
		return err
	}

	err = get_console_cursor_info(out, &orig_cursor_info)
	if err != nil {
		return err
	}

	show_cursor(false)
	term_size = get_term_size(out)
	back_buffer.init(int(term_size.x), int(term_size.y))
	front_buffer.init(int(term_size.x), int(term_size.y))
	back_buffer.clear()
	front_buffer.clear()
	clear()

	diffbuf = make([]diff_msg, 0, 32)

	go input_event_producer()
	IsInit = true
	return nil
}

// Finalizes termbox library, should be called after successful initialization
// when termbox's functionality isn't required anymore.
func Close() {
	// we ignore errors here, because we can't really do anything about them
	Clear(0, 0)
	Flush()

	// stop event producer
	cancel_comm <- true
	set_event(interrupt)
	select {
		case <-input_comm:
		default:
	}
	<-cancel_done_comm

	set_console_cursor_info(out, &orig_cursor_info)
	set_console_cursor_position(out, coord{})
	set_console_screen_buffer_size(out, orig_size)
	set_console_mode(in, orig_mode)
	syscall.Close(in)
	syscall.Close(out)
	syscall.Close(interrupt)
	IsInit = false
}

// Interrupt an in-progress call to PollEvent by causing it to return
// EventInterrupt.  Note that this function will block until the PollEvent
// function has successfully been interrupted.
func Interrupt() {
	interrupt_comm <- struct{}{}
}

// Synchronizes the internal back buffer with the terminal.
func Flush() error {
	update_size_maybe()
	prepare_diff_messages()
	for _, diff := range diffbuf {
		r := small_rect{
			left:   0,
			top:    diff.pos,
			right:  term_size.x - 1,
			bottom: diff.pos + diff.lines - 1,
		}
		write_console_output(out, diff.chars, r)
	}
	if !is_cursor_hidden(cursor_x, cursor_y) {
		move_cursor(cursor_x, cursor_y)
	}
	return nil
}

// Sets the position of the cursor. See also HideCursor().
func SetCursor(x, y int) {
	if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
		show_cursor(true)
	}

	if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
		show_cursor(false)
	}

	cursor_x, cursor_y = x, y
	if !is_cursor_hidden(cursor_x, cursor_y) {
		move_cursor(cursor_x, cursor_y)
	}
}

// The shortcut for SetCursor(-1, -1).
func HideCursor() {
	SetCursor(cursor_hidden, cursor_hidden)
}

// Changes cell's parameters in the internal back buffer at the specified
// position.
func SetCell(x, y int, ch rune, fg, bg Attribute) {
	if x < 0 || x >= back_buffer.width {
		return
	}
	if y < 0 || y >= back_buffer.height {
		return
	}

	back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
}

// Returns a slice into the termbox's back buffer. You can get its dimensions
// using 'Size' function. The slice remains valid as long as no 'Clear' or
// 'Flush' function calls were made after call to this function.
func CellBuffer() []Cell {
	return back_buffer.cells
}

// Wait for an event and return it. This is a blocking function call.
func PollEvent() Event {
	select {
	case ev := <-input_comm:
		return ev
	case <-interrupt_comm:
		return Event{Type: EventInterrupt}
	}
}

// Returns the size of the internal back buffer (which is mostly the same as
// console's window size in characters). But it doesn't always match the size
// of the console window, after the console size has changed, the internal back
// buffer will get in sync only after Clear or Flush function calls.
func Size() (int, int) {
	return int(term_size.x), int(term_size.y)
}

// Clears the internal back buffer.
func Clear(fg, bg Attribute) error {
	foreground, background = fg, bg
	update_size_maybe()
	back_buffer.clear()
	return nil
}

// Sets termbox input mode. Termbox has two input modes:
//
// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC means KeyEsc. This is the default input mode.
//
// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
//
// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
// enable mouse button click events.
//
// If 'mode' is InputCurrent, returns the current input mode. See also Input*
// constants.
func SetInputMode(mode InputMode) InputMode {
	if mode == InputCurrent {
		return input_mode
	}
	if mode&InputMouse != 0 {
		err := set_console_mode(in, enable_window_input|enable_mouse_input|enable_extended_flags)
		if err != nil {
			panic(err)
		}
	} else {
		err := set_console_mode(in, enable_window_input)
		if err != nil {
			panic(err)
		}
	}

	input_mode = mode
	return input_mode
}

// Sets the termbox output mode.
//
// Windows console does not support extra colour modes,
// so this will always set and return OutputNormal.
func SetOutputMode(mode OutputMode) OutputMode {
	return OutputNormal
}

// Sync comes handy when something causes desync between termbox's understanding
// of a terminal buffer and the reality. Such as a third party process. Sync
// forces a complete resync between the termbox and a terminal, it may not be
// visually pretty though. At the moment on Windows it does nothing.
func Sync() error {
	return nil
}
<|endoftext|>


<commit_before>package schema

import (
	"context"
	"fmt"
	"net/http"
	"strings"

	"hermes/models"

	"github.com/jinzhu/gorm"
	"github.com/labstack/echo"
)

type (
	entity struct {
		Table string
		Field string
	}

	field struct {
		Name      string
		Operator  string
		Value     Value
		Next      *operation
		Condition *string
	}

	operation struct {
		Condition string
		Field     field
	}

	Resolver struct{}
)

func errorResponse() error {
	return echo.NewHTTPError(http.StatusInternalServerError)
}

func (r *Resolver) Count(context context.Context, args struct{ Field field }) (int32, error) {
	var total int32

	if db, castOk := context.Value(DB).(*gorm.DB); castOk {
		fields := args.Field.flatten([]*field{})
		queries := []*gorm.DB{}

		for index, field := range fields {
			query := field.query(db)
			errorList := query.GetErrors()

			queries = append(queries, query)

			if !(len(errorList) > 0 || query.Error != nil || query.Value == nil) {
				if field.Condition != nil {
					switch *field.Condition {
					case "OR":
						var count int32

						query.Count(&count)

						total += count
					case "AND":
						// TODO: Implement reducer for AND queries
					}
				} else if index == 0 {
					var count int32

					query.Count(&count)

					total += count
				}
			}
			// TODO: Handle db error
		}
	}

	// TODO: Handle non existent db

	return total, nil
}

func (r *Resolver) Average(context context.Context, args struct{ Field field }) (float64, error) {
	// TODO: Implement

	return 0, nil
}

func (f *field) flatten(buffer []*field) []*field {
	if f.Next != nil {
		f.Next.Field.Condition = &f.Next.Condition
		f.Next.Field.flatten(buffer)
	} else {
		buffer = append(buffer, f)
	}

	return buffer
}

func (f *field) query(db *gorm.DB) *gorm.DB {
	var value interface{}

	operator := f.resolveOperator(f.Value)
	entity := f.getEntity()
	where := fmt.Sprintf("%s %s ?", entity.Field, operator)

	if f.Value.String != nil {
		value = f.Value.String
	} else if f.Value.Int != nil {
		value = f.Value.Int
	} else if f.Value.Float != nil {
		value = f.Value.Float
	} else if f.Value.Bool != nil {
		value = f.Value.Bool
	}

	switch entity.Table {
	case "apps":
		return db.Where(where, value).Find(&[]models.App{})
	case "appusers":
		return db.Where(where, value).Find(&[]models.AppUser{})
	case "brands":
		return db.Where(where, value).Find(&[]models.Brand{})
	case "browsers":
		return db.Where(where, value).Find(&[]models.Browser{})
	case "devices":
		return db.Where(where, value).Find(&[]models.Device{})
	case "messages":
		return db.Where(where, value).Find(&[]models.Message{})
	case "platforms":
		return db.Where(where, value).Find(&[]models.Platform{})
	case "ranges":
		return db.Where(where, value).Find(&[]models.Range{})
	case "ratings":
		fallthrough
	default:
		return db.Where(where, value).Find(&[]models.Rating{})
	}
}

func (f *field) getEntity() entity {
	splitField := strings.Split(f.Name, ".")

	return entity{Table: splitField[0], Field: splitField[1]}
}

func (f *field) resolveOperator(value interface{}) string {
	switch f.Operator {
	case "EQ":
		return f.resolveEQOperator(value)
	}

	return f.Operator
}

func (f *field) resolveEQOperator(value interface{}) string {
	switch value.(type) {
	case string:
		return "LIKE"
	default:
		return "="
	}
}
<commit_msg>Extracted getValue()<commit_after>package schema

import (
	"context"
	"fmt"
	"net/http"
	"strings"

	"hermes/models"

	"github.com/jinzhu/gorm"
	"github.com/labstack/echo"
)

type (
	entity struct {
		Table string
		Field string
	}

	field struct {
		Name      string
		Operator  string
		Value     Value
		Next      *operation
		Condition *string
	}

	operation struct {
		Condition string
		Field     field
	}

	Resolver struct{}
)

func errorResponse() error {
	return echo.NewHTTPError(http.StatusInternalServerError)
}

func (r *Resolver) Count(context context.Context, args struct{ Field field }) (int32, error) {
	var total int32

	if db, castOk := context.Value(DB).(*gorm.DB); castOk {
		fields := args.Field.flatten([]*field{})
		queries := []*gorm.DB{}

		for index, field := range fields {
			query := field.query(db)
			errorList := query.GetErrors()

			queries = append(queries, query)

			if !(len(errorList) > 0 || query.Error != nil || query.Value == nil) {
				if field.Condition != nil {
					switch *field.Condition {
					case "OR":
						var count int32

						query.Count(&count)

						total += count
					case "AND":
						// TODO: Implement reducer for AND queries
					}
				} else if index == 0 {
					var count int32

					query.Count(&count)

					total += count
				}
			}
			// TODO: Handle db error
		}
	}

	// TODO: Handle non existent db

	return total, nil
}

func (r *Resolver) Average(context context.Context, args struct{ Field field }) (float64, error) {
	// TODO: Implement

	return 0, nil
}

func (f *field) flatten(buffer []*field) []*field {
	if f.Next != nil {
		f.Next.Field.Condition = &f.Next.Condition
		f.Next.Field.flatten(buffer)
	} else {
		buffer = append(buffer, f)
	}

	return buffer
}

func (f *field) query(db *gorm.DB) *gorm.DB {
	operator := f.resolveOperator(f.Value)
	entity := f.getEntity()
	value := f.getValue()
	where := fmt.Sprintf("%s %s ?", entity.Field, operator)

	switch entity.Table {
	case "apps":
		return db.Where(where, value).Find(&[]models.App{})
	case "appusers":
		return db.Where(where, value).Find(&[]models.AppUser{})
	case "brands":
		return db.Where(where, value).Find(&[]models.Brand{})
	case "browsers":
		return db.Where(where, value).Find(&[]models.Browser{})
	case "devices":
		return db.Where(where, value).Find(&[]models.Device{})
	case "messages":
		return db.Where(where, value).Find(&[]models.Message{})
	case "platforms":
		return db.Where(where, value).Find(&[]models.Platform{})
	case "ranges":
		return db.Where(where, value).Find(&[]models.Range{})
	case "ratings":
		fallthrough
	default:
		return db.Where(where, value).Find(&[]models.Rating{})
	}
}

func (f *field) getEntity() entity {
	splitField := strings.Split(f.Name, ".")

	return entity{Table: splitField[0], Field: splitField[1]}
}

func (f *field) getValue() interface{} {
	if f.Value.String != nil {
		return f.Value.String
	} else if f.Value.Int != nil {
		return f.Value.Int
	} else if f.Value.Float != nil {
		return f.Value.Float
	} else if f.Value.Bool != nil {
		return f.Value.Bool
	}

	return nil
}

func (f *field) resolveOperator(value interface{}) string {
	switch f.Operator {
	case "EQ":
		return f.resolveEQOperator(value)
	}

	return f.Operator
}

func (f *field) resolveEQOperator(value interface{}) string {
	switch value.(type) {
	case string:
		return "LIKE"
	default:
		return "="
	}
}
<|endoftext|>


<commit_before>package bot

import (
	"math/rand"
	"regexp"

	"github.com/etcinit/phabulous/app/factories"
	"github.com/etcinit/phabulous/app/messages"
	"github.com/nlopes/slack"
)

// NewBot creates a new instance of a Bot.
func NewBot(
	slacker *SlackService,
	slackRTM *slack.RTM,
	slackInfo *slack.Info,
) *Bot {
	bot := &Bot{
		Slacker:      slacker,
		slackInfo:    slackInfo,
		slackRTM:     slackRTM,
		imChannelIDs: map[string]bool{},
	}

	// Make it easy to lookup if a channel is an IM channel.
	for _, im := range slackInfo.IMs {
		bot.imChannelIDs[im.ID] = true
	}

	// Load message handlers
	bot.loadHandlers()

	return bot
}

// Bot represents the state of the bot. It also contains functions related to
// the interactive portion of Phabulous.
type Bot struct {
	Slacker *SlackService
	Factory *factories.GonduitFactory

	slackInfo    *slack.Info
	slackRTM     *slack.RTM
	imChannelIDs map[string]bool
	handlers     map[*regexp.Regexp]func(*slack.MessageEvent, []string)
	imHandlers   map[*regexp.Regexp]func(*slack.MessageEvent, []string)
}

func (b *Bot) mentionRegex(contents string) *regexp.Regexp {
	username := b.slackInfo.User.ID

	return regexp.MustCompile("^<@" + username + ">: " + contents + "$")
}

func (b *Bot) loadHandlers() {
	b.handlers = map[*regexp.Regexp]func(*slack.MessageEvent, []string){}
	b.imHandlers = map[*regexp.Regexp]func(*slack.MessageEvent, []string){}

	b.imHandlers[regexp.MustCompile("^lookup ([T|D][0-9]{1,16})$")] =
		b.HandleLookup
	b.imHandlers[regexp.MustCompile("^([T|D][0-9]{1,16})$")] =
		b.HandleLookup
	b.imHandlers[regexp.MustCompile("^help$")] = b.HandleHelp

	b.imHandlers[regexp.MustCompile("dev:post:feed:test")] =
		b.HandleTestFeedMessage

	b.handlers[b.mentionRegex("summon D([0-9]{1,16})")] =
		b.HandleSummon
	b.handlers[b.mentionRegex("help")] = b.HandleHelp
	b.handlers[b.mentionRegex("([T|D][0-9]{1,16})")] = b.HandleLookup
	b.handlers[b.mentionRegex("lookup ([T|D][0-9]{1,16})")] = b.HandleLookup
	b.handlers[regexp.MustCompile("^([T|D][0-9]{1,16})$")] = b.HandleLookup
	b.handlers[regexp.MustCompile(
		"meme ([^ ]{1,128}) \"(.{1,128})\" \"(.{1,128})\"$",
	)] = b.HandleCreateMeme
}

// Excuse comes up with an excuse of why something failed.
func (b *Bot) Excuse(ev *slack.MessageEvent, err error) {
	b.Slacker.Logger.Error(err)

	if b.Slacker.Config.GetBool("server.serious") {
		b.Slacker.SimplePost(
			ev.Channel,
			"An error ocurred and I was unable to fulfill your request.",
			messages.IconDefault,
			true,
		)

		return
	}

	excuses := []string{
		"There is some interference right now and I can't fulfill your request.",
		"Oh noes. I messed up.",
		"Whoops. Something went wrong.",
		"1000s lines of code and I still cant get some things right.",
		"[explodes]",
		"Error: WHY U NO WORK?!",
		"OMG! It failed.",
		"such failure. such request.",
		"Oops I did it again...",
		"A cat is walking over my keywpdfahsgasgdadfk kj h",
	}

	b.Slacker.SimplePost(
		ev.Channel,
		excuses[rand.Intn(len(excuses))],
		messages.IconDefault,
		true,
	)
}

// ProcessIMOpen handles IM open events.
func (b *Bot) ProcessIMOpen(ev *slack.IMOpenEvent) {
	b.imChannelIDs[ev.Channel] = true
}

// ProcessMessage processes incoming messages events and calls the appropriate
// handlers.
func (b *Bot) ProcessMessage(ev *slack.MessageEvent) {
	// Ignore messages from the bot itself.
	if ev.User == b.slackInfo.User.ID {
		return
	}

	// If the message is an IM, use IM handlers.
	if _, ok := b.imChannelIDs[ev.Channel]; ok {
		handled := false

		for re, handler := range b.imHandlers {
			if result := re.FindStringSubmatch(ev.Text); result != nil {
				go handler(ev, result)

				handled = true
			}
		}

		// On an IM, we will show a small help message if no handlers are found.
		if handled == false {
			go b.HandleUsage(ev, []string{})
		}

		return
	}

	for re, handler := range b.handlers {
		if result := re.FindStringSubmatch(ev.Text); result != nil {
			go handler(ev, result)
		}
	}
}
<commit_msg>Make colon in @mention optional<commit_after>package bot

import (
	"math/rand"
	"regexp"

	"github.com/etcinit/phabulous/app/factories"
	"github.com/etcinit/phabulous/app/messages"
	"github.com/nlopes/slack"
)

// NewBot creates a new instance of a Bot.
func NewBot(
	slacker *SlackService,
	slackRTM *slack.RTM,
	slackInfo *slack.Info,
) *Bot {
	bot := &Bot{
		Slacker:      slacker,
		slackInfo:    slackInfo,
		slackRTM:     slackRTM,
		imChannelIDs: map[string]bool{},
	}

	// Make it easy to lookup if a channel is an IM channel.
	for _, im := range slackInfo.IMs {
		bot.imChannelIDs[im.ID] = true
	}

	// Load message handlers
	bot.loadHandlers()

	return bot
}

// Bot represents the state of the bot. It also contains functions related to
// the interactive portion of Phabulous.
type Bot struct {
	Slacker *SlackService
	Factory *factories.GonduitFactory

	slackInfo    *slack.Info
	slackRTM     *slack.RTM
	imChannelIDs map[string]bool
	handlers     map[*regexp.Regexp]func(*slack.MessageEvent, []string)
	imHandlers   map[*regexp.Regexp]func(*slack.MessageEvent, []string)
}

func (b *Bot) mentionRegex(contents string) *regexp.Regexp {
	username := b.slackInfo.User.ID

	return regexp.MustCompile("^<@" + username + ">:? " + contents + "$")
}

func (b *Bot) loadHandlers() {
	b.handlers = map[*regexp.Regexp]func(*slack.MessageEvent, []string){}
	b.imHandlers = map[*regexp.Regexp]func(*slack.MessageEvent, []string){}

	b.imHandlers[regexp.MustCompile("^lookup ([T|D][0-9]{1,16})$")] =
		b.HandleLookup
	b.imHandlers[regexp.MustCompile("^([T|D][0-9]{1,16})$")] =
		b.HandleLookup
	b.imHandlers[regexp.MustCompile("^help$")] = b.HandleHelp

	b.imHandlers[regexp.MustCompile("dev:post:feed:test")] =
		b.HandleTestFeedMessage

	b.handlers[b.mentionRegex("summon D([0-9]{1,16})")] =
		b.HandleSummon
	b.handlers[b.mentionRegex("help")] = b.HandleHelp
	b.handlers[b.mentionRegex("([T|D][0-9]{1,16})")] = b.HandleLookup
	b.handlers[b.mentionRegex("lookup ([T|D][0-9]{1,16})")] = b.HandleLookup
	b.handlers[regexp.MustCompile("^([T|D][0-9]{1,16})$")] = b.HandleLookup
	b.handlers[regexp.MustCompile(
		"meme ([^ ]{1,128}) \"(.{1,128})\" \"(.{1,128})\"$",
	)] = b.HandleCreateMeme
}

// Excuse comes up with an excuse of why something failed.
func (b *Bot) Excuse(ev *slack.MessageEvent, err error) {
	b.Slacker.Logger.Error(err)

	if b.Slacker.Config.GetBool("server.serious") {
		b.Slacker.SimplePost(
			ev.Channel,
			"An error ocurred and I was unable to fulfill your request.",
			messages.IconDefault,
			true,
		)

		return
	}

	excuses := []string{
		"There is some interference right now and I can't fulfill your request.",
		"Oh noes. I messed up.",
		"Whoops. Something went wrong.",
		"1000s lines of code and I still cant get some things right.",
		"[explodes]",
		"Error: WHY U NO WORK?!",
		"OMG! It failed.",
		"such failure. such request.",
		"Oops I did it again...",
		"A cat is walking over my keywpdfahsgasgdadfk kj h",
	}

	b.Slacker.SimplePost(
		ev.Channel,
		excuses[rand.Intn(len(excuses))],
		messages.IconDefault,
		true,
	)
}

// ProcessIMOpen handles IM open events.
func (b *Bot) ProcessIMOpen(ev *slack.IMOpenEvent) {
	b.imChannelIDs[ev.Channel] = true
}

// ProcessMessage processes incoming messages events and calls the appropriate
// handlers.
func (b *Bot) ProcessMessage(ev *slack.MessageEvent) {
	// Ignore messages from the bot itself.
	if ev.User == b.slackInfo.User.ID {
		return
	}

	// If the message is an IM, use IM handlers.
	if _, ok := b.imChannelIDs[ev.Channel]; ok {
		handled := false

		for re, handler := range b.imHandlers {
			if result := re.FindStringSubmatch(ev.Text); result != nil {
				go handler(ev, result)

				handled = true
			}
		}

		// On an IM, we will show a small help message if no handlers are found.
		if handled == false {
			go b.HandleUsage(ev, []string{})
		}

		return
	}

	for re, handler := range b.handlers {
		if result := re.FindStringSubmatch(ev.Text); result != nil {
			go handler(ev, result)
		}
	}
}
<|endoftext|>


<commit_before>package dptest

import (
	"strconv"
	"sync"
	"sync/atomic"
	"time"

	"github.com/signalfx/golib/v3/datapoint"
	"github.com/signalfx/golib/v3/event"
	"github.com/signalfx/golib/v3/pointer"
	"github.com/signalfx/golib/v3/trace"
)

// DatapointSource is a simple way to generate throw away datapoints
type DatapointSource struct {
	mu sync.Mutex

	CurrentIndex int64
	Metric       string
	Dims         map[string]string
	Dptype       datapoint.MetricType
	TimeSource   func() time.Time
}

var globalSource DatapointSource

func init() {
	globalSource.Metric = "random"
	globalSource.Dims = map[string]string{"source": "randtest"}
	globalSource.Dptype = datapoint.Gauge
	globalSource.TimeSource = time.Now
	globalEventSource.EventType = "imanotify.notify_instance"
	globalEventSource.Dims = map[string]string{"host": "mwp-signalbox", "plugin": "my_plugin", "f": "x", "plugin_instance": "my_plugin_instance", "k": "v"}
	globalEventSource.Meta = map[string]interface{}{"string": "value", "boolean": true, "int": int64(40), "double": 0.0}
	globalEventSource.TimeSource = time.Now
	globalEventSource.Category = event.COLLECTD
	globalSpanSource.TimeSource = time.Now().UnixNano
	globalSpanSource.Name = "test-span"
}

// Next returns a unique datapoint
func (d *DatapointSource) Next() *datapoint.Datapoint {
	d.mu.Lock()
	defer d.mu.Unlock()
	return datapoint.New(d.Metric+":"+strconv.FormatInt(atomic.AddInt64(&d.CurrentIndex, 1), 10), d.Dims, datapoint.NewIntValue(0), d.Dptype, d.TimeSource())
}

// DP generates and returns a unique datapoint to use for testing purposes
func DP() *datapoint.Datapoint {
	return globalSource.Next()
}

// EventSource is a simple way to generate throw away events
type EventSource struct {
	mu sync.Mutex

	CurrentIndex int64
	EventType    string
	Category     event.Category
	Dims         map[string]string
	Meta         map[string]interface{}
	TimeSource   func() time.Time
}

var globalEventSource EventSource

// Next returns a unique event
func (d *EventSource) Next() *event.Event {
	d.mu.Lock()
	defer d.mu.Unlock()

	dims := make(map[string]string, len(d.Dims)+1)
	for k, v := range d.Dims {
		dims[k] = v
	}
	dims["index"] = strconv.FormatInt(atomic.AddInt64(&d.CurrentIndex, 1), 10)

	return event.NewWithProperties(d.EventType, d.Category, d.Dims, d.Meta, d.TimeSource())
}

// E generates and returns a unique event to use for testing purposes
func E() *event.Event {
	return globalEventSource.Next()
}

// SpanSource is a simple way to generate throw away spans
type SpanSource struct {
	mu sync.Mutex

	TimeSource   func() int64
	Name         string
	CurrentIndex int64
}

var globalSpanSource SpanSource

// Next return a unique span
func (d *SpanSource) Next() *trace.Span {
	d.mu.Lock()
	defer d.mu.Unlock()

	randomID := strconv.FormatInt(d.TimeSource(), 16)
	return &trace.Span{
		TraceID:   randomID,
		ID:        randomID,
		Name:      &d.Name,
		Timestamp: pointer.Int64(atomic.AddInt64(&d.CurrentIndex, 1)),
		Duration:  pointer.Int64((d.CurrentIndex % 15) + 5), // set duration in the range [5..20}
	}
}

// S generates and returns a unique span to use for testing purposes
func S() *trace.Span {
	return globalSpanSource.Next()
}
<commit_msg>Update dptest to copy dims so fewer data races<commit_after>package dptest

import (
	"strconv"
	"sync"
	"sync/atomic"
	"time"

	"github.com/signalfx/golib/v3/datapoint"
	"github.com/signalfx/golib/v3/event"
	"github.com/signalfx/golib/v3/pointer"
	"github.com/signalfx/golib/v3/trace"
)

// DatapointSource is a simple way to generate throw away datapoints
type DatapointSource struct {
	mu sync.Mutex

	CurrentIndex int64
	Metric       string
	Dims         map[string]string
	Dptype       datapoint.MetricType
	TimeSource   func() time.Time
}

var globalSource DatapointSource

func init() {
	globalSource.Metric = "random"
	globalSource.Dims = map[string]string{"source": "randtest"}
	globalSource.Dptype = datapoint.Gauge
	globalSource.TimeSource = time.Now
	globalEventSource.EventType = "imanotify.notify_instance"
	globalEventSource.Dims = map[string]string{"host": "mwp-signalbox", "plugin": "my_plugin", "f": "x", "plugin_instance": "my_plugin_instance", "k": "v"}
	globalEventSource.Meta = map[string]interface{}{"string": "value", "boolean": true, "int": int64(40), "double": 0.0}
	globalEventSource.TimeSource = time.Now
	globalEventSource.Category = event.COLLECTD
	globalSpanSource.TimeSource = time.Now().UnixNano
	globalSpanSource.Name = "test-span"
}

func copyMap(in map[string]string) map[string]string {
	ret := make(map[string]string, len(in))
	for k, v := range in {
		ret[k] = v
	}
	return ret
}

// Next returns a unique datapoint
func (d *DatapointSource) Next() *datapoint.Datapoint {
	d.mu.Lock()
	defer d.mu.Unlock()
	return datapoint.New(d.Metric+":"+strconv.FormatInt(atomic.AddInt64(&d.CurrentIndex, 1), 10), copyMap(d.Dims), datapoint.NewIntValue(0), d.Dptype, d.TimeSource())
}

// DP generates and returns a unique datapoint to use for testing purposes
func DP() *datapoint.Datapoint {
	return globalSource.Next()
}

// EventSource is a simple way to generate throw away events
type EventSource struct {
	mu sync.Mutex

	CurrentIndex int64
	EventType    string
	Category     event.Category
	Dims         map[string]string
	Meta         map[string]interface{}
	TimeSource   func() time.Time
}

var globalEventSource EventSource

// Next returns a unique event
func (d *EventSource) Next() *event.Event {
	d.mu.Lock()
	defer d.mu.Unlock()

	dims := make(map[string]string, len(d.Dims)+1)
	for k, v := range d.Dims {
		dims[k] = v
	}
	dims["index"] = strconv.FormatInt(atomic.AddInt64(&d.CurrentIndex, 1), 10)

	return event.NewWithProperties(d.EventType, d.Category, d.Dims, d.Meta, d.TimeSource())
}

// E generates and returns a unique event to use for testing purposes
func E() *event.Event {
	return globalEventSource.Next()
}

// SpanSource is a simple way to generate throw away spans
type SpanSource struct {
	mu sync.Mutex

	TimeSource   func() int64
	Name         string
	CurrentIndex int64
}

var globalSpanSource SpanSource

// Next return a unique span
func (d *SpanSource) Next() *trace.Span {
	d.mu.Lock()
	defer d.mu.Unlock()

	randomID := strconv.FormatInt(d.TimeSource(), 16)
	return &trace.Span{
		TraceID:   randomID,
		ID:        randomID,
		Name:      &d.Name,
		Timestamp: pointer.Int64(atomic.AddInt64(&d.CurrentIndex, 1)),
		Duration:  pointer.Int64((d.CurrentIndex % 15) + 5), // set duration in the range [5..20}
	}
}

// S generates and returns a unique span to use for testing purposes
func S() *trace.Span {
	return globalSpanSource.Next()
}
<|endoftext|>