<commit_before>package commands

import (
	"errors"
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"
	namesys "github.com/ipfs/go-ipfs/namesys"
	u "github.com/ipfs/go-ipfs/util"
)

var IpnsCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Gets the value currently published at an IPNS name",
		ShortDescription: `
IPNS is a PKI namespace, where names are the hashes of public keys, and
the private key enables publishing new (signed) values. In resolve, the
default value of <name> is your own identity public key.
`,
		LongDescription: `
IPNS is a PKI namespace, where names are the hashes of public keys, and
the private key enables publishing new (signed) values. In resolve, the
default value of <name> is your own identity public key.

Examples:

Resolve the value of your identity:

  > ipfs name resolve
  QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

Resolve the value of another name:

  > ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
  QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

`,
	},

	Arguments: []cmds.Argument{
		cmds.StringArg("name", false, false, "The IPNS name to resolve. Defaults to your node's peerID.").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.BoolOption("recursive", "r", "Resolve until the result is not an IPNS name"),
	},
	Run: func(req cmds.Request, res cmds.Response) {

		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		if !n.OnlineMode() {
			err := n.SetupOfflineRouting()
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}
		}

		var name string

		if len(req.Arguments()) == 0 {
			if n.Identity == "" {
				res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
				return
			}
			name = n.Identity.Pretty()

		} else {
			name = req.Arguments()[0]
		}

		recursive, _, _ := req.Option("recursive").Bool()
		depth := 1
		if recursive {
			depth = namesys.DefaultDepthLimit
		}

		resolver := namesys.NewRoutingResolver(n.Routing)
		output, err := resolver.ResolveN(req.Context(), name, depth)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		// TODO: better errors (in the case of not finding the name, we get "failed to find any peer in table")

		res.SetOutput(&ResolvedPath{output})
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			output, ok := res.Output().(*ResolvedPath)
			if !ok {
				return nil, u.ErrCast()
			}
			return strings.NewReader(output.Path.String()), nil
		},
	},
	Type: ResolvedPath{},
}
<commit_msg>allow ipfs name resolve to respect --local flag for local name resolution<commit_after>package commands

import (
	"errors"
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"
	namesys "github.com/ipfs/go-ipfs/namesys"
	offline "github.com/ipfs/go-ipfs/routing/offline"
	u "github.com/ipfs/go-ipfs/util"
)

var IpnsCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Gets the value currently published at an IPNS name",
		ShortDescription: `
IPNS is a PKI namespace, where names are the hashes of public keys, and
the private key enables publishing new (signed) values. In resolve, the
default value of <name> is your own identity public key.
`,
		LongDescription: `
IPNS is a PKI namespace, where names are the hashes of public keys, and
the private key enables publishing new (signed) values. In resolve, the
default value of <name> is your own identity public key.

Examples:

Resolve the value of your identity:

  > ipfs name resolve
  QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

Resolve the value of another name:

  > ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
  QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

`,
	},

	Arguments: []cmds.Argument{
		cmds.StringArg("name", false, false, "The IPNS name to resolve. Defaults to your node's peerID.").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.BoolOption("recursive", "r", "Resolve until the result is not an IPNS name"),
	},
	Run: func(req cmds.Request, res cmds.Response) {

		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		if !n.OnlineMode() {
			err := n.SetupOfflineRouting()
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}
		}

		router := n.Routing
		if local, _, _ := req.Option("local").Bool(); local {
			router = offline.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey)
		}

		var name string

		if len(req.Arguments()) == 0 {
			if n.Identity == "" {
				res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
				return
			}
			name = n.Identity.Pretty()

		} else {
			name = req.Arguments()[0]
		}

		recursive, _, _ := req.Option("recursive").Bool()
		depth := 1
		if recursive {
			depth = namesys.DefaultDepthLimit
		}

		resolver := namesys.NewRoutingResolver(router)
		output, err := resolver.ResolveN(req.Context(), name, depth)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		// TODO: better errors (in the case of not finding the name, we get "failed to find any peer in table")

		res.SetOutput(&ResolvedPath{output})
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			output, ok := res.Output().(*ResolvedPath)
			if !ok {
				return nil, u.ErrCast()
			}
			return strings.NewReader(output.Path.String()), nil
		},
	},
	Type: ResolvedPath{},
}
<|endoftext|>


<commit_before>package commands

import (
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"
	dag "github.com/ipfs/go-ipfs/core/commands/dag"
	files "github.com/ipfs/go-ipfs/core/commands/files"
	ocmd "github.com/ipfs/go-ipfs/core/commands/object"
	unixfs "github.com/ipfs/go-ipfs/core/commands/unixfs"
	logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
)

var log = logging.Logger("core/commands")

const (
	ApiOption = "api"
)

var Root = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline:  "Global p2p merkle-dag filesystem.",
		Synopsis: "ipfs [--config=<config> | -c] [--debug=<debug> | -D] [--help=<help>] [-h=<h>] [--local=<local> | -L] [--api=<api>] <command> ...",
		Subcommands: `
BASIC COMMANDS
  init          Initialize ipfs local configuration
  add <path>    Add a file to IPFS
  cat <ref>     Show IPFS object data
  get <ref>     Download IPFS objects
  ls <ref>      List links from an object
  refs <ref>    List hashes of links from an object

DATA STRUCTURE COMMANDS
  block         Interact with raw blocks in the datastore
  object        Interact with raw dag nodes
  files         Interact with objects as if they were a unix filesystem

ADVANCED COMMANDS
  daemon        Start a long-running daemon process
  mount         Mount an IPFS read-only mountpoint
  resolve       Resolve any type of name
  name          Publish or resolve IPNS names
  dns           Resolve DNS links
  pin           Pin objects to local storage
  repo          Manipulate the IPFS repository

NETWORK COMMANDS
  id            Show info about IPFS peers
  bootstrap     Add or remove bootstrap peers
  swarm         Manage connections to the p2p network
  dht           Query the DHT for values or peers
  ping          Measure the latency of a connection
  diag          Print diagnostics

TOOL COMMANDS
  config        Manage configuration
  version       Show ipfs version information
  update        Download and apply go-ipfs updates
  commands      List all available commands

Use 'ipfs <command> --help' to learn more about each command.

ipfs uses a repository in the local file system. By default, the repo is located
at ~/.ipfs. To change the repo location, set the $IPFS_PATH environment variable:

  export IPFS_PATH=/path/to/ipfsrepo

EXIT STATUS

The CLI will exits with one of the following values:

0     Successful execution.
1     Failed executions.
`,
	},
	Options: []cmds.Option{
		cmds.StringOption("config", "c", "Path to the configuration file to use."),
		cmds.BoolOption("debug", "D", "Operate in debug mode.").Default(false),
		cmds.BoolOption("help", "Show the full command help text.").Default(false),
		cmds.BoolOption("h", "Show a short version of the command help text.").Default(false),
		cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon.").Default(false),
		cmds.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"),
	},
}

// commandsDaemonCmd is the "ipfs commands" command for daemon
var CommandsDaemonCmd = CommandsCmd(Root)

var rootSubcommands = map[string]*cmds.Command{
	"add":       AddCmd,
	"block":     BlockCmd,
	"bootstrap": BootstrapCmd,
	"cat":       CatCmd,
	"commands":  CommandsDaemonCmd,
	"config":    ConfigCmd,
	"dag":       dag.DagCmd,
	"dht":       DhtCmd,
	"diag":      DiagCmd,
	"dns":       DNSCmd,
	"files":     files.FilesCmd,
	"get":       GetCmd,
	"id":        IDCmd,
	"log":       LogCmd,
	"ls":        LsCmd,
	"mount":     MountCmd,
	"name":      NameCmd,
	"object":    ocmd.ObjectCmd,
	"pin":       PinCmd,
	"ping":      PingCmd,
	"pubsub":    PubsubCmd,
	"refs":      RefsCmd,
	"repo":      RepoCmd,
	"resolve":   ResolveCmd,
	"stats":     StatsCmd,
	"swarm":     SwarmCmd,
	"tar":       TarCmd,
	"tour":      tourCmd,
	"file":      unixfs.UnixFSCmd,
	"update":    ExternalBinary(),
	"version":   VersionCmd,
	"bitswap":   BitswapCmd,
}

// RootRO is the readonly version of Root
var RootRO = &cmds.Command{}

var CommandsDaemonROCmd = CommandsCmd(RootRO)

var RefsROCmd = &cmds.Command{}

var rootROSubcommands = map[string]*cmds.Command{
	"block": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"stat": blockStatCmd,
			"get":  blockGetCmd,
		},
	},
	"cat":      CatCmd,
	"commands": CommandsDaemonROCmd,
	"dns":      DNSCmd,
	"get":      GetCmd,
	"ls":       LsCmd,
	"name": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"resolve": IpnsCmd,
		},
	},
	"object": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"data":  ocmd.ObjectDataCmd,
			"links": ocmd.ObjectLinksCmd,
			"get":   ocmd.ObjectGetCmd,
			"stat":  ocmd.ObjectStatCmd,
			"patch": ocmd.ObjectPatchCmd,
		},
	},
	"refs":    RefsROCmd,
	"resolve": ResolveCmd,
	"version": VersionCmd,
}

func init() {
	Root.ProcessHelp()
	*RootRO = *Root

	// sanitize readonly refs command
	*RefsROCmd = *RefsCmd
	RefsROCmd.Subcommands = map[string]*cmds.Command{}

	Root.Subcommands = rootSubcommands
	RootRO.Subcommands = rootROSubcommands
}

type MessageOutput struct {
	Message string
}

func MessageTextMarshaler(res cmds.Response) (io.Reader, error) {
	return strings.NewReader(res.Output().(*MessageOutput).Message), nil
}
<commit_msg>Fix typo<commit_after>package commands

import (
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"
	dag "github.com/ipfs/go-ipfs/core/commands/dag"
	files "github.com/ipfs/go-ipfs/core/commands/files"
	ocmd "github.com/ipfs/go-ipfs/core/commands/object"
	unixfs "github.com/ipfs/go-ipfs/core/commands/unixfs"
	logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
)

var log = logging.Logger("core/commands")

const (
	ApiOption = "api"
)

var Root = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline:  "Global p2p merkle-dag filesystem.",
		Synopsis: "ipfs [--config=<config> | -c] [--debug=<debug> | -D] [--help=<help>] [-h=<h>] [--local=<local> | -L] [--api=<api>] <command> ...",
		Subcommands: `
BASIC COMMANDS
  init          Initialize ipfs local configuration
  add <path>    Add a file to IPFS
  cat <ref>     Show IPFS object data
  get <ref>     Download IPFS objects
  ls <ref>      List links from an object
  refs <ref>    List hashes of links from an object

DATA STRUCTURE COMMANDS
  block         Interact with raw blocks in the datastore
  object        Interact with raw dag nodes
  files         Interact with objects as if they were a unix filesystem

ADVANCED COMMANDS
  daemon        Start a long-running daemon process
  mount         Mount an IPFS read-only mountpoint
  resolve       Resolve any type of name
  name          Publish or resolve IPNS names
  dns           Resolve DNS links
  pin           Pin objects to local storage
  repo          Manipulate the IPFS repository

NETWORK COMMANDS
  id            Show info about IPFS peers
  bootstrap     Add or remove bootstrap peers
  swarm         Manage connections to the p2p network
  dht           Query the DHT for values or peers
  ping          Measure the latency of a connection
  diag          Print diagnostics

TOOL COMMANDS
  config        Manage configuration
  version       Show ipfs version information
  update        Download and apply go-ipfs updates
  commands      List all available commands

Use 'ipfs <command> --help' to learn more about each command.

ipfs uses a repository in the local file system. By default, the repo is located
at ~/.ipfs. To change the repo location, set the $IPFS_PATH environment variable:

  export IPFS_PATH=/path/to/ipfsrepo

EXIT STATUS

The CLI will exit with one of the following values:

0     Successful execution.
1     Failed executions.
`,
	},
	Options: []cmds.Option{
		cmds.StringOption("config", "c", "Path to the configuration file to use."),
		cmds.BoolOption("debug", "D", "Operate in debug mode.").Default(false),
		cmds.BoolOption("help", "Show the full command help text.").Default(false),
		cmds.BoolOption("h", "Show a short version of the command help text.").Default(false),
		cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon.").Default(false),
		cmds.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"),
	},
}

// commandsDaemonCmd is the "ipfs commands" command for daemon
var CommandsDaemonCmd = CommandsCmd(Root)

