<commit_before>package main

import (
	"errors"
	"fmt"
	"io"
	"net"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/codegangsta/cli"
	"github.com/kr/pty"
	"github.com/mattn/go-shellwords"
	"github.com/pkg/term"

	"github.com/cloudfoundry-incubator/garden"
	gclient "github.com/cloudfoundry-incubator/garden/client"
	gconn "github.com/cloudfoundry-incubator/garden/client/connection"
)

func handleComplete(c *cli.Context) {
	// This will complete if no args are passed
	if c.Args().Present() {
		return
	}

	containers, err := client(c).Containers(nil)
	failIf(err)

	for _, container := range containers {
		fmt.Println(container.Handle())
	}
}

func fail(err error) {
	fmt.Fprintln(os.Stderr, "failed:", err)
	os.Exit(1)
}

func failIf(err error) {
	if err != nil {
		fail(err)
	}
}

func client(c *cli.Context) garden.Client {
	target := c.GlobalString("target")
	return gclient.New(gconn.New("tcp", target))
}

func handle(c *cli.Context) string {
	if len(c.Args()) == 0 {
		fail(errors.New("must provide container handle"))
	}
	return c.Args().First()
}

func main() {
	app := cli.NewApp()
	app.Name = "gaol"
	app.Usage = "a cli for garden"
	app.Version = "0.0.1"
	app.Author = "Chris Brown"
	app.Email = "cbrown@pivotal.io"
	app.EnableBashCompletion = true

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "target, t",
			Value:  "localhost:7777",
			Usage:  "server to which commands are sent",
			EnvVar: "GAOL_TARGET",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:  "ping",
			Usage: "check if the server is running",
			Action: func(c *cli.Context) {
				err := client(c).Ping()
				failIf(err)
			},
		},
		{
			Name:  "create",
			Usage: "create a container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "handle, n",
					Usage: "name to give container",
				},
				cli.StringFlag{
					Name:  "rootfs, r",
					Usage: "rootfs image with which to create the container",
				},
				cli.StringSliceFlag{
					Name:  "env, e",
					Usage: "set environment variables",
					Value: &cli.StringSlice{},
				},
				cli.DurationFlag{
					Name:  "grace, g",
					Usage: "grace time (resetting ttl) of container",
					Value: 5 * time.Minute,
				},
				cli.BoolFlag{
					Name:  "privileged, p",
					Usage: "privileged user in container is privileged in host",
				},
				cli.StringSliceFlag{
					Name:  "bind-mount, m",
					Usage: "bind-mount host-path:container-path",
					Value: &cli.StringSlice{},
				},
			},
			Action: func(c *cli.Context) {
				handle := c.String("handle")
				grace := c.Duration("grace")
				rootfs := c.String("rootfs")
				env := c.StringSlice("env")
				privileged := c.Bool("privileged")
				mounts := c.StringSlice("bind-mount")

				var bindMounts []garden.BindMount
				for _, pair := range mounts {
					segs := strings.SplitN(pair, ":", 2)
					if len(segs) != 2 {
						fail(fmt.Errorf("invalid bind-mount segment (must be host-path:container-path): %s", pair))
					}

					bindMounts = append(bindMounts, garden.BindMount{
						SrcPath: segs[0],
						DstPath: segs[1],
						Mode:    garden.BindMountModeRW,
						Origin:  garden.BindMountOriginHost,
					})
				}

				container, err := client(c).Create(garden.ContainerSpec{
					Handle:     handle,
					GraceTime:  grace,
					RootFSPath: rootfs,
					Privileged: privileged,
					Env:        env,
					BindMounts: bindMounts,
				})
				failIf(err)

				fmt.Println(container.Handle())
			},
		},
		{
			Name:         "destroy",
			Usage:        "destroy a container",
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				client := client(c)
				handles := c.Args()

				for _, handle := range handles {
					err := client.Destroy(handle)
					failIf(err)
				}
			},
		},
		{
			Name:  "list",
			Usage: "get a list of running containers",
			Flags: []cli.Flag{
				cli.StringSliceFlag{
					Name:  "properties, p",
					Usage: "filter by properties (name=val)",
					Value: &cli.StringSlice{},
				},
				cli.BoolFlag{
					Name:  "verbose, v",
					Usage: "print additional details about each container",
				},
				cli.StringFlag{
					Name:  "separator",
					Usage: "separator to print between containers in verbose mode",
					Value: "\n",
				},
			},
			Action: func(c *cli.Context) {
				separator := c.String("separator")

				properties := garden.Properties{}
				for _, prop := range c.StringSlice("properties") {
					segs := strings.SplitN(prop, "=", 2)
					if len(segs) < 2 {
						fail(errors.New("malformed property pair (must be name=value)"))
					}

					properties[segs[0]] = segs[1]
				}

				containers, err := client(c).Containers(properties)
				failIf(err)

				verbose := c.Bool("verbose")

				for _, container := range containers {
					fmt.Println(container.Handle())

					if verbose {
						props, _ := container.Properties()
						for k, v := range props {
							fmt.Printf("  %s=%s\n", k, v)
						}

						fmt.Print(separator)
					}
				}
			},
		},
		{
			Name:  "run",
			Usage: "run a command in a container",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "attach, a",
					Usage: "attach to the process after it is started",
				},
				cli.StringFlag{
					Name:  "dir, d",
					Usage: "current working directory of process",
				},
				cli.StringFlag{
					Name:  "user, u",
					Usage: "user to run the process as",
				},
				cli.StringFlag{
					Name:  "command, c",
					Usage: "the command to run",
				},
				cli.StringSliceFlag{
					Name:  "env, e",
					Usage: "set environment variables",
					Value: &cli.StringSlice{},
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				attach := c.Bool("attach")
				dir := c.String("dir")
				user := c.String("user")
				command := c.String("command")
				env := c.StringSlice("env")

				handle := handle(c)
				container, err := client(c).Lookup(handle)
				failIf(err)

				var processIo garden.ProcessIO
				if attach {
					processIo = garden.ProcessIO{
						Stdin:  os.Stdin,
						Stdout: os.Stdout,
						Stderr: os.Stderr,
					}
				} else {
					processIo = garden.ProcessIO{}
				}

				args, err := shellwords.Parse(command)
				failIf(err)

				process, err := container.Run(garden.ProcessSpec{
					Path: args[0],
					Args: args[1:],
					Dir:  dir,
					User: user,
					Env:  env,
				}, processIo)
				failIf(err)

				if attach {
					status, err := process.Wait()
					failIf(err)
					os.Exit(status)
				} else {
					fmt.Println(process.ID())
				}
			},
		},
		{
			Name:  "attach",
			Usage: "attach to command running in the container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "pid, p",
					Usage: "process id to connect to",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				pid := c.String("pid")
				if pid == "" {
					err := errors.New("must specify pid to attach to")
					failIf(err)
				}

				handle := handle(c)
				container, err := client(c).Lookup(handle)
				failIf(err)

				process, err := container.Attach(pid, garden.ProcessIO{
					Stdin:  os.Stdin,
					Stdout: os.Stdout,
					Stderr: os.Stderr,
				})
				failIf(err)

				_, err = process.Wait()
				failIf(err)
			},
		},
		{
			Name:  "shell",
			Usage: "open a shell inside the running container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "user, u",
					Usage: "user to open shell as",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				container, err := client(c).Lookup(handle(c))
				failIf(err)

				term, err := term.Open(os.Stdin.Name())
				failIf(err)

				err = term.SetRaw()
				failIf(err)

				rows, cols, err := pty.Getsize(os.Stdin)
				failIf(err)

				process, err := container.Run(garden.ProcessSpec{
					User: c.String("user"),
					Path: "/bin/sh",
					Args: []string{"-l"},
					Env:  []string{"TERM=" + os.Getenv("TERM")},
					TTY: &garden.TTYSpec{
						WindowSize: &garden.WindowSize{
							Rows:    rows,
							Columns: cols,
						},
					},
				}, garden.ProcessIO{
					Stdin:  term,
					Stdout: term,
					Stderr: term,
				})
				if err != nil {
					term.Restore()
					failIf(err)
				}

				resized := make(chan os.Signal, 10)
				signal.Notify(resized, syscall.SIGWINCH)

				go func() {
					for {
						<-resized

						rows, cols, err := pty.Getsize(os.Stdin)
						if err == nil {
							process.SetTTY(garden.TTYSpec{
								WindowSize: &garden.WindowSize{
									Rows:    rows,
									Columns: cols,
								},
							})
						}
					}
				}()

				process.Wait()
				term.Restore()
			},
		},
		{
			Name:  "stream-in",
			Usage: "stream data into the container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "destination, d",
					Usage: "destination path in the container",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				handle := handle(c)

				dst := c.String("destination")
				if dst == "" {
					fail(errors.New("missing --destination flag"))
				}

				container, err := client(c).Lookup(handle)
				failIf(err)

				streamInSpec := garden.StreamInSpec{
					Path:      dst,
					TarStream: os.Stdin,
				}

				err = container.StreamIn(streamInSpec)
				failIf(err)
			},
		},
		{
			Name:  "stream-out",
			Usage: "stream data out of the container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "source, s",
					Usage: "source path in the container",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				handle := handle(c)

				src := c.String("source")
				if src == "" {
					fail(errors.New("missing --source flag"))
				}

				container, err := client(c).Lookup(handle)
				failIf(err)

				streamOutSpec := garden.StreamOutSpec{Path: src}
				output, err := container.StreamOut(streamOutSpec)
				failIf(err)

				io.Copy(os.Stdout, output)
			},
		},
		{
			Name:  "net-in",
			Usage: "map a port on the host to a port in the container",
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "port, p",
					Usage: "container port",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				target := c.GlobalString("target")
				requestedContainerPort := uint32(c.Int("port"))

				if target == "" {
					fail(errors.New("target must be set"))
				}

				handle := handle(c)
				container, err := client(c).Lookup(handle)
				failIf(err)

				hostPort, _, err := container.NetIn(0, requestedContainerPort)
				failIf(err)

				host, _, err := net.SplitHostPort(target)
				failIf(err)

				fmt.Println(net.JoinHostPort(host, fmt.Sprintf("%d", hostPort)))
			},
		},
	}

	app.Run(os.Args)
}
<commit_msg>add network flag to create<commit_after>package main

import (
	"errors"
	"fmt"
	"io"
	"net"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/codegangsta/cli"
	"github.com/kr/pty"
	"github.com/mattn/go-shellwords"
	"github.com/pkg/term"

	"github.com/cloudfoundry-incubator/garden"
	gclient "github.com/cloudfoundry-incubator/garden/client"
	gconn "github.com/cloudfoundry-incubator/garden/client/connection"
)

func handleComplete(c *cli.Context) {
	// This will complete if no args are passed
	if c.Args().Present() {
		return
	}

	containers, err := client(c).Containers(nil)
	failIf(err)

	for _, container := range containers {
		fmt.Println(container.Handle())
	}
}

func fail(err error) {
	fmt.Fprintln(os.Stderr, "failed:", err)
	os.Exit(1)
}

func failIf(err error) {
	if err != nil {
		fail(err)
	}
}

func client(c *cli.Context) garden.Client {
	target := c.GlobalString("target")
	return gclient.New(gconn.New("tcp", target))
}

func handle(c *cli.Context) string {
	if len(c.Args()) == 0 {
		fail(errors.New("must provide container handle"))
	}
	return c.Args().First()
}

