<commit_before>package core

import (
	"fmt"
	"strings"
	"time"
)

type DbType string

type Uri struct {
	DbType  DbType
	Proto   string
	Host    string
	Port    string
	DbName  string
	User    string
	Passwd  string
	Charset string
	Laddr   string
	Raddr   string
	Timeout time.Duration
	Schema  string
}

// a dialect is a driver's wrapper
type Dialect interface {
	SetLogger(logger ILogger)
	Init(*DB, *Uri, string, string) error
	URI() *Uri
	DB() *DB
	DBType() DbType
	SqlType(*Column) string
	FormatBytes(b []byte) string

	DriverName() string
	DataSourceName() string

	QuoteStr() string
	IsReserved(string) bool
	Quote(string) string
	AndStr() string
	OrStr() string
	EqStr() string
	RollBackStr() string
	AutoIncrStr() string

	SupportInsertMany() bool
	SupportEngine() bool
	SupportCharset() bool
	SupportDropIfExists() bool
	IndexOnTable() bool
	ShowCreateNull() bool

	IndexCheckSql(tableName, idxName string) (string, []interface{})
	TableCheckSql(tableName string) (string, []interface{})

	IsColumnExist(tableName string, colName string) (bool, error)

	CreateTableSql(table *Table, tableName, storeEngine, charset string) string
	DropTableSql(tableName string) string
	CreateIndexSql(tableName string, index *Index) string
	DropIndexSql(tableName string, index *Index) string

	ModifyColumnSql(tableName string, col *Column) string

	ForUpdateSql(query string) string

	//CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
	//MustDropTable(tableName string) error

	GetColumns(tableName string) ([]string, map[string]*Column, error)
	GetTables() ([]*Table, error)
	GetIndexes(tableName string) (map[string]*Index, error)

	Filters() []Filter
}

func OpenDialect(dialect Dialect) (*DB, error) {
	return Open(dialect.DriverName(), dialect.DataSourceName())
}

type Base struct {
	db             *DB
	dialect        Dialect
	driverName     string
	dataSourceName string
	logger         ILogger
	*Uri
}

func (b *Base) DB() *DB {
	return b.db
}

func (b *Base) SetLogger(logger ILogger) {
	b.logger = logger
}

func (b *Base) Init(db *DB, dialect Dialect, uri *Uri, drivername, dataSourceName string) error {
	b.db, b.dialect, b.Uri = db, dialect, uri
	b.driverName, b.dataSourceName = drivername, dataSourceName
	return nil
}

func (b *Base) URI() *Uri {
	return b.Uri
}

func (b *Base) DBType() DbType {
	return b.Uri.DbType
}

func (b *Base) FormatBytes(bs []byte) string {
	return fmt.Sprintf("0x%x", bs)
}

func (b *Base) DriverName() string {
	return b.driverName
}

func (b *Base) ShowCreateNull() bool {
	return true
}

func (b *Base) DataSourceName() string {
	return b.dataSourceName
}

func (b *Base) AndStr() string {
	return "AND"
}

func (b *Base) OrStr() string {
	return "OR"
}

func (b *Base) EqStr() string {
	return "="
}

func (db *Base) RollBackStr() string {
	return "ROLL BACK"
}

func (db *Base) SupportDropIfExists() bool {
	return true
}

func (db *Base) DropTableSql(tableName string) string {
	return fmt.Sprintf("DROP TABLE IF EXISTS `%s`", tableName)
}

func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
	db.LogSQL(query, args)
	rows, err := db.DB().Query(query, args...)
	if err != nil {
		return false, err
	}
	defer rows.Close()

	if rows.Next() {
		return true, nil
	}
	return false, nil
}

func (db *Base) IsColumnExist(tableName, colName string) (bool, error) {
	query := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?"
	query = strings.Replace(query, "`", db.dialect.QuoteStr(), -1)
	return db.HasRecords(query, db.DbName, tableName, colName)
}

/*
func (db *Base) CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error {
	sql, args := db.dialect.TableCheckSql(tableName)
	rows, err := db.DB().Query(sql, args...)
	if db.Logger != nil {
		db.Logger.Info("[sql]", sql, args)
	}
	if err != nil {
		return err
	}
	defer rows.Close()

	if rows.Next() {
		return nil
	}

	sql = db.dialect.CreateTableSql(table, tableName, storeEngine, charset)
	_, err = db.DB().Exec(sql)
	if db.Logger != nil {
		db.Logger.Info("[sql]", sql)
	}
	return err
}*/

func (db *Base) CreateIndexSql(tableName string, index *Index) string {
	quote := db.dialect.Quote
	var unique string
	var idxName string
	if index.Type == UniqueType {
		unique = " UNIQUE"
	}
	idxName = index.XName(tableName)
	return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v)", unique,
		quote(idxName), quote(tableName),
		quote(strings.Join(index.Cols, quote(","))))
}

func (db *Base) DropIndexSql(tableName string, index *Index) string {
	quote := db.dialect.Quote
	var name string
	if index.IsRegular {
		name = index.XName(tableName)
	} else {
		name = index.Name
	}
	return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName))
}

func (db *Base) ModifyColumnSql(tableName string, col *Column) string {
	return fmt.Sprintf("alter table %s MODIFY COLUMN %s", tableName, col.StringNoPk(db.dialect))
}

func (b *Base) CreateTableSql(table *Table, tableName, storeEngine, charset string) string {
	var sql string
	sql = "CREATE TABLE IF NOT EXISTS "
	if tableName == "" {
		tableName = table.Name
	}

	sql += b.dialect.Quote(tableName)
	sql += " ("

	if len(table.ColumnsSeq()) > 0 {
		pkList := table.PrimaryKeys

		for _, colName := range table.ColumnsSeq() {
			col := table.GetColumn(colName)
			if col.IsPrimaryKey && len(pkList) == 1 {
				sql += col.String(b.dialect)
			} else {
				sql += col.StringNoPk(b.dialect)
			}
			sql = strings.TrimSpace(sql)
			sql += ", "
		}

		if len(pkList) > 1 {
			sql += "PRIMARY KEY ( "
			sql += b.dialect.Quote(strings.Join(pkList, b.dialect.Quote(",")))
			sql += " ), "
		}

		sql = sql[:len(sql)-2]
	}
	sql += ")"

	if b.dialect.SupportEngine() && storeEngine != "" {
		sql += " ENGINE=" + storeEngine
	}
	if b.dialect.SupportCharset() {
		if len(charset) == 0 {
			charset = b.dialect.URI().Charset
		}
		if len(charset) > 0 {
			sql += " DEFAULT CHARSET " + charset
		}
	}

	return sql
}

func (b *Base) ForUpdateSql(query string) string {
	return query + " FOR UPDATE"
}

func (b *Base) LogSQL(sql string, args []interface{}) {
	if b.logger != nil && b.logger.IsShowSQL() {
		if len(args) > 0 {
			b.logger.Info("[sql]", sql, args)
		} else {
			b.logger.Info("[sql]", sql)
		}
	}
}

var (
	dialects = map[DbType]func() Dialect{}
)

func RegisterDialect(dbName DbType, dialectFunc func() Dialect) {
	if dialectFunc == nil {
		panic("core: Register dialect is nil")
	}
	dialects[dbName] = dialectFunc // !nashtsai! allow override dialect
}

func QueryDialect(dbName DbType) Dialect {
	return dialects[dbName]()
}
<commit_msg>don't panic but return nil when query dialect<commit_after>package core

import (
	"fmt"
	"strings"
	"time"
)

type DbType string

type Uri struct {
	DbType  DbType
	Proto   string
	Host    string
	Port    string
	DbName  string
	User    string
	Passwd  string
	Charset string
	Laddr   string
	Raddr   string
	Timeout time.Duration
	Schema  string
}

// a dialect is a driver's wrapper
type Dialect interface {
	SetLogger(logger ILogger)
	Init(*DB, *Uri, string, string) error
	URI() *Uri
	DB() *DB
	DBType() DbType
	SqlType(*Column) string
	FormatBytes(b []byte) string

	DriverName() string
	DataSourceName() string

	QuoteStr() string
	IsReserved(string) bool
	Quote(string) string
	AndStr() string
	OrStr() string
	EqStr() string
	RollBackStr() string
	AutoIncrStr() string

	SupportInsertMany() bool
	SupportEngine() bool
	SupportCharset() bool
	SupportDropIfExists() bool
	IndexOnTable() bool
	ShowCreateNull() bool

	IndexCheckSql(tableName, idxName string) (string, []interface{})
	TableCheckSql(tableName string) (string, []interface{})

	IsColumnExist(tableName string, colName string) (bool, error)

	CreateTableSql(table *Table, tableName, storeEngine, charset string) string
	DropTableSql(tableName string) string
	CreateIndexSql(tableName string, index *Index) string
	DropIndexSql(tableName string, index *Index) string

	ModifyColumnSql(tableName string, col *Column) string

	ForUpdateSql(query string) string

	//CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
	//MustDropTable(tableName string) error

	GetColumns(tableName string) ([]string, map[string]*Column, error)
	GetTables() ([]*Table, error)
	GetIndexes(tableName string) (map[string]*Index, error)

	Filters() []Filter
}

func OpenDialect(dialect Dialect) (*DB, error) {
	return Open(dialect.DriverName(), dialect.DataSourceName())
}

type Base struct {
	db             *DB
	dialect        Dialect
	driverName     string
	dataSourceName string
	logger         ILogger
	*Uri
}

func (b *Base) DB() *DB {
	return b.db
}

func (b *Base) SetLogger(logger ILogger) {
	b.logger = logger
}

func (b *Base) Init(db *DB, dialect Dialect, uri *Uri, drivername, dataSourceName string) error {
	b.db, b.dialect, b.Uri = db, dialect, uri
	b.driverName, b.dataSourceName = drivername, dataSourceName
	return nil
}

func (b *Base) URI() *Uri {
	return b.Uri
}

func (b *Base) DBType() DbType {
	return b.Uri.DbType
}

func (b *Base) FormatBytes(bs []byte) string {
	return fmt.Sprintf("0x%x", bs)
}

func (b *Base) DriverName() string {
	return b.driverName
}

func (b *Base) ShowCreateNull() bool {
	return true
}

func (b *Base) DataSourceName() string {
	return b.dataSourceName
}

func (b *Base) AndStr() string {
	return "AND"
}

func (b *Base) OrStr() string {
	return "OR"
}

func (b *Base) EqStr() string {
	return "="
}

func (db *Base) RollBackStr() string {
	return "ROLL BACK"
}

func (db *Base) SupportDropIfExists() bool {
	return true
}

func (db *Base) DropTableSql(tableName string) string {
	return fmt.Sprintf("DROP TABLE IF EXISTS `%s`", tableName)
}

func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
	db.LogSQL(query, args)
	rows, err := db.DB().Query(query, args...)
	if err != nil {
		return false, err
	}
	defer rows.Close()

	if rows.Next() {
		return true, nil
	}
	return false, nil
}

func (db *Base) IsColumnExist(tableName, colName string) (bool, error) {
	query := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?"
	query = strings.Replace(query, "`", db.dialect.QuoteStr(), -1)
	return db.HasRecords(query, db.DbName, tableName, colName)
}

/*
func (db *Base) CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error {
	sql, args := db.dialect.TableCheckSql(tableName)
	rows, err := db.DB().Query(sql, args...)
	if db.Logger != nil {
		db.Logger.Info("[sql]", sql, args)
	}
	if err != nil {
		return err
	}
	defer rows.Close()

	if rows.Next() {
		return nil
	}

	sql = db.dialect.CreateTableSql(table, tableName, storeEngine, charset)
	_, err = db.DB().Exec(sql)
	if db.Logger != nil {
		db.Logger.Info("[sql]", sql)
	}
	return err
}*/

func (db *Base) CreateIndexSql(tableName string, index *Index) string {
	quote := db.dialect.Quote
	var unique string
	var idxName string
	if index.Type == UniqueType {
		unique = " UNIQUE"
	}
	idxName = index.XName(tableName)
	return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v)", unique,
		quote(idxName), quote(tableName),
		quote(strings.Join(index.Cols, quote(","))))
}

func (db *Base) DropIndexSql(tableName string, index *Index) string {
	quote := db.dialect.Quote
	var name string
	if index.IsRegular {
		name = index.XName(tableName)
	} else {
		name = index.Name
	}
	return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName))
}

func (db *Base) ModifyColumnSql(tableName string, col *Column) string {
	return fmt.Sprintf("alter table %s MODIFY COLUMN %s", tableName, col.StringNoPk(db.dialect))
}

func (b *Base) CreateTableSql(table *Table, tableName, storeEngine, charset string) string {
	var sql string
	sql = "CREATE TABLE IF NOT EXISTS "
	if tableName == "" {
		tableName = table.Name
	}

	sql += b.dialect.Quote(tableName)
	sql += " ("

	if len(table.ColumnsSeq()) > 0 {
		pkList := table.PrimaryKeys

		for _, colName := range table.ColumnsSeq() {
			col := table.GetColumn(colName)
			if col.IsPrimaryKey && len(pkList) == 1 {
				sql += col.String(b.dialect)
			} else {
				sql += col.StringNoPk(b.dialect)
			}
			sql = strings.TrimSpace(sql)
			sql += ", "
		}

		if len(pkList) > 1 {
			sql += "PRIMARY KEY ( "
			sql += b.dialect.Quote(strings.Join(pkList, b.dialect.Quote(",")))
			sql += " ), "
		}

		sql = sql[:len(sql)-2]
	}
	sql += ")"

	if b.dialect.SupportEngine() && storeEngine != "" {
		sql += " ENGINE=" + storeEngine
	}
	if b.dialect.SupportCharset() {
		if len(charset) == 0 {
			charset = b.dialect.URI().Charset
		}
		if len(charset) > 0 {
			sql += " DEFAULT CHARSET " + charset
		}
	}

	return sql
}

func (b *Base) ForUpdateSql(query string) string {
	return query + " FOR UPDATE"
}

func (b *Base) LogSQL(sql string, args []interface{}) {
	if b.logger != nil && b.logger.IsShowSQL() {
		if len(args) > 0 {
			b.logger.Info("[sql]", sql, args)
		} else {
			b.logger.Info("[sql]", sql)
		}
	}
}