var rootSubcommands = map[string]*cmds.Command{
	"add":       AddCmd,
	"block":     BlockCmd,
	"bootstrap": BootstrapCmd,
	"cat":       CatCmd,
	"commands":  CommandsDaemonCmd,
	"config":    ConfigCmd,
	"dag":       dag.DagCmd,
	"dht":       DhtCmd,
	"diag":      DiagCmd,
	"dns":       DNSCmd,
	"files":     files.FilesCmd,
	"get":       GetCmd,
	"id":        IDCmd,
	"log":       LogCmd,
	"ls":        LsCmd,
	"mount":     MountCmd,
	"name":      NameCmd,
	"object":    ocmd.ObjectCmd,
	"pin":       PinCmd,
	"ping":      PingCmd,
	"pubsub":    PubsubCmd,
	"refs":      RefsCmd,
	"repo":      RepoCmd,
	"resolve":   ResolveCmd,
	"stats":     StatsCmd,
	"swarm":     SwarmCmd,
	"tar":       TarCmd,
	"tour":      tourCmd,
	"file":      unixfs.UnixFSCmd,
	"update":    ExternalBinary(),
	"version":   VersionCmd,
	"bitswap":   BitswapCmd,
}

// RootRO is the readonly version of Root
var RootRO = &cmds.Command{}

var CommandsDaemonROCmd = CommandsCmd(RootRO)

var RefsROCmd = &cmds.Command{}

var rootROSubcommands = map[string]*cmds.Command{
	"block": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"stat": blockStatCmd,
			"get":  blockGetCmd,
		},
	},
	"cat":      CatCmd,
	"commands": CommandsDaemonROCmd,
	"dns":      DNSCmd,
	"get":      GetCmd,
	"ls":       LsCmd,
	"name": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"resolve": IpnsCmd,
		},
	},
	"object": &cmds.Command{
		Subcommands: map[string]*cmds.Command{
			"data":  ocmd.ObjectDataCmd,
			"links": ocmd.ObjectLinksCmd,
			"get":   ocmd.ObjectGetCmd,
			"stat":  ocmd.ObjectStatCmd,
			"patch": ocmd.ObjectPatchCmd,
		},
	},
	"refs":    RefsROCmd,
	"resolve": ResolveCmd,
	"version": VersionCmd,
}

func init() {
	Root.ProcessHelp()
	*RootRO = *Root

	// sanitize readonly refs command
	*RefsROCmd = *RefsCmd
	RefsROCmd.Subcommands = map[string]*cmds.Command{}

	Root.Subcommands = rootSubcommands
	RootRO.Subcommands = rootROSubcommands
}

type MessageOutput struct {
	Message string
}

func MessageTextMarshaler(res cmds.Response) (io.Reader, error) {
	return strings.NewReader(res.Output().(*MessageOutput).Message), nil
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"io"
	"os"
	"strings"
	"time"
)

type AppInfoService interface {
	GetAppInfo() (AppInfo, error)
}

func New() (AppInfoService, error) {

	return &appInfoBaseline{}, nil

}

//appInfoBaseline is the implementation of the AppInfoService interface.  This implementation has a bug where
// the Namespace value is not populated.
type appInfoBaseline struct {
}

//GetAppInfo returns the app info of the running application
func (s *appInfoBaseline) GetAppInfo() (AppInfo, error) {

	info := AppInfo{}
	info.Labels = make(map[string]string)

	info.PodName = os.Getenv("MY_POD_NAME") //custom defined in the deployment spec
	//time.Sleep(3*time.Second)
	info.Namespace = os.Getenv("MY_POD_NAMESPACE") //custom defined in the deployment spec

	file, err := os.Open("/etc/labels")
	if err != nil {
		return info, err
	}
	defer file.Close()

	//overkill, but read it fresh each time
	reader := bufio.NewReader(file)

	for {
		line, err := reader.ReadString('\n')

		// check if the line has = sign
		// and process the line. Ignore the rest.
		if equal := strings.Index(line, "="); equal >= 0 {
			if key := strings.TrimSpace(line[:equal]); len(key) > 0 {
				value := ""
				if len(line) > equal {
					value = strings.TrimSpace(line[equal+1:])
				}

				value = strings.Replace(value, "\"", "", -1)
				switch key {
				case "app":
					info.AppName = value
				case "release":
					info.Release = value
				default:
					info.Labels[key] = value
				}
			}
		}
		if err == io.EOF {
			break
		}
		if err != nil {
			return info, err
		}
	}

	//return info, fmt.Errorf("Forced error")
	return info, err
}

<commit_msg>Remove import<commit_after>package main

import (
	"bufio"
	"io"
	"os"
	"strings"
)

type AppInfoService interface {
	GetAppInfo() (AppInfo, error)
}

func New() (AppInfoService, error) {

	return &appInfoBaseline{}, nil

}

//appInfoBaseline is the implementation of the AppInfoService interface.  This implementation has a bug where
// the Namespace value is not populated.
type appInfoBaseline struct {
}

//GetAppInfo returns the app info of the running application
func (s *appInfoBaseline) GetAppInfo() (AppInfo, error) {

	info := AppInfo{}
	info.Labels = make(map[string]string)

	info.PodName = os.Getenv("MY_POD_NAME") //custom defined in the deployment spec
	//time.Sleep(3*time.Second)
	info.Namespace = os.Getenv("MY_POD_NAMESPACE") //custom defined in the deployment spec

	file, err := os.Open("/etc/labels")
	if err != nil {
		return info, err
	}
	defer file.Close()

	//overkill, but read it fresh each time
	reader := bufio.NewReader(file)

	for {
		line, err := reader.ReadString('\n')

		// check if the line has = sign
		// and process the line. Ignore the rest.
		if equal := strings.Index(line, "="); equal >= 0 {
			if key := strings.TrimSpace(line[:equal]); len(key) > 0 {
				value := ""
				if len(line) > equal {
					value = strings.TrimSpace(line[equal+1:])
				}

				value = strings.Replace(value, "\"", "", -1)
				switch key {
				case "app":
					info.AppName = value
				case "release":
					info.Release = value
				default:
					info.Labels[key] = value
				}
			}
		}
		if err == io.EOF {
			break
		}
		if err != nil {
			return info, err
		}
	}

	//return info, fmt.Errorf("Forced error")
	return info, err
}

<|endoftext|>


<commit_before>/*

memory is a simple example game based on memory--where players take turn
flipping over two cards, and keeping them if they match.

*/
package memory

import (
	"fmt"
	"github.com/jkomoros/boardgame"
	"strconv"
	"strings"
)

//go:generate autoreader

var computedPropertiesConfig *boardgame.ComputedPropertiesConfig

//computeCurrentPlayerHasCardsToReveal is used in our ComputedPropertyConfig.
func computeCurrentPlayerHasCardsToReveal(state boardgame.State) (interface{}, error) {

	game, players := concreteStates(state)

	p := players[game.CurrentPlayer]

	return p.CardsLeftToReveal > 0, nil

}

func init() {
	computedPropertiesConfig = &boardgame.ComputedPropertiesConfig{
		Global: map[string]boardgame.ComputedGlobalPropertyDefinition{
			"CurrentPlayerHasCardsToReveal": boardgame.ComputedGlobalPropertyDefinition{
				Dependencies: []boardgame.StatePropertyRef{
					{
						Group:    boardgame.StateGroupGame,
						PropName: "CurrentPlayer",
					},
					{
						Group:    boardgame.StateGroupPlayer,
						PropName: "CardsLeftToReveal",
					},
				},
				PropType: boardgame.TypeBool,
				Compute:  computeCurrentPlayerHasCardsToReveal,
			},
		},
	}
}

type gameDelegate struct {
	boardgame.DefaultGameDelegate
}

func (g *gameDelegate) Name() string {
	return "memory"
}

func (g *gameDelegate) DisplayName() string {
	return "Memory"
}

func (g *gameDelegate) DefaultNumPlayeres() int {
	return 2
}

func (g *gameDelegate) ComputedPropertiesConfig() *boardgame.ComputedPropertiesConfig {
	return computedPropertiesConfig
}

func (g *gameDelegate) LegalNumPlayers(numPlayers int) bool {
	return numPlayers < 4 && numPlayers > 1
}

func (g *gameDelegate) CurrentPlayerIndex(state boardgame.State) boardgame.PlayerIndex {
	game, _ := concreteStates(state)
	return game.CurrentPlayer
}

func (g *gameDelegate) EmptyGameState() boardgame.MutableSubState {

	cards := g.Manager().Chest().Deck(cardsDeckName)

	if cards == nil {
		return nil
	}

	return &gameState{
		CurrentPlayer:  0,
		HiddenCards:    boardgame.NewSizedStack(cards, len(cards.Components())),
		RevealedCards:  boardgame.NewSizedStack(cards, len(cards.Components())),
		HideCardsTimer: boardgame.NewTimer(),
	}
}

func (g *gameDelegate) EmptyPlayerState(playerIndex boardgame.PlayerIndex) boardgame.MutablePlayerState {

	cards := g.Manager().Chest().Deck(cardsDeckName)

	if cards == nil {
		return nil
	}

	return &playerState{
		playerIndex: playerIndex,
		WonCards:    boardgame.NewGrowableStack(cards, 0),
	}
}

func (g *gameDelegate) DistributeComponentToStarterStack(state boardgame.State, c *boardgame.Component) (boardgame.Stack, error) {
	game, _ := concreteStates(state)

	return game.HiddenCards, nil

}

func (g *gameDelegate) FinishSetUp(state boardgame.MutableState) {
	game, players := concreteStates(state)

	game.HiddenCards.Shuffle()

	players[0].CardsLeftToReveal = 2
}

func (g *gameDelegate) Diagram(state boardgame.State) string {
	game, players := concreteStates(state)

	var result []string

	result = append(result, "Board")

	for i, c := range game.HiddenCards.Components() {

		//If there's no hidden card in this slot, see if there is a revealed one.
		if c == nil {
			c = game.RevealedCards.ComponentAt(i)
		}

		value := fmt.Sprintf("%2d", i) + ": "

		if c == nil {
			value += "<empty>"
		} else {
			value += c.Values.(*cardValue).Type
		}

		result = append(result, "\t"+value)

	}

	result = append(result, "*****")

	for i, player := range players {
		playerName := "Player " + strconv.Itoa(i)
		if boardgame.PlayerIndex(i) == game.CurrentPlayer {
			playerName += " *CURRENT* " + strconv.Itoa(player.CardsLeftToReveal)
		}
		result = append(result, playerName)
		result = append(result, strconv.Itoa(player.WonCards.NumComponents()))
	}

	return strings.Join(result, "\n")
}

var policy *boardgame.StatePolicy

func (g *gameDelegate) StateSanitizationPolicy() *boardgame.StatePolicy {

	if policy == nil {
		policy = &boardgame.StatePolicy{
			Game: map[string]boardgame.GroupPolicy{
				"HiddenCards": boardgame.GroupPolicy{
					boardgame.GroupAll: boardgame.PolicyLen,
				},
			},
		}
	}

	return policy

}

func (g *gameDelegate) CheckGameFinished(state boardgame.State) (finished bool, winners []boardgame.PlayerIndex) {
	game, players := concreteStates(state)

	if game.HiddenCards.NumComponents() != 0 || game.RevealedCards.NumComponents() != 0 {
		return false, nil
	}

	//If we get to here, the game is over. Who won?
	maxScore := 0

	for _, player := range players {
		score := player.WonCards.NumComponents()
		if score > maxScore {
			maxScore = score
		}
	}

	for i, player := range players {
		score := player.WonCards.NumComponents()

		if score >= maxScore {
			winners = append(winners, boardgame.PlayerIndex(i))
		}
	}

	return true, winners

}

func NewManager(storage boardgame.StorageManager) *boardgame.GameManager {
	chest := boardgame.NewComponentChest()

	cards := boardgame.NewDeck()

	for _, val := range cardNames {
		cards.AddComponentMulti(&cardValue{
			Type: val,
		}, 2)
	}

	cards.SetShadowValues(&cardValue{
		Type: "<hidden>",
	})

	chest.AddDeck(cardsDeckName, cards)

	manager := boardgame.NewGameManager(&gameDelegate{}, chest, storage)

	if manager == nil {
		panic("No manager returned")
	}

	manager.AddFixUpMoveFactory(MoveAdvanceNextPlayerFactory)
	manager.AddFixUpMoveFactory(MoveCaptureCardsFactory)
	manager.AddFixUpMoveFactory(MoveStartHideCardsTimerFactory)
	manager.AddPlayerMoveFactory(MoveRevealCardFactory)
	manager.AddPlayerMoveFactory(MoveHideCardsFactory)

	manager.AddAgent(&Agent{})

	manager.SetUp()

	return manager
}
<commit_msg>Memory game uses PolicyOrder for hidden cards. Part of #350.<commit_after>/*

memory is a simple example game based on memory--where players take turn
flipping over two cards, and keeping them if they match.

*/
package memory

import (
	"fmt"
	"github.com/jkomoros/boardgame"
	"strconv"
	"strings"
)

//go:generate autoreader