func main() {
	app := cli.NewApp()
	app.Name = "gaol"
	app.Usage = "a cli for garden"
	app.Version = "0.0.1"
	app.Author = "Chris Brown"
	app.Email = "cbrown@pivotal.io"
	app.EnableBashCompletion = true

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "target, t",
			Value:  "localhost:7777",
			Usage:  "server to which commands are sent",
			EnvVar: "GAOL_TARGET",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:  "ping",
			Usage: "check if the server is running",
			Action: func(c *cli.Context) {
				err := client(c).Ping()
				failIf(err)
			},
		},
		{
			Name:  "create",
			Usage: "create a container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "handle, n",
					Usage: "name to give container",
				},
				cli.StringFlag{
					Name:  "rootfs, r",
					Usage: "rootfs image with which to create the container",
				},
				cli.StringSliceFlag{
					Name:  "env, e",
					Usage: "set environment variables",
					Value: &cli.StringSlice{},
				},
				cli.DurationFlag{
					Name:  "grace, g",
					Usage: "grace time (resetting ttl) of container",
					Value: 5 * time.Minute,
				},
				cli.BoolFlag{
					Name:  "privileged, p",
					Usage: "privileged user in container is privileged in host",
				},
				cli.StringFlag{
					Name:  "network",
					Usage: "the subnet of the container",
				},
				cli.StringSliceFlag{
					Name:  "bind-mount, m",
					Usage: "bind-mount host-path:container-path",
					Value: &cli.StringSlice{},
				},
			},
			Action: func(c *cli.Context) {
				handle := c.String("handle")
				grace := c.Duration("grace")
				rootfs := c.String("rootfs")
				env := c.StringSlice("env")
				privileged := c.Bool("privileged")
				network := c.String("network")
				mounts := c.StringSlice("bind-mount")

				var bindMounts []garden.BindMount
				for _, pair := range mounts {
					segs := strings.SplitN(pair, ":", 2)
					if len(segs) != 2 {
						fail(fmt.Errorf("invalid bind-mount segment (must be host-path:container-path): %s", pair))
					}

					bindMounts = append(bindMounts, garden.BindMount{
						SrcPath: segs[0],
						DstPath: segs[1],
						Mode:    garden.BindMountModeRW,
						Origin:  garden.BindMountOriginHost,
					})
				}

				container, err := client(c).Create(garden.ContainerSpec{
					Handle:     handle,
					GraceTime:  grace,
					RootFSPath: rootfs,
					Privileged: privileged,
					Env:        env,
					Network:    network,
					BindMounts: bindMounts,
				})
				failIf(err)

				fmt.Println(container.Handle())
			},
		},
		{
			Name:         "destroy",
			Usage:        "destroy a container",
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				client := client(c)
				handles := c.Args()

				for _, handle := range handles {
					err := client.Destroy(handle)
					failIf(err)
				}
			},
		},
		{
			Name:  "list",
			Usage: "get a list of running containers",
			Flags: []cli.Flag{
				cli.StringSliceFlag{
					Name:  "properties, p",
					Usage: "filter by properties (name=val)",
					Value: &cli.StringSlice{},
				},
				cli.BoolFlag{
					Name:  "verbose, v",
					Usage: "print additional details about each container",
				},
				cli.StringFlag{
					Name:  "separator",
					Usage: "separator to print between containers in verbose mode",
					Value: "\n",
				},
			},
			Action: func(c *cli.Context) {
				separator := c.String("separator")

				properties := garden.Properties{}
				for _, prop := range c.StringSlice("properties") {
					segs := strings.SplitN(prop, "=", 2)
					if len(segs) < 2 {
						fail(errors.New("malformed property pair (must be name=value)"))
					}

					properties[segs[0]] = segs[1]
				}

				containers, err := client(c).Containers(properties)
				failIf(err)

				verbose := c.Bool("verbose")

				for _, container := range containers {
					fmt.Println(container.Handle())

					if verbose {
						props, _ := container.Properties()
						for k, v := range props {
							fmt.Printf("  %s=%s\n", k, v)
						}

						fmt.Print(separator)
					}
				}
			},
		},
		{
			Name:  "run",
			Usage: "run a command in a container",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "attach, a",
					Usage: "attach to the process after it is started",
				},
				cli.StringFlag{
					Name:  "dir, d",
					Usage: "current working directory of process",
				},
				cli.StringFlag{
					Name:  "user, u",
					Usage: "user to run the process as",
				},
				cli.StringFlag{
					Name:  "command, c",
					Usage: "the command to run",
				},
				cli.StringSliceFlag{
					Name:  "env, e",
					Usage: "set environment variables",
					Value: &cli.StringSlice{},
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				attach := c.Bool("attach")
				dir := c.String("dir")
				user := c.String("user")
				command := c.String("command")
				env := c.StringSlice("env")

				handle := handle(c)
				container, err := client(c).Lookup(handle)
				failIf(err)

				var processIo garden.ProcessIO
				if attach {
					processIo = garden.ProcessIO{
						Stdin:  os.Stdin,
						Stdout: os.Stdout,
						Stderr: os.Stderr,
					}
				} else {
					processIo = garden.ProcessIO{}
				}

				args, err := shellwords.Parse(command)
				failIf(err)

				process, err := container.Run(garden.ProcessSpec{
					Path: args[0],
					Args: args[1:],
					Dir:  dir,
					User: user,
					Env:  env,
				}, processIo)
				failIf(err)

				if attach {
					status, err := process.Wait()
					failIf(err)
					os.Exit(status)
				} else {
					fmt.Println(process.ID())
				}
			},
		},
		{
			Name:  "attach",
			Usage: "attach to command running in the container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "pid, p",
					Usage: "process id to connect to",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				pid := c.String("pid")
				if pid == "" {
					err := errors.New("must specify pid to attach to")
					failIf(err)
				}

				handle := handle(c)
				container, err := client(c).Lookup(handle)
				failIf(err)

				process, err := container.Attach(pid, garden.ProcessIO{
					Stdin:  os.Stdin,
					Stdout: os.Stdout,
					Stderr: os.Stderr,
				})
				failIf(err)

				_, err = process.Wait()
				failIf(err)
			},
		},
		{
			Name:  "shell",
			Usage: "open a shell inside the running container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "user, u",
					Usage: "user to open shell as",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				container, err := client(c).Lookup(handle(c))
				failIf(err)

				term, err := term.Open(os.Stdin.Name())
				failIf(err)

				err = term.SetRaw()
				failIf(err)

				rows, cols, err := pty.Getsize(os.Stdin)
				failIf(err)

				process, err := container.Run(garden.ProcessSpec{
					User: c.String("user"),
					Path: "/bin/sh",
					Args: []string{"-l"},
					Env:  []string{"TERM=" + os.Getenv("TERM")},
					TTY: &garden.TTYSpec{
						WindowSize: &garden.WindowSize{
							Rows:    rows,
							Columns: cols,
						},
					},
				}, garden.ProcessIO{
					Stdin:  term,
					Stdout: term,
					Stderr: term,
				})
				if err != nil {
					term.Restore()
					failIf(err)
				}

				resized := make(chan os.Signal, 10)
				signal.Notify(resized, syscall.SIGWINCH)

				go func() {
					for {
						<-resized

						rows, cols, err := pty.Getsize(os.Stdin)
						if err == nil {
							process.SetTTY(garden.TTYSpec{
								WindowSize: &garden.WindowSize{
									Rows:    rows,
									Columns: cols,
								},
							})
						}
					}
				}()

				process.Wait()
				term.Restore()
			},
		},
		{
			Name:  "stream-in",
			Usage: "stream data into the container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "destination, d",
					Usage: "destination path in the container",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				handle := handle(c)

				dst := c.String("destination")
				if dst == "" {
					fail(errors.New("missing --destination flag"))
				}

				container, err := client(c).Lookup(handle)
				failIf(err)

				streamInSpec := garden.StreamInSpec{
					Path:      dst,
					TarStream: os.Stdin,
				}

				err = container.StreamIn(streamInSpec)
				failIf(err)
			},
		},
		{
			Name:  "stream-out",
			Usage: "stream data out of the container",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "source, s",
					Usage: "source path in the container",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				handle := handle(c)

				src := c.String("source")
				if src == "" {
					fail(errors.New("missing --source flag"))
				}

				container, err := client(c).Lookup(handle)
				failIf(err)

				streamOutSpec := garden.StreamOutSpec{Path: src}
				output, err := container.StreamOut(streamOutSpec)
				failIf(err)

				io.Copy(os.Stdout, output)
			},
		},
		{
			Name:  "net-in",
			Usage: "map a port on the host to a port in the container",
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "port, p",
					Usage: "container port",
				},
			},
			BashComplete: handleComplete,
			Action: func(c *cli.Context) {
				target := c.GlobalString("target")
				requestedContainerPort := uint32(c.Int("port"))

				if target == "" {
					fail(errors.New("target must be set"))
				}

				handle := handle(c)
				container, err := client(c).Lookup(handle)
				failIf(err)

				hostPort, _, err := container.NetIn(0, requestedContainerPort)
				failIf(err)

				host, _, err := net.SplitHostPort(target)
				failIf(err)

				fmt.Println(net.JoinHostPort(host, fmt.Sprintf("%d", hostPort)))
			},
		},
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package goPy

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

//TCPRoute is used to set the Host and Port pair
type TCPRoute struct {
	Host string
	Port string
}

// Data structure to be used to make RPC call
type Data struct {
	Method string        `json:"method"`
	Args   []interface{} `json:"args"`
	Time   string        `json:"time"`
}

// DataResponse of data from RPC CALL
type DataResponse struct {
	Response string `json:"response"`
}

// Connection  interface from net package
type Connection struct {
	Conn net.Conn
}

// RandomJSON is used to send random data as string
// {"data":"USER INPUT STRING DATA"}
type RandomJSON struct {
	StringData string `json:"data"`
}

// Connect is used to connect with host and port on a TCP stream
func (obj *TCPRoute) Connect() (*Connection, error) {
	addr := obj.Host + ":" + obj.Port
	fmt.Println("host and port to connect", addr)
	client, err := net.Dial("tcp", addr)
	ret := &Connection{client}
	if err != nil {
		return nil, err
	}
	return ret, nil
}

// MakeRPC is used to send *Data  over TCP stream
func (obj *Connection) MakeRPC(dataIN *Data) (bool, error) {
	jsonData, err := json.Marshal(*dataIN)
	if err != nil {
		return false, err
	}
	obj.Conn.Write(jsonData)
	return true, nil
}

// SendRandomJSON method can be used to send any sort of StringData
func (obj *Connection) SendRandomJSON(dataIN *RandomJSON) error {
	jsonData, err := json.Marshal(*dataIN)
	if err != nil {
		return err
	}
	obj.Conn.Write(jsonData)
	return nil
}

// RecvData is used to RecvData data over TCP stream
func (obj *Connection) RecvData() (*DataResponse, error) {
	r := make([]byte, 4096)
	n, _ := obj.Conn.Read(r)
	response := r[:n]
	var v DataResponse
	err := json.Unmarshal(response, &v)
	if err != nil {
		return &v, err
	}
	return &v, nil
}