var (
	dialects = map[DbType]func() Dialect{}
)

// RegisterDialect register database dialect
func RegisterDialect(dbName DbType, dialectFunc func() Dialect) {
	if dialectFunc == nil {
		panic("core: Register dialect is nil")
	}
	dialects[dbName] = dialectFunc // !nashtsai! allow override dialect
}

// QueryDialect query if registed database dialect
func QueryDialect(dbName DbType) Dialect {
	if d, ok := dialects[dbName]; ok {
		return d()
	}
	return nil
}
<|endoftext|>


<commit_before>// Discordgo - Discord bindings for Go
// Available at https://github.com/bwmarrin/discordgo

// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains high level helper functions and easy entry points for the
// entire discordgo package.  These functions are beling developed and are very
// experimental at this point.  They will most likley change so please use the
// low level functions if that's a problem.

// package discordgo provides Discord binding for Go
package discordgo

import "fmt"

// Discordgo Version, follows Symantic Versioning. (http://semver.org/)
const VERSION = "0.11.0-alpha"

// New creates a new Discord session and will automate some startup
// tasks if given enough information to do so.  Currently you can pass zero
// arguments and it will return an empty Discord session.
// There are 3 ways to call New:
//     With a single auth token - All requests will use the token blindly,
//         no verification of the token will be done and requests may fail.
//     With an email and password - Discord will sign in with the provided
//         credentials.
//     With an email, password and auth token - Discord will verify the auth
//         token, if it is invalid it will sign in with the provided
//         credentials. This is the Discord recommended way to sign in.
func New(args ...interface{}) (s *Session, err error) {

	// Create an empty Session interface.
	s = &Session{
		State:                  NewState(),
		StateEnabled:           true,
		Compress:               true,
		ShouldReconnectOnError: true,
	}

	// If no arguments are passed return the empty Session interface.
	// Later I will add default values, if appropriate.
	if args == nil {
		return
	}

	// Variables used below when parsing func arguments
	var auth, pass string

	// Parse passed arguments
	for _, arg := range args {

		switch v := arg.(type) {

		case []string:
			if len(v) > 3 {
				err = fmt.Errorf("Too many string parameters provided.")
				return
			}

			// First string is either token or username
			if len(v) > 0 {
				auth = v[0]
			}

			// If second string exists, it must be a password.
			if len(v) > 1 {
				pass = v[1]
			}

			// If third string exists, it must be an auth token.
			if len(v) > 2 {
				s.Token = v[2]
			}

		case string:
			// First string must be either auth token or username.
			// Second string must be a password.
			// Only 2 input strings are supported.

			if auth == "" {
				auth = v
			} else if pass == "" {
				pass = v
			} else if s.Token == "" {
				s.Token = v
			} else {
				err = fmt.Errorf("Too many string parameters provided.")
				return
			}

			//		case Config:
			// TODO: Parse configuration

		default:
			err = fmt.Errorf("Unsupported parameter type provided.")
			return
		}
	}

	// If only one string was provided, assume it is an auth token.
	// Otherwise get auth token from Discord, if a token was specified
	// Discord will verify it for free, or log the user in if it is
	// invalid.
	if pass == "" {
		s.Token = auth
	} else {
		err = s.Login(auth, pass)
		if err != nil || s.Token == "" {
			err = fmt.Errorf("Unable to fetch discord authentication token. %v", err)
			return
		}
	}

	// The Session is now able to have RestAPI methods called on it.
	// It is recommended that you now call Open() so that events will trigger.

	return
}
<commit_msg>Linting.<commit_after>// Discordgo - Discord bindings for Go
// Available at https://github.com/bwmarrin/discordgo

// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains high level helper functions and easy entry points for the
// entire discordgo package.  These functions are beling developed and are very
// experimental at this point.  They will most likley change so please use the
// low level functions if that's a problem.

// Package discordgo provides Discord binding for Go
package discordgo

import "fmt"

// VERSION of Discordgo, follows Symantic Versioning. (http://semver.org/)
const VERSION = "0.11.0-alpha"

// New creates a new Discord session and will automate some startup
// tasks if given enough information to do so.  Currently you can pass zero
// arguments and it will return an empty Discord session.
// There are 3 ways to call New:
//     With a single auth token - All requests will use the token blindly,
//         no verification of the token will be done and requests may fail.
//     With an email and password - Discord will sign in with the provided
//         credentials.
//     With an email, password and auth token - Discord will verify the auth
//         token, if it is invalid it will sign in with the provided
//         credentials. This is the Discord recommended way to sign in.
func New(args ...interface{}) (s *Session, err error) {

	// Create an empty Session interface.
	s = &Session{
		State:                  NewState(),
		StateEnabled:           true,
		Compress:               true,
		ShouldReconnectOnError: true,
	}

	// If no arguments are passed return the empty Session interface.
	// Later I will add default values, if appropriate.
	if args == nil {
		return
	}

	// Variables used below when parsing func arguments
	var auth, pass string

	// Parse passed arguments
	for _, arg := range args {

		switch v := arg.(type) {

		case []string:
			if len(v) > 3 {
				err = fmt.Errorf("Too many string parameters provided.")
				return
			}

			// First string is either token or username
			if len(v) > 0 {
				auth = v[0]
			}

			// If second string exists, it must be a password.
			if len(v) > 1 {
				pass = v[1]
			}

			// If third string exists, it must be an auth token.
			if len(v) > 2 {
				s.Token = v[2]
			}

		case string:
			// First string must be either auth token or username.
			// Second string must be a password.
			// Only 2 input strings are supported.

			if auth == "" {
				auth = v
			} else if pass == "" {
				pass = v
			} else if s.Token == "" {
				s.Token = v
			} else {
				err = fmt.Errorf("Too many string parameters provided.")
				return
			}

			//		case Config:
			// TODO: Parse configuration

		default:
			err = fmt.Errorf("Unsupported parameter type provided.")
			return
		}
	}

	// If only one string was provided, assume it is an auth token.
	// Otherwise get auth token from Discord, if a token was specified
	// Discord will verify it for free, or log the user in if it is
	// invalid.
	if pass == "" {
		s.Token = auth
	} else {
		err = s.Login(auth, pass)
		if err != nil || s.Token == "" {
			err = fmt.Errorf("Unable to fetch discord authentication token. %v", err)
			return
		}
	}

	// The Session is now able to have RestAPI methods called on it.
	// It is recommended that you now call Open() so that events will trigger.

	return
}
<|endoftext|>


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

package flag

/*
 * Flags
 *
 * Usage:
 *	1) Define flags using flag.String(), Bool(), Int(), etc. Example:
 *		import flag "flag"
 *		var ip *int = flag.Int("flagname", 1234, "help message for flagname")
 *	If you like, you can bind the flag to a variable using the Var() functions.
 *		var flagvar int
 *		func init() {
 *              	flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
 *		}
 *	2) After all flags are defined, call
 *		flag.Parse()
 *	to parse the command line into the defined flags.
 *
 *	3) Flags may then be used directly. If you're using the flags themselves,
 *	they are all pointers; if you bind to variables, they're values.
 *		print("ip has value ", *ip, "\n");
 *		print("flagvar has value ", flagvar, "\n");
 *
 *	4) After parsing, flag.Arg(i) is the i'th argument after the flags.
 *	Args are indexed from 0 up to flag.NArg().
 *
 *	Command line flag syntax:
 *		-flag
 *		-flag=x
 *		-flag x
 *	One or two minus signs may be used; they are equivalent.
 *
 *	Flag parsing stops just before the first non-flag argument
 *	("-" is a non-flag argument) or after the terminator "--".
 *
 *	Integer flags accept 1234, 0664, 0x1234 and may be negative.
 *	Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
 */

import "fmt"

// BUG: ctoi, atoi, atob belong elsewhere
func ctoi(c int64) int64 {
	if '0' <= c && c <= '9' {
		return c - '0'
	}
	if 'a' <= c && c <= 'f' {
		return c - 'a'
	}
	if 'A' <= c && c <= 'F' {
		return c - 'A'
	}
	return 1000   // too large for any base
}

func atoi(s string) (value int64, ok bool) {
	if len(s) == 0 {
		return 0, false
	}
	if s[0] == '-' {
		n, t := atoi(s[1:len(s)]);
		return -n, t
	}
	var base int64 = 10;
	i := 0;
	if s[0] == '0' {
		base = 8;
		if len(s) > 1 && (s[1] == 'x' || s[1] == 'X') {
			base = 16;
			i += 2;
		}
	}
	var n int64 = 0;
	for ; i < len(s); i++ {
		k := ctoi(int64(s[i]));
		if k >= base {
			return 0, false
		}
		n = n * base + k
	}
	return n, true
}

func atob(str string) (value bool, ok bool) {
	switch str {
		case "1", "t", "T", "true", "TRUE", "True":
			return true, true;
		case "0", "f", "F", "false", "FALSE", "False":
			return false, true
	}
	return false, false
}

type (
	boolValue struct;
	intValue struct;
	int64Value struct;
	uintValue struct;
	uint64Value struct;
	stringValue struct;
)

// -- Bool Value
type boolValue struct {
	p *bool;
}

func newBoolValue(val bool, p *bool) *boolValue {
	*p = val;
	return &boolValue{p}
}

func (b *boolValue) set(val bool) {
	*b.p = val;
}

func (b *boolValue) str() string {
	return fmt.Sprintf("%v", *b.p)
}

// -- Int Value
type intValue struct {
	p	*int;
}

func newIntValue(val int, p *int) *intValue {
	*p = val;
	return &intValue{p}
}

func (i *intValue) set(val int) {
	*i.p = val;
}

func (i *intValue) str() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- Int64 Value
type int64Value struct {
	p	*int64;
}

func newInt64Value(val int64, p *int64) *int64Value {
	*p = val;
	return &int64Value{p}
}

func (i *int64Value) set(val int64) {
	*i.p = val;
}

func (i *int64Value) str() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- Uint Value
type uintValue struct {
	p	*uint;
}

func newUintValue(val uint, p *uint) *uintValue {
	*p = val;
	return &uintValue{p}
}

func (i *uintValue) set(val uint) {
	*i.p = val
}

func (i *uintValue) str() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- uint64 Value
type uint64Value struct {
	p	*uint64;
}

func newUint64Value(val uint64, p *uint64) *uint64Value {
	*p = val;
	return &uint64Value{p}
}

func (i *uint64Value) set(val uint64) {
	*i.p = val;
}

func (i *uint64Value) str() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- string Value
type stringValue struct {
	p	*string;
}

func newStringValue(val string, p *string) *stringValue {
	*p = val;
	return &stringValue{p}
}

func (s *stringValue) set(val string) {
	*s.p = val;
}

func (s *stringValue) str() string {
	return fmt.Sprintf("%#q", *s.p)
}

// -- Value interface
type Value interface {
	str() string;
}

// -- Flag structure (internal)
export type Flag struct {
	name	string;
	usage	string;
	value	Value;
}

type allFlags struct {
	actual map[string] *Flag;
	formal map[string] *Flag;
	first_arg	int;
}

func New() *allFlags {
	f := new(allFlags);
	f.first_arg = 1;	// 0 is the program name, 1 is first arg
	f.actual = make(map[string] *Flag);
	f.formal = make(map[string] *Flag);
	return f;
}

var flags *allFlags = New();

export func PrintDefaults() {
	for k, f := range flags.formal {
		print("  -", f.name, "=", f.value.str(), ": ", f.usage, "\n");
	}
}

export func Usage() {
	if sys.argc() > 0 {
		print("Usage of ", sys.argv(0), ": \n");
	} else {
		print("Usage: \n");
	}
	PrintDefaults();
	sys.exit(1);
}

export func NFlag() int {
	return len(flags.actual)
}

export func Arg(i int) string {
	i += flags.first_arg;
	if i < 0 || i >= sys.argc() {
		return "";
	}
	return sys.argv(i)
}

export func NArg() int {
	return sys.argc() - flags.first_arg
}

func add(name string, value Value, usage string) {
	f := new(Flag);
	f.name = name;
	f.usage = usage;
	f.value = value;
	dummy, alreadythere := flags.formal[name];
	if alreadythere {
		print("flag redefined: ", name, "\n");
		panic("flag redefinition");
	}
	flags.formal[name] = f;
}

export func Bool(name string, value bool, usage string) *bool {
	p := new(bool);
	add(name, newBoolValue(value, p), usage);
	return p;
}

export func BoolVar(p *bool, name string, value bool, usage string) {
	add(name, newBoolValue(value, p), usage);
}

export func Int(name string, value int, usage string) *int {
	p := new(int);
	add(name, newIntValue(value, p), usage);
	return p;
}

export func IntVar(p *int, name string, value int, usage string) {
	add(name, newIntValue(value, p), usage);
}

export func Int64(name string, value int64, usage string) *int64 {
	p := new(int64);
	add(name, newInt64Value(value, p), usage);
	return p;
}

export func Int64Var(p *int64, name string, value int64, usage string) {
	add(name, newInt64Value(value, p), usage);
}

export func Uint(name string, value uint, usage string) *uint {
	p := new(uint);
	add(name, newUintValue(value, p), usage);
	return p;
}

export func UintVar(p *uint, name string, value uint, usage string) {
	add(name, newUintValue(value, p), usage);
}

export func Uint64(name string, value uint64, usage string) *uint64 {
	p := new(uint64);
	add(name, newUint64Value(value, p), usage);
	return p;
}

export func Uint64Var(p *uint64, name string, value uint64, usage string) {
	add(name, newUint64Value(value, p), usage);
}

export func String(name, value string, usage string) *string {
	p := new(string);
	add(name, newStringValue(value, p), usage);
	return p;
}

export func StringVar(p *string, name, value string, usage string) {
	add(name, newStringValue(value, p), usage);
}