var computedPropertiesConfig *boardgame.ComputedPropertiesConfig

//computeCurrentPlayerHasCardsToReveal is used in our ComputedPropertyConfig.
func computeCurrentPlayerHasCardsToReveal(state boardgame.State) (interface{}, error) {

	game, players := concreteStates(state)

	p := players[game.CurrentPlayer]

	return p.CardsLeftToReveal > 0, nil

}

func init() {
	computedPropertiesConfig = &boardgame.ComputedPropertiesConfig{
		Global: map[string]boardgame.ComputedGlobalPropertyDefinition{
			"CurrentPlayerHasCardsToReveal": boardgame.ComputedGlobalPropertyDefinition{
				Dependencies: []boardgame.StatePropertyRef{
					{
						Group:    boardgame.StateGroupGame,
						PropName: "CurrentPlayer",
					},
					{
						Group:    boardgame.StateGroupPlayer,
						PropName: "CardsLeftToReveal",
					},
				},
				PropType: boardgame.TypeBool,
				Compute:  computeCurrentPlayerHasCardsToReveal,
			},
		},
	}
}

type gameDelegate struct {
	boardgame.DefaultGameDelegate
}

func (g *gameDelegate) Name() string {
	return "memory"
}

func (g *gameDelegate) DisplayName() string {
	return "Memory"
}

func (g *gameDelegate) DefaultNumPlayeres() int {
	return 2
}

func (g *gameDelegate) ComputedPropertiesConfig() *boardgame.ComputedPropertiesConfig {
	return computedPropertiesConfig
}

func (g *gameDelegate) LegalNumPlayers(numPlayers int) bool {
	return numPlayers < 4 && numPlayers > 1
}

func (g *gameDelegate) CurrentPlayerIndex(state boardgame.State) boardgame.PlayerIndex {
	game, _ := concreteStates(state)
	return game.CurrentPlayer
}

func (g *gameDelegate) EmptyGameState() boardgame.MutableSubState {

	cards := g.Manager().Chest().Deck(cardsDeckName)

	if cards == nil {
		return nil
	}

	return &gameState{
		CurrentPlayer:  0,
		HiddenCards:    boardgame.NewSizedStack(cards, len(cards.Components())),
		RevealedCards:  boardgame.NewSizedStack(cards, len(cards.Components())),
		HideCardsTimer: boardgame.NewTimer(),
	}
}

func (g *gameDelegate) EmptyPlayerState(playerIndex boardgame.PlayerIndex) boardgame.MutablePlayerState {

	cards := g.Manager().Chest().Deck(cardsDeckName)

	if cards == nil {
		return nil
	}

	return &playerState{
		playerIndex: playerIndex,
		WonCards:    boardgame.NewGrowableStack(cards, 0),
	}
}

func (g *gameDelegate) DistributeComponentToStarterStack(state boardgame.State, c *boardgame.Component) (boardgame.Stack, error) {
	game, _ := concreteStates(state)

	return game.HiddenCards, nil

}

func (g *gameDelegate) FinishSetUp(state boardgame.MutableState) {
	game, players := concreteStates(state)

	game.HiddenCards.Shuffle()

	players[0].CardsLeftToReveal = 2
}

func (g *gameDelegate) Diagram(state boardgame.State) string {
	game, players := concreteStates(state)

	var result []string

	result = append(result, "Board")

	for i, c := range game.HiddenCards.Components() {

		//If there's no hidden card in this slot, see if there is a revealed one.
		if c == nil {
			c = game.RevealedCards.ComponentAt(i)
		}

		value := fmt.Sprintf("%2d", i) + ": "

		if c == nil {
			value += "<empty>"
		} else {
			value += c.Values.(*cardValue).Type
		}

		result = append(result, "\t"+value)

	}

	result = append(result, "*****")

	for i, player := range players {
		playerName := "Player " + strconv.Itoa(i)
		if boardgame.PlayerIndex(i) == game.CurrentPlayer {
			playerName += " *CURRENT* " + strconv.Itoa(player.CardsLeftToReveal)
		}
		result = append(result, playerName)
		result = append(result, strconv.Itoa(player.WonCards.NumComponents()))
	}

	return strings.Join(result, "\n")
}

var policy *boardgame.StatePolicy

func (g *gameDelegate) StateSanitizationPolicy() *boardgame.StatePolicy {

	if policy == nil {
		policy = &boardgame.StatePolicy{
			Game: map[string]boardgame.GroupPolicy{
				"HiddenCards": boardgame.GroupPolicy{
					boardgame.GroupAll: boardgame.PolicyOrder,
				},
			},
		}
	}

	return policy

}

func (g *gameDelegate) CheckGameFinished(state boardgame.State) (finished bool, winners []boardgame.PlayerIndex) {
	game, players := concreteStates(state)

	if game.HiddenCards.NumComponents() != 0 || game.RevealedCards.NumComponents() != 0 {
		return false, nil
	}

	//If we get to here, the game is over. Who won?
	maxScore := 0

	for _, player := range players {
		score := player.WonCards.NumComponents()
		if score > maxScore {
			maxScore = score
		}
	}

	for i, player := range players {
		score := player.WonCards.NumComponents()

		if score >= maxScore {
			winners = append(winners, boardgame.PlayerIndex(i))
		}
	}

	return true, winners

}

func NewManager(storage boardgame.StorageManager) *boardgame.GameManager {
	chest := boardgame.NewComponentChest()

	cards := boardgame.NewDeck()

	for _, val := range cardNames {
		cards.AddComponentMulti(&cardValue{
			Type: val,
		}, 2)
	}

	cards.SetShadowValues(&cardValue{
		Type: "<hidden>",
	})

	chest.AddDeck(cardsDeckName, cards)

	manager := boardgame.NewGameManager(&gameDelegate{}, chest, storage)

	if manager == nil {
		panic("No manager returned")
	}

	manager.AddFixUpMoveFactory(MoveAdvanceNextPlayerFactory)
	manager.AddFixUpMoveFactory(MoveCaptureCardsFactory)
	manager.AddFixUpMoveFactory(MoveStartHideCardsTimerFactory)
	manager.AddPlayerMoveFactory(MoveRevealCardFactory)
	manager.AddPlayerMoveFactory(MoveHideCardsFactory)

	manager.AddAgent(&Agent{})

	manager.SetUp()

	return manager
}
<|endoftext|>


<commit_before>package getter

import "net/url"

// RedactURL is a port of url.Redacted from the standard library,
// which is like url.String but replaces any password with "xxxxx".
// Only the password in u.URL is redacted. This allows the library
// to maintain compatibility with go1.14.
func RedactURL(u *url.URL) string {
	if u == nil {
		return ""
	}

	ru := *u
	if _, has := ru.User.Password(); has {
		ru.User = url.UserPassword(ru.User.Username(), "redacted")
	}
	q := ru.Query()
	if q.Get("sshkey") != "" {
		q.Set("sshkey", "redacted")
		ru.RawQuery = q.Encode()
	}
	return ru.String()
}
<commit_msg>Redact SSH key from URL query parameter<commit_after>package getter

import "net/url"

// RedactURL is a port of url.Redacted from the standard library,
// which is like url.String but replaces any password with "redacted".
// Only the password in u.URL is redacted. This allows the library
// to maintain compatibility with go1.14.
// This port was also extended to redact SSH key from URL query parameter.
func RedactURL(u *url.URL) string {
	if u == nil {
		return ""
	}

	ru := *u
	if _, has := ru.User.Password(); has {
		ru.User = url.UserPassword(ru.User.Username(), "redacted")
	}
	q := ru.Query()
	if q.Get("sshkey") != "" {
		q.Set("sshkey", "redacted")
		ru.RawQuery = q.Encode()
	}
	return ru.String()
}
<|endoftext|>


<commit_before>package parser

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"../models"
	"time"
	"strings"
	"strconv"
)

const (
	URL = "http://mds-club.ru/cgi-bin/index.cgi?r=84&lang=rus"
	AGENT = "Mozilla/5.0 (Winxp; Windows x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36"
	SLEEP = 200			// millisecond
	START_FROM = 0		// position
	TIMEOUT = 15		// seconds
)

var (
	total_elements int = 1312
	current_element int
	totalChan chan int
	statusChan chan int
	errorChan chan error
	quitChan chan bool
)

type Element struct {
	Url			string
	Author		string
	Book		string
	Date		string
	Station		string
	Files 		[]*models.File
}

func checkErr(err error) {
	if err != nil {
		errorChan <- err
		return
	}
}

func getDocument(url string) (*goquery.Document, error) {
	return GetDocument(AGENT, url, time.Duration(TIMEOUT * time.Second))
}

func getNextUrl(doc *goquery.Document) (string, bool) {
	return doc.Find("#main #body_content #roller_active").First().NextFiltered("#roller_passive").Find("a").Attr("href")
}

func getUrl(doc *goquery.Selection) (string, bool) {
	return doc.Find("a").Attr("href")
}

func getElementsFromPage(doc *goquery.Document) ([]*Element, error) {

	elements := make([]*Element, 0)

	table := doc.Find("#catalogtable").Find("tbody").First()
	trs := table.Find("tr.w")
	for tr_i := range trs.Nodes {

		tr := trs.Eq(tr_i)
		node := tr.Find("td")

		element := new(Element)
		url, b := getUrl(node.Eq(0))
		if b {
			element.Url = url
		}

		element.Author = node.Eq(1).Text()
		element.Book = node.Eq(2).Text()
		element.Date = node.Eq(3).Text()
		element.Station = node.Eq(5).Text()
		elements = append(elements, element)
	}

	return elements, nil
}

func getFiles(doc *goquery.Document) ([]*models.File, error) {

	files := make([]*models.File, 0)

	table := doc.Find("#catalogtable").Find("tbody").First()
	trs := table.Find("tr.w")
	for tr_i := range trs.Nodes {
		tr := trs.Eq(tr_i)
		node := tr.Find("td")

		file := new(models.File)

		url, b := getUrl(node.Eq(3))
		if b {
			file.Url = url
		}

		file.Name = node.Eq(3).Text()
		file.Size = node.Eq(4).Text()

		files = append(files, file)
	}

	return files, nil
}

func parseDate(val string) (time.Time, error) {

	valArr := strings.Split(val, ".")
	day, err := strconv.Atoi(valArr[0])
	if err != nil {
		return time.Now(), err
	}

	month, err := strconv.Atoi(valArr[1])
	if err != nil {
		return time.Now(), err
	}

	year, err := strconv.Atoi(valArr[2])
	if err != nil {
		return time.Now(), err
	}

	return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC), nil
}

func scanCatalog(url string) error {

	page, err := getDocument(url)
	if err != nil {
		checkErr(err)
		return err
	}

	elements, err := getElementsFromPage(page)
	if err != nil {
		checkErr(err)
		return err
	}

	for _, element := range elements {

		current_element += 1
		statusChan <- current_element

		if START_FROM != 0 && current_element < START_FROM {
			time.Sleep(time.Millisecond * 100)
			continue
		}

		if element.Url != "" {
			element_page, err := getDocument(element.Url)
			if err != nil {
				checkErr(err)
				continue
			}

			element.Files, err = getFiles(element_page)
			if err != nil {
				checkErr(err)
				continue
			}
		}

		// save author
		// ----------------------------------------------------
		author, err := models.AuthorGet(element.Author)
		if err != nil || author == nil {
			author = new(models.Author)
			author.Name = element.Author
			author.Save()
		}

		if author.Id == 0 {
			err = fmt.Errorf("author not init: %s\n", author.Name)
			checkErr(err)
//			return err
			continue
		}

		// station
		// ----------------------------------------------------
		station, err := models.StationGet(element.Station)
		if err != nil || station == nil {
			station = new(models.Station)
			station.Name = element.Station
			station.Save()
		}

		if station.Id == 0 {
			err = fmt.Errorf("station not init: %s\n", station.Name)
			checkErr(err)
//			return err
			continue
		}

		// book
		// ----------------------------------------------------
		book, err := models.BookGet(element.Book)
		if err != nil || book == nil {

			book = new(models.Book)
			book.Name = element.Book
			book.Station_id = station.Id
			book.Author_id = author.Id

			date, err := parseDate(element.Date)
			if err == nil {
				book.Date = date
			}

			book.Save()

		} else {

			if assigned := author.IsAssigned(book); !assigned {
				author.AddBook(book)
			}
		}

//		if book.Author_id == 0 {
//			err = fmt.Errorf("book not assigned to author: %s\n", author.Name)
//			checkErr(err)
//			return err
//		}
//
//		if book.Id == 0 {
//			err = fmt.Errorf("book not init: %s\n", book.Name)
//			checkErr(err)
//			return err
//		}
//
//		// save files
//		// ----------------------------------------------------
//		for _, file := range element.Files {
//
//			if file_id, _ := models.FileExist(file.Name, file.Url); file_id != 0 {
//				file.Id = file_id
//
//				if !book.FileExist(file) {
//					book.AddFile(file)
//				}
//			} else {
//				file.Save()
//				book.AddFile(file)
//			}
//		}

		time.Sleep( time.Duration(SLEEP) * time.Millisecond)
	}

	next_url, b := getNextUrl(page)
	if b {
		if err := scanCatalog(next_url); err != nil {
			return err
		}
	}

	return nil
}