// func main() {
// 	cli := &TCProute{"localhost", "9000"}
// 	tIni := (strconv.Itoa(t0.Hour())) + ":" + (strconv.Itoa(t0.Minute())) + ":" + strconv.Itoa(t0.Second()) + "." + strconv.Itoa(t0.Nanosecond())[:6]
// 	conn, _ := cli.connect()
// 	t0 := time.Now()
// 	d := &data{"show", []interface{}{10, 20.2, 30, 40, "i am nikhil"}, tIni}
// 	conn.sendData(d)
// 	recv, _ := conn.recvData()
// 	fmt.Println(recv)
//
// }
<commit_msg>Ready TO USE<commit_after>package goPy

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

//TCPRoute is used to set the Host and Port pair
type TCPRoute struct {
	Host string
	Port string
}

// Data structure to be used to make RPC call
type Data struct {
	Method string        `json:"method"`
	Args   []interface{} `json:"args"`
	Time   string        `json:"time"`
}

// DataResponse of data from RPC CALL
type DataResponse struct {
	Response string `json:"response"`
}

// Connection  interface from net package
type Connection struct {
	Conn net.Conn
}

// RandomJSON is used to send random data as string
// {"data":"USER INPUT STRING DATA"}
type RandomJSON struct {
	StringData string `json:"data"`
}

// Connect is used to connect with host and port on a TCP stream
func (obj *TCPRoute) Connect() (*Connection, error) {
	addr := obj.Host + ":" + obj.Port
	fmt.Println("host and port to connect", addr)
	client, err := net.Dial("tcp", addr)
	ret := &Connection{client}
	if err != nil {
		return nil, err
	}
	return ret, nil
}

// MakeRPC is used to send *Data  over TCP stream
func (obj *Connection) MakeRPC(dataIN *Data) (bool, error) {
	jsonData, err := json.Marshal(*dataIN)
	if err != nil {
		return false, err
	}
	obj.Conn.Write(jsonData)
	return true, nil
}

// SendRandomJSON method can be used to send any sort of StringData
func (obj *Connection) SendRandomJSON(dataIN *RandomJSON) error {
	jsonData, err := json.Marshal(*dataIN)
	if err != nil {
		return err
	}
	obj.Conn.Write(jsonData)
	return nil
}

// RecvData is used to RecvData data over TCP stream
func (obj *Connection) RecvData() (*DataResponse, error) {
	r := make([]byte, 4096)
	n, _ := obj.Conn.Read(r)
	response := r[:n]
	var v DataResponse
	err := json.Unmarshal(response, &v)
	if err != nil {
		return &v, err
	}
	return &v, nil
}
<|endoftext|>


<commit_before>package gobf

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

// Program represents brainfuck programm
type Program struct {
	code []byte
	ip   int // next instruction index in code
}

// NewProgram initialize new program
func NewProgram(r io.Reader) *Program {
	code, err := ioutil.ReadAll(r)
	if err != nil {
		panic(fmt.Sprintf("Failed to read program code: %v", err))
	}
	return &Program{
		code: code,
		ip:   -1,
	}
}

// Run runs brainfuck program
func (p *Program) Run() error {
	for p.nextCmd() {
		err := p.runCmd()
		if err != nil {
			return err
		}
	}
	return fmt.Errorf("Not implemented")
}

func (p *Program) nextCmd() bool {
	if p.ip+1 < len(p.code) {
		p.ip++
		return true
	}
	return false
}

func (p *Program) runCmd() error {
	return fmt.Errorf("Bad cmd symbol: '%c' (%v)", p.code[p.ip], p.code[p.ip])
}
<commit_msg>add cmd()<commit_after>package gobf

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

// Program represents brainfuck programm
type Program struct {
	code []byte
	ip   int // next instruction index in code
}

// NewProgram initialize new program
func NewProgram(r io.Reader) *Program {
	code, err := ioutil.ReadAll(r)
	if err != nil {
		panic(fmt.Sprintf("Failed to read program code: %v", err))
	}
	return &Program{
		code: code,
		ip:   -1,
	}
}

// Run runs brainfuck program
func (p *Program) Run() error {
	for p.nextCmd() {
		err := p.runCmd()
		if err != nil {
			return err
		}
	}
	return fmt.Errorf("Not implemented")
}

func (p *Program) nextCmd() bool {
	if p.ip+1 < len(p.code) {
		p.ip++
		return true
	}
	return false
}

func (p *Program) cmd() byte {
	return p.code[p.ip]
}

func (p *Program) runCmd() error {

	return fmt.Errorf("Bad cmd symbol: '%c' (%v)", p.cmd(), p.cmd())
}
<|endoftext|>


<commit_before>package gois

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"strings"
	"time"
	"unicode/utf8"

	"github.com/jinzhu/now"
)

//go:generate go run cmd/generate-whois-servers/main.go
//go:generate go fmt servers.go

// Record holds the information returned by the whois server
type Record struct {
	Domain        string
	TrimmedDomain string
	CreatedOn     time.Time
	Registered    bool
}

func longestTLDSuffix(domain string) string {
	longestTld := ""
	for tld := range TLDWhoisServers {
		if strings.HasSuffix(domain, "."+tld) && utf8.RuneCountInString(tld) > utf8.RuneCountInString(longestTld) {
			longestTld = tld
		}
	}
	return longestTld
}

func trimSubdomains(domain, tld string) (trimmedDomain string) {
	noTld := strings.TrimSuffix(domain, "."+tld)
	parts := strings.Split(noTld, ".")
	trimmedDomain = fmt.Sprintf("%s.%s", parts[len(parts)-1], tld)
	return trimmedDomain
}

// Whois returns the public whois information for a domain
func Whois(domain string) (record *Record, err error) {
	tld := longestTLDSuffix(domain)
	server := TLDWhoisServers[tld]

	trimmedDomain := trimSubdomains(domain, tld)
	requestDomain := trimmedDomain
	if server == "whois.verisign-grs.com" {
		requestDomain = "=" + trimmedDomain
	} else if server == "whois.denic.de" {
		requestDomain = "-T dn,ace " + trimmedDomain
	}

	response, err := QueryWhoisServer(requestDomain, server)
	if err != nil {
		return
	}

	record, err = parse(response)
	if err == nil {
		record.Domain = domain
		record.TrimmedDomain = trimmedDomain
	}

	return
}

// QueryWhoisServer queries a particular whois server for information about a domain
func QueryWhoisServer(domain, server string) (response string, err error) {
	conn, err := net.Dial("tcp", server+":43")
	if err != nil {
		return
	}
	defer conn.Close()

	fmt.Fprintf(conn, "%s\r\n", domain)
	if buf, err := ioutil.ReadAll(conn); err == nil {
		response = string(buf)
	}

	return
}

func parse(response string) (record *Record, err error) {
	for _, line := range strings.Split(response, "\n") {
		line = strings.TrimSpace(line)
		if line == "" || !strings.Contains(line, ":") {
			continue
		}
		parts := strings.SplitN(line, ":", 2)
		key, value := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
		if strings.ToLower(key) == "created" || strings.ToLower(key) == "creation date" || strings.ToLower(key) == "changed" || strings.ToLower(key) == "domain create date" {
			if parsedDate, parseErr := now.Parse(value); parseErr != nil {
				err = parseErr
			} else {
				record = &Record{CreatedOn: parsedDate, Registered: true}
			}
			return
		}
	}
	return nil, errors.New("Unable to parse whois record")
}

func init() {
	now.TimeFormats = append(now.TimeFormats, "02-Jan-2006")
	now.TimeFormats = append(now.TimeFormats, "02-Jan-2006 15:04:05 MST")
	now.TimeFormats = append(now.TimeFormats, "2006-01-02T15:04:05.0Z")
	now.TimeFormats = append(now.TimeFormats, "2006-01-02T15:04:05Z")
	now.TimeFormats = append(now.TimeFormats, "2006-01-02T15:04:05-07:00")
	now.TimeFormats = append(now.TimeFormats, "2006.01.02")
}
<commit_msg>Use slice expansion for setting time formats<commit_after>package gois

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"strings"
	"time"
	"unicode/utf8"

	"github.com/jinzhu/now"
)

//go:generate go run cmd/generate-whois-servers/main.go
//go:generate go fmt servers.go

var timeFormats = []string{
	"02-Jan-2006",
	"2006.01.02",
	"02-Jan-2006 15:04:05 MST",
	"2006-01-02T15:04:05.0Z",
	"2006-01-02T15:04:05Z",
	"2006-01-02T15:04:05-07:00",
}

func init() {
	now.TimeFormats = append(now.TimeFormats, timeFormats...)
}

// Record holds the information returned by the whois server
type Record struct {
	Domain        string
	TrimmedDomain string
	CreatedOn     time.Time
	Registered    bool
}

func longestTLDSuffix(domain string) string {
	longestTld := ""
	for tld := range TLDWhoisServers {
		if strings.HasSuffix(domain, "."+tld) && utf8.RuneCountInString(tld) > utf8.RuneCountInString(longestTld) {
			longestTld = tld
		}
	}
	return longestTld
}

func trimSubdomains(domain, tld string) (trimmedDomain string) {
	noTld := strings.TrimSuffix(domain, "."+tld)
	parts := strings.Split(noTld, ".")
	trimmedDomain = fmt.Sprintf("%s.%s", parts[len(parts)-1], tld)
	return trimmedDomain
}

// Whois returns the public whois information for a domain
func Whois(domain string) (record *Record, err error) {
	tld := longestTLDSuffix(domain)
	server := TLDWhoisServers[tld]

	trimmedDomain := trimSubdomains(domain, tld)
	requestDomain := trimmedDomain
	if server == "whois.verisign-grs.com" {
		requestDomain = "=" + trimmedDomain
	} else if server == "whois.denic.de" {
		requestDomain = "-T dn,ace " + trimmedDomain
	}

	response, err := QueryWhoisServer(requestDomain, server)
	if err != nil {
		return
	}

	record, err = parse(response)
	if err == nil {
		record.Domain = domain
		record.TrimmedDomain = trimmedDomain
	}

	return
}

// QueryWhoisServer queries a particular whois server for information about a domain
func QueryWhoisServer(domain, server string) (response string, err error) {
	conn, err := net.Dial("tcp", server+":43")
	if err != nil {
		return
	}
	defer conn.Close()

	fmt.Fprintf(conn, "%s\r\n", domain)
	if buf, err := ioutil.ReadAll(conn); err == nil {
		response = string(buf)
	}

	return
}

func parse(response string) (record *Record, err error) {
	for _, line := range strings.Split(response, "\n") {
		line = strings.TrimSpace(line)
		if line == "" || !strings.Contains(line, ":") {
			continue
		}
		parts := strings.SplitN(line, ":", 2)
		key, value := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
		if strings.ToLower(key) == "created" || strings.ToLower(key) == "creation date" || strings.ToLower(key) == "changed" || strings.ToLower(key) == "domain create date" {
			if parsedDate, parseErr := now.Parse(value); parseErr != nil {
				err = parseErr
			} else {
				record = &Record{CreatedOn: parsedDate, Registered: true}
			}
			return
		}
	}
	return nil, errors.New("Unable to parse whois record")
}
<|endoftext|>


<commit_before>package goma

import (
	"database/sql"
	"fmt"
	"reflect"
	"regexp"
	"strconv"
	"time"
)

const (
	timeFormat = "2006-01-02 15:04:05.999999"
)

var (
	gomaParseTime = time.UTC
)

// ParseTime will configure goma to convert dates of the given location
func ParseTime(location *time.Location) {
	gomaParseTime = location
}