func (f *allFlags) ParseOne(index int) (ok bool, next int)
{
	s := sys.argv(index);
	f.first_arg = index;  // until proven otherwise
	if len(s) == 0 {
		return false, -1
	}
	if s[0] != '-' {
		return false, -1
	}
	num_minuses := 1;
	if len(s) == 1 {
		return false, index
	}
	if s[1] == '-' {
		num_minuses++;
		if len(s) == 2 {	// "--" terminates the flags
			return false, index + 1
		}
	}
	name := s[num_minuses : len(s)];
	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
		print("bad flag syntax: ", s, "\n");
		Usage();
	}

	// it's a flag. does it have an argument?
	has_value := false;
	value := "";
	for i := 1; i < len(name); i++ {  // equals cannot be first
		if name[i] == '=' {
			value = name[i+1 : len(name)];
			has_value = true;
			name = name[0 : i];
			break;
		}
	}
	flag, alreadythere := flags.actual[name];
	if alreadythere {
		print("flag specified twice: -", name, "\n");
		Usage();
	}
	m := flags.formal;
	flag, alreadythere = m[name]; // BUG
	if !alreadythere {
		print("flag provided but not defined: -", name, "\n");
		Usage();
	}
	if f, ok := flag.value.(*boolValue); ok {
		if has_value {
			k, ok := atob(value);
			if !ok {
				print("invalid boolean value ", value, " for flag: -", name, "\n");
				Usage();
			}
			f.set(k)
		} else {
			f.set(true)
		}
	} else {
		// It must have a value, which might be the next argument.
		if !has_value && index < sys.argc()-1 {
			// value is the next arg
			has_value = true;
			index++;
			value = sys.argv(index);
		}
		if !has_value {
			print("flag needs an argument: -", name, "\n");
			Usage();
		}
		if f, ok := flag.value.(*stringValue); ok {
			f.set(value)
		} else {
			// It's an integer flag.  TODO(r): check for overflow?
			k, ok := atoi(value);
			if !ok {
				print("invalid integer value ", value, " for flag: -", name, "\n");
				Usage();
			}
			if f, ok := flag.value.(*intValue); ok {
				f.set(int(k));
			} else if f, ok := flag.value.(*int64Value); ok {
				f.set(k);
			} else if f, ok := flag.value.(*uintValue); ok {
				f.set(uint(k));
			} else if f, ok := flag.value.(*uint64Value); ok {
				f.set(uint64(k));
			}
		}
	}
	flags.actual[name] = flag;
	return true, index + 1
}

export func Parse() {
	for i := 1; i < sys.argc(); {
		ok, next := flags.ParseOne(i);
		if next > 0 {
			flags.first_arg = next;
			i = next;
		}
		if !ok {
			break
		}
	}
}
<commit_msg>casify flag.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flag

/*
 * Flags
 *
 * Usage:
 *	1) Define flags using flag.String(), Bool(), Int(), etc. Example:
 *		import flag "flag"
 *		var ip *int = flag.Int("flagname", 1234, "help message for flagname")
 *	If you like, you can bind the flag to a variable using the Var() functions.
 *		var flagvar int
 *		func init() {
 *              	flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
 *		}
 *	2) After all flags are defined, call
 *		flag.Parse()
 *	to parse the command line into the defined flags.
 *
 *	3) Flags may then be used directly. If you're using the flags themselves,
 *	they are all pointers; if you bind to variables, they're values.
 *		print("ip has value ", *ip, "\n");
 *		print("flagvar has value ", flagvar, "\n");
 *
 *	4) After parsing, flag.Arg(i) is the i'th argument after the flags.
 *	Args are indexed from 0 up to flag.NArg().
 *
 *	Command line flag syntax:
 *		-flag
 *		-flag=x
 *		-flag x
 *	One or two minus signs may be used; they are equivalent.
 *
 *	Flag parsing stops just before the first non-flag argument
 *	("-" is a non-flag argument) or after the terminator "--".
 *
 *	Integer flags accept 1234, 0664, 0x1234 and may be negative.
 *	Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
 */

import "fmt"

// BUG: ctoi, atoi, atob belong elsewhere
func ctoi(c int64) int64 {
	if '0' <= c && c <= '9' {
		return c - '0'
	}
	if 'a' <= c && c <= 'f' {
		return c - 'a'
	}
	if 'A' <= c && c <= 'F' {
		return c - 'A'
	}
	return 1000   // too large for any base
}

func atoi(s string) (value int64, ok bool) {
	if len(s) == 0 {
		return 0, false
	}
	if s[0] == '-' {
		n, t := atoi(s[1:len(s)]);
		return -n, t
	}
	var base int64 = 10;
	i := 0;
	if s[0] == '0' {
		base = 8;
		if len(s) > 1 && (s[1] == 'x' || s[1] == 'X') {
			base = 16;
			i += 2;
		}
	}
	var n int64 = 0;
	for ; i < len(s); i++ {
		k := ctoi(int64(s[i]));
		if k >= base {
			return 0, false
		}
		n = n * base + k
	}
	return n, true
}

func atob(str string) (value bool, ok bool) {
	switch str {
		case "1", "t", "T", "true", "TRUE", "True":
			return true, true;
		case "0", "f", "F", "false", "FALSE", "False":
			return false, true
	}
	return false, false
}

type (
	boolValue struct;
	intValue struct;
	int64Value struct;
	uintValue struct;
	uint64Value struct;
	stringValue struct;
)

// -- Bool Value
type boolValue struct {
	p *bool;
}

func newBoolValue(val bool, p *bool) *boolValue {
	*p = val;
	return &boolValue{p}
}

func (b *boolValue) set(val bool) {
	*b.p = val;
}

func (b *boolValue) str() string {
	return fmt.Sprintf("%v", *b.p)
}

// -- Int Value
type intValue struct {
	p	*int;
}

func newIntValue(val int, p *int) *intValue {
	*p = val;
	return &intValue{p}
}

func (i *intValue) set(val int) {
	*i.p = val;
}

func (i *intValue) str() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- Int64 Value
type int64Value struct {
	p	*int64;
}

func newInt64Value(val int64, p *int64) *int64Value {
	*p = val;
	return &int64Value{p}
}

func (i *int64Value) set(val int64) {
	*i.p = val;
}

func (i *int64Value) str() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- Uint Value
type uintValue struct {
	p	*uint;
}

func newUintValue(val uint, p *uint) *uintValue {
	*p = val;
	return &uintValue{p}
}

func (i *uintValue) set(val uint) {
	*i.p = val
}

func (i *uintValue) str() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- uint64 Value
type uint64Value struct {
	p	*uint64;
}

func newUint64Value(val uint64, p *uint64) *uint64Value {
	*p = val;
	return &uint64Value{p}
}

func (i *uint64Value) set(val uint64) {
	*i.p = val;
}

func (i *uint64Value) str() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- string Value
type stringValue struct {
	p	*string;
}

func newStringValue(val string, p *string) *stringValue {
	*p = val;
	return &stringValue{p}
}

func (s *stringValue) set(val string) {
	*s.p = val;
}

func (s *stringValue) str() string {
	return fmt.Sprintf("%#q", *s.p)
}

// -- Value interface
type _Value interface {
	str() string;
}

// -- Flag structure (internal)
export type Flag struct {
	name	string;
	usage	string;
	value	_Value;
}

type allFlags struct {
	actual map[string] *Flag;
	formal map[string] *Flag;
	first_arg	int;	// 0 is the program name, 1 is first arg
}

var flags *allFlags = &allFlags{make(map[string] *Flag), make(map[string] *Flag), 1}

export func PrintDefaults() {
	for k, f := range flags.formal {
		print("  -", f.name, "=", f.value.str(), ": ", f.usage, "\n");
	}
}

export func Usage() {
	if sys.argc() > 0 {
		print("Usage of ", sys.argv(0), ": \n");
	} else {
		print("Usage: \n");
	}
	PrintDefaults();
	sys.exit(1);
}

export func NFlag() int {
	return len(flags.actual)
}

export func Arg(i int) string {
	i += flags.first_arg;
	if i < 0 || i >= sys.argc() {
		return "";
	}
	return sys.argv(i)
}

export func NArg() int {
	return sys.argc() - flags.first_arg
}

func add(name string, value _Value, usage string) {
	f := new(Flag);
	f.name = name;
	f.usage = usage;
	f.value = value;
	dummy, alreadythere := flags.formal[name];
	if alreadythere {
		print("flag redefined: ", name, "\n");
		panic("flag redefinition");
	}
	flags.formal[name] = f;
}

export func Bool(name string, value bool, usage string) *bool {
	p := new(bool);
	add(name, newBoolValue(value, p), usage);
	return p;
}

export func BoolVar(p *bool, name string, value bool, usage string) {
	add(name, newBoolValue(value, p), usage);
}

export func Int(name string, value int, usage string) *int {
	p := new(int);
	add(name, newIntValue(value, p), usage);
	return p;
}

export func IntVar(p *int, name string, value int, usage string) {
	add(name, newIntValue(value, p), usage);
}

export func Int64(name string, value int64, usage string) *int64 {
	p := new(int64);
	add(name, newInt64Value(value, p), usage);
	return p;
}

export func Int64Var(p *int64, name string, value int64, usage string) {
	add(name, newInt64Value(value, p), usage);
}

export func Uint(name string, value uint, usage string) *uint {
	p := new(uint);
	add(name, newUintValue(value, p), usage);
	return p;
}

export func UintVar(p *uint, name string, value uint, usage string) {
	add(name, newUintValue(value, p), usage);
}

export func Uint64(name string, value uint64, usage string) *uint64 {
	p := new(uint64);
	add(name, newUint64Value(value, p), usage);
	return p;
}

export func Uint64Var(p *uint64, name string, value uint64, usage string) {
	add(name, newUint64Value(value, p), usage);
}

export func String(name, value string, usage string) *string {
	p := new(string);
	add(name, newStringValue(value, p), usage);
	return p;
}

export func StringVar(p *string, name, value string, usage string) {
	add(name, newStringValue(value, p), usage);
}

func (f *allFlags) ParseOne(index int) (ok bool, next int)
{
	s := sys.argv(index);
	f.first_arg = index;  // until proven otherwise
	if len(s) == 0 {
		return false, -1
	}
	if s[0] != '-' {
		return false, -1
	}
	num_minuses := 1;
	if len(s) == 1 {
		return false, index
	}
	if s[1] == '-' {
		num_minuses++;
		if len(s) == 2 {	// "--" terminates the flags
			return false, index + 1
		}
	}
	name := s[num_minuses : len(s)];
	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
		print("bad flag syntax: ", s, "\n");
		Usage();
	}

	// it's a flag. does it have an argument?
	has_value := false;
	value := "";
	for i := 1; i < len(name); i++ {  // equals cannot be first
		if name[i] == '=' {
			value = name[i+1 : len(name)];
			has_value = true;
			name = name[0 : i];
			break;
		}
	}
	flag, alreadythere := flags.actual[name];
	if alreadythere {
		print("flag specified twice: -", name, "\n");
		Usage();
	}
	m := flags.formal;
	flag, alreadythere = m[name]; // BUG
	if !alreadythere {
		print("flag provided but not defined: -", name, "\n");
		Usage();
	}
	if f, ok := flag.value.(*boolValue); ok {
		if has_value {
			k, ok := atob(value);
			if !ok {
				print("invalid boolean value ", value, " for flag: -", name, "\n");
				Usage();
			}
			f.set(k)
		} else {
			f.set(true)
		}
	} else {
		// It must have a value, which might be the next argument.
		if !has_value && index < sys.argc()-1 {
			// value is the next arg
			has_value = true;
			index++;
			value = sys.argv(index);
		}
		if !has_value {
			print("flag needs an argument: -", name, "\n");
			Usage();
		}
		if f, ok := flag.value.(*stringValue); ok {
			f.set(value)
		} else {
			// It's an integer flag.  TODO(r): check for overflow?
			k, ok := atoi(value);
			if !ok {
				print("invalid integer value ", value, " for flag: -", name, "\n");
				Usage();
			}
			if f, ok := flag.value.(*intValue); ok {
				f.set(int(k));
			} else if f, ok := flag.value.(*int64Value); ok {
				f.set(k);
			} else if f, ok := flag.value.(*uintValue); ok {
				f.set(uint(k));
			} else if f, ok := flag.value.(*uint64Value); ok {
				f.set(uint64(k));
			}
		}
	}
	flags.actual[name] = flag;
	return true, index + 1
}

export func Parse() {
	for i := 1; i < sys.argc(); {
		ok, next := flags.ParseOne(i);
		if next > 0 {
			flags.first_arg = next;
			i = next;
		}
		if !ok {
			break
		}
	}
}
<|endoftext|>


<commit_before>/**
* This test plugin has an alias conlicts with the core command alias 'p'
**/

package main

import (
	"fmt"

	"github.com/cloudfoundry/cli/plugin"
)

type AliasConflicts struct {
}

func (c *AliasConflicts) Run(cliConnection plugin.CliConnection, args []string) {
	if args[0] == "conflict-cmd" || args[0] == "conflict-alias" {
		cmd()
	}
}

func (c *AliasConflicts) GetMetadata() plugin.PluginMetadata {
	return plugin.PluginMetadata{
		Name: "AliasConflicts",
		Commands: []plugin.Command{
			{
				Name:     "conflict-cmd",
				Alias:    "conflict-alias",
				HelpText: "help text for AliasConflicts",
			},
		},
	}
}

func cmd() {
	fmt.Println("You called AliasConflicts")
}

func main() {
	plugin.Start(new(AliasConflicts))
}
<commit_msg>remove incorrect comment in test fixtures<commit_after>package main

import (
	"fmt"

	"github.com/cloudfoundry/cli/plugin"
)

type AliasConflicts struct {
}

func (c *AliasConflicts) Run(cliConnection plugin.CliConnection, args []string) {
	if args[0] == "conflict-cmd" || args[0] == "conflict-alias" {
		cmd()
	}
}

func (c *AliasConflicts) GetMetadata() plugin.PluginMetadata {
	return plugin.PluginMetadata{
		Name: "AliasConflicts",
		Commands: []plugin.Command{
			{
				Name:     "conflict-cmd",
				Alias:    "conflict-alias",
				HelpText: "help text for AliasConflicts",
			},
		},
	}
}

func cmd() {
	fmt.Println("You called AliasConflicts")
}

func main() {
	plugin.Start(new(AliasConflicts))
}
<|endoftext|>


<commit_before>package junos

import (
	"encoding/xml"
)