func GetTotalElements(url string) (int, error) {

	if total_elements != 0 {
		return total_elements, nil
	}

	var total int

	for {
		page, err := getDocument(url)
		if err != nil {
			checkErr(err)
			return 0, err
		}

		elements, err := getElementsFromPage(page)
		if err != nil {
			checkErr(err)
			return 0, err
		}

		total += len(elements)

		next_url, b := getNextUrl(page)
		if !b {
			break
		}
		url = next_url
	}

	total_elements = total

	return total, nil
}

func Run() (chan bool, chan int, chan int, chan error) {

	quitChan = make(chan bool, 1)
	totalChan = make(chan int, 1)
	statusChan = make(chan int, 1)
	errorChan = make(chan error, 1)

	total, err := GetTotalElements(URL)
	if err != nil {
		errorChan <- err
		quitChan <- true
	}

	totalChan <- total

	current_element = 0
	go func() {
		scanCatalog(URL)
		defer close(quitChan)
		defer close(totalChan)
		defer close(statusChan)
		defer close(errorChan)
		quitChan <- true
	}()

	return quitChan, totalChan, statusChan, errorChan
}<commit_msg>catalog parser<commit_after>package parser

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"../models"
	"time"
	"strings"
	"strconv"
)

const (
	URL = "http://mds-club.ru/cgi-bin/index.cgi?r=84&lang=rus"
	AGENT = "Mozilla/5.0 (Winxp; Windows x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36"
	SLEEP = 200			// millisecond
	START_FROM = 0		// position
	TIMEOUT = 15		// seconds
)

var (
	total_elements int = 1312
	current_element int
	totalChan chan int
	statusChan chan int
	errorChan chan error
	quitChan chan bool
)

type Element struct {
	Url			string
	Author		string
	Book		string
	Date		string
	Station		string
	Files 		[]*models.File
}

func checkErr(err error) {
	if err != nil {
		errorChan <- err
		return
	}
}

func getDocument(url string) (*goquery.Document, error) {
	return GetDocument(AGENT, url, time.Duration(TIMEOUT * time.Second))
}

func getNextUrl(doc *goquery.Document) (string, bool) {
	return doc.Find("#main #body_content #roller_active").First().NextFiltered("#roller_passive").Find("a").Attr("href")
}

func getUrl(doc *goquery.Selection) (string, bool) {
	return doc.Find("a").Attr("href")
}

func getElementsFromPage(doc *goquery.Document) ([]*Element, error) {

	elements := make([]*Element, 0)

	table := doc.Find("#catalogtable").Find("tbody").First()
	trs := table.Find("tr.w")
	for tr_i := range trs.Nodes {

		tr := trs.Eq(tr_i)
		node := tr.Find("td")

		element := new(Element)
		url, b := getUrl(node.Eq(0))
		if b {
			element.Url = url
		}

		element.Author = node.Eq(1).Text()
		element.Book = node.Eq(2).Text()
		element.Date = node.Eq(3).Text()
		element.Station = node.Eq(5).Text()
		elements = append(elements, element)
	}

	return elements, nil
}

func getFiles(doc *goquery.Document) ([]*models.File, error) {

	files := make([]*models.File, 0)

	table := doc.Find("#catalogtable").Find("tbody").First()
	trs := table.Find("tr.w")
	for tr_i := range trs.Nodes {
		tr := trs.Eq(tr_i)
		node := tr.Find("td")

		file := new(models.File)

		url, b := getUrl(node.Eq(3))
		if b {
			file.Url = url
		}

		file.Name = node.Eq(3).Text()
		file.Size = node.Eq(4).Text()

		files = append(files, file)
	}

	return files, nil
}

func parseDate(val string) (time.Time, error) {

	valArr := strings.Split(val, ".")
	day, err := strconv.Atoi(valArr[0])
	if err != nil {
		return time.Now(), err
	}

	month, err := strconv.Atoi(valArr[1])
	if err != nil {
		return time.Now(), err
	}

	year, err := strconv.Atoi(valArr[2])
	if err != nil {
		return time.Now(), err
	}

	return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC), nil
}

func scanCatalog(url string) error {

	page, err := getDocument(url)
	if err != nil {
		checkErr(err)
		return err
	}

	elements, err := getElementsFromPage(page)
	if err != nil {
		checkErr(err)
		return err
	}

	for _, element := range elements {

		current_element += 1
		statusChan <- current_element

		if START_FROM != 0 && current_element < START_FROM {
			time.Sleep(time.Millisecond * 100)
			continue
		}

		if element.Url != "" {
			element_page, err := getDocument(element.Url)
			if err != nil {
				checkErr(err)
				continue
			}

			element.Files, err = getFiles(element_page)
			if err != nil {
				checkErr(err)
				continue
			}
		}

		// save author
		// ----------------------------------------------------
		author, err := models.AuthorGet(element.Author)
		if err != nil || author == nil {
			author = new(models.Author)
			author.Name = element.Author
			author.Save()
		}

		if author.Id == 0 {
			err = fmt.Errorf("author not init: %s\n", author.Name)
			checkErr(err)
//			return err
			continue
		}

		// station
		// ----------------------------------------------------
		station, err := models.StationGet(element.Station)
		if err != nil || station == nil {
			station = new(models.Station)
			station.Name = element.Station
			station.Save()
		}

		if station.Id == 0 {
			err = fmt.Errorf("station not init: %s\n", station.Name)
			checkErr(err)
//			return err
			continue
		}

		// book
		// ----------------------------------------------------
		book, err := models.BookGet(element.Book)
		if err != nil || book == nil {

			book = new(models.Book)
			book.Name = element.Book
			book.Station_id = station.Id
			book.Author_id = author.Id

			date, err := parseDate(element.Date)
			if err == nil {
				book.Date = date
			}

			book.Save()

		} else {

			if assigned := author.IsAssigned(book); !assigned {
				author.AddBook(book)
			}
		}

		if book.Author_id == 0 {
			err = fmt.Errorf("book not assigned to author: %s\n", author.Name)
			checkErr(err)
			return err
		}

		if book.Id == 0 {
			err = fmt.Errorf("book not init: %s\n", book.Name)
			checkErr(err)
			return err
		}

		// save files
		// ----------------------------------------------------
		for _, file := range element.Files {

			if file_id, _ := models.FileExist(file.Name, file.Url); file_id != 0 {
				file.Id = file_id

				if !book.FileExist(file) {
					book.AddFile(file)
				}
			} else {
				file.Save()
				book.AddFile(file)
			}
		}

		time.Sleep( time.Duration(SLEEP) * time.Millisecond)
	}

	next_url, b := getNextUrl(page)
	if b {
		if err := scanCatalog(next_url); err != nil {
			return err
		}
	}

	return nil
}

func GetTotalElements(url string) (int, error) {

	if total_elements != 0 {
		return total_elements, nil
	}

	var total int

	for {
		page, err := getDocument(url)
		if err != nil {
			checkErr(err)
			return 0, err
		}

		elements, err := getElementsFromPage(page)
		if err != nil {
			checkErr(err)
			return 0, err
		}

		total += len(elements)

		next_url, b := getNextUrl(page)
		if !b {
			break
		}
		url = next_url
	}

	total_elements = total

	return total, nil
}

func Run() (chan bool, chan int, chan int, chan error) {

	quitChan = make(chan bool, 1)
	totalChan = make(chan int, 1)
	statusChan = make(chan int, 1)
	errorChan = make(chan error, 1)

	total, err := GetTotalElements(URL)
	if err != nil {
		errorChan <- err
		quitChan <- true
	}

	totalChan <- total

	current_element = 0
	go func() {
		scanCatalog(URL)
		defer close(quitChan)
		defer close(totalChan)
		defer close(statusChan)
		defer close(errorChan)
		quitChan <- true
	}()

	return quitChan, totalChan, statusChan, errorChan
}<|endoftext|>


<commit_before>// +build soong

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

import (
	"fmt"

	"android/soong/android"
	"android/soong/cc"

	"github.com/google/blueprint/proptools"

	"github.com/ARM-software/bob-build/utils"
)

type ccLibraryCommonProps struct {
	Name               *string
	Stem               *string
	Srcs               []string
	Exclude_srcs       []string
	Cflags             []string
	Include_dirs       []string
	Local_include_dirs []string
	Static_libs        []string
	Whole_static_libs  []string
	Ldflags            []string
}

type ccStaticOrSharedProps struct {
	Export_include_dirs []string
}

// Convert between Bob module names, and the name we will give the generated
// cc_library module. This is required when a module supports being built on
// host and target; we cannot create two modules with the same name, so
// instead, we use the `shortName()` (which may include a `__host` or
// `__target` suffix) to disambiguate, and use the `stem` property to fix up
// the output filename.
func ccModuleName(mctx android.TopDownMutatorContext, name string) string {
	m, _ := mctx.GetDirectDep(name + bobModuleSuffix)

	if l, ok := getLibrary(m); ok {
		return l.shortName()
	}

	return m.Name()
}

func ccModuleNames(mctx android.TopDownMutatorContext, nameLists ...[]string) []string {
	ccModules := []string{}
	for _, nameList := range nameLists {
		for _, name := range nameList {
			ccModules = append(ccModules, ccModuleName(mctx, name))
		}
	}
	return ccModules
}

func (l *library) getExportedCflags(mctx android.TopDownMutatorContext) []string {
	visited := map[string]bool{}
	cflags := []string{}
	mctx.VisitDirectDeps(func(dep android.Module) {
		if !(mctx.OtherModuleDependencyTag(dep) == wholeStaticDepTag ||
			mctx.OtherModuleDependencyTag(dep) == staticDepTag ||
			mctx.OtherModuleDependencyTag(dep) == sharedDepTag ||
			mctx.OtherModuleDependencyTag(dep) == reexportLibsTag) {
			return
		} else if _, ok := visited[dep.Name()]; ok {
			// VisitDirectDeps will visit a module once for each
			// dependency. We've already done this module.
			return
		}

		if sl, ok := getLibrary(dep); ok {
			cflags = append(cflags, sl.Properties.Export_cflags...)
		}
	})
	return cflags
}

func (l *library) setupCcLibraryProps(mctx android.TopDownMutatorContext) *ccLibraryCommonProps {
	if len(l.Properties.Export_include_dirs) > 0 {
		panic(fmt.Errorf("Module %s exports non-local include dirs %v - this is not supported",
			mctx.ModuleName(), l.Properties.Export_include_dirs))
	}

	cflags := utils.NewStringSlice(l.Properties.Cflags,
		l.Properties.Export_cflags, l.getExportedCflags(mctx))

	props := &ccLibraryCommonProps{
		Name:               proptools.StringPtr(l.shortName()),
		Stem:               proptools.StringPtr(l.Name()),
		Srcs:               utils.Filter(utils.IsCompilableSource, l.Properties.Srcs),
		Exclude_srcs:       l.Properties.Exclude_srcs,
		Cflags:             cflags,
		Include_dirs:       l.Properties.Include_dirs,
		Local_include_dirs: l.Properties.Local_include_dirs,
		Static_libs:        ccModuleNames(mctx, l.Properties.ResolvedStaticLibs),
		Whole_static_libs:  ccModuleNames(mctx, l.Properties.Whole_static_libs),
		Ldflags:            l.Properties.Ldflags,
	}

	return props
}

// Create a module which only builds on the device. The closest thing Soong
// provides will also allow building on the host, which is not quite what we
// want.
func libraryTargetStaticFactory() android.Module {
	module, library := cc.NewLibrary(android.DeviceSupported)
	library.BuildOnlyStatic()
	return module.Init()
}

func (l *staticLibrary) soongBuildActions(mctx android.TopDownMutatorContext) {
	if !isEnabled(l) {
		return
	}

	commonProps := l.setupCcLibraryProps(mctx)

	libProps := &ccStaticOrSharedProps{
		// Soong's `export_include_dirs` field is relative to the module dir.
		Export_include_dirs: l.Properties.Export_local_include_dirs,
	}

	switch l.Properties.TargetType {
	case tgtTypeHost:
		mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryHostStaticFactory), commonProps, libProps)
	case tgtTypeTarget:
		mctx.CreateModule(android.ModuleFactoryAdaptor(libraryTargetStaticFactory), commonProps, libProps)
	}
}