// Goma is sql.DB access wrapper.
type Goma struct {
	*sql.DB
	options Options
}

// QueryArgs sql query args
type QueryArgs map[string]interface{}

// Open is create goma client.
// - database open
func Open(configPath string) (*sql.DB, error) {
	opts, err := NewOptions(configPath)
	if err != nil {
		return nil, err
	}
	return OpenOptions(opts)
}

// OpenOptions is create goma client.
// - database open
func OpenOptions(options Options) (*sql.DB, error) {
	return sql.Open(options.Driver, options.Source())
}

// Close sql.DB close.
func (d *Goma) Close() error {
	d.debugPrintln("goma close")

	err := d.DB.Close()

	return err
}

// MySQLGenerateQuery generate bind args query
func MySQLGenerateQuery(queryString string, args QueryArgs) string {
	if len(args) <= 0 {
		return queryString
	}

	for key, val := range args {
		re := regexp.MustCompile(`\/\* ` + key + ` \*\/.*`)

		replaceWord := ""
		switch v := val.(type) {
		default:
			switch reflect.TypeOf(val).Kind() {
			case reflect.String:
				replaceWord = "'" + reflect.ValueOf(v).String() + "'"
			}
		case int:
			replaceWord = strconv.Itoa(v)
		case bool:
			if val.(bool) {
				replaceWord = "true"
			} else {
				replaceWord = "false"
			}
		case float32:
			replaceWord = strconv.FormatFloat(float64(v), 'f', 3, 32)
		case float64:
			replaceWord = strconv.FormatFloat(v, 'f', 3, 64)
		case int64:
			replaceWord = strconv.FormatInt(v, 10)
		case string:
			replaceWord = "'" + v + "'"
		case []uint8:
			replaceWord = "'" + string(v) + "'"
			//		case Time:
			//			replaceWord = "'" + val.(Time).Time.Format("15:04:05") + "'"
			//		case Date:
			//			replaceWord = "'" + time.Time(val.(Date)).Format("2006-01-02") + "'"
			//		case Timestamp:
			//			replaceWord = "'" + time.Time(val.(Timestamp)).Format("2006-01-02 15:04:05.999999999") + "'"
			//		case mysql.NullTime:
			//			replaceWord = "'" + val.(mysql.NullTime).Time.Format("2006-01-02 15:04:05.999999999") + "'"
		case time.Time:
			fmt.Println(val)
			if v.IsZero() {
				replaceWord = "'0000-00-00'"
			} else {
				replaceWord = "'" + v.In(gomaParseTime).Format(timeFormat) + "'"
			}
		}
		queryString = re.ReplaceAllString(queryString, replaceWord)
	}

	return queryString
}

// PostgresGenerateQuery generate bind args query
func PostgresGenerateQuery(queryString string, args QueryArgs) string {
	if len(args) <= 0 {
		return queryString
	}

	for key, val := range args {
		re := regexp.MustCompile(`\/\* ` + key + ` \*\/.*`)

		replaceWord := ""
		switch v := val.(type) {
		case int:
			replaceWord = strconv.Itoa(v)
		case bool:
			replaceWord = strconv.FormatBool(v)
		case float32:
			replaceWord = strconv.FormatFloat(float64(v), 'f', 3, 32)
		case float64:
			replaceWord = strconv.FormatFloat(v, 'f', 3, 64)
		case int64:
			replaceWord = strconv.FormatInt(v, 10)
		case string:
			replaceWord = "'" + v + "'"
		case []uint8:
			replaceWord = "'" + string(v) + "'"
			//		case Time:
			//			replaceWord = "'" + val.(Time).Time.Format("15:04:05") + "'"
			//		case Date:
			//			replaceWord = "'" + time.Time(val.(Date)).Format("2006-01-02") + "'"
			//		case Timestamp:
			//			replaceWord = "'" + time.Time(val.(Timestamp)).Format("2006-01-02 15:04:05.999999999") + "'"
			//		case mysql.NullTime:
			//			replaceWord = "'" + val.(mysql.NullTime).Time.Format("2006-01-02 15:04:05.999999999") + "'"
		case time.Time:
			if v.IsZero() {
				replaceWord = "'0000-00-00'"
			} else {
				replaceWord = "'" + v.In(gomaParseTime).Format(timeFormat) + "'"
			}
		}
		queryString = re.ReplaceAllString(queryString, replaceWord)
	}

	return queryString
}

func (d *Goma) debugPrintln(v ...interface{}) {
	if d.options.Debug {
		fmt.Println(v...)
	}
}
<commit_msg>removed: log<commit_after>package goma

import (
	"database/sql"
	"fmt"
	"reflect"
	"regexp"
	"strconv"
	"time"
)

const (
	timeFormat = "2006-01-02 15:04:05.999999"
)

var (
	gomaParseTime = time.UTC
)

// ParseTime will configure goma to convert dates of the given location
func ParseTime(location *time.Location) {
	gomaParseTime = location
}

// Goma is sql.DB access wrapper.
type Goma struct {
	*sql.DB
	options Options
}

// QueryArgs sql query args
type QueryArgs map[string]interface{}

// Open is create goma client.
// - database open
func Open(configPath string) (*sql.DB, error) {
	opts, err := NewOptions(configPath)
	if err != nil {
		return nil, err
	}
	return OpenOptions(opts)
}

// OpenOptions is create goma client.
// - database open
func OpenOptions(options Options) (*sql.DB, error) {
	return sql.Open(options.Driver, options.Source())
}

// Close sql.DB close.
func (d *Goma) Close() error {
	d.debugPrintln("goma close")

	err := d.DB.Close()

	return err
}

// MySQLGenerateQuery generate bind args query
func MySQLGenerateQuery(queryString string, args QueryArgs) string {
	if len(args) <= 0 {
		return queryString
	}

	for key, val := range args {
		re := regexp.MustCompile(`\/\* ` + key + ` \*\/.*`)

		replaceWord := ""
		switch v := val.(type) {
		default:
			switch reflect.TypeOf(val).Kind() {
			case reflect.String:
				replaceWord = "'" + reflect.ValueOf(v).String() + "'"
			}
		case int:
			replaceWord = strconv.Itoa(v)
		case bool:
			if val.(bool) {
				replaceWord = "true"
			} else {
				replaceWord = "false"
			}
		case float32:
			replaceWord = strconv.FormatFloat(float64(v), 'f', 3, 32)
		case float64:
			replaceWord = strconv.FormatFloat(v, 'f', 3, 64)
		case int64:
			replaceWord = strconv.FormatInt(v, 10)
		case string:
			replaceWord = "'" + v + "'"
		case []uint8:
			replaceWord = "'" + string(v) + "'"
			//		case Time:
			//			replaceWord = "'" + val.(Time).Time.Format("15:04:05") + "'"
			//		case Date:
			//			replaceWord = "'" + time.Time(val.(Date)).Format("2006-01-02") + "'"
			//		case Timestamp:
			//			replaceWord = "'" + time.Time(val.(Timestamp)).Format("2006-01-02 15:04:05.999999999") + "'"
			//		case mysql.NullTime:
			//			replaceWord = "'" + val.(mysql.NullTime).Time.Format("2006-01-02 15:04:05.999999999") + "'"
		case time.Time:
			if v.IsZero() {
				replaceWord = "'0000-00-00'"
			} else {
				replaceWord = "'" + v.In(gomaParseTime).Format(timeFormat) + "'"
			}
		}
		queryString = re.ReplaceAllString(queryString, replaceWord)
	}

	return queryString
}

// PostgresGenerateQuery generate bind args query
func PostgresGenerateQuery(queryString string, args QueryArgs) string {
	if len(args) <= 0 {
		return queryString
	}

	for key, val := range args {
		re := regexp.MustCompile(`\/\* ` + key + ` \*\/.*`)

		replaceWord := ""
		switch v := val.(type) {
		case int:
			replaceWord = strconv.Itoa(v)
		case bool:
			replaceWord = strconv.FormatBool(v)
		case float32:
			replaceWord = strconv.FormatFloat(float64(v), 'f', 3, 32)
		case float64:
			replaceWord = strconv.FormatFloat(v, 'f', 3, 64)
		case int64:
			replaceWord = strconv.FormatInt(v, 10)
		case string:
			replaceWord = "'" + v + "'"
		case []uint8:
			replaceWord = "'" + string(v) + "'"
			//		case Time:
			//			replaceWord = "'" + val.(Time).Time.Format("15:04:05") + "'"
			//		case Date:
			//			replaceWord = "'" + time.Time(val.(Date)).Format("2006-01-02") + "'"
			//		case Timestamp:
			//			replaceWord = "'" + time.Time(val.(Timestamp)).Format("2006-01-02 15:04:05.999999999") + "'"
			//		case mysql.NullTime:
			//			replaceWord = "'" + val.(mysql.NullTime).Time.Format("2006-01-02 15:04:05.999999999") + "'"
		case time.Time:
			if v.IsZero() {
				replaceWord = "'0000-00-00'"
			} else {
				replaceWord = "'" + v.In(gomaParseTime).Format(timeFormat) + "'"
			}
		}
		queryString = re.ReplaceAllString(queryString, replaceWord)
	}

	return queryString
}