// DeviceList holds a []Device slice of every device within Space.
type DeviceList struct {
	XMLName xml.Name `xml:"devices"`
	Devices  []Device `xml:"device"`
}

// Device holds all the information about each device within Space.
type Device struct {
	ID        string `xml:"key,attr"`
	Family    string `xml:"deviceFamily"`
	Version   string `xml:"OSVersion"`
	Platform  string `xml:"platform"`
	Serial    string `xml:"serialNumber"`
	IPAddress string `xml:"ipAddr"`
	Name      string `xml:"name"`
}

// Devices queries the Junos Space server and returns all of the information
// about each device that is managed by Space.
func (s *JunosSpace) Devices() (*DeviceList, error) {
	var devices DeviceList
	data, err := s.APICall("device-management/devices")
	if err != nil {
		return nil, err
	}

	err = xml.Unmarshal(data, &devices)
	if err != nil {
		return nil, err
	}

	return &devices, nil
}
<commit_msg>Updated APICall function<commit_after>package junos

import (
	"encoding/xml"
)

// DeviceList holds a []Device slice of every device within Space.
type DeviceList struct {
	XMLName xml.Name `xml:"devices"`
	Devices  []Device `xml:"device"`
}

// Device holds all the information about each device within Space.
type Device struct {
	ID        string `xml:"key,attr"`
	Family    string `xml:"deviceFamily"`
	Version   string `xml:"OSVersion"`
	Platform  string `xml:"platform"`
	Serial    string `xml:"serialNumber"`
	IPAddress string `xml:"ipAddr"`
	Name      string `xml:"name"`
}

// Devices queries the Junos Space server and returns all of the information
// about each device that is managed by Space.
func (s *JunosSpace) Devices() (*DeviceList, error) {
	var devices DeviceList
	data, err := s.APICall("get", "device-management/devices", nil)
	if err != nil {
		return nil, err
	}

	err = xml.Unmarshal(data, &devices)
	if err != nil {
		return nil, err
	}

	return &devices, nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/codegangsta/cli"
	"github.com/fsouza/go-dockerclient"
	"os"
	"sync"
	"time"
)

func collectAPIImages(images []docker.APIImages, client *docker.Client, ctx *cli.Context) {
	var imageSync sync.WaitGroup
	for _, image := range images {
		imageSync.Add(1)
		go func(image *docker.APIImages, client *docker.Client, grace time.Duration, quiet bool, force bool, noPrune bool) {
			defer imageSync.Done()
			imageDetail, _ := client.InspectImage(image.ID)
			handleImage(imageDetail, client, grace, quiet, force, noPrune)
		}(&image, client, ctx.Duration("grace"), ctx.Bool("quiet"), ctx.Bool("force"), ctx.Bool("no-prune"))
	}
	imageSync.Wait()
}

func handleImage(image *docker.Image, client *docker.Client, grace time.Duration, quiet bool, force bool, noPrune bool) {
	now := time.Now()
	options := docker.RemoveImageOptions{
		Force:   force,
		NoPrune: noPrune,
	}
	if now.Sub(image.Created) >= grace {
		client.RemoveImageExtended(image.ID, options)
	}
}

func collectAPIContainers(containers []docker.APIContainers, client *docker.Client, ctx *cli.Context) {
	var containerSync sync.WaitGroup
	for _, container := range containers {
		containerSync.Add(1)
		go func(container *docker.APIContainers, client *docker.Client, grace time.Duration, quiet bool, force bool, removeVolumes bool) {
			defer containerSync.Done()
			containerDetail, _ := client.InspectContainer(container.ID)
			handleContainer(containerDetail, client, grace, quiet, force, removeVolumes)
		}(&container, client, ctx.Duration("grace"), ctx.Bool("quiet"), ctx.Bool("force"), ctx.BoolT("remove-volumes"))
	}
	containerSync.Wait()
}

func handleContainer(container *docker.Container, client *docker.Client, grace time.Duration, quiet bool, force bool, removeVolumes bool) {
	now := time.Now()
	options := docker.RemoveContainerOptions{
		ID:            container.ID,
		RemoveVolumes: removeVolumes,
		Force:         force,
	}
	if now.Sub(container.Created) >= grace {
		client.RemoveContainer(options)
	}
}

func runDgc(ctx *cli.Context) {
	var dgcSync sync.WaitGroup
	client, _ := docker.NewClient(ctx.String("socket"))
	images, _ := client.ListImages(docker.ListImagesOptions{All: false})
	containers, _ := client.ListContainers(docker.ListContainersOptions{All: false})
	dgcSync.Add(2)
	go func(containers []docker.APIContainers, client *docker.Client, ctx *cli.Context) {
		defer dgcSync.Done()
		collectAPIContainers(containers, client, ctx)
	}(containers, client, ctx)
	go func(images []docker.APIImages, client *docker.Client, ctx *cli.Context) {
		defer dgcSync.Done()
		collectAPIImages(images, client, ctx)
	}(images, client, ctx)
	dgcSync.Wait()
}

func main() {
	dgc := cli.NewApp()
	dgc.EnableBashCompletion = true
	dgc.Name = "dgc"
	dgc.Usage = "A minimal docker garbage collector"
	dgc.Version = "0.1.0"
	dgc.Author = "David J Felix <davidjfelix@davidjfelix.com>"
	dgc.Action = runDgc
	dgc.Flags = []cli.Flag{
		cli.DurationFlag{
			Name:   "grace, g",
			Value:  time.Duration(3600) * time.Second,
			Usage:  "the grace period for a container. Accepted compostable time units: [h, m, s, ms, ns us]",
			EnvVar: "GRACE_PERIOD_SECONDS,GRACE_PERIOD",
		},
		cli.StringFlag{
			Name:   "socket, s",
			Value:  "unix:///var/run/docker.sock",
			Usage:  "the docker remote socket",
			EnvVar: "DOCKER_SOCKET",
		},
		cli.StringFlag{
			Name:   "exclude, e",
			Value:  "/etc/docker-gc-exclude",
			Usage:  "the list of containers to exclude from garbage collection, as a file or directory",
			EnvVar: "EXCLUDE_FROM_GC",
		},
		cli.BoolFlag{
			Name:  "quiet, q",
			Usage: "don't print name of garbage-collected containers",
		},
		cli.BoolTFlag{
			Name:  "remove-volumes, r",
			Usage: "remove volumes with the container",
		},
		cli.BoolFlag{
			Name:  "force, f",
			Usage: "force images and containers to stop and be collected",
		},
		cli.BoolFlag{
			Name:  "no-prune, n",
			Usage: "don't prune parent images to a GC'd image",
		},
	}
	dgc.Run(os.Args)
}
<commit_msg>Refactor lambda and handle functions<commit_after>package main

import (
	"github.com/codegangsta/cli"
	"github.com/fsouza/go-dockerclient"
	"fmt"
	"os"
	"sync"
	"time"
)

func collectAPIImages(images []docker.APIImages, client *docker.Client, ctx *cli.Context) {
	var imageSync sync.WaitGroup
	grace := ctx.Duration("grace")
	quiet := ctx.Bool("quiet")
	options := docker.RemoveImageOptions{
		Force:   ctx.Bool("force"),
		NoPrune: ctx.Bool("no-prune"),
	}
	for _, image := range images {
		imageSync.Add(1)
		go func(image *docker.APIImages) {
			defer imageSync.Done()
			imageDetail, _ := client.InspectImage(image.ID)
			now := time.Now()
			if now.Sub(imageDetail.Created) >= grace {
				client.RemoveImageExtended(image.ID, options)
				if !quiet {
					//TODO: inject image name
					fmt.Printf("Deleting image.\n")
				}
			} else {
				if !quiet {
					//TODO: inject image name
					fmt.Printf("Not deleting image.\n")
				}
			}
		}(&image)
	}
	imageSync.Wait()
}

func collectAPIContainers(containers []docker.APIContainers, client *docker.Client, ctx *cli.Context) {
	var containerSync sync.WaitGroup
	grace := ctx.Duration("grace")
	quiet := ctx.Bool("quiet")
	for _, container := range containers {
		containerSync.Add(1)
		go func(container *docker.APIContainers){
			defer containerSync.Done()
			containerDetail, _ := client.InspectContainer(container.ID)
			now := time.Now()
			if now.Sub(containerDetail.Created) >= grace {
				options := docker.RemoveContainerOptions{
					ID:            containerDetail.ID,
					RemoveVolumes: ctx.Bool("remove-volumes"),
					Force:         ctx.Bool("force"),
				}
				client.RemoveContainer(options)
				if !quiet {
					//TODO: inject container name
					fmt.Printf("Deleting container.\n")
				}
			} else {
				if !quiet {
					//TODO: inject container name
					fmt.Printf("Not deleting container.\n")
				}
			}
		}(&container)
	}
	containerSync.Wait()
}

func runDgc(ctx *cli.Context) {
	var dgcSync sync.WaitGroup
	client, _ := docker.NewClient(ctx.String("socket"))
	images, _ := client.ListImages(docker.ListImagesOptions{All: false})
	containers, _ := client.ListContainers(docker.ListContainersOptions{All: false})
	dgcSync.Add(2)
	go func(containers []docker.APIContainers, client *docker.Client, ctx *cli.Context) {
		defer dgcSync.Done()
		collectAPIContainers(containers, client, ctx)
	}(containers, client, ctx)
	go func(images []docker.APIImages, client *docker.Client, ctx *cli.Context) {
		defer dgcSync.Done()
		collectAPIImages(images, client, ctx)
	}(images, client, ctx)
	dgcSync.Wait()
}

func main() {
	dgc := cli.NewApp()
	dgc.EnableBashCompletion = true
	dgc.Name = "dgc"
	dgc.Usage = "A minimal docker garbage collector"
	dgc.Version = "0.1.0"
	dgc.Author = "David J Felix <davidjfelix@davidjfelix.com>"
	dgc.Action = runDgc
	dgc.Flags = []cli.Flag{
		cli.DurationFlag{
			Name:   "grace, g",
			Value:  time.Duration(3600) * time.Second,
			Usage:  "the grace period for a container. Accepted compostable time units: [h, m, s, ms, ns us]",
			EnvVar: "GRACE_PERIOD_SECONDS,GRACE_PERIOD",
		},
		cli.StringFlag{
			Name:   "socket, s",
			Value:  "unix:///var/run/docker.sock",
			Usage:  "the docker remote socket",
			EnvVar: "DOCKER_SOCKET",
		},
		cli.StringFlag{
			Name:   "exclude, e",
			Value:  "/etc/docker-gc-exclude",
			Usage:  "the list of containers to exclude from garbage collection, as a file or directory",
			EnvVar: "EXCLUDE_FROM_GC",
		},
		cli.BoolFlag{
			Name:  "quiet, q",
			Usage: "don't print name of garbage-collected containers",
		},
		cli.BoolTFlag{
			Name:  "remove-volumes, r",
			Usage: "remove volumes with the container",
		},
		cli.BoolFlag{
			Name:  "force, f",
			Usage: "force images and containers to stop and be collected",
		},
		cli.BoolFlag{
			Name:  "no-prune, n",
			Usage: "don't prune parent images to a GC'd image",
		},
	}
	dgc.Run(os.Args)
}
<|endoftext|>


<commit_before>package dht

import (
	"crypto"
	_ "crypto/sha1"
	"encoding/binary"
	"errors"
	"fmt"
	"github.com/nsf/libtorgo/bencode"
	"io"
	"log"
	"net"
	"os"
	"sync"
	"time"
)

type Server struct {
	ID               string
	Socket           *net.UDPConn
	transactions     []*transaction
	transactionIDInt uint64
	nodes            map[string]*Node
	mu               sync.Mutex
}

type Node struct {
	addr          *net.UDPAddr
	id            string
	lastHeardFrom time.Time
	lastSentTo    time.Time
}

func (n *Node) Good() bool {
	if len(n.id) != 20 {
		return false
	}
	if time.Now().Sub(n.lastHeardFrom) >= 15*time.Minute {
		return false
	}
	return true
}

type Msg map[string]interface{}

var _ fmt.Stringer = Msg{}

func (m Msg) String() string {
	return fmt.Sprintf("%#v", m)
}

type transaction struct {
	remoteAddr net.Addr
	t          string
	Response   chan Msg
	response   chan Msg
}

func (s *Server) setDefaults() {
	if s.ID == "" {
		var id [20]byte
		h := crypto.SHA1.New()
		ss, err := os.Hostname()
		if err != nil {
			log.Print(err)
		}
		ss += s.Socket.LocalAddr().String()
		h.Write([]byte(ss))
		if b := h.Sum(id[:0:20]); len(b) != 20 {
			panic(len(b))
		}
		if len(id) != 20 {
			panic(len(id))
		}
		s.ID = string(id[:])
	}
}

func (s *Server) Init() {
	s.setDefaults()
}

func (s *Server) Serve() error {
	for {
		var b [1500]byte
		n, addr, err := s.Socket.ReadFromUDP(b[:])
		if err != nil {
			return err
		}
		var d map[string]interface{}
		err = bencode.Unmarshal(b[:n], &d)
		if err != nil {
			log.Printf("bad krpc message: %s", err)
			continue
		}
		s.mu.Lock()
		if d["y"] == "q" {
			s.handleQuery(addr, d)
			s.mu.Unlock()
			continue
		}
		t := s.findResponseTransaction(d["t"].(string), addr)
		if t == nil {
			log.Printf("unexpected message: %#v", d)
			s.mu.Unlock()
			continue
		}
		t.response <- d
		s.removeTransaction(t)
		id := ""
		if d["y"] == "r" {
			id = d["r"].(map[string]interface{})["id"].(string)
		}
		s.heardFromNode(addr, id)
		s.mu.Unlock()
	}
}

func (s *Server) AddNode(ni NodeInfo) {
	if s.nodes == nil {
		s.nodes = make(map[string]*Node)
	}
	n := s.getNode(ni.Addr)
	if n.id == "" {
		n.id = string(ni.ID[:])
	}
}

func (s *Server) handleQuery(source *net.UDPAddr, m Msg) {
	log.Print(m["q"])
	if m["q"] != "ping" {
		return
	}
	s.heardFromNode(source, m["a"].(map[string]interface{})["id"].(string))
	s.reply(source, m["t"].(string))
}