// From Soong's cc/binary.go. This is needed here because it is not exported by Soong.
func binaryHostFactory() android.Module {
	module, _ := cc.NewBinary(android.HostSupported)
	return module.Init()
}

// Like libraryTargetStaticFactory, create a module which is only buildable on the device.
func binaryTargetFactory() android.Module {
	module, _ := cc.NewBinary(android.DeviceSupported)
	return module.Init()
}

func (b *binary) soongBuildActions(mctx android.TopDownMutatorContext) {
	if !isEnabled(b) {
		return
	}

	commonProps := b.setupCcLibraryProps(mctx)

	switch b.Properties.TargetType {
	case tgtTypeHost:
		mctx.CreateModule(android.ModuleFactoryAdaptor(binaryHostFactory), commonProps)
	case tgtTypeTarget:
		mctx.CreateModule(android.ModuleFactoryAdaptor(binaryTargetFactory), commonProps)
	}

}
<commit_msg>Build shared libraries<commit_after>// +build soong

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

import (
	"fmt"

	"android/soong/android"
	"android/soong/cc"

	"github.com/google/blueprint/proptools"

	"github.com/ARM-software/bob-build/utils"
)

type ccLibraryCommonProps struct {
	Name               *string
	Stem               *string
	Srcs               []string
	Exclude_srcs       []string
	Cflags             []string
	Include_dirs       []string
	Local_include_dirs []string
	Static_libs        []string
	Whole_static_libs  []string
	Shared_libs        []string
	Ldflags            []string
}

type ccStaticOrSharedProps struct {
	Export_include_dirs []string
}

// Convert between Bob module names, and the name we will give the generated
// cc_library module. This is required when a module supports being built on
// host and target; we cannot create two modules with the same name, so
// instead, we use the `shortName()` (which may include a `__host` or
// `__target` suffix) to disambiguate, and use the `stem` property to fix up
// the output filename.
func ccModuleName(mctx android.TopDownMutatorContext, name string) string {
	m, _ := mctx.GetDirectDep(name + bobModuleSuffix)

	if l, ok := getLibrary(m); ok {
		return l.shortName()
	}

	return m.Name()
}

func ccModuleNames(mctx android.TopDownMutatorContext, nameLists ...[]string) []string {
	ccModules := []string{}
	for _, nameList := range nameLists {
		for _, name := range nameList {
			ccModules = append(ccModules, ccModuleName(mctx, name))
		}
	}
	return ccModules
}

func (l *library) getExportedCflags(mctx android.TopDownMutatorContext) []string {
	visited := map[string]bool{}
	cflags := []string{}
	mctx.VisitDirectDeps(func(dep android.Module) {
		if !(mctx.OtherModuleDependencyTag(dep) == wholeStaticDepTag ||
			mctx.OtherModuleDependencyTag(dep) == staticDepTag ||
			mctx.OtherModuleDependencyTag(dep) == sharedDepTag ||
			mctx.OtherModuleDependencyTag(dep) == reexportLibsTag) {
			return
		} else if _, ok := visited[dep.Name()]; ok {
			// VisitDirectDeps will visit a module once for each
			// dependency. We've already done this module.
			return
		}

		if sl, ok := getLibrary(dep); ok {
			cflags = append(cflags, sl.Properties.Export_cflags...)
		}
	})
	return cflags
}

func (l *library) setupCcLibraryProps(mctx android.TopDownMutatorContext) *ccLibraryCommonProps {
	if len(l.Properties.Export_include_dirs) > 0 {
		panic(fmt.Errorf("Module %s exports non-local include dirs %v - this is not supported",
			mctx.ModuleName(), l.Properties.Export_include_dirs))
	}

	cflags := utils.NewStringSlice(l.Properties.Cflags,
		l.Properties.Export_cflags, l.getExportedCflags(mctx))

	props := &ccLibraryCommonProps{
		Name:               proptools.StringPtr(l.shortName()),
		Stem:               proptools.StringPtr(l.Name()),
		Srcs:               utils.Filter(utils.IsCompilableSource, l.Properties.Srcs),
		Exclude_srcs:       l.Properties.Exclude_srcs,
		Cflags:             cflags,
		Include_dirs:       l.Properties.Include_dirs,
		Local_include_dirs: l.Properties.Local_include_dirs,
		Static_libs:        ccModuleNames(mctx, l.Properties.ResolvedStaticLibs),
		Whole_static_libs:  ccModuleNames(mctx, l.Properties.Whole_static_libs),
		Shared_libs:        ccModuleNames(mctx, l.Properties.Shared_libs, l.Properties.Export_shared_libs),
		Ldflags:            l.Properties.Ldflags,
	}

	return props
}

// Create a module which only builds on the device. The closest thing Soong
// provides will also allow building on the host, which is not quite what we
// want.
func libraryTargetStaticFactory() android.Module {
	module, library := cc.NewLibrary(android.DeviceSupported)
	library.BuildOnlyStatic()
	return module.Init()
}

func (l *staticLibrary) soongBuildActions(mctx android.TopDownMutatorContext) {
	if !isEnabled(l) {
		return
	}

	commonProps := l.setupCcLibraryProps(mctx)

	libProps := &ccStaticOrSharedProps{
		// Soong's `export_include_dirs` field is relative to the module dir.
		Export_include_dirs: l.Properties.Export_local_include_dirs,
	}

	switch l.Properties.TargetType {
	case tgtTypeHost:
		mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryHostStaticFactory), commonProps, libProps)
	case tgtTypeTarget:
		mctx.CreateModule(android.ModuleFactoryAdaptor(libraryTargetStaticFactory), commonProps, libProps)
	}
}

// Create a module which only builds on the device. The closest thing Soong
// provides will also allow building on the host, which is not quite what we
// want.
func libraryTargetSharedFactory() android.Module {
	module, library := cc.NewLibrary(android.DeviceSupported)
	library.BuildOnlyShared()
	return module.Init()
}

func (l *sharedLibrary) soongBuildActions(mctx android.TopDownMutatorContext) {
	if !isEnabled(l) {
		return
	}

	commonProps := l.setupCcLibraryProps(mctx)

	libProps := &ccStaticOrSharedProps{
		// Soong's `export_include_dirs` field is relative to the module dir.
		Export_include_dirs: l.Properties.Export_local_include_dirs,
	}

	switch l.Properties.TargetType {
	case tgtTypeHost:
		mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryHostSharedFactory), commonProps, libProps)
	case tgtTypeTarget:
		mctx.CreateModule(android.ModuleFactoryAdaptor(libraryTargetSharedFactory), commonProps, libProps)
	}
}

// From Soong's cc/binary.go. This is needed here because it is not exported by Soong.
func binaryHostFactory() android.Module {
	module, _ := cc.NewBinary(android.HostSupported)
	return module.Init()
}

// Like libraryTargetStaticFactory, create a module which is only buildable on the device.
func binaryTargetFactory() android.Module {
	module, _ := cc.NewBinary(android.DeviceSupported)
	return module.Init()
}

func (b *binary) soongBuildActions(mctx android.TopDownMutatorContext) {
	if !isEnabled(b) {
		return
	}

	commonProps := b.setupCcLibraryProps(mctx)

	switch b.Properties.TargetType {
	case tgtTypeHost:
		mctx.CreateModule(android.ModuleFactoryAdaptor(binaryHostFactory), commonProps)
	case tgtTypeTarget:
		mctx.CreateModule(android.ModuleFactoryAdaptor(binaryTargetFactory), commonProps)
	}

}
<|endoftext|>


<commit_before>// Copyright © 2014 Daniele Tricoli <eriol@mornie.org>.
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main // import "eriol.xyz/perpetua"

import (
	"log"
	"os"
	"os/signal"

	ircevent "github.com/thoj/go-ircevent"
	"gopkg.in/alecthomas/kingpin.v2"

	"eriol.xyz/perpetua/config"
	"eriol.xyz/perpetua/db"
	"eriol.xyz/perpetua/irc"
)

func main() {

	var (
		conf  config.Config
		store db.Store
	)
	var (
		configFile = kingpin.Flag("config", "Configuration file path.").Short('c').Default("").String()
	)

	isDone := make(chan bool, 1)
	ircChan := make(chan *ircevent.Connection, 1)
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, os.Kill)

	kingpin.Version(config.Version)
	kingpin.CommandLine.Help = "Quote bot for IRC."
	kingpin.Parse()

	if err := conf.Read(*configFile); err != nil {
		log.Fatal(err)
	}

	if err := store.Open(config.DATABASE_FILE); err != nil {
		log.Fatal(err)
	}
	defer store.Close()

	log.Println("Starting...")
	go irc.Client(&conf, &store, ircChan, isDone)

	sig := <-sigChan
	log.Printf("Got signal %v, exiting now.\n", sig)

	conn := <-ircChan
	conn.Quit()

	done := <-isDone

	if done {
		log.Println("Stopping...")
	}

}
<commit_msg>Log when client disconnect from the server<commit_after>// Copyright © 2014 Daniele Tricoli <eriol@mornie.org>.
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main // import "eriol.xyz/perpetua"

import (
	"log"
	"os"
	"os/signal"

	ircevent "github.com/thoj/go-ircevent"
	"gopkg.in/alecthomas/kingpin.v2"

	"eriol.xyz/perpetua/config"
	"eriol.xyz/perpetua/db"
	"eriol.xyz/perpetua/irc"
)

func main() {

	var (
		conf  config.Config
		store db.Store
	)
	var (
		configFile = kingpin.Flag("config", "Configuration file path.").Short('c').Default("").String()
	)

	isDone := make(chan bool, 1)
	ircChan := make(chan *ircevent.Connection, 1)
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, os.Kill)

	kingpin.Version(config.Version)
	kingpin.CommandLine.Help = "Quote bot for IRC."
	kingpin.Parse()

	if err := conf.Read(*configFile); err != nil {
		log.Fatal(err)
	}

	if err := store.Open(config.DATABASE_FILE); err != nil {
		log.Fatal(err)
	}
	defer store.Close()

	log.Println("Starting...")
	go irc.Client(&conf, &store, ircChan, isDone)

	sig := <-sigChan
	log.Printf("Got signal %v, exiting now.\n", sig)

	conn := <-ircChan
	log.Printf("Quitting from %v.\n", conn.Server)
	conn.Quit()

	done := <-isDone

	if done {
		log.Println("Stopped.")
	}

}
<|endoftext|>


<commit_before>// Copyright ©2020 The Gonum Authors. All rights reserved.
// Use of this code is governed by a BSD-style
// license that can be found in the LICENSE file.

// TODO(kortschak): Delete this file for v0.9.0.

package floats

import "gonum.org/v1/gonum/floats/scalar"

var (
	// Deprecated: Use scalar.EqualWithinAbs.
	EqualWithinAbs = scalar.EqualWithinAbs

	// Deprecated: Use scalar.EqualWithinAbsOrRel.
	EqualWithinAbsOrRel = scalar.EqualWithinAbsOrRel

	// Deprecated: Use scalar.EqualWithinRel.
	EqualWithinRel = scalar.EqualWithinRel

	// Deprecated: Use scalar.EqualWithinULP.
	EqualWithinULP = scalar.EqualWithinULP

	// Deprecated: Use scalar.NaNPayload.
	NaNPayload = scalar.NaNPayload

	// Deprecated: Use scalar.NaNWith.
	NaNWith = scalar.NaNWith

	// Deprecated: Use scalar.ParseWithNA.
	ParseWithNA = scalar.ParseWithNA

	// Deprecated: Use scalar.Round.
	Round = scalar.Round

	// Deprecated: Use scalar.RoundEven.
	RoundEven = scalar.RoundEven
)
<commit_msg>floats: remove deprecated functions<commit_after><|endoftext|>


<commit_before>package commands

import (
	"fmt"
	"runtime"
	"strconv"

	update "github.com/inconshreveable/go-update"
	"github.com/vbauerster/mpb/v4"
	"github.com/vbauerster/mpb/v4/decor"

	"github.com/concourse/concourse"
	"github.com/concourse/concourse/atc"
	"github.com/concourse/concourse/fly/commands/internal/displayhelpers"
	"github.com/concourse/concourse/fly/rc"
	"github.com/concourse/concourse/fly/ui"
)

type SyncCommand struct {
	Force          bool         `long:"force" short:"f" description:"Sync even if versions already match."`
	ATCURL         string       `long:"concourse-url" short:"c" description:"Concourse URL to sync with"`
	CACert         atc.PathFlag `long:"ca-cert" description:"Path to Concourse PEM-encoded CA certificate file."`
	ClientCertPath atc.PathFlag `long:"client-certificate" description:"Path to a PEM-encoded client certificate file."`
	ClientKeyPath  atc.PathFlag `long:"client-key" description:"Path to a PEM-encoded client key file."`
}