func (d *Goma) debugPrintln(v ...interface{}) {
	if d.options.Debug {
		fmt.Println(v...)
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 JT Olds
// See LICENSE for copying information

package whgoth // import "gopkg.in/go-webhelp/whgoth.v1"

import (
	"crypto/rand"
	"encoding/hex"
	"log"
	"net/http"
	"net/url"
	"sync"

	"github.com/markbates/goth"
	"github.com/spacemonkeygo/errors"
	"golang.org/x/net/context"
	"gopkg.in/webhelp.v1"
	"gopkg.in/webhelp.v1/whcache"
	"gopkg.in/webhelp.v1/whcompat"
	"gopkg.in/webhelp.v1/wherr"
	"gopkg.in/webhelp.v1/whmux"
	"gopkg.in/webhelp.v1/whredir"
	"gopkg.in/webhelp.v1/whroute"
	"gopkg.in/webhelp.v1/whsess"
)

var (
	userKey      = webhelp.GenSym()
	providerName = whmux.NewStringArg()
)

type AuthProvider struct {
	goth.Provider
	baseURL          string
	sessionNamespace string
}

func newAuthProvider(p goth.Provider, baseURL, sessionNamespace string) (
	a *AuthProvider) {
	return &AuthProvider{
		Provider:         p,
		baseURL:          baseURL,
		sessionNamespace: sessionNamespace,
	}
}

func (a *AuthProvider) login(w http.ResponseWriter, r *http.Request) {
	ctx := whcompat.Context(r)

	u, err := a.User(ctx)
	if err == nil && u != nil {
		whredir.Redirect(w, r, safeRedirect(r.FormValue("redirect_to"), "/"))
		return
	}

	state := newState()
	sess, err := a.Provider.BeginAuthCtx(ctx, state)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	url, err := sess.GetAuthURL()
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	session, err := whsess.Load(ctx, a.sessionNamespace)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}
	for key := range session.Values {
		delete(session.Values, key)
	}
	session.Values["state"] = state
	session.Values["logged_in"] = false
	session.Values["redirect_to"] = safeRedirect(r.FormValue("redirect_to"), "/")
	session.Values["auth"] = sess.Marshal()
	err = session.Save(ctx, w)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	whredir.Redirect(w, r, url)
}

func (a *AuthProvider) Logout(ctx context.Context, w http.ResponseWriter) (
	err error) {
	session, err := whsess.Load(ctx, a.sessionNamespace)
	if err != nil {
		return err
	}
	return session.Clear(ctx, w)
}

func (a *AuthProvider) callback(w http.ResponseWriter, r *http.Request) {
	ctx := whcompat.Context(r)
	session, err := whsess.Load(ctx, a.sessionNamespace)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	if loggedIn, _ := session.Values["logged_in"].(bool); loggedIn {
		wherr.Handle(w, r, wherr.BadRequest.New("already logged in"))
		return
	}

	auth, ok := session.Values["auth"].(string)
	if !ok {
		wherr.Handle(w, r, wherr.InternalServerError.New(
			"no existing session found"))
		return
	}

	sess, err := a.Provider.UnmarshalSession(auth)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	authToken, err := sess.AuthorizeCtx(ctx, a.Provider, r.URL.Query())
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	redirectTo, _ := session.Values["redirect_to"].(string)
	session.Values["auth_token"] = authToken
	session.Values["logged_in"] = true
	session.Values["redirect_to"] = nil
	session.Values["auth"] = sess.Marshal()
	err = session.Save(ctx, w)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	whredir.Redirect(w, r, safeRedirect(redirectTo, "/"))
}

func (a *AuthProvider) User(ctx context.Context) (*goth.User, error) {
	session, err := whsess.Load(ctx, a.sessionNamespace)
	if err != nil {
		return nil, err
	}

	if loggedIn, _ := session.Values["logged_in"].(bool); !loggedIn {
		return nil, nil
	}

	auth, ok := session.Values["auth"].(string)
	if !ok {
		return nil, nil
	}

	sess, err := a.Provider.UnmarshalSession(auth)
	if err != nil {
		log.Printf("failed to unmarshal session: %v", err)
		return nil, nil
	}

	u, err := a.Provider.FetchUserCtx(ctx, sess)
	if err != nil {
		log.Printf("failed to fetch user: %v", err)
		return nil, nil
	}

	if u.UserID == "" || u.Provider == "" {
		log.Printf("user had no user id or provider set")
		return nil, nil
	}
	return &u, nil
}

func (a *AuthProvider) LoginURL(redirectTo string) string {
	return a.baseURL + "/login?" + url.Values{
		"redirect_to": {redirectTo}}.Encode()
}

type AuthProviders struct {
	baseURL, sessionNamespace string
	providersCallback         func(context.Context) ([]goth.Provider, error)
	whmux.Dir

	providersMtx    sync.Mutex
	providersSetup  bool
	providers       []*AuthProvider
	providersByName map[string]*AuthProvider
}

func NewAuthProviders(baseURL, sessionNamespace string,
	providers ...goth.Provider) (a *AuthProviders) {
	return NewLazyAuthProviders(baseURL, sessionNamespace,
		func(context.Context) ([]goth.Provider, error) {
			return providers, nil
		})
}

func NewLazyAuthProviders(baseURL, sessionNamespace string,
	providers func(context.Context) ([]goth.Provider, error)) (
	a *AuthProviders) {

	a = &AuthProviders{
		baseURL:           baseURL,
		sessionNamespace:  sessionNamespace,
		providersCallback: providers,
	}
	a.Dir = whmux.Dir{
		"logout": whmux.Exact(http.HandlerFunc(a.logout)),
		"provider": providerName.Shift(whmux.Dir{
			"login":    whmux.Exact(http.HandlerFunc(a.login)),
			"callback": whmux.Exact(http.HandlerFunc(a.callback)),
		}),
	}
	return a
}

func (a *AuthProviders) setupProviders(ctx context.Context) error {
	a.providersMtx.Lock()
	defer a.providersMtx.Unlock()
	if a.providersSetup {
		return nil
	}

	providers, err := a.providersCallback(ctx)
	if err != nil {
		return err
	}

	p := make([]*AuthProvider, 0, len(providers))
	providersByName := make(map[string]*AuthProvider, len(providers))
	for _, provider := range providers {
		w := newAuthProvider(provider,
			a.baseURL+"/provider/"+provider.Name(),
			a.sessionNamespace+"."+provider.Name())
		p = append(p, w)
		if provider.Name() != "" {
			providersByName[provider.Name()] = w
		}
	}
	a.providers = p
	a.providersByName = providersByName
	a.providersSetup = true

	return nil
}

func (a *AuthProviders) login(w http.ResponseWriter, r *http.Request) {
	ctx := whcompat.Context(r)
	err := a.setupProviders(ctx)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	name := providerName.Get(ctx)
	if p, ok := a.providersByName[name]; ok {
		p.login(w, r)
	} else {
		wherr.Handle(w, r, wherr.NotFound.New("provider %s not found", name))
	}
}

func (a *AuthProviders) callback(w http.ResponseWriter, r *http.Request) {
	ctx := whcompat.Context(r)
	err := a.setupProviders(ctx)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	name := providerName.Get(ctx)
	if p, ok := a.providersByName[name]; ok {
		p.callback(w, r)
	} else {
		wherr.Handle(w, r, wherr.NotFound.New("provider %s not found", name))
	}
}

func (a *AuthProviders) Logout(ctx context.Context, w http.ResponseWriter) (
	err error) {
	err = a.setupProviders(ctx)
	if err != nil {
		return err
	}

	var errs errors.ErrorGroup
	for _, provider := range a.providers {
		errs.Add(provider.Logout(ctx, w))
	}
	return errs.Finalize()
}

func (a *AuthProviders) logout(w http.ResponseWriter, r *http.Request) {
	err := a.Logout(whcompat.Context(r), w)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}
	whredir.Redirect(w, r, safeRedirect(r.FormValue("redirect_to"), "/"))
}

func safeRedirect(redirectTo, def string) string {
	u, err := url.Parse(redirectTo)
	if err != nil {
		return def
	}
	if u.RawQuery == "" {
		if u.Path == "" {
			return def
		}
		return u.Path
	}
	return u.Path + "?" + u.RawQuery
}

func (a *AuthProviders) Providers(ctx context.Context) (
	[]*AuthProvider, error) {
	err := a.setupProviders(ctx)
	if err != nil {
		return nil, err
	}

	return a.providers, nil
}

func (a *AuthProviders) User(ctx context.Context) (*goth.User, error) {
	if u, ok := whcache.Get(ctx, userKey).(*goth.User); ok && u != nil {
		return u, nil
	}
	err := a.setupProviders(ctx)
	if err != nil {
		return nil, err
	}

	for _, provider := range a.providers {
		u, err := provider.User(ctx)
		if err != nil || u != nil {
			whcache.Set(ctx, userKey, u)
			return u, err
		}
	}
	return nil, nil
}

func (a *AuthProviders) RequireUser(
	authorizedHandler, unauthorizedHandler http.Handler) http.Handler {
	return whroute.HandlerFunc(authorizedHandler,
		func(w http.ResponseWriter, r *http.Request) {
			ctx := whcompat.Context(r)
			u, err := a.User(ctx)
			if err != nil {
				wherr.Handle(w, r, err)
				return
			}
			if u == nil {
				unauthorizedHandler.ServeHTTP(w, r)
			} else {
				authorizedHandler.ServeHTTP(w, r)
			}
		})
}

func (a *AuthProviders) LogoutURL(redirectTo string) string {
	return a.baseURL + "/logout?" + url.Values{
		"redirect_to": {redirectTo}}.Encode()
}

func newState() string {
	var p [16]byte
	_, err := rand.Read(p[:])
	if err != nil {
		panic(err)
	}
	return hex.EncodeToString(p[:])
}
<commit_msg>switch to forked goth<commit_after>// Copyright (C) 2016 JT Olds
// See LICENSE for copying information

package whgoth // import "gopkg.in/go-webhelp/whgoth.v1"

import (
	"crypto/rand"
	"encoding/hex"
	"log"
	"net/http"
	"net/url"
	"sync"

	"github.com/jtolds/goth"
	"github.com/spacemonkeygo/errors"
	"golang.org/x/net/context"
	"gopkg.in/webhelp.v1"
	"gopkg.in/webhelp.v1/whcache"
	"gopkg.in/webhelp.v1/whcompat"
	"gopkg.in/webhelp.v1/wherr"
	"gopkg.in/webhelp.v1/whmux"
	"gopkg.in/webhelp.v1/whredir"
	"gopkg.in/webhelp.v1/whroute"
	"gopkg.in/webhelp.v1/whsess"
)

var (
	userKey      = webhelp.GenSym()
	providerName = whmux.NewStringArg()
)

type AuthProvider struct {
	goth.Provider
	baseURL          string
	sessionNamespace string
}

func newAuthProvider(p goth.Provider, baseURL, sessionNamespace string) (
	a *AuthProvider) {
	return &AuthProvider{
		Provider:         p,
		baseURL:          baseURL,
		sessionNamespace: sessionNamespace,
	}
}

func (a *AuthProvider) login(w http.ResponseWriter, r *http.Request) {
	ctx := whcompat.Context(r)

	u, err := a.User(ctx)
	if err == nil && u != nil {
		whredir.Redirect(w, r, safeRedirect(r.FormValue("redirect_to"), "/"))
		return
	}

	state := newState()
	sess, err := a.Provider.BeginAuthCtx(ctx, state)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	url, err := sess.GetAuthURL()
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	session, err := whsess.Load(ctx, a.sessionNamespace)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}
	for key := range session.Values {
		delete(session.Values, key)
	}
	session.Values["state"] = state
	session.Values["logged_in"] = false
	session.Values["redirect_to"] = safeRedirect(r.FormValue("redirect_to"), "/")
	session.Values["auth"] = sess.Marshal()
	err = session.Save(ctx, w)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	whredir.Redirect(w, r, url)
}

func (a *AuthProvider) Logout(ctx context.Context, w http.ResponseWriter) (
	err error) {
	session, err := whsess.Load(ctx, a.sessionNamespace)
	if err != nil {
		return err
	}
	return session.Clear(ctx, w)
}

func (a *AuthProvider) callback(w http.ResponseWriter, r *http.Request) {
	ctx := whcompat.Context(r)
	session, err := whsess.Load(ctx, a.sessionNamespace)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	if loggedIn, _ := session.Values["logged_in"].(bool); loggedIn {
		wherr.Handle(w, r, wherr.BadRequest.New("already logged in"))
		return
	}

	auth, ok := session.Values["auth"].(string)
	if !ok {
		wherr.Handle(w, r, wherr.InternalServerError.New(
			"no existing session found"))
		return
	}

	sess, err := a.Provider.UnmarshalSession(auth)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	authToken, err := sess.AuthorizeCtx(ctx, a.Provider, r.URL.Query())
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	redirectTo, _ := session.Values["redirect_to"].(string)
	session.Values["auth_token"] = authToken
	session.Values["logged_in"] = true
	session.Values["redirect_to"] = nil
	session.Values["auth"] = sess.Marshal()
	err = session.Save(ctx, w)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	whredir.Redirect(w, r, safeRedirect(redirectTo, "/"))
}