func (s *Server) reply(addr *net.UDPAddr, t string) {
	m := map[string]interface{}{
		"t": t,
		"y": "r",
		"r": map[string]string{
			"id": s.IDString(),
		},
	}
	b, err := bencode.Marshal(m)
	if err != nil {
		panic(err)
	}
	err = s.writeToNode(b, addr)
	if err != nil {
		panic(err)
	}
}

func (s *Server) heardFromNode(addr *net.UDPAddr, id string) {
	n := s.getNode(addr)
	n.id = id
	n.lastHeardFrom = time.Now()
}

func (s *Server) getNode(addr *net.UDPAddr) (n *Node) {
	n = s.nodes[addr.String()]
	if n == nil {
		n = &Node{
			addr: addr,
		}
		s.nodes[addr.String()] = n
	}
	return
}

func (s *Server) writeToNode(b []byte, node *net.UDPAddr) (err error) {
	n, err := s.Socket.WriteTo(b, node)
	if err != nil {
		return
	}
	if n != len(b) {
		err = io.ErrShortWrite
		return
	}
	s.sentToNode(node)
	return
}

func (s *Server) sentToNode(addr *net.UDPAddr) {
	n := s.getNode(addr)
	n.lastSentTo = time.Now()
}

func (s *Server) findResponseTransaction(transactionID string, sourceNode net.Addr) *transaction {
	for _, t := range s.transactions {
		if t.t == transactionID && t.remoteAddr.String() == sourceNode.String() {
			return t
		}
	}
	return nil
}

func (s *Server) nextTransactionID() string {
	var b [binary.MaxVarintLen64]byte
	n := binary.PutUvarint(b[:], s.transactionIDInt)
	s.transactionIDInt++
	return string(b[:n])
}

func (s *Server) removeTransaction(t *transaction) {
	for i, tt := range s.transactions {
		if t == tt {
			last := len(s.transactions) - 1
			s.transactions[i] = s.transactions[last]
			s.transactions = s.transactions[:last]
			return
		}
	}
	panic("transaction not found")
}

func (s *Server) addTransaction(t *transaction) {
	s.transactions = append(s.transactions, t)
}

func (s *Server) IDString() string {
	if len(s.ID) != 20 {
		panic("bad node id")
	}
	return s.ID
}

func (s *Server) query(node *net.UDPAddr, q string, a map[string]string) (t *transaction, err error) {
	tid := s.nextTransactionID()
	if a == nil {
		a = make(map[string]string, 1)
	}
	a["id"] = s.IDString()
	d := map[string]interface{}{
		"t": tid,
		"y": "q",
		"q": q,
		"a": a,
	}
	b, err := bencode.Marshal(d)
	if err != nil {
		return
	}
	t = &transaction{
		remoteAddr: node,
		t:          tid,
		Response:   make(chan Msg, 1),
	}
	t.response = t.Response
	s.addTransaction(t)
	err = s.writeToNode(b, node)
	if err != nil {
		s.removeTransaction(t)
	}
	return
}

const CompactNodeInfoLen = 26

type NodeInfo struct {
	ID   [20]byte
	Addr *net.UDPAddr
}

func (ni *NodeInfo) PutCompact(b []byte) error {
	if n := copy(b[:], ni.ID[:]); n != 20 {
		panic(n)
	}
	ip := ni.Addr.IP.To4()
	if len(ip) != 4 {
		panic(ip)
	}
	if n := copy(b[20:], ip); n != 4 {
		panic(n)
	}
	binary.BigEndian.PutUint16(b[24:], uint16(ni.Addr.Port))
	return nil
}

func (cni *NodeInfo) UnmarshalCompact(b []byte) error {
	if len(b) != 26 {
		return errors.New("expected 26 bytes")
	}
	if 20 != copy(cni.ID[:], b[:20]) {
		panic("impossibru!")
	}
	if cni.Addr == nil {
		cni.Addr = &net.UDPAddr{}
	}
	cni.Addr.IP = net.IPv4(b[20], b[21], b[22], b[23])
	cni.Addr.Port = int(binary.BigEndian.Uint16(b[24:26]))
	return nil
}

func (s *Server) Ping(node *net.UDPAddr) (*transaction, error) {
	return s.query(node, "ping", nil)
}

type findNodeResponse struct {
	Nodes []NodeInfo
}

func getResponseNodes(m Msg) (s string, err error) {
	defer func() {
		r := recover()
		if r == nil {
			return
		}
		err = fmt.Errorf("couldn't get response nodes: %s: %#v", r, m)
	}()
	s = m["r"].(map[string]interface{})["nodes"].(string)
	return
}

func (me *findNodeResponse) UnmarshalKRPCMsg(m Msg) error {
	b, err := getResponseNodes(m)
	if err != nil {
		return err
	}
	for i := 0; i < len(b); i += 26 {
		var n NodeInfo
		err := n.UnmarshalCompact([]byte(b[i : i+26]))
		if err != nil {
			return err
		}
		me.Nodes = append(me.Nodes, n)
	}
	return nil
}

func (s *Server) FindNode(addr *net.UDPAddr, targetID string) (t *transaction, err error) {
	t, err = s.query(addr, "find_node", map[string]string{"target": targetID})
	if err != nil {
		return
	}
	ch := make(chan Msg)
	t.response = ch
	go func() {
		d, ok := <-t.response
		if !ok {
			close(t.Response)
			return
		}
		if d["y"] == "r" {
			var r findNodeResponse
			err = r.UnmarshalKRPCMsg(d)
			if err != nil {
				log.Print(err)
			} else {
				s.mu.Lock()
				for _, cni := range r.Nodes {
					n := s.getNode(cni.Addr)
					n.id = string(cni.ID[:])
				}
				s.mu.Unlock()
			}
		}
		t.Response <- d
	}()
	return
}

func (s *Server) addRootNode() error {
	addr, err := net.ResolveUDPAddr("udp4", "router.bittorrent.com:6881")
	if err != nil {
		return err
	}
	s.nodes[addr.String()] = &Node{
		addr: addr,
	}
	return nil
}

// Populates the node table.
func (s *Server) Bootstrap() (err error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	if len(s.nodes) == 0 {
		err = s.addRootNode()
		if err != nil {
			return
		}
	}
	for _, node := range s.nodes {
		var t *transaction
		s.mu.Unlock()
		t, err = s.FindNode(node.addr, s.ID)
		s.mu.Lock()
		if err != nil {
			return
		}
		go func() {
			<-t.Response
		}()
	}
	return
}

func (s *Server) GoodNodes() (nis []NodeInfo) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, node := range s.nodes {
		if !node.Good() {
			continue
		}
		ni := NodeInfo{
			Addr: node.addr,
		}
		if n := copy(ni.ID[:], node.id); n != 20 {
			panic(n)
		}
		nis = append(nis, ni)
	}
	return
}

func (s *Server) StopServing() {
	s.Socket.Close()
}
<commit_msg>Some function doc<commit_after>package dht

import (
	"crypto"
	_ "crypto/sha1"
	"encoding/binary"
	"errors"
	"fmt"
	"github.com/nsf/libtorgo/bencode"
	"io"
	"log"
	"net"
	"os"
	"sync"
	"time"
)

type Server struct {
	ID               string
	Socket           *net.UDPConn
	transactions     []*transaction
	transactionIDInt uint64
	nodes            map[string]*Node
	mu               sync.Mutex
}

type Node struct {
	addr          *net.UDPAddr
	id            string
	lastHeardFrom time.Time
	lastSentTo    time.Time
}

func (n *Node) Good() bool {
	if len(n.id) != 20 {
		return false
	}
	if time.Now().Sub(n.lastHeardFrom) >= 15*time.Minute {
		return false
	}
	return true
}

type Msg map[string]interface{}

var _ fmt.Stringer = Msg{}

func (m Msg) String() string {
	return fmt.Sprintf("%#v", m)
}

type transaction struct {
	remoteAddr net.Addr
	t          string
	Response   chan Msg
	response   chan Msg
}

func (s *Server) setDefaults() {
	if s.ID == "" {
		var id [20]byte
		h := crypto.SHA1.New()
		ss, err := os.Hostname()
		if err != nil {
			log.Print(err)
		}
		ss += s.Socket.LocalAddr().String()
		h.Write([]byte(ss))
		if b := h.Sum(id[:0:20]); len(b) != 20 {
			panic(len(b))
		}
		if len(id) != 20 {
			panic(len(id))
		}
		s.ID = string(id[:])
	}
}

func (s *Server) Init() {
	s.setDefaults()
}

func (s *Server) Serve() error {
	for {
		var b [1500]byte
		n, addr, err := s.Socket.ReadFromUDP(b[:])
		if err != nil {
			return err
		}
		var d map[string]interface{}
		err = bencode.Unmarshal(b[:n], &d)
		if err != nil {
			log.Printf("bad krpc message: %s", err)
			continue
		}
		s.mu.Lock()
		if d["y"] == "q" {
			s.handleQuery(addr, d)
			s.mu.Unlock()
			continue
		}
		t := s.findResponseTransaction(d["t"].(string), addr)
		if t == nil {
			log.Printf("unexpected message: %#v", d)
			s.mu.Unlock()
			continue
		}
		t.response <- d
		s.removeTransaction(t)
		id := ""
		if d["y"] == "r" {
			id = d["r"].(map[string]interface{})["id"].(string)
		}
		s.heardFromNode(addr, id)
		s.mu.Unlock()
	}
}

func (s *Server) AddNode(ni NodeInfo) {
	if s.nodes == nil {
		s.nodes = make(map[string]*Node)
	}
	n := s.getNode(ni.Addr)
	if n.id == "" {
		n.id = string(ni.ID[:])
	}
}

func (s *Server) handleQuery(source *net.UDPAddr, m Msg) {
	log.Print(m["q"])
	if m["q"] != "ping" {
		return
	}
	s.heardFromNode(source, m["a"].(map[string]interface{})["id"].(string))
	s.reply(source, m["t"].(string))
}

func (s *Server) reply(addr *net.UDPAddr, t string) {
	m := map[string]interface{}{
		"t": t,
		"y": "r",
		"r": map[string]string{
			"id": s.IDString(),
		},
	}
	b, err := bencode.Marshal(m)
	if err != nil {
		panic(err)
	}
	err = s.writeToNode(b, addr)
	if err != nil {
		panic(err)
	}
}

func (s *Server) heardFromNode(addr *net.UDPAddr, id string) {
	n := s.getNode(addr)
	n.id = id
	n.lastHeardFrom = time.Now()
}

func (s *Server) getNode(addr *net.UDPAddr) (n *Node) {
	n = s.nodes[addr.String()]
	if n == nil {
		n = &Node{
			addr: addr,
		}
		s.nodes[addr.String()] = n
	}
	return
}

func (s *Server) writeToNode(b []byte, node *net.UDPAddr) (err error) {
	n, err := s.Socket.WriteTo(b, node)
	if err != nil {
		return
	}
	if n != len(b) {
		err = io.ErrShortWrite
		return
	}
	s.sentToNode(node)
	return
}

func (s *Server) sentToNode(addr *net.UDPAddr) {
	n := s.getNode(addr)
	n.lastSentTo = time.Now()
}

func (s *Server) findResponseTransaction(transactionID string, sourceNode net.Addr) *transaction {
	for _, t := range s.transactions {
		if t.t == transactionID && t.remoteAddr.String() == sourceNode.String() {
			return t
		}
	}
	return nil
}

func (s *Server) nextTransactionID() string {
	var b [binary.MaxVarintLen64]byte
	n := binary.PutUvarint(b[:], s.transactionIDInt)
	s.transactionIDInt++
	return string(b[:n])
}

func (s *Server) removeTransaction(t *transaction) {
	for i, tt := range s.transactions {
		if t == tt {
			last := len(s.transactions) - 1
			s.transactions[i] = s.transactions[last]
			s.transactions = s.transactions[:last]
			return
		}
	}
	panic("transaction not found")
}

func (s *Server) addTransaction(t *transaction) {
	s.transactions = append(s.transactions, t)
}

func (s *Server) IDString() string {
	if len(s.ID) != 20 {
		panic("bad node id")
	}
	return s.ID
}

func (s *Server) query(node *net.UDPAddr, q string, a map[string]string) (t *transaction, err error) {
	tid := s.nextTransactionID()
	if a == nil {
		a = make(map[string]string, 1)
	}
	a["id"] = s.IDString()
	d := map[string]interface{}{
		"t": tid,
		"y": "q",
		"q": q,
		"a": a,
	}
	b, err := bencode.Marshal(d)
	if err != nil {
		return
	}
	t = &transaction{
		remoteAddr: node,
		t:          tid,
		Response:   make(chan Msg, 1),
	}
	t.response = t.Response
	s.addTransaction(t)
	err = s.writeToNode(b, node)
	if err != nil {
		s.removeTransaction(t)
	}
	return
}

const CompactNodeInfoLen = 26

type NodeInfo struct {
	ID   [20]byte
	Addr *net.UDPAddr
}

func (ni *NodeInfo) PutCompact(b []byte) error {
	if n := copy(b[:], ni.ID[:]); n != 20 {
		panic(n)
	}
	ip := ni.Addr.IP.To4()
	if len(ip) != 4 {
		panic(ip)
	}
	if n := copy(b[20:], ip); n != 4 {
		panic(n)
	}
	binary.BigEndian.PutUint16(b[24:], uint16(ni.Addr.Port))
	return nil
}

func (cni *NodeInfo) UnmarshalCompact(b []byte) error {
	if len(b) != 26 {
		return errors.New("expected 26 bytes")
	}
	if 20 != copy(cni.ID[:], b[:20]) {
		panic("impossibru!")
	}
	if cni.Addr == nil {
		cni.Addr = &net.UDPAddr{}
	}
	cni.Addr.IP = net.IPv4(b[20], b[21], b[22], b[23])
	cni.Addr.Port = int(binary.BigEndian.Uint16(b[24:26]))
	return nil
}

func (s *Server) Ping(node *net.UDPAddr) (*transaction, error) {
	return s.query(node, "ping", nil)
}