func (command *SyncCommand) Execute(args []string) error {
	var target rc.Target
	var err error

	if Fly.Target != "" {
		target, err = rc.LoadTarget(Fly.Target, Fly.Verbose)
	} else {
		target, err = rc.NewUnauthenticatedTarget(
			"dummy",
			command.ATCURL,
			"",
			false,
			string(command.CACert),
			string(command.ClientCertPath),
			string(command.ClientKeyPath),
			Fly.Verbose,
		)
	}
	if err != nil {
		return err
	}

	info, err := target.Client().GetInfo()
	if err != nil {
		return err
	}

	if !command.Force && info.Version == concourse.Version {
		fmt.Printf("version %s already matches; skipping\n", info.Version)
		return nil
	}

	updateOptions := update.Options{}
	err = updateOptions.CheckPermissions()
	if err != nil {
		displayhelpers.FailWithErrorf("update failed", err)
	}

	client := target.Client()
	body, headers, err := client.GetCLIReader(runtime.GOARCH, runtime.GOOS)
	if err != nil {
		return err
	}

	fmt.Printf("downloading fly from %s...\n", client.URL())
	fmt.Println()

	size, err := strconv.ParseInt(headers.Get("Content-Length"), 10, 64)
	if err != nil {
		fmt.Printf("warning: failed to parse Content-Length: %s\n", err)
		size = 0
	}

	progress := mpb.New(mpb.WithWidth(50))

	progressBar := progress.AddBar(
		size,
		mpb.PrependDecorators(decor.Name("fly "+ui.Embolden("v"+info.Version))),
		mpb.AppendDecorators(decor.CountersKibiByte("%.1f/%.1f")),
	)

	err = update.Apply(progressBar.ProxyReader(body), updateOptions)
	if err != nil {
		displayhelpers.FailWithErrorf("failed to apply update", err)
	}

	if size == 0 {
		progressBar.SetTotal(progressBar.Current(), true)
	}

	progress.Wait()

	fmt.Println("done")

	return nil
}
<commit_msg>fly: Backport insecure flag to the sync command<commit_after>package commands

import (
	"fmt"
	"runtime"
	"strconv"

	update "github.com/inconshreveable/go-update"
	"github.com/vbauerster/mpb/v4"
	"github.com/vbauerster/mpb/v4/decor"

	"github.com/concourse/concourse"
	"github.com/concourse/concourse/atc"
	"github.com/concourse/concourse/fly/commands/internal/displayhelpers"
	"github.com/concourse/concourse/fly/rc"
	"github.com/concourse/concourse/fly/ui"
)

type SyncCommand struct {
	Force          bool         `long:"force" short:"f" description:"Sync even if versions already match."`
	ATCURL         string       `long:"concourse-url" short:"c" description:"Concourse URL to sync with"`
	Insecure       bool         `short:"k" long:"insecure" description:"Skip verification of the endpoint's SSL certificate"`
	CACert         atc.PathFlag `long:"ca-cert" description:"Path to Concourse PEM-encoded CA certificate file."`
	ClientCertPath atc.PathFlag `long:"client-certificate" description:"Path to a PEM-encoded client certificate file."`
	ClientKeyPath  atc.PathFlag `long:"client-key" description:"Path to a PEM-encoded client key file."`
}

func (command *SyncCommand) Execute(args []string) error {
	var target rc.Target
	var err error

	if Fly.Target != "" {
		target, err = rc.LoadTarget(Fly.Target, Fly.Verbose)
	} else {
		target, err = rc.NewUnauthenticatedTarget(
			"dummy",
			command.ATCURL,
			"",
			command.Insecure,
			string(command.CACert),
			string(command.ClientCertPath),
			string(command.ClientKeyPath),
			Fly.Verbose,
		)
	}
	if err != nil {
		return err
	}

	info, err := target.Client().GetInfo()
	if err != nil {
		return err
	}

	if !command.Force && info.Version == concourse.Version {
		fmt.Printf("version %s already matches; skipping\n", info.Version)
		return nil
	}

	updateOptions := update.Options{}
	err = updateOptions.CheckPermissions()
	if err != nil {
		displayhelpers.FailWithErrorf("update failed", err)
	}

	client := target.Client()
	body, headers, err := client.GetCLIReader(runtime.GOARCH, runtime.GOOS)
	if err != nil {
		return err
	}

	fmt.Printf("downloading fly from %s...\n", client.URL())
	fmt.Println()

	size, err := strconv.ParseInt(headers.Get("Content-Length"), 10, 64)
	if err != nil {
		fmt.Printf("warning: failed to parse Content-Length: %s\n", err)
		size = 0
	}

	progress := mpb.New(mpb.WithWidth(50))

	progressBar := progress.AddBar(
		size,
		mpb.PrependDecorators(decor.Name("fly "+ui.Embolden("v"+info.Version))),
		mpb.AppendDecorators(decor.CountersKibiByte("%.1f/%.1f")),
	)

	err = update.Apply(progressBar.ProxyReader(body), updateOptions)
	if err != nil {
		displayhelpers.FailWithErrorf("failed to apply update", err)
	}

	if size == 0 {
		progressBar.SetTotal(progressBar.Current(), true)
	}

	progress.Wait()

	fmt.Println("done")

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/codegangsta/cli"
)

func exitOnError(err error) {
	log.SetFlags(0)
	if err != nil {
		log.Fatalln(err)
	}
}

//Parse table to copy to from given filename or passed flags
func parseTableName(c *cli.Context, filename string) string {
	tableName := c.GlobalString("table")
	if tableName == "" {
		if filename == "" {
			// if no filename is not set, we reading stdin
			filename = "stdin"
		}
		base := filepath.Base(filename)
		ext := filepath.Ext(filename)
		tableName = strings.TrimSuffix(base, ext)
	}
	return postgresify(tableName)
}

func main() {
	app := cli.NewApp()
	app.Name = "pgfutter"
	app.Version = "1.0"
	app.Usage = "Import JSON and CSV into PostgreSQL the easy way"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "dbname, db",
			Value:  "postgres",
			Usage:  "database to connect to",
			EnvVar: "DB_NAME",
		},
		cli.StringFlag{
			Name:   "host",
			Value:  "localhost",
			Usage:  "host name",
			EnvVar: "DB_HOST",
		},
		cli.StringFlag{
			Name:   "port",
			Value:  "5432",
			Usage:  "port",
			EnvVar: "DB_PORT",
		},
		cli.StringFlag{
			Name:   "username, user",
			Value:  "postgres",
			Usage:  "username",
			EnvVar: "DB_USER",
		},
		cli.BoolFlag{
			Name:  "ssl",
			Usage: "require ssl mode",
		},
		cli.StringFlag{
			Name:   "pass, pw",
			Value:  "",
			Usage:  "password",
			EnvVar: "DB_PASS",
		},
		cli.StringFlag{
			Name:   "schema",
			Value:  "import",
			Usage:  "database schema",
			EnvVar: "DB_SCHEMA",
		},
		cli.StringFlag{
			Name:   "table",
			Usage:  "destination table",
			EnvVar: "DB_TABLE",
		},
		cli.BoolFlag{
			Name:  "ignore-errors",
			Usage: "halt transaction on inconsistencies",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:  "json",
			Usage: "Import newline-delimited JSON objects into database",
			Action: func(c *cli.Context) {
				cli.CommandHelpTemplate = strings.Replace(cli.CommandHelpTemplate, "[arguments...]", "<json-file>", -1)

				filename := c.Args().First()

				ignoreErrors := c.GlobalBool("ignore-errors")
				schema := c.GlobalString("schema")
				tableName := parseTableName(c, filename)

				connStr := parseConnStr(c)
				err := importJSON(filename, connStr, schema, tableName, ignoreErrors)
				exitOnError(err)
			},
		},
		{
			Name:  "jsonobj",
			Usage: "Import single JSON object into database",
			Action: func(c *cli.Context) {
				cli.CommandHelpTemplate = strings.Replace(cli.CommandHelpTemplate, "[arguments...]", "<json-file>", -1)

				filename := c.Args().First()

				schema := c.GlobalString("schema")
				tableName := parseTableName(c, filename)

				connStr := parseConnStr(c)
				err := importJSONObject(filename, connStr, schema, tableName)
				exitOnError(err)
			},
		},
		{
			Name:  "csv",
			Usage: "Import CSV into database",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "skip-header",
					Usage: "skip header row",
				},
				cli.StringFlag{
					Name:  "fields",
					Usage: "comma separated field names if no header row",
				},
				cli.StringFlag{
					Name:  "delimiter, d",
					Value: ",",
					Usage: "field delimiter",
				},
			},
			Action: func(c *cli.Context) {
				cli.CommandHelpTemplate = strings.Replace(cli.CommandHelpTemplate, "[arguments...]", "<csv-file>", -1)

				filename := c.Args().First()

				ignoreErrors := c.GlobalBool("ignore-errors")
				schema := c.GlobalString("schema")
				tableName := parseTableName(c, filename)

				skipHeader := c.Bool("skip-header")
				fields := c.String("fields")
				delimiter := c.String("delimiter")

				connStr := parseConnStr(c)
				err := importCSV(filename, connStr, schema, tableName, ignoreErrors, skipHeader, fields, delimiter)
				exitOnError(err)
			},
		},
	}

	app.Run(os.Args)
}
<commit_msg>Return error in CLI funcs<commit_after>package main

import (
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/codegangsta/cli"
)

func exitOnError(err error) {
	log.SetFlags(0)
	if err != nil {
		log.Fatalln(err)
	}
}

//Parse table to copy to from given filename or passed flags
func parseTableName(c *cli.Context, filename string) string {
	tableName := c.GlobalString("table")
	if tableName == "" {
		if filename == "" {
			// if no filename is not set, we reading stdin
			filename = "stdin"
		}
		base := filepath.Base(filename)
		ext := filepath.Ext(filename)
		tableName = strings.TrimSuffix(base, ext)
	}
	return postgresify(tableName)
}

func main() {
	app := cli.NewApp()
	app.Name = "pgfutter"
	app.Version = "1.0"
	app.Usage = "Import JSON and CSV into PostgreSQL the easy way"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "dbname, db",
			Value:  "postgres",
			Usage:  "database to connect to",
			EnvVar: "DB_NAME",
		},
		cli.StringFlag{
			Name:   "host",
			Value:  "localhost",
			Usage:  "host name",
			EnvVar: "DB_HOST",
		},
		cli.StringFlag{
			Name:   "port",
			Value:  "5432",
			Usage:  "port",
			EnvVar: "DB_PORT",
		},
		cli.StringFlag{
			Name:   "username, user",
			Value:  "postgres",
			Usage:  "username",
			EnvVar: "DB_USER",
		},
		cli.BoolFlag{
			Name:  "ssl",
			Usage: "require ssl mode",
		},
		cli.StringFlag{
			Name:   "pass, pw",
			Value:  "",
			Usage:  "password",
			EnvVar: "DB_PASS",
		},
		cli.StringFlag{
			Name:   "schema",
			Value:  "import",
			Usage:  "database schema",
			EnvVar: "DB_SCHEMA",
		},
		cli.StringFlag{
			Name:   "table",
			Usage:  "destination table",
			EnvVar: "DB_TABLE",
		},
		cli.BoolFlag{
			Name:  "ignore-errors",
			Usage: "halt transaction on inconsistencies",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:  "json",
			Usage: "Import newline-delimited JSON objects into database",
			Action: func(c *cli.Context) error {
				cli.CommandHelpTemplate = strings.Replace(cli.CommandHelpTemplate, "[arguments...]", "<json-file>", -1)

				filename := c.Args().First()

				ignoreErrors := c.GlobalBool("ignore-errors")
				schema := c.GlobalString("schema")
				tableName := parseTableName(c, filename)

				connStr := parseConnStr(c)
				err := importJSON(filename, connStr, schema, tableName, ignoreErrors)
				return err
			},
		},
		{
			Name:  "jsonobj",
			Usage: "Import single JSON object into database",
			Action: func(c *cli.Context) error {
				cli.CommandHelpTemplate = strings.Replace(cli.CommandHelpTemplate, "[arguments...]", "<json-file>", -1)

				filename := c.Args().First()

				schema := c.GlobalString("schema")
				tableName := parseTableName(c, filename)

				connStr := parseConnStr(c)
				err := importJSONObject(filename, connStr, schema, tableName)
				return err
			},
		},
		{
			Name:  "csv",
			Usage: "Import CSV into database",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "skip-header",
					Usage: "skip header row",
				},
				cli.StringFlag{
					Name:  "fields",
					Usage: "comma separated field names if no header row",
				},
				cli.StringFlag{
					Name:  "delimiter, d",
					Value: ",",
					Usage: "field delimiter",
				},
			},
			Action: func(c *cli.Context) error {
				cli.CommandHelpTemplate = strings.Replace(cli.CommandHelpTemplate, "[arguments...]", "<csv-file>", -1)

				filename := c.Args().First()

				ignoreErrors := c.GlobalBool("ignore-errors")
				schema := c.GlobalString("schema")
				tableName := parseTableName(c, filename)

				skipHeader := c.Bool("skip-header")
				fields := c.String("fields")
				delimiter := c.String("delimiter")

				connStr := parseConnStr(c)
				err := importCSV(filename, connStr, schema, tableName, ignoreErrors, skipHeader, fields, delimiter)
				return err
			},
		},
	}

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


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