func (a *AuthProvider) User(ctx context.Context) (*goth.User, error) {
	session, err := whsess.Load(ctx, a.sessionNamespace)
	if err != nil {
		return nil, err
	}

	if loggedIn, _ := session.Values["logged_in"].(bool); !loggedIn {
		return nil, nil
	}

	auth, ok := session.Values["auth"].(string)
	if !ok {
		return nil, nil
	}

	sess, err := a.Provider.UnmarshalSession(auth)
	if err != nil {
		log.Printf("failed to unmarshal session: %v", err)
		return nil, nil
	}

	u, err := a.Provider.FetchUserCtx(ctx, sess)
	if err != nil {
		log.Printf("failed to fetch user: %v", err)
		return nil, nil
	}

	if u.UserID == "" || u.Provider == "" {
		log.Printf("user had no user id or provider set")
		return nil, nil
	}
	return &u, nil
}

func (a *AuthProvider) LoginURL(redirectTo string) string {
	return a.baseURL + "/login?" + url.Values{
		"redirect_to": {redirectTo}}.Encode()
}

type AuthProviders struct {
	baseURL, sessionNamespace string
	providersCallback         func(context.Context) ([]goth.Provider, error)
	whmux.Dir

	providersMtx    sync.Mutex
	providersSetup  bool
	providers       []*AuthProvider
	providersByName map[string]*AuthProvider
}

func NewAuthProviders(baseURL, sessionNamespace string,
	providers ...goth.Provider) (a *AuthProviders) {
	return NewLazyAuthProviders(baseURL, sessionNamespace,
		func(context.Context) ([]goth.Provider, error) {
			return providers, nil
		})
}

func NewLazyAuthProviders(baseURL, sessionNamespace string,
	providers func(context.Context) ([]goth.Provider, error)) (
	a *AuthProviders) {

	a = &AuthProviders{
		baseURL:           baseURL,
		sessionNamespace:  sessionNamespace,
		providersCallback: providers,
	}
	a.Dir = whmux.Dir{
		"logout": whmux.Exact(http.HandlerFunc(a.logout)),
		"provider": providerName.Shift(whmux.Dir{
			"login":    whmux.Exact(http.HandlerFunc(a.login)),
			"callback": whmux.Exact(http.HandlerFunc(a.callback)),
		}),
	}
	return a
}

func (a *AuthProviders) setupProviders(ctx context.Context) error {
	a.providersMtx.Lock()
	defer a.providersMtx.Unlock()
	if a.providersSetup {
		return nil
	}

	providers, err := a.providersCallback(ctx)
	if err != nil {
		return err
	}

	p := make([]*AuthProvider, 0, len(providers))
	providersByName := make(map[string]*AuthProvider, len(providers))
	for _, provider := range providers {
		w := newAuthProvider(provider,
			a.baseURL+"/provider/"+provider.Name(),
			a.sessionNamespace+"."+provider.Name())
		p = append(p, w)
		if provider.Name() != "" {
			providersByName[provider.Name()] = w
		}
	}
	a.providers = p
	a.providersByName = providersByName
	a.providersSetup = true

	return nil
}

func (a *AuthProviders) login(w http.ResponseWriter, r *http.Request) {
	ctx := whcompat.Context(r)
	err := a.setupProviders(ctx)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	name := providerName.Get(ctx)
	if p, ok := a.providersByName[name]; ok {
		p.login(w, r)
	} else {
		wherr.Handle(w, r, wherr.NotFound.New("provider %s not found", name))
	}
}

func (a *AuthProviders) callback(w http.ResponseWriter, r *http.Request) {
	ctx := whcompat.Context(r)
	err := a.setupProviders(ctx)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}

	name := providerName.Get(ctx)
	if p, ok := a.providersByName[name]; ok {
		p.callback(w, r)
	} else {
		wherr.Handle(w, r, wherr.NotFound.New("provider %s not found", name))
	}
}

func (a *AuthProviders) Logout(ctx context.Context, w http.ResponseWriter) (
	err error) {
	err = a.setupProviders(ctx)
	if err != nil {
		return err
	}

	var errs errors.ErrorGroup
	for _, provider := range a.providers {
		errs.Add(provider.Logout(ctx, w))
	}
	return errs.Finalize()
}

func (a *AuthProviders) logout(w http.ResponseWriter, r *http.Request) {
	err := a.Logout(whcompat.Context(r), w)
	if err != nil {
		wherr.Handle(w, r, err)
		return
	}
	whredir.Redirect(w, r, safeRedirect(r.FormValue("redirect_to"), "/"))
}

func safeRedirect(redirectTo, def string) string {
	u, err := url.Parse(redirectTo)
	if err != nil {
		return def
	}
	if u.RawQuery == "" {
		if u.Path == "" {
			return def
		}
		return u.Path
	}
	return u.Path + "?" + u.RawQuery
}

func (a *AuthProviders) Providers(ctx context.Context) (
	[]*AuthProvider, error) {
	err := a.setupProviders(ctx)
	if err != nil {
		return nil, err
	}

	return a.providers, nil
}

func (a *AuthProviders) User(ctx context.Context) (*goth.User, error) {
	if u, ok := whcache.Get(ctx, userKey).(*goth.User); ok && u != nil {
		return u, nil
	}
	err := a.setupProviders(ctx)
	if err != nil {
		return nil, err
	}

	for _, provider := range a.providers {
		u, err := provider.User(ctx)
		if err != nil || u != nil {
			whcache.Set(ctx, userKey, u)
			return u, err
		}
	}
	return nil, nil
}

func (a *AuthProviders) RequireUser(
	authorizedHandler, unauthorizedHandler http.Handler) http.Handler {
	return whroute.HandlerFunc(authorizedHandler,
		func(w http.ResponseWriter, r *http.Request) {
			ctx := whcompat.Context(r)
			u, err := a.User(ctx)
			if err != nil {
				wherr.Handle(w, r, err)
				return
			}
			if u == nil {
				unauthorizedHandler.ServeHTTP(w, r)
			} else {
				authorizedHandler.ServeHTTP(w, r)
			}
		})
}

func (a *AuthProviders) LogoutURL(redirectTo string) string {
	return a.baseURL + "/logout?" + url.Values{
		"redirect_to": {redirectTo}}.Encode()
}

func newState() string {
	var p [16]byte
	_, err := rand.Read(p[:])
	if err != nil {
		panic(err)
	}
	return hex.EncodeToString(p[:])
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"github.com/coopernurse/gorp"
	_ "github.com/mattn/go-sqlite3"
	"log"
)

type User struct {
	Id       int64  `db: "id"`
	Name     string `json: "name"`
	Email    string `json: "email"`
	Password string `json: "password"`
}

type Point struct {
	X int
	Y int
}

type State struct {
	X       int  `json: "x"`
	Y       int  `json: "y"`
	Crashed bool `json: "crashed"`
	Speed   int  `json: "speed"`
}

type Road struct {
	InnerRoad []Point
	OuterRoad []Point
}

type Car struct {
	Color int
	Point Point
	State State
}

type Room struct {
	room_id      int64
	room_channel string
}

func (r Room) NewRoom() (room Room){
    room := Room{}
    room.room_id := GenerateId()
    return
}

func (r Room) GenerateId() int64{
    return 1 // ToDo: random generate number
}

func (u User) Save() {
	dbmap := initDb()
	defer dbmap.Db.Close()

	err := dbmap.Insert(u)
	checkErr(err, "User saving failed")
}

func (u User) Get(id int) User {
	dbmap := initDb()
	defer dbmap.Db.Close()
	user := User{}
	err := dbmap.SelectOne(&user, "Select * from users where id=?", id)
	checkErr(err, "User is unreachable")
	return user
}

func (c Car) MoveTo(point Point) Point {
	c.Point = point
	// ToDo: implement correct algorithm with use of intersection
	// Assume collision detection done on client side for now
	return c.Point
}

func (c Car) Status() State {
	// ToDo: this should return summarized car's status at current time.
	// probably it should contain coords, state, leadership
	return c.State
}

func (u User) GetRoom() string {
	// ToDo this should return users room data, or room itself.
	return "room data"
}

func (u User) MoveToRoom() {
	// ToDo: this will place user to new room
}

func initDb() *gorp.DbMap {
	// connect to db using standard Go database/sql API
	// use whatever database/sql driver you wish
	db, err := sql.Open("sqlite3", "./tmp/post_db.bin")
	checkErr(err, "sql.Open failed")

	// construct a gorp DbMap
	dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}

	// add a table, setting the table name to 'posts' and
	// specifying that the Id property is an auto incrementing PK
	dbmap.AddTableWithName(User{}, "posts").SetKeys(true, "Id")

	// create the table. in a production system you'd generally
	// use a migration tool, or create the tables via scripts
	err = dbmap.CreateTablesIfNotExists()
	checkErr(err, "Create tables failed")

	return dbmap
}

func checkErr(err error, msg string) {
	if err != nil {
		log.Fatalln(msg, err)
	}
}
<commit_msg>and fixes<commit_after>package main

import (
	"database/sql"
	"github.com/coopernurse/gorp"
	_ "github.com/mattn/go-sqlite3"
	"log"
)

type User struct {
	Id       int64  `db: "id"`
	Name     string `json: "name"`
	Email    string `json: "email"`
	Password string `json: "password"`
}

type Point struct {
	X int
	Y int
}

type State struct {
	X       int  `json: "x"`
	Y       int  `json: "y"`
	Crashed bool `json: "crashed"`
	Speed   int  `json: "speed"`
}

type Road struct {
	InnerRoad []Point
	OuterRoad []Point
}

type Car struct {
	Color int
	Point Point
	State State
}

type Room struct {
	room_id      int64
	room_channel string
}

func (r Room) NewRoom() (room Room) {
	room = Room{}
	room.room_id = room.GenerateId()
	return
}

func (r Room) GenerateId() int64 {
	return 1 // ToDo: random generate number
}

func (u User) Save() {
	dbmap := initDb()
	defer dbmap.Db.Close()

	err := dbmap.Insert(u)
	checkErr(err, "User saving failed")
}

func (u User) Get(id int) User {
	dbmap := initDb()
	defer dbmap.Db.Close()
	user := User{}
	err := dbmap.SelectOne(&user, "Select * from users where id=?", id)
	checkErr(err, "User is unreachable")
	return user
}

func (c Car) MoveTo(point Point) Point {
	c.Point = point
	// ToDo: implement correct algorithm with use of intersection
	// Assume collision detection done on client side for now
	return c.Point
}

func (c Car) Status() State {
	// ToDo: this should return summarized car's status at current time.
	// probably it should contain coords, state, leadership
	return c.State
}

func (u User) GetRoom() string {
	// ToDo this should return users room data, or room itself.
	return "room data"
}

func (u User) MoveToRoom() {
	// ToDo: this will place user to new room
}

func initDb() *gorp.DbMap {
	// connect to db using standard Go database/sql API
	// use whatever database/sql driver you wish
	db, err := sql.Open("sqlite3", "./tmp/post_db.bin")
	checkErr(err, "sql.Open failed")

	// construct a gorp DbMap
	dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}

	// add a table, setting the table name to 'posts' and
	// specifying that the Id property is an auto incrementing PK
	dbmap.AddTableWithName(User{}, "posts").SetKeys(true, "Id")

	// create the table. in a production system you'd generally
	// use a migration tool, or create the tables via scripts
	err = dbmap.CreateTablesIfNotExists()
	checkErr(err, "Create tables failed")

	return dbmap
}

func checkErr(err error, msg string) {
	if err != nil {
		log.Fatalln(msg, err)
	}
}
<|endoftext|>


<commit_before>package dokugen