type findNodeResponse struct {
	Nodes []NodeInfo
}

func getResponseNodes(m Msg) (s string, err error) {
	defer func() {
		r := recover()
		if r == nil {
			return
		}
		err = fmt.Errorf("couldn't get response nodes: %s: %#v", r, m)
	}()
	s = m["r"].(map[string]interface{})["nodes"].(string)
	return
}

func (me *findNodeResponse) UnmarshalKRPCMsg(m Msg) error {
	b, err := getResponseNodes(m)
	if err != nil {
		return err
	}
	for i := 0; i < len(b); i += 26 {
		var n NodeInfo
		err := n.UnmarshalCompact([]byte(b[i : i+26]))
		if err != nil {
			return err
		}
		me.Nodes = append(me.Nodes, n)
	}
	return nil
}

// Sends a find_node query to addr. targetID is the node we're looking for.
func (s *Server) FindNode(addr *net.UDPAddr, targetID string) (t *transaction, err error) {
	t, err = s.query(addr, "find_node", map[string]string{"target": targetID})
	if err != nil {
		return
	}
	// Scrape peers from the response to put in the server's table before
	// handing the response back to the caller.
	ch := make(chan Msg)
	t.response = ch
	go func() {
		d, ok := <-t.response
		if !ok {
			close(t.Response)
			return
		}
		if d["y"] == "r" {
			var r findNodeResponse
			err = r.UnmarshalKRPCMsg(d)
			if err != nil {
				log.Print(err)
			} else {
				s.mu.Lock()
				for _, cni := range r.Nodes {
					n := s.getNode(cni.Addr)
					n.id = string(cni.ID[:])
				}
				s.mu.Unlock()
			}
		}
		t.Response <- d
	}()
	return
}

func (s *Server) addRootNode() error {
	addr, err := net.ResolveUDPAddr("udp4", "router.bittorrent.com:6881")
	if err != nil {
		return err
	}
	s.nodes[addr.String()] = &Node{
		addr: addr,
	}
	return nil
}

// Populates the node table.
func (s *Server) Bootstrap() (err error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	if len(s.nodes) == 0 {
		err = s.addRootNode()
		if err != nil {
			return
		}
	}
	for _, node := range s.nodes {
		var t *transaction
		s.mu.Unlock()
		t, err = s.FindNode(node.addr, s.ID)
		s.mu.Lock()
		if err != nil {
			return
		}
		go func() {
			<-t.Response
		}()
	}
	return
}

func (s *Server) GoodNodes() (nis []NodeInfo) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, node := range s.nodes {
		if !node.Good() {
			continue
		}
		ni := NodeInfo{
			Addr: node.addr,
		}
		if n := copy(ni.ID[:], node.id); n != 20 {
			panic(n)
		}
		nis = append(nis, ni)
	}
	return
}

func (s *Server) StopServing() {
	s.Socket.Close()
}
<|endoftext|>


<commit_before>// +build js

package nexus

import (
	"net/url"

	"github.com/jaracil/nxcli/nxcore"
	"github.com/jaracil/wsck"
)

func Dial(s string, _ interface{}) (*nxcore.NexusConn, error) {

	u, err := url.Parse(s)
	if err != nil {
		return nil, err
	}

	conn, err := wsck.Dial(u.String(), "http://gopherjs.nexus")

	if err != nil {
		return nil, err
	}

	return nxcore.NewNexusConn(conn), nil
}
<commit_msg>Solve typo.<commit_after>// +build js

package nexus

import (
	"net/url"

	"github.com/jaracil/nxcli/nxcore"
	"github.com/jaracil/wsck"
)

func Dial(s string, _ interface{}) (*nxcore.NexusConn, error) {

	u, err := url.Parse(s)
	if err != nil {
		return nil, err
	}

	conn, err := websocket.Dial(u.String(), "http://gopherjs.nexus")

	if err != nil {
		return nil, err
	}

	return nxcore.NewNexusConn(conn), nil
}
<|endoftext|>


<commit_before>package mid

import "fmt"

type Map map[string]interface{}

func (m Map) String(key string) string {
	v, ok := m[key]
	if !ok || v == nil {
		return ""
	}
	switch x := v.(type) {
	case string:
		return x
	case []byte:
		return string(x)
	default:
		return fmt.Sprintf("%v", v)
	}
}

var Meta = Map{
	"version":        "0.1",
	"officialAuthor": "midc",
}
<commit_msg>fix meta<commit_after>package mid

import "fmt"

type Map map[string]interface{}

func (m Map) String(key string) string {
	v, ok := m[key]
	if !ok || v == nil {
		return ""
	}
	switch x := v.(type) {
	case string:
		return x
	case []byte:
		return string(x)
	default:
		return fmt.Sprintf("%v", v)
	}
}

var Meta = Map{
	"version":        "0.1.1",
	"officialAuthor": "midc",
}
<|endoftext|>


<commit_before>package gokeepasslib

import (
	"bytes"
	"compress/gzip"
	"crypto/aes"
	"crypto/cipher"
	"crypto/sha256"
	"encoding/binary"
	"encoding/xml"
	"io"
)

const blockSplitRate = 16384

type Encoder struct {
	w io.Writer
}

func (e *Encoder) Encode(db *Database) error {
	err := e.writeData(db)
	return err
}

func NewEncoder(w io.Writer) *Encoder {
	return &Encoder{w: w}
}

func (e *Encoder) writeData(db *Database) error {
	db.LockProtectedEntries()

	xmlHeader := []byte(`<?xml version="1.0" encoding="utf-8" standalone="yes"?>`)

	xmlData, err := xml.MarshalIndent(db.Content, "", "\t")
	if err != nil {
		return err
	}

	xmlData = append(xmlHeader, xmlData...)

	b := new(bytes.Buffer)
	w := gzip.NewWriter(b)
	defer w.Close()

	if _, err = w.Write(xmlData); err != nil {
		return err
	}

	if err = w.Flush(); err != nil {
		return err
	}

	hashData, err := hashBlocks(b.Bytes())
	if err != nil {
		return err
	}

	hashData = append(db.Headers.StreamStartBytes, hashData...)

	masterKey, err := db.Credentials.buildMasterKey(db)
	if err != nil {
		return err
	}

	block, err := aes.NewCipher(masterKey)
	if err != nil {
		return err
	}

	if len(hashData)%32 != 0 {
		padding := make([]byte, 32-(len(hashData)%32))
		hashData = append(hashData, padding...)
	}

	mode := cipher.NewCBCEncrypter(block, db.Headers.EncryptionIV)
	encrypted := make([]byte, len(hashData))
	mode.CryptBlocks(encrypted, hashData)

	db.Signature.WriteSignature(e.w)
	db.Headers.WriteHeaders(e.w)
	e.w.Write(encrypted)

	return nil
}

func hashBlocks(data []byte) ([]byte, error) {
	b := new(bytes.Buffer)

	i := 0
	for len(data) > 0 {
		var block []byte
		if len(data) >= blockSplitRate {
			block = append(block, data[:blockSplitRate]...)
			data = data[blockSplitRate:]
		} else {
			block = append(block, data[:len(data)]...)
			data = make([]byte, 0)
		}

		if err := binary.Write(b, binary.LittleEndian, uint32(i)); err != nil {
			return nil, err
		}

		hash := sha256.Sum256(block)

		if _, err := b.Write(hash[:]); err != nil {
			return nil, err
		}

		if err := binary.Write(b, binary.LittleEndian, uint32(len(block))); err != nil {
			return nil, err
		}

		if _, err := b.Write(block); err != nil {
			return nil, err
		}

		i++
	}

	if err := binary.Write(b, binary.LittleEndian, uint32(i)); err != nil {
		return nil, err
	}

	endBlock := make([]byte, 36)
	if _, err := b.Write(endBlock); err != nil {
		return nil, err
	}

	return b.Bytes(), nil
}
<commit_msg>Even simpler way of returning error :p<commit_after>package gokeepasslib

import (
	"bytes"
	"compress/gzip"
	"crypto/aes"
	"crypto/cipher"
	"crypto/sha256"
	"encoding/binary"
	"encoding/xml"
	"io"
)

const blockSplitRate = 16384

type Encoder struct {
	w io.Writer
}

func (e *Encoder) Encode(db *Database) error {
	return e.writeData(db)
}

func NewEncoder(w io.Writer) *Encoder {
	return &Encoder{w: w}
}

func (e *Encoder) writeData(db *Database) error {
	db.LockProtectedEntries()

	xmlHeader := []byte(`<?xml version="1.0" encoding="utf-8" standalone="yes"?>`)

	xmlData, err := xml.MarshalIndent(db.Content, "", "\t")
	if err != nil {
		return err
	}

	xmlData = append(xmlHeader, xmlData...)

	b := new(bytes.Buffer)
	w := gzip.NewWriter(b)
	defer w.Close()

	if _, err = w.Write(xmlData); err != nil {
		return err
	}

	if err = w.Flush(); err != nil {
		return err
	}

	hashData, err := hashBlocks(b.Bytes())
	if err != nil {
		return err
	}

	hashData = append(db.Headers.StreamStartBytes, hashData...)

	masterKey, err := db.Credentials.buildMasterKey(db)
	if err != nil {
		return err
	}

	block, err := aes.NewCipher(masterKey)
	if err != nil {
		return err
	}

	if len(hashData)%32 != 0 {
		padding := make([]byte, 32-(len(hashData)%32))
		hashData = append(hashData, padding...)
	}

	mode := cipher.NewCBCEncrypter(block, db.Headers.EncryptionIV)
	encrypted := make([]byte, len(hashData))
	mode.CryptBlocks(encrypted, hashData)

	db.Signature.WriteSignature(e.w)
	db.Headers.WriteHeaders(e.w)
	e.w.Write(encrypted)

	return nil
}

func hashBlocks(data []byte) ([]byte, error) {
	b := new(bytes.Buffer)

	i := 0
	for len(data) > 0 {
		var block []byte
		if len(data) >= blockSplitRate {
			block = append(block, data[:blockSplitRate]...)
			data = data[blockSplitRate:]
		} else {
			block = append(block, data[:len(data)]...)
			data = make([]byte, 0)
		}

		if err := binary.Write(b, binary.LittleEndian, uint32(i)); err != nil {
			return nil, err
		}

		hash := sha256.Sum256(block)

		if _, err := b.Write(hash[:]); err != nil {
			return nil, err
		}

		if err := binary.Write(b, binary.LittleEndian, uint32(len(block))); err != nil {
			return nil, err
		}

		if _, err := b.Write(block); err != nil {
			return nil, err
		}

		i++
	}

	if err := binary.Write(b, binary.LittleEndian, uint32(i)); err != nil {
		return nil, err
	}

	endBlock := make([]byte, 36)
	if _, err := b.Write(endBlock); err != nil {
		return nil, err
	}

	return b.Bytes(), nil
}
<|endoftext|>


<commit_before>package amino

import (
	"encoding/binary"
	"io"
	"math"
	"time"
)

//----------------------------------------
// Signed

func EncodeInt8(w io.Writer, i int8) (err error) {
	return EncodeVarint(w, int64(i))
}

func EncodeInt16(w io.Writer, i int16) (err error) {
	return EncodeVarint(w, int64(i))
}

func EncodeInt32(w io.Writer, i int32) (err error) {
	var buf [4]byte
	binary.LittleEndian.PutUint32(buf[:], uint32(i))
	_, err = w.Write(buf[:])
	return
}

func EncodeInt64(w io.Writer, i int64) (err error) {
	var buf [8]byte
	binary.LittleEndian.PutUint64(buf[:], uint64(i))
	_, err = w.Write(buf[:])
	return err
}

func EncodeVarint(w io.Writer, i int64) (err error) {
	var buf [10]byte
	n := binary.PutVarint(buf[:], i)
	_, err = w.Write(buf[0:n])
	return
}

func VarintSize(i int64) int {
	var buf [10]byte
	n := binary.PutVarint(buf[:], i)
	return n
}

//----------------------------------------
// Unsigned

func EncodeByte(w io.Writer, b byte) (err error) {
	return EncodeUvarint(w, uint64(b))
}

func EncodeUint8(w io.Writer, u uint8) (err error) {
	return EncodeUvarint(w, uint64(u))
}

func EncodeUint16(w io.Writer, u uint16) (err error) {
	return EncodeUvarint(w, uint64(u))
}

func EncodeUint32(w io.Writer, u uint32) (err error) {
	var buf [4]byte
	binary.LittleEndian.PutUint32(buf[:], u)
	_, err = w.Write(buf[:])
	return
}

func EncodeUint64(w io.Writer, u uint64) (err error) {
	var buf [8]byte
	binary.LittleEndian.PutUint64(buf[:], u)
	_, err = w.Write(buf[:])
	return
}

func EncodeUvarint(w io.Writer, u uint64) (err error) {
	var buf [10]byte
	n := binary.PutUvarint(buf[:], u)
	_, err = w.Write(buf[0:n])
	return
}

func UvarintSize(u uint64) int {
	var buf [10]byte
	n := binary.PutUvarint(buf[:], u)
	return n
}

//----------------------------------------
// Other

func EncodeBool(w io.Writer, b bool) (err error) {
	if b {
		err = EncodeUint8(w, 1) // same as EncodeUvarint(w, 1).
	} else {
		err = EncodeUint8(w, 0) // same as EncodeUvarint(w, 0).
	}
	return
}

// NOTE: UNSAFE
func EncodeFloat32(w io.Writer, f float32) (err error) {
	return EncodeUint32(w, math.Float32bits(f))
}

// NOTE: UNSAFE
func EncodeFloat64(w io.Writer, f float64) (err error) {
	return EncodeUint64(w, math.Float64bits(f))
}

// EncodeTime writes the number of seconds (int64) and nanoseconds (int32),
// with millisecond resolution since January 1, 1970 UTC to the Writer as an
// Int64.
// Milliseconds are used to ease compatibility with Javascript,
// which does not support finer resolution.
func EncodeTime(w io.Writer, t time.Time) (err error) {
	var s = t.Unix()
	var ns = int32(t.Nanosecond()) // this int64 -> int32 is safe.

	// TODO: We are hand-encoding a struct until MarshalAmino/UnmarshalAmino is supported.

	err = encodeFieldNumberAndTyp3(w, 1, Typ3_8Byte)
	if err != nil {
		return
	}
	err = EncodeInt64(w, s)
	if err != nil {
		return
	}

	err = encodeFieldNumberAndTyp3(w, 2, Typ3_4Byte)
	if err != nil {
		return
	}
	err = EncodeInt32(w, ns)
	if err != nil {
		return
	}

	return
}