package main

import (
	"database/sql"
	"fmt"
	"log"
	"math"
	"math/rand"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/codahale/hdrhistogram"
	"github.com/pkg/errors"
)

type worker struct {
	idx       int
	db        *sql.DB
	warehouse int
	latency   struct {
		sync.Mutex
		*hdrhistogram.WindowedHistogram
		byOp []*hdrhistogram.WindowedHistogram
	}
}

func clampLatency(d, min, max time.Duration) time.Duration {
	if d < min {
		return min
	}
	if d > max {
		return max
	}
	return d
}

type txType int

const (
	newOrderType txType = iota
	paymentType
	orderStatusType
	deliveryType
	stockLevelType
)
const nTxTypes = 5

type tpccTx interface {
	run(db *sql.DB, wID int) (interface{}, error)
}

type tx struct {
	tpccTx
	weight     int    // percent likelihood that each transaction type is run
	name       string // display name
	numOps     uint64
	keyingTime int     // keying time in seconds, see 5.2.5.7
	thinkTime  float64 // minimum mean of think time distribution, 5.2.5.7
}

func (t tx) randThinkTime() time.Duration {
	// 5.2.5.4: Think time is taken independently from a negative exponential
	// distribution. Think time = -log(r) * u, where r is a uniform random number
	// between 0 and 1 and u is the mean think time per operation.
	// Each distribution is truncated at 10 times its mean value.
	thinkTime := -math.Log(rand.Float64()) * float64(t.thinkTime)
	if thinkTime > (t.thinkTime * 10) {
		thinkTime = t.thinkTime * 10
	}
	return time.Duration(thinkTime) * time.Second
}

// Keep this in the same order as the const type enum above, since it's used as a map from tx type
// to struct.
var txs = [...]tx{
	newOrderType: {
		tpccTx: newOrder{}, name: "newOrder",
		keyingTime: 18,
		thinkTime:  12,
	},
	paymentType: {
		tpccTx: payment{}, name: "payment",
		keyingTime: 3,
		thinkTime:  12,
	},
	orderStatusType: {
		tpccTx: orderStatus{}, name: "orderStatus",
		keyingTime: 2,
		thinkTime:  10,
	},
	deliveryType: {
		tpccTx: delivery{}, name: "delivery",
		keyingTime: 2,
		thinkTime:  5,
	},
	stockLevelType: {
		tpccTx: stockLevel{}, name: "stockLevel",
		keyingTime: 2,
		thinkTime:  5,
	},
}

var totalWeight int

// deck contains indexes into the txs slice.
var deck []int

func initializeMix() {
	nameToTx := make(map[string]txType)
	for i, tx := range txs {
		nameToTx[tx.name] = txType(i)
	}

	items := strings.Split(*mix, ",")
	for _, item := range items {
		kv := strings.Split(item, "=")
		if len(kv) != 2 {
			log.Fatalf("Invalid mix %s: %s is not a k=v pair", *mix, item)
		}
		txName, weightStr := kv[0], kv[1]

		weight, err := strconv.Atoi(weightStr)
		if err != nil {
			log.Fatalf("Invalid percentage mix %s: %s is not an integer", *mix, weightStr)
		}

		txIdx, ok := nameToTx[txName]
		if !ok {
			log.Fatalf("Invalid percentage mix %s: no such transaction %s", *mix, txName)
		}

		txs[txIdx].weight = weight
		totalWeight += weight
	}
	deck = make([]int, 0, totalWeight)
	for i, t := range txs {
		for j := 0; j < t.weight; j++ {
			deck = append(deck, i)
		}
	}

	if *verbose {
		scaleFactor := 100.0 / float64(totalWeight)

		fmt.Printf("Running with mix ")
		for _, tx := range txs {
			fmt.Printf("%s=%.0f%% ", tx.name, float64(tx.weight)*scaleFactor)
		}
		fmt.Printf("\n")
	}
}

func newWorker(i, warehouse int, db *sql.DB, wg *sync.WaitGroup) *worker {
	wg.Add(1)
	w := &worker{idx: i, db: db, warehouse: warehouse}
	w.latency.WindowedHistogram = hdrhistogram.NewWindowed(1,
		minLatency.Nanoseconds(), maxLatency.Nanoseconds(), 1)

	w.latency.byOp = make([]*hdrhistogram.WindowedHistogram, nTxTypes)
	for i := 0; i < nTxTypes; i++ {
		w.latency.byOp[i] = hdrhistogram.NewWindowed(1,
			minLatency.Nanoseconds(), maxLatency.Nanoseconds(), 1)
	}
	return w
}

func (w *worker) run(errCh chan<- error) {
	deckPerm := make([]int, len(deck))
	copy(deckPerm, deck)
	permIdx := len(deck)

	for firstRun := true; ; {
		// 5.2.4.2: the required mix is achieved by selecting each new transaction
		// uniformly at random from a deck whose content guarantees the required
		// transaction mix. Each pass through a deck must be made in a different
		// uniformly random order.
		if permIdx == len(deck) {
			rand.Shuffle(len(deckPerm), func(i, j int) {
				deckPerm[i], deckPerm[j] = deckPerm[j], deckPerm[i]
			})
			permIdx = 0
		}
		// Move through our permutation slice until its exhausted, using each value to
		// to index into our deck of transactions, which contains indexes into the
		// txs slice.
		opIdx := deckPerm[permIdx]
		t := txs[opIdx]
		permIdx++

		if !*noWait {
			sleepTime := time.Duration(t.keyingTime) * time.Second
			// TODO(peter): now that we have the -ramp flag, do we need to do this
			// firstRun stuff?
			if firstRun {
				// Sleep for a random duration up to the keying time to smooth out any
				// potential thundering herd effects when the load generator starts.
				sleepTime = time.Duration(float64(sleepTime) * rand.Float64())
				firstRun = false
			}
			time.Sleep(sleepTime)
		}

		start := time.Now()
		if _, err := t.run(w.db, w.warehouse); err != nil {
			errCh <- errors.Wrapf(err, "error in %s", t.name)
			continue
		}
		elapsed := clampLatency(time.Since(start), minLatency, maxLatency).Nanoseconds()
		w.latency.Lock()
		if err := w.latency.Current.RecordValue(elapsed); err != nil {
			log.Fatal(err)
		}
		if err := w.latency.byOp[opIdx].Current.RecordValue(elapsed); err != nil {
			log.Fatal(err)
		}
		w.latency.Unlock()
		atomic.AddUint64(&txs[opIdx].numOps, 1)
		v := atomic.AddUint64(&numOps, 1)
		if *maxOps > 0 && v >= *maxOps {
			return
		}

		if !*noWait {
			time.Sleep(t.randThinkTime())
		}
	}
}
<commit_msg>tpcc: remove the firstRun sleep randomization<commit_after>// Copyright 2017 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License. See the AUTHORS file
// for names of contributors.

package main

import (
	"database/sql"
	"fmt"
	"log"
	"math"
	"math/rand"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/codahale/hdrhistogram"
	"github.com/pkg/errors"
)

type worker struct {
	idx       int
	db        *sql.DB
	warehouse int
	latency   struct {
		sync.Mutex
		*hdrhistogram.WindowedHistogram
		byOp []*hdrhistogram.WindowedHistogram
	}
}

func clampLatency(d, min, max time.Duration) time.Duration {
	if d < min {
		return min
	}
	if d > max {
		return max
	}
	return d
}

type txType int

const (
	newOrderType txType = iota
	paymentType
	orderStatusType
	deliveryType
	stockLevelType
)
const nTxTypes = 5

type tpccTx interface {
	run(db *sql.DB, wID int) (interface{}, error)
}

type tx struct {
	tpccTx
	weight     int    // percent likelihood that each transaction type is run
	name       string // display name
	numOps     uint64
	keyingTime int     // keying time in seconds, see 5.2.5.7
	thinkTime  float64 // minimum mean of think time distribution, 5.2.5.7
}

func (t tx) randThinkTime() time.Duration {
	// 5.2.5.4: Think time is taken independently from a negative exponential
	// distribution. Think time = -log(r) * u, where r is a uniform random number
	// between 0 and 1 and u is the mean think time per operation.
	// Each distribution is truncated at 10 times its mean value.
	thinkTime := -math.Log(rand.Float64()) * float64(t.thinkTime)
	if thinkTime > (t.thinkTime * 10) {
		thinkTime = t.thinkTime * 10
	}
	return time.Duration(thinkTime) * time.Second
}

// Keep this in the same order as the const type enum above, since it's used as a map from tx type
// to struct.
var txs = [...]tx{
	newOrderType: {
		tpccTx: newOrder{}, name: "newOrder",
		keyingTime: 18,
		thinkTime:  12,
	},
	paymentType: {
		tpccTx: payment{}, name: "payment",
		keyingTime: 3,
		thinkTime:  12,
	},
	orderStatusType: {
		tpccTx: orderStatus{}, name: "orderStatus",
		keyingTime: 2,
		thinkTime:  10,
	},
	deliveryType: {
		tpccTx: delivery{}, name: "delivery",
		keyingTime: 2,
		thinkTime:  5,
	},
	stockLevelType: {
		tpccTx: stockLevel{}, name: "stockLevel",
		keyingTime: 2,
		thinkTime:  5,
	},
}

var totalWeight int

// deck contains indexes into the txs slice.
var deck []int

func initializeMix() {
	nameToTx := make(map[string]txType)
	for i, tx := range txs {
		nameToTx[tx.name] = txType(i)
	}

	items := strings.Split(*mix, ",")
	for _, item := range items {
		kv := strings.Split(item, "=")
		if len(kv) != 2 {
			log.Fatalf("Invalid mix %s: %s is not a k=v pair", *mix, item)
		}
		txName, weightStr := kv[0], kv[1]

		weight, err := strconv.Atoi(weightStr)
		if err != nil {
			log.Fatalf("Invalid percentage mix %s: %s is not an integer", *mix, weightStr)
		}

		txIdx, ok := nameToTx[txName]
		if !ok {
			log.Fatalf("Invalid percentage mix %s: no such transaction %s", *mix, txName)
		}

		txs[txIdx].weight = weight
		totalWeight += weight
	}
	deck = make([]int, 0, totalWeight)
	for i, t := range txs {
		for j := 0; j < t.weight; j++ {
			deck = append(deck, i)
		}
	}

	if *verbose {
		scaleFactor := 100.0 / float64(totalWeight)

		fmt.Printf("Running with mix ")
		for _, tx := range txs {
			fmt.Printf("%s=%.0f%% ", tx.name, float64(tx.weight)*scaleFactor)
		}
		fmt.Printf("\n")
	}
}

func newWorker(i, warehouse int, db *sql.DB, wg *sync.WaitGroup) *worker {
	wg.Add(1)
	w := &worker{idx: i, db: db, warehouse: warehouse}
	w.latency.WindowedHistogram = hdrhistogram.NewWindowed(1,
		minLatency.Nanoseconds(), maxLatency.Nanoseconds(), 1)

	w.latency.byOp = make([]*hdrhistogram.WindowedHistogram, nTxTypes)
	for i := 0; i < nTxTypes; i++ {
		w.latency.byOp[i] = hdrhistogram.NewWindowed(1,
			minLatency.Nanoseconds(), maxLatency.Nanoseconds(), 1)
	}
	return w
}