import (
	"log"
	"strings"
)

//TODO: Support non-squared DIMS (logic in Block() would need updating)
const BLOCK_DIM = 3
const DIM = BLOCK_DIM * BLOCK_DIM
const ROW_SEP = "\n"
const COL_SEP = "|"
const ALT_COL_SEP = "||"

type Grid struct {
	initalized bool
	cells      [DIM * DIM]Cell
	rows       [DIM][]*Cell
	cols       [DIM][]*Cell
	blocks     [DIM][]*Cell
	queue      *FiniteQueue
}

func NewGrid() *Grid {
	result := &Grid{}
	result.queue = NewFiniteQueue(1, DIM)
	i := 0
	for r := 0; r < DIM; r++ {
		for c := 0; c < DIM; c++ {
			result.cells[i] = NewCell(result, r, c)
			//The cell can't insert itself because it doesn't know where it will actually live in memory yet.
			result.queue.Insert(&result.cells[i])
			i++
		}
	}
	result.initalized = true
	return result
}

func LoadGrid(data string) *Grid {
	result := NewGrid()
	data = strings.Replace(data, ALT_COL_SEP, COL_SEP, -1)
	for r, row := range strings.Split(data, ROW_SEP) {
		for c, data := range strings.Split(row, COL_SEP) {
			cell := result.Cell(r, c)
			cell.Load(data)
		}
	}
	return result
}

func (self *Grid) Row(index int) []*Cell {
	if index < 0 || index >= DIM {
		log.Println("Invalid index passed to Row: ", index)
		return nil
	}
	if self.rows[index] == nil {
		self.rows[index] = self.cellList(index, 0, index, DIM-1)
	}
	return self.rows[index]
}

func (self *Grid) Col(index int) []*Cell {
	if index < 0 || index >= DIM {
		log.Println("Invalid index passed to Col: ", index)
		return nil
	}
	if self.cols[index] == nil {
		self.cols[index] = self.cellList(0, index, DIM-1, index)
	}
	return self.cols[index]
}

func (self *Grid) Block(index int) []*Cell {
	if index < 0 || index >= DIM {
		log.Println("Invalid index passed to Block: ", index)
		return nil
	}
	if self.blocks[index] == nil {
		topRow, topCol, bottomRow, bottomCol := self.blockExtents(index)
		self.blocks[index] = self.cellList(topRow, topCol, bottomRow, bottomCol)
	}
	return self.blocks[index]
}

func (self *Grid) blockExtents(index int) (topRow int, topCol int, bottomRow int, bottomCol int) {
	//Conceptually, we'll pretend like the grid is made up of blocks that are arrayed with row/column
	//Once we find the block r/c, we'll multiply by the actual dim to get the upper left corner.

	blockCol := index % BLOCK_DIM
	blockRow := (index - blockCol) / BLOCK_DIM

	col := blockCol * BLOCK_DIM
	row := blockRow * BLOCK_DIM

	return row, col, row + BLOCK_DIM - 1, col + BLOCK_DIM - 1
}

func (self *Grid) blockForCell(row int, col int) int {
	blockCol := col / BLOCK_DIM
	blockRow := row / BLOCK_DIM
	return blockRow*BLOCK_DIM + blockCol
}

func (self *Grid) Cell(row int, col int) *Cell {
	index := row*DIM + col
	if index >= DIM*DIM || index < 0 {
		log.Println("Invalid row/col index passed to Cell: ", row, ", ", col)
		return nil
	}
	return &self.cells[index]
}

func (self *Grid) cellList(rowOne int, colOne int, rowTwo int, colTwo int) []*Cell {
	length := (rowTwo - rowOne + 1) * (colTwo - colOne + 1)
	result := make([]*Cell, length)
	currentRow := rowOne
	currentCol := colOne
	for i := 0; i < length; i++ {
		result[i] = self.Cell(currentRow, currentCol)
		if colTwo > currentCol {
			currentCol++
		} else {
			if rowTwo > currentRow {
				currentRow++
				currentCol = colOne
			} else {
				//This should only happen the last time through the loop.
			}
		}
	}
	return result
}

//Fills in all of the cells it can without branching or doing any advanced
//techniques that require anything more than a single cell's possibles list.
func (self *Grid) fillSimpleCells() int {
	count := 0
	obj := self.queue.GetSmallerThan(2)
	for obj != nil {
		cell, ok := obj.(*Cell)
		if !ok {
			continue
		}
		cell.SetNumber(cell.implicitNumber())
		count++
		obj = self.queue.GetSmallerThan(2)
	}
	return count
}

func (self *Grid) DataString() string {
	var rows []string
	for r := 0; r < DIM; r++ {
		var row []string
		for c := 0; c < DIM; c++ {
			row = append(row, self.cells[r*DIM+c].DataString())
		}
		rows = append(rows, strings.Join(row, COL_SEP))
	}
	return strings.Join(rows, ROW_SEP)
}

func (self *Grid) String() string {
	var rows []string
	for r := 0; r < DIM; r++ {
		var row []string
		for c := 0; c < DIM; c++ {
			row = append(row, self.cells[r*DIM+c].String())
		}
		rows = append(rows, strings.Join(row, COL_SEP))
	}
	return strings.Join(rows, ROW_SEP)
}
<commit_msg>Implemented Grid.blockHasNeighbors. Not tested.<commit_after>package dokugen

import (
	"log"
	"strings"
)

//TODO: Support non-squared DIMS (logic in Block() would need updating)
const BLOCK_DIM = 3
const DIM = BLOCK_DIM * BLOCK_DIM
const ROW_SEP = "\n"
const COL_SEP = "|"
const ALT_COL_SEP = "||"

type Grid struct {
	initalized bool
	cells      [DIM * DIM]Cell
	rows       [DIM][]*Cell
	cols       [DIM][]*Cell
	blocks     [DIM][]*Cell
	queue      *FiniteQueue
}

func NewGrid() *Grid {
	result := &Grid{}
	result.queue = NewFiniteQueue(1, DIM)
	i := 0
	for r := 0; r < DIM; r++ {
		for c := 0; c < DIM; c++ {
			result.cells[i] = NewCell(result, r, c)
			//The cell can't insert itself because it doesn't know where it will actually live in memory yet.
			result.queue.Insert(&result.cells[i])
			i++
		}
	}
	result.initalized = true
	return result
}

func LoadGrid(data string) *Grid {
	result := NewGrid()
	data = strings.Replace(data, ALT_COL_SEP, COL_SEP, -1)
	for r, row := range strings.Split(data, ROW_SEP) {
		for c, data := range strings.Split(row, COL_SEP) {
			cell := result.Cell(r, c)
			cell.Load(data)
		}
	}
	return result
}

func (self *Grid) Row(index int) []*Cell {
	if index < 0 || index >= DIM {
		log.Println("Invalid index passed to Row: ", index)
		return nil
	}
	if self.rows[index] == nil {
		self.rows[index] = self.cellList(index, 0, index, DIM-1)
	}
	return self.rows[index]
}

func (self *Grid) Col(index int) []*Cell {
	if index < 0 || index >= DIM {
		log.Println("Invalid index passed to Col: ", index)
		return nil
	}
	if self.cols[index] == nil {
		self.cols[index] = self.cellList(0, index, DIM-1, index)
	}
	return self.cols[index]
}

func (self *Grid) Block(index int) []*Cell {
	if index < 0 || index >= DIM {
		log.Println("Invalid index passed to Block: ", index)
		return nil
	}
	if self.blocks[index] == nil {
		topRow, topCol, bottomRow, bottomCol := self.blockExtents(index)
		self.blocks[index] = self.cellList(topRow, topCol, bottomRow, bottomCol)
	}
	return self.blocks[index]
}

func (self *Grid) blockExtents(index int) (topRow int, topCol int, bottomRow int, bottomCol int) {
	//Conceptually, we'll pretend like the grid is made up of blocks that are arrayed with row/column
	//Once we find the block r/c, we'll multiply by the actual dim to get the upper left corner.

	blockCol := index % BLOCK_DIM
	blockRow := (index - blockCol) / BLOCK_DIM

	col := blockCol * BLOCK_DIM
	row := blockRow * BLOCK_DIM

	return row, col, row + BLOCK_DIM - 1, col + BLOCK_DIM - 1
}

func (self *Grid) blockForCell(row int, col int) int {
	blockCol := col / BLOCK_DIM
	blockRow := row / BLOCK_DIM
	return blockRow*BLOCK_DIM + blockCol
}

func (self *Grid) blockHasNeighbors(index int) (top bool, right bool, bottom bool, left bool) {
	topRow, topCol, bottomRow, bottomCol := self.blockExtents(index)
	top = topRow != 0
	bottom = bottomRow != DIM-1
	left = topCol != 0
	right = bottomCol != DIM-1
	return
}

func (self *Grid) Cell(row int, col int) *Cell {
	index := row*DIM + col
	if index >= DIM*DIM || index < 0 {
		log.Println("Invalid row/col index passed to Cell: ", row, ", ", col)
		return nil
	}
	return &self.cells[index]
}

func (self *Grid) cellList(rowOne int, colOne int, rowTwo int, colTwo int) []*Cell {
	length := (rowTwo - rowOne + 1) * (colTwo - colOne + 1)
	result := make([]*Cell, length)
	currentRow := rowOne
	currentCol := colOne
	for i := 0; i < length; i++ {
		result[i] = self.Cell(currentRow, currentCol)
		if colTwo > currentCol {
			currentCol++
		} else {
			if rowTwo > currentRow {
				currentRow++
				currentCol = colOne
			} else {
				//This should only happen the last time through the loop.
			}
		}
	}
	return result
}

//Fills in all of the cells it can without branching or doing any advanced
//techniques that require anything more than a single cell's possibles list.
func (self *Grid) fillSimpleCells() int {
	count := 0
	obj := self.queue.GetSmallerThan(2)
	for obj != nil {
		cell, ok := obj.(*Cell)
		if !ok {
			continue
		}
		cell.SetNumber(cell.implicitNumber())
		count++
		obj = self.queue.GetSmallerThan(2)
	}
	return count
}

func (self *Grid) DataString() string {
	var rows []string
	for r := 0; r < DIM; r++ {
		var row []string
		for c := 0; c < DIM; c++ {
			row = append(row, self.cells[r*DIM+c].DataString())
		}
		rows = append(rows, strings.Join(row, COL_SEP))
	}
	return strings.Join(rows, ROW_SEP)
}

func (self *Grid) String() string {
	var rows []string
	for r := 0; r < DIM; r++ {
		var row []string
		for c := 0; c < DIM; c++ {
			row = append(row, self.cells[r*DIM+c].String())
		}
		rows = append(rows, strings.Join(row, COL_SEP))
	}
	return strings.Join(rows, ROW_SEP)
}
<|endoftext|>


<commit_before>package logger

import (
	"os"

	"fmt"
	"time"

	"github.com/Sirupsen/logrus"
	"gopkg.in/gin-gonic/gin.v1"
)

// Init initialize the logging system
func Init() {
	customFormatter := new(logrus.TextFormatter)
	customFormatter.TimestampFormat = time.RFC3339
	customFormatter.FullTimestamp = true
	logrus.SetFormatter(customFormatter)
	logrus.SetOutput(os.Stdout)
	logrus.SetLevel(logrus.DebugLevel)
}

// Info logging with INFO level
func Info(msg string, a ...interface{}) {
	logrus.Info(fmt.Sprintf(msg, a...))
}