func EncodeByteSlice(w io.Writer, bz []byte) (err error) {
	err = EncodeUvarint(w, uint64(len(bz)))
	if err != nil {
		return
	}
	_, err = w.Write(bz)
	return
}

func ByteSliceSize(bz []byte) int {
	return UvarintSize(uint64(len(bz))) + len(bz)
}

func EncodeString(w io.Writer, s string) (err error) {
	return EncodeByteSlice(w, []byte(s))
}
<commit_msg>skip over default values when encoding time (#178)<commit_after>package amino

import (
	"encoding/binary"
	"io"
	"math"
	"time"
)

//----------------------------------------
// Signed

func EncodeInt8(w io.Writer, i int8) (err error) {
	return EncodeVarint(w, int64(i))
}

func EncodeInt16(w io.Writer, i int16) (err error) {
	return EncodeVarint(w, int64(i))
}

func EncodeInt32(w io.Writer, i int32) (err error) {
	var buf [4]byte
	binary.LittleEndian.PutUint32(buf[:], uint32(i))
	_, err = w.Write(buf[:])
	return
}

func EncodeInt64(w io.Writer, i int64) (err error) {
	var buf [8]byte
	binary.LittleEndian.PutUint64(buf[:], uint64(i))
	_, err = w.Write(buf[:])
	return err
}

func EncodeVarint(w io.Writer, i int64) (err error) {
	var buf [10]byte
	n := binary.PutVarint(buf[:], i)
	_, err = w.Write(buf[0:n])
	return
}

func VarintSize(i int64) int {
	var buf [10]byte
	n := binary.PutVarint(buf[:], i)
	return n
}

//----------------------------------------
// Unsigned

func EncodeByte(w io.Writer, b byte) (err error) {
	return EncodeUvarint(w, uint64(b))
}

func EncodeUint8(w io.Writer, u uint8) (err error) {
	return EncodeUvarint(w, uint64(u))
}

func EncodeUint16(w io.Writer, u uint16) (err error) {
	return EncodeUvarint(w, uint64(u))
}

func EncodeUint32(w io.Writer, u uint32) (err error) {
	var buf [4]byte
	binary.LittleEndian.PutUint32(buf[:], u)
	_, err = w.Write(buf[:])
	return
}

func EncodeUint64(w io.Writer, u uint64) (err error) {
	var buf [8]byte
	binary.LittleEndian.PutUint64(buf[:], u)
	_, err = w.Write(buf[:])
	return
}

func EncodeUvarint(w io.Writer, u uint64) (err error) {
	var buf [10]byte
	n := binary.PutUvarint(buf[:], u)
	_, err = w.Write(buf[0:n])
	return
}

func UvarintSize(u uint64) int {
	var buf [10]byte
	n := binary.PutUvarint(buf[:], u)
	return n
}

//----------------------------------------
// Other

func EncodeBool(w io.Writer, b bool) (err error) {
	if b {
		err = EncodeUint8(w, 1) // same as EncodeUvarint(w, 1).
	} else {
		err = EncodeUint8(w, 0) // same as EncodeUvarint(w, 0).
	}
	return
}

// NOTE: UNSAFE
func EncodeFloat32(w io.Writer, f float32) (err error) {
	return EncodeUint32(w, math.Float32bits(f))
}

// NOTE: UNSAFE
func EncodeFloat64(w io.Writer, f float64) (err error) {
	return EncodeUint64(w, math.Float64bits(f))
}

// EncodeTime writes the number of seconds (int64) and nanoseconds (int32),
// with millisecond resolution since January 1, 1970 UTC to the Writer as an
// Int64.
// Milliseconds are used to ease compatibility with Javascript,
// which does not support finer resolution.
func EncodeTime(w io.Writer, t time.Time) (err error) {
	var s = t.Unix()
	var ns = int32(t.Nanosecond()) // this int64 -> int32 is safe.

	// TODO: We are hand-encoding a struct until MarshalAmino/UnmarshalAmino is supported.
	// skip if default/zero value:
	if s != 0 {
		err = encodeFieldNumberAndTyp3(w, 1, Typ3_8Byte)
		if err != nil {
			return
		}
		err = EncodeInt64(w, s)
		if err != nil {
			return
		}
	}
	// skip if default/zero value:
	if ns != 0 {
		err = encodeFieldNumberAndTyp3(w, 2, Typ3_4Byte)
		if err != nil {
			return
		}
		err = EncodeInt32(w, ns)
		if err != nil {
			return
		}
	}

	return
}

func EncodeByteSlice(w io.Writer, bz []byte) (err error) {
	err = EncodeUvarint(w, uint64(len(bz)))
	if err != nil {
		return
	}
	_, err = w.Write(bz)
	return
}

func ByteSliceSize(bz []byte) int {
	return UvarintSize(uint64(len(bz))) + len(bz)
}

func EncodeString(w io.Writer, s string) (err error) {
	return EncodeByteSlice(w, []byte(s))
}
<|endoftext|>


<commit_before>package gokeepasslib

import (
	"bytes"
	"compress/gzip"
	"encoding/xml"
	"io"
	"regexp"
)

// Header to be put before xml content in kdbx file
var xmlHeader = []byte(`<?xml version="1.0" encoding="utf-8" standalone="yes"?>` + "\n")

// Encoder is used to automaticaly encrypt and write a database to a file, network, etc
type Encoder struct {
	w io.Writer
}

// Encode writes db to e's internal writer
func (e *Encoder) Encode(db *Database) error {
	return e.writeData(db)
}

// NewEncoder creates a new encoder with writer w, identical to gokeepasslib.Encoder{w}
func NewEncoder(w io.Writer) *Encoder {
	return &Encoder{w: w}
}

// writeData is an internal function to write database to encoder's writer, called by Encode
func (e *Encoder) writeData(db *Database) error {
	db.LockProtectedEntries()

	// Creates XML data with from database content, and appends header to top
	xmlData, err := xml.MarshalIndent(db.Content, "", "\t")
	if err != nil {
		return err
	}
	xmlData = append(xmlHeader, xmlData...)
	xmlData, err = encodingPostProcessing(xmlData)
	if err != nil {
		return err
	}

	if db.Headers.CompressionFlags == GzipCompressionFlag { //If database header says to compress with gzip, compress xml data and put into block form
		b := new(bytes.Buffer)
		w := gzip.NewWriter(b)
		defer w.Close()

		if _, err = w.Write(xmlData); err != nil {
			return err
		}

		if err = w.Flush(); err != nil {
			return err
		}

		xmlData = b.Bytes()
		if err != nil {
			return err
		}
	}
	hashData, err := EncodeBlocks(xmlData)

	//Appends the StreamStartBytes from db header to the blocked data, used to verify that the key is correct when decrypting
	hashData = append(db.Headers.StreamStartBytes, hashData...)

	//Adds padding to data as required to encrypt properly
	if len(hashData)%16 != 0 {
		padding := make([]byte, 16-(len(hashData)%16))
		for i := 0; i < len(padding); i++ {
			padding[i] = byte(len(padding))
		}
		hashData = append(hashData, padding...)
	}

	mode,err := db.Encrypter()
	if err != nil {
		return err
	}
	encrypted := make([]byte, len(hashData))
	mode.CryptBlocks(encrypted, hashData)

	//Writes file signature (tells program it's a kdbx file of x version)
	if err = db.Signature.WriteTo(e.w); err != nil {
		return err
	}

	//Writes headers of database
	if err = db.Headers.WriteTo(e.w); err != nil {
		return err
	}

	//Writes the encrypted database content
	if _, err = e.w.Write(encrypted); err != nil {
		return err
	}

	return nil
}

func encodingPostProcessing(data []byte) ([]byte, error) {
	// Keepass2 requires binary reference values to written as self closing tags
	binRefReplacement, err := regexp.Compile("<Value Ref=\"(\\d+)\"></Value>")
	if err != nil {
		return nil, err
	}
	return binRefReplacement.ReplaceAll(data, []byte("<Value Ref=\"$1\"/>")), nil
}
<commit_msg>refactor encoder to read better<commit_after>package gokeepasslib

import (
	"bytes"
	"compress/gzip"
	"encoding/xml"
	"io"
	"regexp"
)

// Header to be put before xml content in kdbx file
var xmlHeader = []byte(`<?xml version="1.0" encoding="utf-8" standalone="yes"?>` + "\n")

// Encoder is used to automaticaly encrypt and write a database to a file, network, etc
type Encoder struct {
	w io.Writer
}

// Encode writes db to e's internal writer
func (e *Encoder) Encode(db *Database) (err error) {
	//Writes file signature (tells program it's a kdbx file of x version)
	if err = db.Signature.WriteTo(e.w); err != nil {
		return err
	}

	//Writes headers of database
	if err = db.Headers.WriteTo(e.w); err != nil {
		return err
	}

	//Write database content, encrypted
	if err = e.writeData(db); err != nil {
		return err
	}

	return nil
}

// NewEncoder creates a new encoder with writer w, identical to gokeepasslib.Encoder{w}
func NewEncoder(w io.Writer) *Encoder {
	return &Encoder{w: w}
}

// writeData is an internal function to write database to encoder's writer, called by Encode
func (e *Encoder) writeData(db *Database) error {
	db.LockProtectedEntries()

	// Creates XML data with from database content, and appends header to top
	xmlData, err := xml.MarshalIndent(db.Content, "", "\t")
	if err != nil {
		return err
	}
	xmlData = append(xmlHeader, xmlData...)
	xmlData, err = encodingPostProcessing(xmlData)
	if err != nil {
		return err
	}

	if db.Headers.CompressionFlags == GzipCompressionFlag { //If database header says to compress with gzip, compress xml data and put into block form
		b := new(bytes.Buffer)
		w := gzip.NewWriter(b)
		defer w.Close()

		if _, err = w.Write(xmlData); err != nil {
			return err
		}

		if err = w.Flush(); err != nil {
			return err
		}

		xmlData = b.Bytes()
		if err != nil {
			return err
		}
	}
	hashData, err := EncodeBlocks(xmlData)

	//Appends the StreamStartBytes from db header to the blocked data, used to verify that the key is correct when decrypting
	hashData = append(db.Headers.StreamStartBytes, hashData...)

	//Adds padding to data as required to encrypt properly
	if len(hashData)%16 != 0 {
		padding := make([]byte, 16-(len(hashData)%16))
		for i := 0; i < len(padding); i++ {
			padding[i] = byte(len(padding))
		}
		hashData = append(hashData, padding...)
	}

	mode,err := db.Encrypter()
	if err != nil {
		return err
	}
	encrypted := make([]byte, len(hashData))
	mode.CryptBlocks(encrypted, hashData)

	//Writes the encrypted database content
	if _, err = e.w.Write(encrypted); err != nil {
		return err
	}

	return nil
}

func encodingPostProcessing(data []byte) ([]byte, error) {
	// Keepass2 requires binary reference values to written as self closing tags
	binRefReplacement, err := regexp.Compile("<Value Ref=\"(\\d+)\"></Value>")
	if err != nil {
		return nil, err
	}
	return binRefReplacement.ReplaceAll(data, []byte("<Value Ref=\"$1\"/>")), nil
}
<|endoftext|>


<commit_before>package irc

import (
	"errors"
	"io"
	"sync"
)

var DefaultEncoderBufferrSize = 1024

type Encoder struct {
	w   io.Writer
	buf []byte
	*sync.Mutex
}

func NewEncoder(w io.Writer) *Encoder {
	return &Encoder{w,
		make([]byte, DefaultEncoderBufferrSize),
		&sync.Mutex{}}
}

func (e *Encoder) AppendByte(b byte) {
	e.buf = append(e.buf, b)
}

func (e *Encoder) Append(p []byte) {
	e.buf = append(e.buf, p...)
}

func (e *Encoder) Encode(msg *Msg) (n int, err error) {
	e.Lock()
	defer e.Unlock()

	e.buf = e.buf[:0]

	if msg.cmd == nil {
		return 0, errors.New("no command")
	}

	if msg.prefix != nil {
		e.AppendByte(prefixSymbol)
		e.Append(msg.prefix)
		e.AppendByte(space)
	}

	e.Append(msg.cmd)

	if msg.paramsCount != 0 {
		e.AppendByte(space)
		for i := 0; i < msg.paramsCount; i++ {
			e.Append(msg.params[i])
			if i != msg.paramsCount-1 {
				e.AppendByte(space)
			}
		}
	}

	if msg.trailing != nil {
		e.AppendByte(space)
		e.AppendByte(prefixSymbol)
		e.Append(msg.trailing)
	}

	e.Append([]byte("\r\n"))
	return e.w.Write(e.buf)
}
<commit_msg>private append<commit_after>package irc

import (
	"errors"
	"io"
	"sync"
)

var DefaultEncoderBufferrSize = 1024

type Encoder struct {
	w   io.Writer
	buf []byte
	*sync.Mutex
}

func NewEncoder(w io.Writer) *Encoder {
	return &Encoder{w,
		make([]byte, DefaultEncoderBufferrSize),
		&sync.Mutex{}}
}

func (e *Encoder) appendByte(b byte) {
	e.buf = append(e.buf, b)
}

func (e *Encoder) append(p []byte) {
	e.buf = append(e.buf, p...)
}

func (e *Encoder) Encode(msg *Msg) (n int, err error) {
	e.Lock()
	defer e.Unlock()

	e.buf = e.buf[:0]

	if msg.cmd == nil {
		return 0, errors.New("no command")
	}

	if msg.prefix != nil {
		e.appendByte(prefixSymbol)
		e.append(msg.prefix)
		e.appendByte(space)
	}

	e.append(msg.cmd)

	if msg.paramsCount != 0 {
		e.appendByte(space)
		for i := 0; i < msg.paramsCount; i++ {
			e.append(msg.params[i])
			if i != msg.paramsCount-1 {
				e.appendByte(space)
			}
		}
	}

	if msg.trailing != nil {
		e.appendByte(space)
		e.appendByte(prefixSymbol)
		e.append(msg.trailing)
	}

	e.append([]byte("\r\n"))
	return e.w.Write(e.buf)
}
<|endoftext|>


<commit_before>package kinesis

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/kinesis"
)