func (w *worker) run(errCh chan<- error) {
	deckPerm := make([]int, len(deck))
	copy(deckPerm, deck)
	permIdx := len(deck)

	for {
		// 5.2.4.2: the required mix is achieved by selecting each new transaction
		// uniformly at random from a deck whose content guarantees the required
		// transaction mix. Each pass through a deck must be made in a different
		// uniformly random order.
		if permIdx == len(deck) {
			rand.Shuffle(len(deckPerm), func(i, j int) {
				deckPerm[i], deckPerm[j] = deckPerm[j], deckPerm[i]
			})
			permIdx = 0
		}
		// Move through our permutation slice until its exhausted, using each value to
		// to index into our deck of transactions, which contains indexes into the
		// txs slice.
		opIdx := deckPerm[permIdx]
		t := txs[opIdx]
		permIdx++

		if !*noWait {
			time.Sleep(time.Duration(t.keyingTime) * time.Second)
		}

		start := time.Now()
		if _, err := t.run(w.db, w.warehouse); err != nil {
			errCh <- errors.Wrapf(err, "error in %s", t.name)
			continue
		}
		elapsed := clampLatency(time.Since(start), minLatency, maxLatency).Nanoseconds()
		w.latency.Lock()
		if err := w.latency.Current.RecordValue(elapsed); err != nil {
			log.Fatal(err)
		}
		if err := w.latency.byOp[opIdx].Current.RecordValue(elapsed); err != nil {
			log.Fatal(err)
		}
		w.latency.Unlock()
		atomic.AddUint64(&txs[opIdx].numOps, 1)
		v := atomic.AddUint64(&numOps, 1)
		if *maxOps > 0 && v >= *maxOps {
			return
		}

		if !*noWait {
			time.Sleep(t.randThinkTime())
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/masci/flickr.go/flickr"
	"github.com/masci/flickr.go/flickr/auth/oauth"
	"github.com/masci/flickr.go/flickr/test"
	"os"
)

func main() {
	// retrieve Flickr credentials from env vars
	apik := os.Getenv("FLICKRSYNC_API_KEY")
	apisec := os.Getenv("FLICKRSYNC_API_SECRET")
	// do not proceed if credentials were not provided
	if apik == "" || apisec == "" {
		fmt.Fprintln(os.Stderr, "Please set FLICKRSYNC_API_KEY and FLICKRSYNC_API_SECRET env vars")
		os.Exit(1)
	}

	// create an API client with credentials
	client := flickr.NewFlickrClient(apik, apisec)

	// ask user to authorize this application

	// first, get a request token
	tok, err := flickr.GetRequestToken(client)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(2)
	}

	// build the authorizatin URL
	url, _ := flickr.GetAuthorizeUrl(client, tok)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(3)
	}

	// ask user to hit the authorization url with
	// their browser, authorize this application and coming
	// back with the confirmation token
	var oauthVerifier string
	fmt.Println("Open your browser at this url:", url)
	fmt.Print("Then, insert the code:")
	fmt.Scanln(&oauthVerifier)

	// finally, get the access token
	accessTok, err := flickr.GetAccessToken(client, tok, oauthVerifier)
	client.OAuthToken = accessTok.OAuthToken
	client.OAuthTokenSecret = accessTok.OAuthTokenSecret
	fmt.Println("Successfully retrieved OAuth token", client.OAuthToken)

	// check everything works
	resp, err := test.Login(client)
	if err != nil {
		fmt.Println(err)

	} else {
		fmt.Println(resp.Status, resp.User)
	}
}
<commit_msg>fixed example code<commit_after>package main

import (
	"fmt"
	"github.com/masci/flickr.go/flickr"
	"github.com/masci/flickr.go/flickr/test"
	"os"
)

func main() {
	// retrieve Flickr credentials from env vars
	apik := os.Getenv("FLICKRSYNC_API_KEY")
	apisec := os.Getenv("FLICKRSYNC_API_SECRET")
	// do not proceed if credentials were not provided
	if apik == "" || apisec == "" {
		fmt.Fprintln(os.Stderr, "Please set FLICKRSYNC_API_KEY and FLICKRSYNC_API_SECRET env vars")
		os.Exit(1)
	}

	// create an API client with credentials
	client := flickr.NewFlickrClient(apik, apisec)

	// ask user to authorize this application

	// first, get a request token
	tok, err := flickr.GetRequestToken(client)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(2)
	}

	// build the authorizatin URL
	url, _ := flickr.GetAuthorizeUrl(client, tok)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(3)
	}

	// ask user to hit the authorization url with
	// their browser, authorize this application and coming
	// back with the confirmation token
	var oauthVerifier string
	fmt.Println("Open your browser at this url:", url)
	fmt.Print("Then, insert the code:")
	fmt.Scanln(&oauthVerifier)

	// finally, get the access token
	accessTok, err := flickr.GetAccessToken(client, tok, oauthVerifier)
	client.OAuthToken = accessTok.OAuthToken
	client.OAuthTokenSecret = accessTok.OAuthTokenSecret
	fmt.Println("Successfully retrieved OAuth token", client.OAuthToken)

	// check everything works
	resp, err := test.Login(client)
	if err != nil {
		fmt.Println(err)

	} else {
		fmt.Println(resp.Status, resp.User)
	}
}
<|endoftext|>


<commit_before>package rpc

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

	"github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/logger/glog"
	"github.com/ethereum/go-ethereum/xeth"
	"github.com/rs/cors"
)

var rpclistener *stoppableTCPListener

const (
	jsonrpcver       = "2.0"
	maxSizeReqLength = 1024 * 1024 // 1MB
)

func Start(pipe *xeth.XEth, config RpcConfig) error {
	if rpclistener != nil {
		if fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort) != rpclistener.Addr().String() {
			return fmt.Errorf("RPC service already running on %s ", rpclistener.Addr().String())
		}
		return nil // RPC service already running on given host/port
	}

	l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort))
	if err != nil {
		glog.V(logger.Error).Infof("Can't listen on %s:%d: %v", config.ListenAddress, config.ListenPort, err)
		return err
	}
	rpclistener = l

	var handler http.Handler
	if len(config.CorsDomain) > 0 {
		var opts cors.Options
		opts.AllowedMethods = []string{"POST"}
		opts.AllowedOrigins = []string{config.CorsDomain}

		c := cors.New(opts)
		handler = newStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop)
	} else {
		handler = newStoppableHandler(JSONRPC(pipe), l.stop)
	}

	go http.Serve(l, handler)

	return nil
}

func Stop() error {
	if rpclistener != nil {
		rpclistener.Stop()
		rpclistener = nil
	}

	return nil
}

// JSONRPC returns a handler that implements the Ethereum JSON-RPC API.
func JSONRPC(pipe *xeth.XEth) http.Handler {
	api := NewEthereumApi(pipe)

	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "application/json")

		// Limit request size to resist DoS
		if req.ContentLength > maxSizeReqLength {
			jsonerr := &RpcErrorObject{-32700, "Request too large"}
			send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
			return
		}

		// Read request body
		defer req.Body.Close()
		body, err := ioutil.ReadAll(req.Body)
		if err != nil {
			jsonerr := &RpcErrorObject{-32700, "Could not read request body"}
			send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
		}

		// Try to parse the request as a single
		var reqSingle RpcRequest
		if err := json.Unmarshal(body, &reqSingle); err == nil {
			response := RpcResponse(api, &reqSingle)
			if reqSingle.Id != nil {
				send(w, &response)
			}
			return
		}

		// Try to parse the request to batch
		var reqBatch []RpcRequest
		if err := json.Unmarshal(body, &reqBatch); err == nil {
			// Build response batch
			resBatch := make([]*interface{}, len(reqBatch))
			resCount := 0

			for i, request := range reqBatch {
				response := RpcResponse(api, &request)
				// this leaves nil entries in the response batch for later removal
				if request.Id != nil {
					resBatch[i] = response
					resCount = resCount + 1
				}
			}

			// make response omitting nil entries
			respBatchComp := make([]*interface{}, resCount)
			for _, v := range resBatch {
				if v != nil {
					respBatchComp[len(respBatchComp)-resCount] = v
					resCount = resCount - 1
				}
			}

			send(w, respBatchComp)
			return
		}

		// Not a batch or single request, error
		jsonerr := &RpcErrorObject{-32600, "Could not decode request"}
		send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
	})
}

func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} {
	var reply, response interface{}
	reserr := api.GetRequestReply(request, &reply)
	switch reserr.(type) {
	case nil:
		response = &RpcSuccessResponse{Jsonrpc: jsonrpcver, Id: request.Id, Result: reply}
	case *NotImplementedError, *NotAvailableError:
		jsonerr := &RpcErrorObject{-32601, reserr.Error()}
		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
	case *DecodeParamError, *InsufficientParamsError, *ValidationError, *InvalidTypeError:
		jsonerr := &RpcErrorObject{-32602, reserr.Error()}
		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
	default:
		jsonerr := &RpcErrorObject{-32603, reserr.Error()}
		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
	}

	glog.V(logger.Detail).Infof("Generated response: %T %s", response, response)
	return &response
}

func send(writer io.Writer, v interface{}) (n int, err error) {
	var payload []byte
	payload, err = json.MarshalIndent(v, "", "\t")
	if err != nil {
		glog.V(logger.Error).Infoln("Error marshalling JSON", err)
		return 0, err
	}
	glog.V(logger.Detail).Infof("Sending payload: %s", payload)

	return writer.Write(payload)
}
<commit_msg>Permit multiple CORS domains<commit_after>package rpc

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

	"github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/logger/glog"
	"github.com/ethereum/go-ethereum/xeth"
	"github.com/rs/cors"
)

var rpclistener *stoppableTCPListener

const (
	jsonrpcver       = "2.0"
	maxSizeReqLength = 1024 * 1024 // 1MB
)

func Start(pipe *xeth.XEth, config RpcConfig) error {
	if rpclistener != nil {
		if fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort) != rpclistener.Addr().String() {
			return fmt.Errorf("RPC service already running on %s ", rpclistener.Addr().String())
		}
		return nil // RPC service already running on given host/port
	}

	l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", config.ListenAddress, config.ListenPort))
	if err != nil {
		glog.V(logger.Error).Infof("Can't listen on %s:%d: %v", config.ListenAddress, config.ListenPort, err)
		return err
	}
	rpclistener = l

	var handler http.Handler
	if len(config.CorsDomain) > 0 {
		var opts cors.Options
		opts.AllowedMethods = []string{"POST"}
		opts.AllowedOrigins = strings.Split(config.CorsDomain, " ")

		c := cors.New(opts)
		handler = newStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop)
	} else {
		handler = newStoppableHandler(JSONRPC(pipe), l.stop)
	}

	go http.Serve(l, handler)

	return nil
}

func Stop() error {
	if rpclistener != nil {
		rpclistener.Stop()
		rpclistener = nil
	}

	return nil
}

// JSONRPC returns a handler that implements the Ethereum JSON-RPC API.
func JSONRPC(pipe *xeth.XEth) http.Handler {
	api := NewEthereumApi(pipe)

	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "application/json")

		// Limit request size to resist DoS
		if req.ContentLength > maxSizeReqLength {
			jsonerr := &RpcErrorObject{-32700, "Request too large"}
			send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
			return
		}

		// Read request body
		defer req.Body.Close()
		body, err := ioutil.ReadAll(req.Body)
		if err != nil {
			jsonerr := &RpcErrorObject{-32700, "Could not read request body"}
			send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
		}

		// Try to parse the request as a single
		var reqSingle RpcRequest
		if err := json.Unmarshal(body, &reqSingle); err == nil {
			response := RpcResponse(api, &reqSingle)
			if reqSingle.Id != nil {
				send(w, &response)
			}
			return
		}

		// Try to parse the request to batch
		var reqBatch []RpcRequest
		if err := json.Unmarshal(body, &reqBatch); err == nil {
			// Build response batch
			resBatch := make([]*interface{}, len(reqBatch))
			resCount := 0

			for i, request := range reqBatch {
				response := RpcResponse(api, &request)
				// this leaves nil entries in the response batch for later removal
				if request.Id != nil {
					resBatch[i] = response
					resCount = resCount + 1
				}
			}

			// make response omitting nil entries
			respBatchComp := make([]*interface{}, resCount)
			for _, v := range resBatch {
				if v != nil {
					respBatchComp[len(respBatchComp)-resCount] = v
					resCount = resCount - 1
				}
			}

			send(w, respBatchComp)
			return
		}

		// Not a batch or single request, error
		jsonerr := &RpcErrorObject{-32600, "Could not decode request"}
		send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr})
	})
}

func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} {
	var reply, response interface{}
	reserr := api.GetRequestReply(request, &reply)
	switch reserr.(type) {
	case nil:
		response = &RpcSuccessResponse{Jsonrpc: jsonrpcver, Id: request.Id, Result: reply}
	case *NotImplementedError, *NotAvailableError:
		jsonerr := &RpcErrorObject{-32601, reserr.Error()}
		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
	case *DecodeParamError, *InsufficientParamsError, *ValidationError, *InvalidTypeError:
		jsonerr := &RpcErrorObject{-32602, reserr.Error()}
		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
	default:
		jsonerr := &RpcErrorObject{-32603, reserr.Error()}
		response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr}
	}

	glog.V(logger.Detail).Infof("Generated response: %T %s", response, response)
	return &response
}

func send(writer io.Writer, v interface{}) (n int, err error) {
	var payload []byte
	payload, err = json.MarshalIndent(v, "", "\t")
	if err != nil {
		glog.V(logger.Error).Infoln("Error marshalling JSON", err)
		return 0, err
	}
	glog.V(logger.Detail).Infof("Sending payload: %s", payload)

	return writer.Write(payload)
}
<|endoftext|>