// Error logging with ERROR level
func Error(msg string, a ...interface{}) {
	logrus.Error(fmt.Sprintf(msg, a...))
}

// Debug logging with DEBUG level
func Debug(msg string, a ...interface{}) {
	logrus.Debug(fmt.Sprintf(msg, a...))
}

// APILogger provide Logrus integration for Gin APIs
func APILogger() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()
		path := c.Request.URL.Path

		c.Next()

		end := time.Now()
		latency := end.Sub(start)

		clientIP := c.ClientIP()
		method := c.Request.Method
		statusCode := c.Writer.Status()
		comment := c.Errors.String()
		userAgent := c.Request.UserAgent()

		timeFormatted := end.Format("2006-01-02 15:04:05")

		msg := fmt.Sprintf(
			"%s %s \"%s %s\" %d %s %s",
			clientIP,
			timeFormatted,
			method,
			path,
			statusCode,
			latency,
			userAgent,
		)

		logrus.StandardLogger().WithFields(logrus.Fields{
			"time":       timeFormatted,
			"method":     method,
			"path":       path,
			"latency":    latency,
			"ip":         clientIP,
			"comment":    comment,
			"status":     statusCode,
			"user-agent": userAgent,
		}).Info(msg)
	}
}
<commit_msg>Add logger.Errorf function<commit_after>package logger

import (
	"os"

	"fmt"
	"time"

	"github.com/Sirupsen/logrus"
	"gopkg.in/gin-gonic/gin.v1"
)

// Init initialize the logging system
func Init() {
	customFormatter := new(logrus.TextFormatter)
	customFormatter.TimestampFormat = time.RFC3339
	customFormatter.FullTimestamp = true
	logrus.SetFormatter(customFormatter)
	logrus.SetOutput(os.Stdout)
	logrus.SetLevel(logrus.DebugLevel)
}

// Info logging with INFO level
func Info(msg string, a ...interface{}) {
	logrus.Info(fmt.Sprintf(msg, a...))
}

// Error logging with ERROR level
func Error(msg string, a ...interface{}) {
	logrus.Error(fmt.Sprintf(msg, a...))
}

// Errorf logging with ERROR level and returns an error struct
func Errorf(msg string, a ...interface{}) error {
	err := fmt.Errorf(msg, a...)
	logrus.Error(err.Error())
	return err
}

// Debug logging with DEBUG level
func Debug(msg string, a ...interface{}) {
	logrus.Debug(fmt.Sprintf(msg, a...))
}

// APILogger provide Logrus integration for Gin APIs
func APILogger() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()
		path := c.Request.URL.Path

		c.Next()

		end := time.Now()
		latency := end.Sub(start)

		clientIP := c.ClientIP()
		method := c.Request.Method
		statusCode := c.Writer.Status()
		comment := c.Errors.String()
		userAgent := c.Request.UserAgent()

		timeFormatted := end.Format("2006-01-02 15:04:05")

		msg := fmt.Sprintf(
			"%s %s \"%s %s\" %d %s %s",
			clientIP,
			timeFormatted,
			method,
			path,
			statusCode,
			latency,
			userAgent,
		)

		logrus.StandardLogger().WithFields(logrus.Fields{
			"time":       timeFormatted,
			"method":     method,
			"path":       path,
			"latency":    latency,
			"ip":         clientIP,
			"comment":    comment,
			"status":     statusCode,
			"user-agent": userAgent,
		}).Info(msg)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"flag"
	"log"
	"net/http"

	_ "github.com/mattn/go-sqlite3"

	"github.com/captncraig/temple"
)

const DebitCreditPrecision int32 = 2

var devMode = flag.Bool("dev", true, "activate dev mode for templates")
var templateManager temple.TemplateStore

var accounts map[int64]*Account

var shares map[string]*Share

var db *sql.DB
var err error

func main() {
	// Data
	accounts = make(map[int64]*Account)
	shares = make(map[string]*Share)

	setupConfig()
	setupTemplates()

	setupDB()

	loadData()

	if len(accounts) == 0 {
		createAccounts()
	}

	r := setupRouting()

	// Bind to a port and pass our router in
	listen := ":8000"
	log.Printf("Starting server on %s\n", listen)
	log.Printf("Template auto reloading: %t\n", *devMode)
	http.ListenAndServe(listen, r)
}

func setupDB() {
	db, err = sql.Open("sqlite3", "./lunchmoney.db")
	if err != nil {
		log.Printf("Error connect to the db: %s\n", err)
	}

	err = db.Ping()
	if err != nil {
		log.Fatal("Error connecting to the db: %s\n", err)
	}

	// goose migrate here
}

func setupConfig() {
	flag.Parse()
}

func setupTemplates() {
	var err error

	// Templates
	templateManager, err = temple.New(*devMode, templates, "templates")
	if err != nil {
		log.Fatal(err)
	}
}

func loadData() {
	query := `SELECT
		id,
		name,
		currency_code,
		currency_symbol_left,
		currency_symbol_right,
		decimal_places,
		icon,
		is_active,
		cleared_total,
		total
	FROM accounts`

	var id, cleared_total, total int64
	var decimal_places int32
	var name, currency_code, currency_symbol_left, currency_symbol_right, icon string
	var is_active bool

	rows, err := db.Query(query)
	defer rows.Close()
	for rows.Next() {
		err := rows.Scan(
			&id,
			&name,
			&currency_code,
			&currency_symbol_left,
			&currency_symbol_right,
			&decimal_places,
			&icon,
			&is_active,
			&cleared_total,
			&total,
		)
		if err != nil {
			log.Printf("%s\n", err)
			return
		}

		acc := &Account{
			ID:                  id,
			Name:                name,
			CurrencyCode:        currency_code,
			CurrencySymbolLeft:  currency_symbol_left,
			CurrencySymbolRight: currency_symbol_right,
			DecimalPlaces:       decimal_places,
			Icon:                icon,
			IsActive:            is_active,
			clearedTotal:        cleared_total,
			total:               total,
		}
		log.Printf("%v\n", acc)

		accounts[acc.ID] = acc
	}
	err = rows.Err()
	if err != nil {
		log.Printf("%s\n", err)
		return
	}

	query = `SELECT stockcode, qty FROM shares`

	var stockcode string
	var qty int64

	rows, err = db.Query(query)
	defer rows.Close()
	for rows.Next() {
		err := rows.Scan(
			&stockcode,
			&qty,
		)
		if err != nil {
			log.Printf("%s\n", err)
			return
		}

		share := &Share{
			Code: stockcode,
			Qty:  qty,
		}
		share.GetValue()
		log.Println(share)

		shares[stockcode] = share
	}

}

func createAccounts() {

	acc1 := &Account{
		Name:               "Savings",
		CurrencySymbolLeft: "$",
		CurrencyCode:       "AUD",
		DecimalPlaces:      DebitCreditPrecision,
		IsActive:           true,
		Icon:               "dollar",
	}
	acc1.Create(db)

	acc2 := &Account{
		Name:               "Credit Card",
		CurrencyCode:       "AUD",
		CurrencySymbolLeft: "$",
		DecimalPlaces:      DebitCreditPrecision,
		IsActive:           true,
		Icon:               "credit-card",
	}
	acc2.Create(db)

	accounts[acc1.ID] = acc1
	accounts[acc2.ID] = acc2
}
<commit_msg>Increase log detail<commit_after>package main

import (
	"database/sql"
	"flag"
	"log"
	"net/http"

	_ "github.com/mattn/go-sqlite3"

	"github.com/captncraig/temple"
)

const DebitCreditPrecision int32 = 2

var devMode = flag.Bool("dev", true, "activate dev mode for templates")
var templateManager temple.TemplateStore

var accounts map[int64]*Account

var shares map[string]*Share

var db *sql.DB
var err error

func main() {
	log.SetFlags(log.LstdFlags | log.Llongfile)
	// Data
	accounts = make(map[int64]*Account)
	shares = make(map[string]*Share)

	setupConfig()
	setupTemplates()

	setupDB()

	loadData()

	if len(accounts) == 0 {
		createAccounts()
	}

	r := setupRouting()

	// Bind to a port and pass our router in
	listen := ":8000"
	log.Printf("Starting server on %s\n", listen)
	log.Printf("Template auto reloading: %t\n", *devMode)
	http.ListenAndServe(listen, r)
}

func setupDB() {
	db, err = sql.Open("sqlite3", "./lunchmoney.db")
	if err != nil {
		log.Printf("Error connect to the db: %s\n", err)
	}

	err = db.Ping()
	if err != nil {
		log.Fatal("Error connecting to the db: %s\n", err)
	}

	// goose migrate here
}

func setupConfig() {
	flag.Parse()
}

func setupTemplates() {
	var err error

	// Templates
	templateManager, err = temple.New(*devMode, templates, "templates")
	if err != nil {
		log.Fatal(err)
	}
}

func loadData() {
	query := `SELECT
		id,
		name,
		currency_code,
		currency_symbol_left,
		currency_symbol_right,
		decimal_places,
		icon,
		is_active,
		cleared_total,
		total
	FROM accounts`

	var id, cleared_total, total int64
	var decimal_places int32
	var name, currency_code, currency_symbol_left, currency_symbol_right, icon string
	var is_active bool

	rows, err := db.Query(query)
	defer rows.Close()
	for rows.Next() {
		err := rows.Scan(
			&id,
			&name,
			&currency_code,
			&currency_symbol_left,
			&currency_symbol_right,
			&decimal_places,
			&icon,
			&is_active,
			&cleared_total,
			&total,
		)
		if err != nil {
			log.Printf("%s\n", err)
			return
		}

		acc := &Account{
			ID:                  id,
			Name:                name,
			CurrencyCode:        currency_code,
			CurrencySymbolLeft:  currency_symbol_left,
			CurrencySymbolRight: currency_symbol_right,
			DecimalPlaces:       decimal_places,
			Icon:                icon,
			IsActive:            is_active,
			clearedTotal:        cleared_total,
			total:               total,
		}
		log.Printf("%v\n", acc)

		accounts[acc.ID] = acc
	}
	err = rows.Err()
	if err != nil {
		log.Printf("%s\n", err)
		return
	}

	query = `SELECT stockcode, qty FROM shares`

	var stockcode string
	var qty int64

	rows, err = db.Query(query)
	defer rows.Close()
	for rows.Next() {
		err := rows.Scan(
			&stockcode,
			&qty,
		)
		if err != nil {
			log.Printf("%s\n", err)
			return
		}

		share := &Share{
			Code: stockcode,
			Qty:  qty,
		}
		share.GetValue()
		log.Println(share)

		shares[stockcode] = share
	}

}

func createAccounts() {

	acc1 := &Account{
		Name:               "Savings",
		CurrencySymbolLeft: "$",
		CurrencyCode:       "AUD",
		DecimalPlaces:      DebitCreditPrecision,
		IsActive:           true,
		Icon:               "dollar",
	}
	acc1.Create(db)

	acc2 := &Account{
		Name:               "Credit Card",
		CurrencyCode:       "AUD",
		CurrencySymbolLeft: "$",
		DecimalPlaces:      DebitCreditPrecision,
		IsActive:           true,
		Icon:               "credit-card",
	}
	acc2.Create(db)

	accounts[acc1.ID] = acc1
	accounts[acc2.ID] = acc2
}
<|endoftext|>