type Drainer struct {
	Buffer *recordBuffer
}

func newDrainer(a *KinesisAdapter, streamName string) {
	buffer, err := newRecordBuffer(a.Client, streamName)
	if err != nil {
		logErr(err)
	}
	d := &Drainer{Buffer: buffer}

	fmt.Printf("\n\n\n\n\n\n\nSTREAM NAME : %s\n\n\n\n\n", streamName)
	_, err = a.Client.CreateStream(&kinesis.CreateStreamInput{
		ShardCount: aws.Int64(1),
		StreamName: aws.String(streamName),
	})

	// If an error occur, return. Unless it's because the stream already exists.
	if err != nil {
		fmt.Println(err)
		if reqErr, ok := err.(awserr.RequestFailure); ok {
			fmt.Println(reqErr)
			if reqErr.Code() == "ResourceInUseException" {
				a.addDrainer(streamName, d)
			} else {
				logErr(err)
			}
		} else {
			logErr(err)
		}
	} else {
		// Wait for the stream to be active.
		go waitForActive(a, d)
	}

	go d.Drain()
}

// Drain flushes the buffer every second.
func (d *Drainer) Drain() {
	for _ = range time.Tick(time.Second * 1) {
		logErr(d.Buffer.Flush())
	}
}

func waitForActive(a *KinesisAdapter, d *Drainer) {
	resp := &kinesis.DescribeStreamOutput{}
	// timeout := make(chan bool, 30)
	streamName := *d.Buffer.input.StreamName

	params := &kinesis.DescribeStreamInput{StreamName: aws.String(streamName)}
	for {
		resp, _ = a.Client.DescribeStream(params)
		if streamStatus := *resp.StreamDescription.StreamStatus; streamStatus == "ACTIVE" {
			log.Printf("kinesis: STREAM '%s' STATUS: %s\n", streamName, streamStatus)
			a.addDrainer(streamName, d)
			break
		} else {
			log.Printf("kinesis: STREAM '%s' STATUS: %s\n", streamName, streamStatus)
			time.Sleep(4 * time.Second)
			// timeout <- true
		}
	}
}
<commit_msg>Moar cleanup.<commit_after>package kinesis

import (
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/kinesis"
)

type Drainer struct {
	Buffer *recordBuffer
}

func newDrainer(a *KinesisAdapter, streamName string) {
	buffer, err := newRecordBuffer(a.Client, streamName)
	if err != nil {
		logErr(err)
	}

	d := &Drainer{Buffer: buffer}
	go d.Drain()

	err = createStream(a, streamName)
	if err != nil {
		if reqErr, ok := err.(awserr.RequestFailure); ok {
			if reqErr.Code() == "ResourceInUseException" {
				a.addDrainer(streamName, d)
			} else {
				logErr(err)
			}
		} else {
			logErr(err)
		}
	} else {
		go waitForActive(a, d)
	}
}

// Drain flushes the buffer every second.
func (d *Drainer) Drain() {
	for _ = range time.Tick(time.Second * 1) {
		logErr(d.Buffer.Flush())
	}
}

func createStream(a *KinesisAdapter, streamName string) error {
	_, err := a.Client.CreateStream(&kinesis.CreateStreamInput{
		ShardCount: aws.Int64(1),
		StreamName: aws.String(streamName),
	})

	return err
}

func waitForActive(a *KinesisAdapter, d *Drainer) {
	streamName := *d.Buffer.input.StreamName
	var streamStatus string

	params := &kinesis.DescribeStreamInput{StreamName: aws.String(streamName)}
	resp := &kinesis.DescribeStreamOutput{}
	for {
		resp, _ = a.Client.DescribeStream(params)
		if streamStatus = *resp.StreamDescription.StreamStatus; streamStatus == "ACTIVE" {
			a.addDrainer(streamName, d)
			break
		} else {
			time.Sleep(4 * time.Second)
		}

		log.Printf("kinesis: STREAM '%s' STATUS: %s\n", streamName, streamStatus)
	}
}
<|endoftext|>


<commit_before>package ds

import (
	"archive/zip"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/sselph/scraper/mamedb"
	"github.com/syndtr/goleveldb/leveldb"
)

const (
	mameDBName   = "mame_history"
	mameZipURL   = "https://storage.googleapis.com/stevenselph.appspot.com/mamehist.zip"
	mameZipName  = "mamehist.zip"
	mameMetaName = "mamehist.meta"
)

// MAME is a Data Source using mamedb and arcade-history.
type MAME struct {
	db *leveldb.DB
}

// GetID implements DS.
func (m *MAME) GetID(p string) (string, error) {
	b := filepath.Base(p)
	id := b[:len(b)-len(filepath.Ext(b))]
	return id, nil
}

// GetName implements DS.
func (m *MAME) GetName(p string) string {
	return ""
}

// Close implements io.Closer.
func (m *MAME) Close() error {
	return m.db.Close()
}

// GetGame implements DS.
func (m *MAME) GetGame(id string) (*Game, error) {
	g, err := mamedb.GetGame(id)
	if err != nil {
		if err == mamedb.ErrNotFound {
			return nil, ErrNotFound
		}
		return nil, err
	}
	game := NewGame()
	game.ID = g.ID
	game.GameTitle = g.Name
	game.ReleaseDate = g.Date
	game.Developer = g.Developer
	game.Genre = g.Genre
	game.Source = g.Source
	game.Players = g.Players
	game.Rating = g.Rating / 10.0
	if g.Title != "" {
		game.Images[ImgTitle] = g.Title
		game.Thumbs[ImgTitle] = g.Title
	}
	if g.Snap != "" {
		game.Images[ImgScreen] = g.Snap
		game.Thumbs[ImgScreen] = g.Snap
	}
	if g.Marquee != "" {
		game.Images[ImgMarquee] = g.Marquee
		game.Thumbs[ImgMarquee] = g.Marquee
	}
	if g.Cabinet != "" {
		game.Images[ImgCabinet] = g.Cabinet
		game.Thumbs[ImgCabinet] = g.Cabinet
	}
	hi, err := m.db.Get([]byte(id), nil)
	if err == nil {
		desc, err := m.db.Get(hi, nil)
		if err == nil {
			game.Overview = string(desc)
		}
	}
	return game, nil
}

func updateMAMEDB(version, p string) error {
	log.Print("INFO: Checking for new MAME History.")
	req, err := http.NewRequest("GET", mameZipURL, nil)
	if err != nil {
		return err
	}
	req.Header.Set("if-none-match", version)
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode == http.StatusNotModified {
		log.Printf("INFO: MAME History %s up to date.", version)
		return nil
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("got %v response", resp.Status)
	}
	dbp := filepath.Join(p, mameDBName)
	err = os.RemoveAll(dbp)
	if err != nil {
		return err
	}
	err = os.Mkdir(dbp, 0775)
	if err != nil {
		return err
	}
	newVersion := resp.Header.Get("etag")
	log.Printf("INFO: Upgrading MAME History: %s -> %s.", version, newVersion)
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	zf := filepath.Join(p, mameZipName)
	err = ioutil.WriteFile(zf, b, 0664)
	if err != nil {
		return err
	}
	rc, err := zip.OpenReader(zf)
	if err != nil {
		return err
	}
	defer rc.Close()
	for _, v := range rc.Reader.File {
		n := v.FileHeader.Name
		frc, err := v.Open()
		if err != nil {
			return err
		}
		defer frc.Close()
		b, err = ioutil.ReadAll(frc)
		if err != nil {
			return err
		}
		err = ioutil.WriteFile(filepath.Join(dbp, n), b, 0664)
		if err != nil {
			return err
		}
	}
	log.Print("INFO: Upgrade Complete.")
	os.Remove(zf)
	ioutil.WriteFile(filepath.Join(p, mameMetaName), []byte(newVersion), 0664)
	return nil
}

func getMAMEDB(p string) (*leveldb.DB, error) {
	var err error
	if p == "" {
		p, err = DefaultCachePath()
		if err != nil {
			return nil, err
		}
	}
	err = mkDir(p)
	var version string
	if err != nil {
		return nil, err
	}
	fp := filepath.Join(p, mameDBName)
	mp := filepath.Join(p, mameMetaName)
	if exists(fp) && exists(mp) {
		b, err := ioutil.ReadFile(mp)
		if err != nil {
			return nil, err
		}
		version = strings.Trim(string(b[:]), "\n\r")
	}
	err = updateMAMEDB(version, p)
	if err != nil {
		return nil, err
	}
	db, err := leveldb.OpenFile(fp, nil)
	if err != nil {
		return nil, err
	}
	return db, nil
}

// NewMAME returns a new MAME. MAME should be closed when not needed.
func NewMAME(p string) (*MAME, error) {
	db, err := getMAMEDB(p)
	if err != nil {
		return nil, err
	}
	return &MAME{db}, nil
}
<commit_msg>Use cached mamehist when server is over quota.<commit_after>package ds

import (
	"archive/zip"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/sselph/scraper/mamedb"
	"github.com/syndtr/goleveldb/leveldb"
)

const (
	mameDBName   = "mame_history"
	mameZipURL   = "https://storage.googleapis.com/stevenselph.appspot.com/mamehist.zip"
	mameZipName  = "mamehist.zip"
	mameMetaName = "mamehist.meta"
)

// MAME is a Data Source using mamedb and arcade-history.
type MAME struct {
	db *leveldb.DB
}

// GetID implements DS.
func (m *MAME) GetID(p string) (string, error) {
	b := filepath.Base(p)
	id := b[:len(b)-len(filepath.Ext(b))]
	return id, nil
}

// GetName implements DS.
func (m *MAME) GetName(p string) string {
	return ""
}

// Close implements io.Closer.
func (m *MAME) Close() error {
	return m.db.Close()
}

// GetGame implements DS.
func (m *MAME) GetGame(id string) (*Game, error) {
	g, err := mamedb.GetGame(id)
	if err != nil {
		if err == mamedb.ErrNotFound {
			return nil, ErrNotFound
		}
		return nil, err
	}
	game := NewGame()
	game.ID = g.ID
	game.GameTitle = g.Name
	game.ReleaseDate = g.Date
	game.Developer = g.Developer
	game.Genre = g.Genre
	game.Source = g.Source
	game.Players = g.Players
	game.Rating = g.Rating / 10.0
	if g.Title != "" {
		game.Images[ImgTitle] = g.Title
		game.Thumbs[ImgTitle] = g.Title
	}
	if g.Snap != "" {
		game.Images[ImgScreen] = g.Snap
		game.Thumbs[ImgScreen] = g.Snap
	}
	if g.Marquee != "" {
		game.Images[ImgMarquee] = g.Marquee
		game.Thumbs[ImgMarquee] = g.Marquee
	}
	if g.Cabinet != "" {
		game.Images[ImgCabinet] = g.Cabinet
		game.Thumbs[ImgCabinet] = g.Cabinet
	}
	hi, err := m.db.Get([]byte(id), nil)
	if err == nil {
		desc, err := m.db.Get(hi, nil)
		if err == nil {
			game.Overview = string(desc)
		}
	}
	return game, nil
}

func updateMAMEDB(version, p string) error {
	log.Print("INFO: Checking for new MAME History.")
	req, err := http.NewRequest("GET", mameZipURL, nil)
	if err != nil {
		return err
	}
	req.Header.Set("if-none-match", version)
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode == http.StatusNotModified {
		log.Printf("INFO: MAME History %s up to date.", version)
		return nil
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("got %v response", resp.Status)
	}
	if version != "" && resp.StatusCode == http.StatusTooManyRequests {
		log.Printf("WARN: Using cached MAME History. Server over quota.")
		return nil
	}
	dbp := filepath.Join(p, mameDBName)
	err = os.RemoveAll(dbp)
	if err != nil {
		return err
	}
	err = os.Mkdir(dbp, 0775)
	if err != nil {
		return err
	}
	newVersion := resp.Header.Get("etag")
	log.Printf("INFO: Upgrading MAME History: %s -> %s.", version, newVersion)
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	zf := filepath.Join(p, mameZipName)
	err = ioutil.WriteFile(zf, b, 0664)
	if err != nil {
		return err
	}
	rc, err := zip.OpenReader(zf)
	if err != nil {
		return err
	}
	defer rc.Close()
	for _, v := range rc.Reader.File {
		n := v.FileHeader.Name
		frc, err := v.Open()
		if err != nil {
			return err
		}
		defer frc.Close()
		b, err = ioutil.ReadAll(frc)
		if err != nil {
			return err
		}
		err = ioutil.WriteFile(filepath.Join(dbp, n), b, 0664)
		if err != nil {
			return err
		}
	}
	log.Print("INFO: Upgrade Complete.")
	os.Remove(zf)
	ioutil.WriteFile(filepath.Join(p, mameMetaName), []byte(newVersion), 0664)
	return nil
}

func getMAMEDB(p string) (*leveldb.DB, error) {
	var err error
	if p == "" {
		p, err = DefaultCachePath()
		if err != nil {
			return nil, err
		}
	}
	err = mkDir(p)
	var version string
	if err != nil {
		return nil, err
	}
	fp := filepath.Join(p, mameDBName)
	mp := filepath.Join(p, mameMetaName)
	if exists(fp) && exists(mp) {
		b, err := ioutil.ReadFile(mp)
		if err != nil {
			return nil, err
		}
		version = strings.Trim(string(b[:]), "\n\r")
	}
	err = updateMAMEDB(version, p)
	if err != nil {
		return nil, err
	}
	db, err := leveldb.OpenFile(fp, nil)
	if err != nil {
		return nil, err
	}
	return db, nil
}

// NewMAME returns a new MAME. MAME should be closed when not needed.
func NewMAME(p string) (*MAME, error) {
	db, err := getMAMEDB(p)
	if err != nil {
		return nil, err
	}
	return &MAME{db}, nil
}
<|endoftext|>