<commit_before>package main

import (
	"fmt"
	"go/build"
	"path/filepath"
	"strings"
)

// initc runs the init subcommand, copies all the external packages for the
// package in the current working directory into the specified directory.
// External packages are packages not located in the standard library, a parent
// directory, or a subdirectory.
// Files are placed in subdirectories based on their package name, if there are
// conflicts the command will fail with a message, those specific packages will
// need to be copied with the cp command, before running init again.
// Includes dependencies from packages located in subdirectories based on the
// `recurse` parameter.
func initc(ctx *build.Context, cwd, dst string, recurse bool) error {
	dst, err := cwdAbs(cwd, dst)
	if err != nil {
		return err
	}
	dsts := make([]string, 0)         // list of destination directories
	cps := make([]cpJob, 0)           // list of pending cp calls
	updates := make([]updateJob, 0)   // list of pending update calls
	dups := make(map[string][]string) // package name to import paths
	hasDups := false
	process := func(pkg *build.Package, err error) error {
		// Filter for the imports to copy into dst directory
		f := func(i string) bool {
			switch {
			case isChildPackage(pkg.ImportPath, i):
				return false // in a subdirectory
			case isChildPackage(i, pkg.ImportPath):
				return false // in a parent diretory
			case isStandardPackage(ctx, cwd, i):
				return false
			}
			return true
		}
		imp := filterImports(getImports(pkg, true), f)
		for _, i := range imp {
			cpPkg, _ := getPackage(ctx, cwd, i)
			if len(cpPkg.ImportPath) == 0 {
				return fmt.Errorf("no import path for %s", i)
			} else if len(cpPkg.Name) == 0 || len(cpPkg.Dir) == 0 {
				// Skip packages without a package name, most
				// likely they have not been retrieved.
				fmt.Printf("skipping %s, was not found\n",
					cpPkg.ImportPath)
				continue
			}
			cpDst := filepath.Join(dst, cpPkg.Name)
			if hasString(dsts, cpDst) {
				hasDups = true
				cps = append(cps,
					cpJob{pkg.Dir, cpPkg.ImportPath, cpDst, false})
			} else if cpImportPath, err := getImportPath(cwd, cpDst); err != nil {
				return err
			} else {
				updates = append(updates,
					updateJob{pkg.Dir, cpPkg.ImportPath, cpImportPath, false})
			}
			dsts = append(dsts, cpDst)
			dups[cpPkg.Name] = appendUnique(dups[cpPkg.Name], cpPkg.ImportPath)
		}
		return nil
	}
	if recurse {
		if err := recursePackages(ctx, cwd, process); err != nil {
			return err
		}
	} else if pkg, err := getPackage(ctx, cwd, cwd); err != nil {
		return err
	} else if err := process(pkg, nil); err != nil {
		return err
	}
	// Report back if there is any packages with the same package name.
	if hasDups {
		return errDupe(dups)
	}
	// Run copy command on each import.
	for _, cj := range cps {
		printBold(fmt.Sprintf("%s => %s", cj.src, cj.dst))
		if err := cp(ctx, cj.cwd, cj.src, cj.dst, cj.recurse); err != nil {
			return err
		}
	}
	// Run update commands on other packages that need updating.
	for _, uj := range updates {
		fmt.Println("update imports in :", uj.src)
		if err := update(ctx, uj.src, uj.from, uj.to, uj.recurse); err != nil {
			return err
		}
	}
	return nil
}

// errDupe is returned when there are duplicate package names when trying to
// run the init command.
// Underlying map is package name to a slice of import paths.
type errDupe map[string][]string

func (d errDupe) Error() string {
	errs := make([]string, 0)
	for name, paths := range d {
		if len(paths) > 1 {
			errs = append(errs, fmt.Sprintf("%s found at %s",
				name, strings.Join(paths, ", ")))
		}
	}
	return fmt.Sprintf("duplicate packages names found :\n%s",
		strings.Join(errs, "\n"))

}

// cpJob holds a pending call to cp.
type cpJob struct {
	cwd, src, dst string
	recurse       bool
}

// updateJob holds a pending call to update.
type updateJob struct {
	src, from, to string
	recurse       bool
}
<commit_msg>Fixed init package filter.<commit_after>package main

import (
	"fmt"
	"go/build"
	"path/filepath"
	"strings"
)

// initc runs the init subcommand, copies all the external packages for the
// package in the current working directory into the specified directory.
// External packages are packages not located in the standard library, a parent
// directory, or a subdirectory.
// Files are placed in subdirectories based on their package name, if there are
// conflicts the command will fail with a message, those specific packages will
// need to be copied with the cp command, before running init again.
// Includes dependencies from packages located in subdirectories based on the
// `recurse` parameter.
func initc(ctx *build.Context, cwd, dst string, recurse bool) error {
	dst, err := cwdAbs(cwd, dst)
	if err != nil {
		return err
	}
	cwdPkg, _ := getPackage(ctx, cwd, cwd)
	if len(cwdPkg.ImportPath) == 0 {
		return fmt.Errorf("no import path for package in current directory")
	}
	// Filter for the imports to copy into dst directory
	f := func(i string) bool {
		switch {
		case isChildPackage(cwdPkg.ImportPath, i):
			return false // in a subdirectory
		case isChildPackage(i, cwdPkg.ImportPath):
			return false // in a parent diretory
		case isStandardPackage(ctx, cwd, i):
			return false
		}
		return true
	}
	dsts := make([]string, 0)         // list of destination directories
	cps := make([]cpJob, 0)           // list of pending cp calls
	updates := make([]updateJob, 0)   // list of pending update calls
	dups := make(map[string][]string) // package name to import paths
	hasDups := false
	process := func(pkg *build.Package, err error) error {
		imp := filterImports(getImports(pkg, true), f)
		for _, i := range imp {
			cpPkg, _ := getPackage(ctx, cwd, i)
			if len(cpPkg.ImportPath) == 0 {
				return fmt.Errorf("no import path for %s", i)
			} else if len(cpPkg.Name) == 0 || len(cpPkg.Dir) == 0 {
				// Skip packages without a package name, most
				// likely they have not been retreived.
				fmt.Printf("skipping %s, was not found\n",
					cpPkg.ImportPath)
				continue
			}
			cpDst := filepath.Join(dst, cpPkg.Name)
			if hasString(dsts, cpDst) {
				hasDups = true
				cps = append(cps,
					cpJob{pkg.Dir, cpPkg.ImportPath, cpDst, false})
			} else if cpImportPath, err := getImportPath(cwd, cpDst); err != nil {
				return err
			} else {
				updates = append(updates,
					updateJob{pkg.Dir, cpPkg.ImportPath, cpImportPath, false})
			}
			dsts = append(dsts, cpDst)
			dups[cpPkg.Name] = appendUnique(dups[cpPkg.Name], cpPkg.ImportPath)
		}
		return nil
	}
	if recurse {
		if err := recursePackages(ctx, cwd, process); err != nil {
			return err
		}
	} else if err := process(cwdPkg, nil); err != nil {
		return err
	}
	// Report back if there is any packages with the same package name.
	if hasDups {
		return errDupe(dups)
	}
	// Run copy command on each import.
	for _, cj := range cps {
		printBold(fmt.Sprintf("%s => %s", cj.src, cj.dst))
		if err := cp(ctx, cj.cwd, cj.src, cj.dst, cj.recurse); err != nil {
			return err
		}
	}
	// Run update commands on other packages that need updating.
	for _, uj := range updates {
		fmt.Println("update imports in :", uj.src)
		if err := update(ctx, uj.src, uj.from, uj.to, uj.recurse); err != nil {
			return err
		}
	}
	return nil
}

// errDupe is returned when there are duplicate package names when trying to
// run the init command.
// Underlying map is package name to a slice of import paths.
type errDupe map[string][]string

func (d errDupe) Error() string {
	errs := make([]string, 0)
	for name, paths := range d {
		if len(paths) > 1 {
			errs = append(errs, fmt.Sprintf("%s found at %s",
				name, strings.Join(paths, ", ")))
		}
	}
	return fmt.Sprintf("duplicate packages names found :\n%s",
		strings.Join(errs, "\n"))

}

// cpJob holds a pending call to cp.
type cpJob struct {
	cwd, src, dst string
	recurse       bool
}

// updateJob holds a pending call to update.
type updateJob struct {
	src, from, to string
	recurse       bool
}
<|endoftext|>


<commit_before>package dynago

import (
	"encoding/json"
	//"log"
	"strconv"
)

const (
	SELECT_ALL        = "ALL_ATTRIBUTES"
	SELECT_PROJECTED  = "ALL_PROJECTED_ATTRIBUTES"
	SELECT_ATTRIBUTES = "SPECIFIC_ATTRIBUTES"
	SELECT_COUNT      = "COUNT"
)

var (
	RETURN_CONSUMED = map[bool]string{true: "TOTAL", false: "NONE"}
)

type ConsumedCapacityDescription struct {
	CapacityUnits float32
	TableName     string
}

type KeyValue struct {
	Key   AttributeDefinition
	Value interface{}
}

// Items are maps of name/value pairs
type Item map[string]interface{}

func (pi *Item) UnmarshalJSON(data []byte) error {
	var dbitem DBItem

	if err := json.Unmarshal(data, &dbitem); err != nil {
		return err
	}

	item := make(Item)

	for k, v := range dbitem {
		item[k] = DecodeValue(v)
	}

	*pi = item
	return nil
}

func AsNumber(v int) json.Number {
	return json.Number(strconv.Itoa(v))
}

//////////////////////////////////////////////////////////////////////////////
//
// GetItem
//

type GetItemRequest struct {
	TableName              string
	Key                    map[string]AttributeValue
	AttributesToGet        []string
	ConsistentRead         bool
	ReturnConsumedCapacity string
}

type GetItemResult struct {
	ConsumedCapacity ConsumedCapacityDescription

	Item DBItem
}

func (db *DBClient) GetItem(tableName string, hashKey *KeyValue, rangeKey *KeyValue, attributes []string, consistent bool, consumed bool) (map[string]interface{}, float32, error) {

	getReq := GetItemRequest{TableName: tableName, AttributesToGet: attributes, ConsistentRead: consistent, ReturnConsumedCapacity: RETURN_CONSUMED[consumed]}
	getReq.Key = EncodeAttribute(hashKey.Key, hashKey.Value)
	if rangeKey != nil {
		getReq.Key[rangeKey.Key.AttributeName] = EncodeAttributeValue(rangeKey.Key, rangeKey.Value)
	}

	var getRes GetItemResult

	if err := db.Query("GetItem", getReq).Decode(&getRes); err != nil {
		return nil, 0.0, err
	}

	if len(getRes.Item) == 0 {
		return nil, getRes.ConsumedCapacity.CapacityUnits, nil
	}

	return DecodeItem(getRes.Item), getRes.ConsumedCapacity.CapacityUnits, nil
}

//////////////////////////////////////////////////////////////////////////////
//
// Query
//

type QueryRequest struct {
	TableName              string
	AttributesToGet        []string `json:",omitempty"`
	ScanIndexForward       bool
	ExclusiveStartKey      AttributeNameValue   `json:",omitempty"`
	KeyConditions          map[string]Condition `json:",omitempty"`
	IndexName              string               `json:",omitempty"`
	Limit                  json.Number          `json:",omitempty"`
	Select                 string               `json:",omitempty"`
	ReturnConsumedCapacity string               `json:",omitempty"`

	table *TableInstance
}

type QueryResult struct {
	Items            []Item
	ConsumedCapacity ConsumedCapacityDescription
	LastEvaluatedKey AttributeNameValue
	Count            int
	ScannedCount     int
}

func QueryTable(table *TableInstance) *QueryRequest {
	return &QueryRequest{TableName: table.Name, ScanIndexForward: true, KeyConditions: make(map[string]Condition), table: table}
}

func Query(tableName string) *QueryRequest {
	return &QueryRequest{TableName: tableName, ScanIndexForward: true, KeyConditions: make(map[string]Condition)}
}

func (queryReq *QueryRequest) WithAttributes(attributes []string) *QueryRequest {
	queryReq.AttributesToGet = attributes
	return queryReq
}

func (queryReq *QueryRequest) WithStartKey(startKey AttributeNameValue) *QueryRequest {
	queryReq.ExclusiveStartKey = startKey
	return queryReq
}

func (queryReq *QueryRequest) WithIndex(indexName string) *QueryRequest {
	queryReq.IndexName = indexName
	return queryReq
}

func (queryReq *QueryRequest) WithCondition(attrName string, condition Condition) *QueryRequest {
	queryReq.KeyConditions[attrName] = condition
	return queryReq
}

func (queryReq *QueryRequest) WithAttrCondition(cond AttrCondition) *QueryRequest {
	for k, v := range cond {
		queryReq.KeyConditions[k] = v
	}

	return queryReq
}

func (queryReq *QueryRequest) WithLimit(limit int) *QueryRequest {
	queryReq.Limit = AsNumber(limit)
	return queryReq
}

func (queryReq *QueryRequest) WithSelect(selectValue string) *QueryRequest {
	queryReq.Select = selectValue
	return queryReq
}

func (queryReq *QueryRequest) WithConsumed(consumed bool) *QueryRequest {
	queryReq.ReturnConsumedCapacity = RETURN_CONSUMED[consumed]
	return queryReq
}

func (queryReq *QueryRequest) Exec(db *DBClient) ([]Item, AttributeNameValue, float32, error) {
	if db == nil && queryReq.table != nil {
		db = queryReq.table.DB
	}

	var queryRes QueryResult

	if err := db.Query("Query", queryReq).Decode(&queryRes); err != nil {
		return nil, nil, 0.0, err
	}

	return queryRes.Items, queryRes.LastEvaluatedKey, queryRes.ConsumedCapacity.CapacityUnits, nil
}

//////////////////////////////////////////////////////////////////////////////
//
// Scan
//

type ScanRequest struct {
	TableName              string
	AttributesToGet        []string
	ExclusiveStartKey      AttributeNameValue
	ScanFilter             map[string]Condition
	Limit                  json.Number `json:",omitempty"`
	Segment                json.Number `json:",omitempty"`
	TotalSegments          json.Number `json:",omitempty"`
	Select                 string      `json:",omitempty"`
	ReturnConsumedCapacity string      `json:",omitempty"`

	table *TableInstance
}

func ScanTable(table *TableInstance) *ScanRequest {
	return &ScanRequest{TableName: table.Name, table: table}
}

func Scan(tableName string) *ScanRequest {
	return &ScanRequest{TableName: tableName}
}

func (scanReq *ScanRequest) WithAttributes(attributes []string) *ScanRequest {
	scanReq.AttributesToGet = attributes
	return scanReq
}

func (scanReq *ScanRequest) WithStartKey(startKey AttributeNameValue) *ScanRequest {
	scanReq.ExclusiveStartKey = startKey
	return scanReq
}

func (scanReq *ScanRequest) WithFilter(attrName string, condition Condition) *ScanRequest {
	if scanReq.ScanFilter == nil {
		scanReq.ScanFilter = map[string]Condition{attrName: condition}
	} else {
		scanReq.ScanFilter[attrName] = condition
	}
	return scanReq
}

func (scanReq *ScanRequest) WithFilters(filters AttrCondition) *ScanRequest {
	scanReq.ScanFilter = filters
	return scanReq
}

func (scanReq *ScanRequest) WithLimit(limit int) *ScanRequest {
	scanReq.Limit = AsNumber(limit)
	return scanReq
}

func (scanReq *ScanRequest) WithSegment(segment, totalSegments int) *ScanRequest {
	scanReq.Segment = AsNumber(segment)
	scanReq.TotalSegments = AsNumber(totalSegments)
	return scanReq
}

func (scanReq *ScanRequest) WithSelect(selectValue string) *ScanRequest {
	scanReq.Select = selectValue
	return scanReq
}

func (scanReq *ScanRequest) WithConsumed(consumed bool) *ScanRequest {
	scanReq.ReturnConsumedCapacity = RETURN_CONSUMED[consumed]
	return scanReq
}

func (scanReq *ScanRequest) Exec(db *DBClient) ([]Item, AttributeNameValue, float32, error) {
	var scanRes QueryResult

	if err := db.Query("Scan", scanReq).Decode(&scanRes); err != nil {
		return nil, nil, 0.0, err
	}

	return scanRes.Items, scanRes.LastEvaluatedKey, scanRes.ConsumedCapacity.CapacityUnits, nil
}

func (scanReq *ScanRequest) Count(db *DBClient) (count int, scount int, consumed float32, err error) {
	var scanRes QueryResult

	req := *scanReq
	req.Select = SELECT_COUNT

	for {
		scanRes.LastEvaluatedKey = nil

		if err = db.Query("Scan", &req).Decode(&scanRes); err != nil {
			break
		}

		count += scanRes.Count
		scount += scanRes.ScannedCount
		consumed += scanRes.ConsumedCapacity.CapacityUnits

		if scanRes.LastEvaluatedKey == nil {
			break
		}

		req.ExclusiveStartKey = make(AttributeNameValue)
		for k, v := range scanRes.LastEvaluatedKey {
			req.ExclusiveStartKey[k] = v
		}
	}

	return
}
<commit_msg>Simplified the 0 vs omitempty thing (not sure this is more clear, but x=nil is now omitted while x=&zerovalue encode the 0 value<commit_after>package dynago

import (
	"encoding/json"
)

const (
	SELECT_ALL        = "ALL_ATTRIBUTES"
	SELECT_PROJECTED  = "ALL_PROJECTED_ATTRIBUTES"
	SELECT_ATTRIBUTES = "SPECIFIC_ATTRIBUTES"
	SELECT_COUNT      = "COUNT"
)

var (
	RETURN_CONSUMED = map[bool]string{true: "TOTAL", false: "NONE"}
)

type ConsumedCapacityDescription struct {
	CapacityUnits float32
	TableName     string
}

type KeyValue struct {
	Key   AttributeDefinition
	Value interface{}
}

// Items are maps of name/value pairs
type Item map[string]interface{}

func (pi *Item) UnmarshalJSON(data []byte) error {
	var dbitem DBItem

	if err := json.Unmarshal(data, &dbitem); err != nil {
		return err
	}

	item := make(Item)

	for k, v := range dbitem {
		item[k] = DecodeValue(v)
	}

	*pi = item
	return nil
}

//////////////////////////////////////////////////////////////////////////////
//
// GetItem
//

type GetItemRequest struct {
	TableName              string
	Key                    map[string]AttributeValue
	AttributesToGet        []string
	ConsistentRead         bool
	ReturnConsumedCapacity string
}

type GetItemResult struct {
	ConsumedCapacity ConsumedCapacityDescription

	Item DBItem
}

func (db *DBClient) GetItem(tableName string, hashKey *KeyValue, rangeKey *KeyValue, attributes []string, consistent bool, consumed bool) (map[string]interface{}, float32, error) {

	getReq := GetItemRequest{TableName: tableName, AttributesToGet: attributes, ConsistentRead: consistent, ReturnConsumedCapacity: RETURN_CONSUMED[consumed]}
	getReq.Key = EncodeAttribute(hashKey.Key, hashKey.Value)
	if rangeKey != nil {
		getReq.Key[rangeKey.Key.AttributeName] = EncodeAttributeValue(rangeKey.Key, rangeKey.Value)
	}

	var getRes GetItemResult

	if err := db.Query("GetItem", getReq).Decode(&getRes); err != nil {
		return nil, 0.0, err
	}

	if len(getRes.Item) == 0 {
		return nil, getRes.ConsumedCapacity.CapacityUnits, nil
	}

	return DecodeItem(getRes.Item), getRes.ConsumedCapacity.CapacityUnits, nil
}

//////////////////////////////////////////////////////////////////////////////
//
// Query
//

type QueryRequest struct {
	TableName              string
	AttributesToGet        []string `json:",omitempty"`
	ScanIndexForward       bool
	ExclusiveStartKey      AttributeNameValue   `json:",omitempty"`
	KeyConditions          map[string]Condition `json:",omitempty"`
	IndexName              string               `json:",omitempty"`
	Limit                  *int                 `json:",omitempty"`
	Select                 string               `json:",omitempty"`
	ReturnConsumedCapacity string               `json:",omitempty"`

	table *TableInstance
}

type QueryResult struct {
	Items            []Item
	ConsumedCapacity ConsumedCapacityDescription
	LastEvaluatedKey AttributeNameValue
	Count            int
	ScannedCount     int
}

func QueryTable(table *TableInstance) *QueryRequest {
	return &QueryRequest{TableName: table.Name, ScanIndexForward: true, KeyConditions: make(map[string]Condition), table: table}
}

func Query(tableName string) *QueryRequest {
	return &QueryRequest{TableName: tableName, ScanIndexForward: true, KeyConditions: make(map[string]Condition)}
}

func (queryReq *QueryRequest) WithAttributes(attributes []string) *QueryRequest {
	queryReq.AttributesToGet = attributes
	return queryReq
}

func (queryReq *QueryRequest) WithStartKey(startKey AttributeNameValue) *QueryRequest {
	queryReq.ExclusiveStartKey = startKey
	return queryReq
}

func (queryReq *QueryRequest) WithIndex(indexName string) *QueryRequest {
	queryReq.IndexName = indexName
	return queryReq
}

func (queryReq *QueryRequest) WithCondition(attrName string, condition Condition) *QueryRequest {
	queryReq.KeyConditions[attrName] = condition
	return queryReq
}

func (queryReq *QueryRequest) WithAttrCondition(cond AttrCondition) *QueryRequest {
	for k, v := range cond {
		queryReq.KeyConditions[k] = v
	}

	return queryReq
}

func (queryReq *QueryRequest) WithLimit(limit int) *QueryRequest {
	queryReq.Limit = &limit
	return queryReq
}

func (queryReq *QueryRequest) WithSelect(selectValue string) *QueryRequest {
	queryReq.Select = selectValue
	return queryReq
}

func (queryReq *QueryRequest) WithConsumed(consumed bool) *QueryRequest {
	queryReq.ReturnConsumedCapacity = RETURN_CONSUMED[consumed]
	return queryReq
}

func (queryReq *QueryRequest) Exec(db *DBClient) ([]Item, AttributeNameValue, float32, error) {
	if db == nil && queryReq.table != nil {
		db = queryReq.table.DB
	}

	var queryRes QueryResult

	if err := db.Query("Query", queryReq).Decode(&queryRes); err != nil {
		return nil, nil, 0.0, err
	}

	return queryRes.Items, queryRes.LastEvaluatedKey, queryRes.ConsumedCapacity.CapacityUnits, nil
}

//////////////////////////////////////////////////////////////////////////////
//
// Scan
//

type ScanRequest struct {
	TableName              string
	AttributesToGet        []string
	ExclusiveStartKey      AttributeNameValue
	ScanFilter             map[string]Condition
	Limit                  *int   `json:",omitempty"`
	Segment                *int   `json:",omitempty"`
	TotalSegments          *int   `json:",omitempty"`
	Select                 string `json:",omitempty"`
	ReturnConsumedCapacity string `json:",omitempty"`

	table *TableInstance
}

func ScanTable(table *TableInstance) *ScanRequest {
	return &ScanRequest{TableName: table.Name, table: table}
}

func Scan(tableName string) *ScanRequest {
	return &ScanRequest{TableName: tableName}
}

func (scanReq *ScanRequest) WithAttributes(attributes []string) *ScanRequest {
	scanReq.AttributesToGet = attributes
	return scanReq
}

func (scanReq *ScanRequest) WithStartKey(startKey AttributeNameValue) *ScanRequest {
	scanReq.ExclusiveStartKey = startKey
	return scanReq
}

func (scanReq *ScanRequest) WithFilter(attrName string, condition Condition) *ScanRequest {
	if scanReq.ScanFilter == nil {
		scanReq.ScanFilter = map[string]Condition{attrName: condition}
	} else {
		scanReq.ScanFilter[attrName] = condition
	}
	return scanReq
}

func (scanReq *ScanRequest) WithFilters(filters AttrCondition) *ScanRequest {
	scanReq.ScanFilter = filters
	return scanReq
}

func (scanReq *ScanRequest) WithLimit(limit int) *ScanRequest {
	scanReq.Limit = &limit
	return scanReq
}

func (scanReq *ScanRequest) WithSegment(segment, totalSegments int) *ScanRequest {
	scanReq.Segment = &segment
	scanReq.TotalSegments = &totalSegments
	return scanReq
}

func (scanReq *ScanRequest) WithSelect(selectValue string) *ScanRequest {
	scanReq.Select = selectValue
	return scanReq
}

func (scanReq *ScanRequest) WithConsumed(consumed bool) *ScanRequest {
	scanReq.ReturnConsumedCapacity = RETURN_CONSUMED[consumed]
	return scanReq
}

func (scanReq *ScanRequest) Exec(db *DBClient) ([]Item, AttributeNameValue, float32, error) {
	var scanRes QueryResult

	if err := db.Query("Scan", scanReq).Decode(&scanRes); err != nil {
		return nil, nil, 0.0, err
	}

	return scanRes.Items, scanRes.LastEvaluatedKey, scanRes.ConsumedCapacity.CapacityUnits, nil
}

func (scanReq *ScanRequest) Count(db *DBClient) (count int, scount int, consumed float32, err error) {
	var scanRes QueryResult

	req := *scanReq
	req.Select = SELECT_COUNT

	for {
		scanRes.LastEvaluatedKey = nil

		if err = db.Query("Scan", &req).Decode(&scanRes); err != nil {
			break
		}

		count += scanRes.Count
		scount += scanRes.ScannedCount
		consumed += scanRes.ConsumedCapacity.CapacityUnits

		if scanRes.LastEvaluatedKey == nil {
			break
		}

		req.ExclusiveStartKey = make(AttributeNameValue)
		for k, v := range scanRes.LastEvaluatedKey {
			req.ExclusiveStartKey[k] = v
		}
	}

	return
}
<|endoftext|>


<commit_before>// Package kace provides common case conversion functions which take into
// consideration common initialisms.
package kace

import (
	"unicode"
)

// Camel returns a camel cased string.
func Camel(s string, ucFirst bool) string {
	tmpBuf := make([]rune, 0, ciMaxLen)
	buf := make([]rune, 0, len(s))

	for i := 0; i < len(s); i++ {
		tmpBuf = tmpBuf[:0]
		if unicode.IsLetter(rune(s[i])) {
			if i == 0 || !unicode.IsLetter(rune(s[i-1])) {
				for n := i; n < len(s) && n-i < ciMaxLen; n++ {
					tmpBuf = append(tmpBuf, unicode.ToUpper(rune(s[n])))
					if n < len(s)-1 && !unicode.IsLetter(rune(s[n+1])) && !unicode.IsDigit(rune(s[n+1])) {
						break
					}
				}
				if ((i == 0 && ucFirst) || i > 0) && ciTrie.find(tmpBuf) {
					buf = append(buf, tmpBuf...)
					i += len(tmpBuf)
					continue
				}
			}

			if i == 0 && ucFirst || i > 0 && !unicode.IsLetter(rune(s[i-1])) {
				buf = append(buf, unicode.ToUpper(rune(s[i])))
			} else {
				buf = append(buf, rune(s[i]))
			}
		}

		if unicode.IsDigit(rune(s[i])) {
			buf = append(buf, rune(s[i]))
		}
	}
	return string(buf)
}

// Snake returns a snake cased string.
func Snake(s string) string {
	return delimitedCase(s, '_', false)
}

// SnakeUpper returns a snake cased string with all upper case letters.
func SnakeUpper(s string) string {
	return delimitedCase(s, '_', true)
}

// Kebab returns a kebab cased string.
func Kebab(s string) string {
	return delimitedCase(s, '-', false)
}

// KebabUpper returns a kebab cased string with all upper case letters.
func KebabUpper(s string) string {
	return delimitedCase(s, '-', true)
}

// Snake returns a snake cased string.
func delimitedCase(s string, delim rune, upper bool) string {
	buf := make([]rune, 0, len(s)*2)

	for i := len(s); i > 0; i-- {
		if unicode.IsLetter(rune(s[i-1])) {
			if i < len(s) && unicode.IsUpper(rune(s[i])) {
				if i > 1 && unicode.IsLower(rune(s[i-1])) || i < len(s)-2 && unicode.IsLower(rune(s[i+1])) {
					buf = append(buf, delim)
				}
			}
			if upper {
				buf = append(buf, unicode.ToUpper(rune(s[i-1])))
			} else {
				buf = append(buf, unicode.ToLower(rune(s[i-1])))
			}
		} else if unicode.IsDigit(rune(s[i-1])) {
			if i == len(s) || i == 1 || unicode.IsDigit(rune(s[i])) {
				buf = append(buf, rune(s[i-1]))
			} else {
				buf = append(buf, delim, rune(s[i-1]))
			}
		} else {
			if i == len(s) {
				continue
			}

			buf = append(buf, delim)
		}
	}

	return string(reverse(buf))
}

func reverse(s []rune) []rune {
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
		s[i], s[j] = s[j], s[i]
	}

	return s
}

func commonInitialismsMaxLen() int {
	l := 0
	for k := range ci {
		if len(k) > l {
			l = len(k)
		}
	}

	return l
}

func commonInitialismsTrie() *node {
	t := newNode()
	for k := range ci {
		t.add([]rune(k))
	}

	return t
}

var (
	// github.com/golang/lint/blob/master/lint.go
	ci = map[string]bool{
		"ACL":   true,
		"API":   true,
		"ASCII": true,
		"CPU":   true,
		"CSS":   true,
		"DNS":   true,
		"EOF":   true,
		"GUID":  true,
		"HTML":  true,
		"HTTP":  true,
		"HTTPS": true,
		"ID":    true,
		"IP":    true,
		"JSON":  true,
		"LHS":   true,
		"QPS":   true,
		"RAM":   true,
		"RHS":   true,
		"RPC":   true,
		"SLA":   true,
		"SMTP":  true,
		"SQL":   true,
		"SSH":   true,
		"TCP":   true,
		"TLS":   true,
		"TTL":   true,
		"UDP":   true,
		"UI":    true,
		"UID":   true,
		"UUID":  true,
		"URI":   true,
		"URL":   true,
		"UTF8":  true,
		"VM":    true,
		"XML":   true,
		"XMPP":  true,
		"XSRF":  true,
		"XSS":   true,
	}

	ciMaxLen = commonInitialismsMaxLen()
	ciTrie   = commonInitialismsTrie()
)
<commit_msg>Update newNode usage.<commit_after>// Package kace provides common case conversion functions which take into
// consideration common initialisms.
package kace

import (
	"unicode"
)

// Camel returns a camel cased string.
func Camel(s string, ucFirst bool) string {
	tmpBuf := make([]rune, 0, ciMaxLen)
	buf := make([]rune, 0, len(s))

	for i := 0; i < len(s); i++ {
		tmpBuf = tmpBuf[:0]
		if unicode.IsLetter(rune(s[i])) {
			if i == 0 || !unicode.IsLetter(rune(s[i-1])) {
				for n := i; n < len(s) && n-i < ciMaxLen; n++ {
					tmpBuf = append(tmpBuf, unicode.ToUpper(rune(s[n])))
					if n < len(s)-1 && !unicode.IsLetter(rune(s[n+1])) && !unicode.IsDigit(rune(s[n+1])) {
						break
					}
				}
				if ((i == 0 && ucFirst) || i > 0) && ciTrie.find(tmpBuf) {
					buf = append(buf, tmpBuf...)
					i += len(tmpBuf)
					continue
				}
			}

			if i == 0 && ucFirst || i > 0 && !unicode.IsLetter(rune(s[i-1])) {
				buf = append(buf, unicode.ToUpper(rune(s[i])))
			} else {
				buf = append(buf, rune(s[i]))
			}
		}

		if unicode.IsDigit(rune(s[i])) {
			buf = append(buf, rune(s[i]))
		}
	}
	return string(buf)
}

// Snake returns a snake cased string.
func Snake(s string) string {
	return delimitedCase(s, '_', false)
}

// SnakeUpper returns a snake cased string with all upper case letters.
func SnakeUpper(s string) string {
	return delimitedCase(s, '_', true)
}

// Kebab returns a kebab cased string.
func Kebab(s string) string {
	return delimitedCase(s, '-', false)
}

// KebabUpper returns a kebab cased string with all upper case letters.
func KebabUpper(s string) string {
	return delimitedCase(s, '-', true)
}

// Snake returns a snake cased string.
func delimitedCase(s string, delim rune, upper bool) string {
	buf := make([]rune, 0, len(s)*2)

	for i := len(s); i > 0; i-- {
		if unicode.IsLetter(rune(s[i-1])) {
			if i < len(s) && unicode.IsUpper(rune(s[i])) {
				if i > 1 && unicode.IsLower(rune(s[i-1])) || i < len(s)-2 && unicode.IsLower(rune(s[i+1])) {
					buf = append(buf, delim)
				}
			}
			if upper {
				buf = append(buf, unicode.ToUpper(rune(s[i-1])))
			} else {
				buf = append(buf, unicode.ToLower(rune(s[i-1])))
			}
		} else if unicode.IsDigit(rune(s[i-1])) {
			if i == len(s) || i == 1 || unicode.IsDigit(rune(s[i])) {
				buf = append(buf, rune(s[i-1]))
			} else {
				buf = append(buf, delim, rune(s[i-1]))
			}
		} else {
			if i == len(s) {
				continue
			}

			buf = append(buf, delim)
		}
	}

	return string(reverse(buf))
}

func reverse(s []rune) []rune {
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
		s[i], s[j] = s[j], s[i]
	}

	return s
}

func commonInitialismsMaxLen() int {
	l := 0
	for k := range ci {
		if len(k) > l {
			l = len(k)
		}
	}

	return l
}

func commonInitialismsTrie() *node {
	t := newNode(0, false)
	for k := range ci {
		t.add([]rune(k))
	}

	return t
}

var (
	// github.com/golang/lint/blob/master/lint.go
	ci = map[string]bool{
		"ACL":   true,
		"API":   true,
		"ASCII": true,
		"CPU":   true,
		"CSS":   true,
		"DNS":   true,
		"EOF":   true,
		"GUID":  true,
		"HTML":  true,
		"HTTP":  true,
		"HTTPS": true,
		"ID":    true,
		"IP":    true,
		"JSON":  true,
		"LHS":   true,
		"QPS":   true,
		"RAM":   true,
		"RHS":   true,
		"RPC":   true,
		"SLA":   true,
		"SMTP":  true,
		"SQL":   true,
		"SSH":   true,
		"TCP":   true,
		"TLS":   true,
		"TTL":   true,
		"UDP":   true,
		"UI":    true,
		"UID":   true,
		"UUID":  true,
		"URI":   true,
		"URL":   true,
		"UTF8":  true,
		"VM":    true,
		"XML":   true,
		"XMPP":  true,
		"XSRF":  true,
		"XSS":   true,
	}

	ciMaxLen = commonInitialismsMaxLen()
	ciTrie   = commonInitialismsTrie()
)
<|endoftext|>


<commit_before>package golist

import (
	"errors"
	"fmt"
	"reflect"
	"sync"
)

type List struct {
	data   []interface{}
	locker sync.Mutex
}

var (
	EmptyListError  = "%v operation from empty list"
	OutOfRangeError = "%s index out of range"
)

// Returns a new List
func New(items ...interface{}) List {

	list := List{data: []interface{}{}}

	if len(items) > 0 {
		list.Append(items...)
	}

	return list
}

// Adds an item to the end of the list data
func (l *List) Append(items ...interface{}) {

	for _, value := range items {
		l.data = append(l.data, value)
	}

}

// Extend the list by appending all the items in te given list.
func (l *List) Extend(target_list List) {

	for _, value := range target_list.data {
		l.data = append(l.data, value)
	}

}

// Returns the length of the list
func (l *List) Len() int {
	return len(l.data)
}

// Insert an item at a given position.
// The first argument is the index of the element before which to insert
func (l *List) Insert(index int, value interface{}) {

	// Resize list to size(list) + 1 to get free space for new element.
	size := l.Len()

	l.Append(value)

	if size+1 >= index {

		for i := size - 1; i >= 0; i-- {

			if index == i {
				l.data[i+1] = l.data[i]
				l.data[index] = value
				break
			} else {
				l.data[i+1] = l.data[i]
			}

		}
	}
}

// Remove the first item from the list whose value is x.
// Returns an error if there is no such item exists.
func (l *List) Remove(value interface{}) error {

	error_text := fmt.Sprintf("'%v' is not in list", value)

	for index, data_value := range l.data {
		if data_value == value {
			l.data = append(l.data[:index], l.data[index+1:]...)
			return nil
		}
	}

	return errors.New(error_text)

}

// Remove the index at the given position in the list, and return it.
// If no index is specified, removes and returns the last item in the list.
func (l *List) Pop(index ...interface{}) (interface{}, error) {

	list_size := l.Len()

	if list_size == 0 {
		return nil, errors.New(fmt.Sprintf(EmptyListError, "Pop"))
	}

	var value interface{}
	var delete_index int

	if len(index) == 0 {

		value = l.data[list_size-1]

		delete_index = list_size - 1

	} else {

		_index := reflect.ValueOf(index[0]).Int()

		if int(_index) > list_size-1 {
			return nil, errors.New(fmt.Sprintf(OutOfRangeError, "Pop"))
		}

		value = l.data[_index]

		delete_index = int(_index)

	}

	error := l.Delete(delete_index)

	if error != nil {
		return nil, error
	}

	return value, nil

}

// Delete the item at the given position in the list.
func (l *List) Delete(index int) error {

	if l.Len() == 0 {
		return errors.New(fmt.Sprintf(EmptyListError, "Delete"))
	}

	l.data = append(l.data[:index], l.data[index+1:]...)

	return nil

}

// Returns the index in the list of the first item whose value is x. It is an error if there is no such item.
func (l *List) Index(value interface{}) (int, error) {

	list_size := l.Len()

	if list_size == 0 {
		return 0, errors.New(fmt.Sprintf(EmptyListError, "Index"))
	}

	for index, data_value := range l.data {
		if data_value == value {
			return index, nil
		}
	}

	error_text := fmt.Sprintf("'%v' is not in list", value)

	return 0, errors.New(error_text)

}

// Return the number of times x appears in the list.
func (l *List) Count(value interface{}) int {
	total_count := 0

	for _, data_value := range l.data {
		if data_value == value {
			total_count++
		}
	}

	return total_count

}

// Reverse the elements of the list, in place.
func (l *List) Reverse() {

	list_size := l.Len()

	if list_size > 0 {
		top_index := list_size - 1
		for index := 0; index < (top_index/2)+1; index++ {
			l.data[index], l.data[top_index-index] = l.data[top_index-index], l.data[index]
		}
	}
}
<commit_msg>operations are now thread-safe.<commit_after>package golist

import (
	"errors"
	"fmt"
	"reflect"
	"sync"
)

type List struct {
	data   []interface{}
	locker sync.Mutex
}

var (
	EmptyListError  = "%v operation from empty list"
	OutOfRangeError = "%s index out of range"
)

// Returns a new List
func New(items ...interface{}) List {

	list := List{data: []interface{}{}}

	if len(items) > 0 {
		list.Append(items...)
	}

	return list
}

// Adds an item to the end of the list data
func (l *List) Append(items ...interface{}) {
	l.locker.Lock()
	l.data = append(l.data, items...)
	l.locker.Unlock()

}

// Extend the list by appending all the items in te given list.
func (l *List) Extend(target_list List) {
	l.locker.Lock()
	for _, value := range target_list.data {
		l.data = append(l.data, value)
	}
	l.locker.Unlock()

}

// Returns the length of the list
func (l *List) Len() int {
	return len(l.data)
}

// Insert an item at a given position.
// The first argument is the index of the element before which to insert
func (l *List) Insert(index int, value interface{}) {

	// Resize list to size(list) + 1 to get free space for new element.
	l.locker.Lock()
	size := l.Len()
	l.locker.Unlock()
	l.Append(value)

	if size+1 >= index {

		for i := size - 1; i >= 0; i-- {

			if index == i {
				l.locker.Lock()
				l.data[i+1] = l.data[i]
				l.data[index] = value
				l.locker.Unlock()
				break
			} else {
				l.locker.Lock()
				l.data[i+1] = l.data[i]
				l.locker.Unlock()
			}

		}
	}
}

// Remove the first item from the list whose value is x.
// Returns an error if there is no such item exists.
func (l *List) Remove(value interface{}) error {

	error_text := fmt.Sprintf("'%v' is not in list", value)
	for index, data_value := range l.data {
		if data_value == value {
			l.locker.Lock()
			l.data = append(l.data[:index], l.data[index+1:]...)
			l.locker.Unlock()
			return nil
		}
	}

	return errors.New(error_text)

}

// Remove the index at the given position in the list, and return it.
// If no index is specified, removes and returns the last item in the list.
func (l *List) Pop(index ...interface{}) (interface{}, error) {

	l.locker.Lock()
	list_size := l.Len()
	l.locker.Unlock()

	if list_size == 0 {
		return nil, errors.New(fmt.Sprintf(EmptyListError, "Pop"))
	}

	var value interface{}
	var delete_index int

	if len(index) == 0 {

		l.locker.Lock()
		value = l.data[list_size-1]

		delete_index = list_size - 1
		l.locker.Unlock()

	} else {
		l.locker.Lock()
		_index := reflect.ValueOf(index[0]).Int()

		if int(_index) > list_size-1 {
			return nil, errors.New(fmt.Sprintf(OutOfRangeError, "Pop"))
		}

		value = l.data[_index]

		delete_index = int(_index)
		l.locker.Unlock()

	}

	error := l.Delete(delete_index)

	if error != nil {
		return nil, error
	}

	return value, nil

}

// Delete the item at the given position in the list.
func (l *List) Delete(index int) error {

	list_size := l.Len()

	if list_size == 0 {
		return errors.New(fmt.Sprintf(EmptyListError, "Delete"))
	}

	if index > list_size-1 {
		return errors.New(fmt.Sprintf(OutOfRangeError, "Delete"))
	}

	l.locker.Lock()
	l.data = append(l.data[:index], l.data[index+1:]...)
	l.locker.Unlock()
	return nil

}

// Returns the index in the list of the first item whose value is x. It is an error if there is no such item.
func (l *List) Index(value interface{}) (int, error) {

	list_size := l.Len()

	if list_size == 0 {
		return 0, errors.New(fmt.Sprintf(EmptyListError, "Index"))
	}

	for index, data_value := range l.data {
		if data_value == value {
			return index, nil
		}
	}

	error_text := fmt.Sprintf("'%v' is not in list", value)

	return 0, errors.New(error_text)

}

// Return the number of times x appears in the list.
func (l *List) Count(value interface{}) int {
	total_count := 0

	l.locker.Lock()

	for _, data_value := range l.data {
		if data_value == value {
			total_count++
		}
	}

	l.locker.Unlock()

	return total_count

}

// Reverse the elements of the list, in place.
func (l *List) Reverse() {

	l.locker.Lock()
	list_size := l.Len()
	l.locker.Unlock()

	if list_size > 0 {
		top_index := list_size - 1
		l.locker.Lock()
		for index := 0; index < (top_index/2)+1; index++ {
			l.locker.Lock()
			l.data[index], l.data[top_index-index] = l.data[top_index-index], l.data[index]
			l.locker.Unlock()
		}
		l.locker.Unlock()

	}

}
<|endoftext|>


<commit_before>package collection

import (
	"bytes"
	"fmt"
	"sync"
)

// List is a dynamically sized list akin to List in the .NET world,
// ArrayList in the Java world, or vector in the C++ world.
type List struct {
	underlyer []interface{}
	key       sync.RWMutex
}

// NewList creates a new list which contains the elements provided.
func NewList(entries ...interface{}) *List {
	return &List{
		underlyer: entries,
	}
}

// Add appends an entry to the logical end of the List.
func (l *List) Add(entries ...interface{}) {
	l.key.Lock()
	defer l.key.Unlock()
	l.underlyer = append(l.underlyer, entries...)
}

// AddAt injects values beginning at `pos`. If multiple values
// are provided in `entries` they are placed in the same order
// they are provided.
func (l *List) AddAt(pos uint, entries ...interface{}) {
	l.key.Lock()
	defer l.key.Unlock()

	l.underlyer = append(l.underlyer[:pos], append(entries, l.underlyer[pos:]...)...)
}

// Enumerate lists each element present in the collection
func (l *List) Enumerate() Enumerator {
	retval := make(chan interface{})

	go func() {
		l.key.RLock()
		defer l.key.RUnlock()

		for _, entry := range l.underlyer {
			retval <- entry
		}
	}()

	return retval
}

// Get retreives the value stored in a particular position of the list.
// If no item exists at the given position, the second parameter will be
// returned as false.
func (l *List) Get(pos uint) (interface{}, bool) {
	l.key.RLock()
	defer l.key.RUnlock()

	if pos > uint(len(l.underlyer)) {
		return nil, false
	}
	return l.underlyer[pos], true
}

// IsEmpty tests to see if this List has any elements present.
func (l *List) IsEmpty() bool {
	l.key.RLock()
	defer l.key.RUnlock()
	return 0 == len(l.underlyer)
}

// Length returns the number of elements in the List.
func (l *List) Length() uint {
	l.key.RLock()
	defer l.key.RUnlock()
	return uint(len(l.underlyer))
}

// Remove retreives a value from this List and shifts all other values.
func (l *List) Remove(pos uint) (interface{}, bool) {
	l.key.Lock()
	defer l.key.Unlock()

	if pos > uint(len(l.underlyer)) {
		return nil, false
	}
	retval := l.underlyer[pos]
	l.underlyer = append(l.underlyer[:pos], l.underlyer[pos+1:]...)
	return retval, true
}

// Set updates the value stored at a given position in the List.
func (l *List) Set(pos uint, val interface{}) bool {
	l.key.Lock()
	defer l.key.Unlock()
	var retval bool
	count := uint(len(l.underlyer))
	if pos > count {
		retval = false
	} else {
		l.underlyer[pos] = val
		retval = true
	}
	return retval
}

// String generates a textual representation of the List for the sake of debugging.
func (l *List) String() string {
	l.key.RLock()
	defer l.key.RUnlock()

	builder := bytes.NewBufferString("[")

	for i, entry := range l.underlyer {
		if i >= 15 {
			builder.WriteString("... ")
			break
		}
		builder.WriteString(fmt.Sprintf("%v ", entry))
	}
	builder.Truncate(builder.Len() - 1)
	builder.WriteRune(']')
	return builder.String()
}

// Swap switches the values that are stored at positions `x` and `y`
func (l *List) Swap(x, y uint) bool {
	l.key.Lock()
	defer l.key.Unlock()
	return l.swap(x, y)
}

func (l *List) swap(x, y uint) bool {
	count := uint(len(l.underlyer))
	if x < count && y < count {
		temp := l.underlyer[x]
		l.underlyer[x] = l.underlyer[y]
		l.underlyer[y] = temp
		return true
	}
	return false
}
<commit_msg>Fixing bug preventing Lists from enumerating.<commit_after>package collection

import (
	"bytes"
	"fmt"
	"sync"
)

// List is a dynamically sized list akin to List in the .NET world,
// ArrayList in the Java world, or vector in the C++ world.
type List struct {
	underlyer []interface{}
	key       sync.RWMutex
}

// NewList creates a new list which contains the elements provided.
func NewList(entries ...interface{}) *List {
	return &List{
		underlyer: entries,
	}
}

// Add appends an entry to the logical end of the List.
func (l *List) Add(entries ...interface{}) {
	l.key.Lock()
	defer l.key.Unlock()
	l.underlyer = append(l.underlyer, entries...)
}

// AddAt injects values beginning at `pos`. If multiple values
// are provided in `entries` they are placed in the same order
// they are provided.
func (l *List) AddAt(pos uint, entries ...interface{}) {
	l.key.Lock()
	defer l.key.Unlock()

	l.underlyer = append(l.underlyer[:pos], append(entries, l.underlyer[pos:]...)...)
}

// Enumerate lists each element present in the collection
func (l *List) Enumerate() Enumerator {
	retval := make(chan interface{})

	go func() {
		l.key.RLock()
		defer l.key.RUnlock()
		defer close(retval)

		for _, entry := range l.underlyer {
			retval <- entry
		}
	}()

	return retval
}

// Get retreives the value stored in a particular position of the list.
// If no item exists at the given position, the second parameter will be
// returned as false.
func (l *List) Get(pos uint) (interface{}, bool) {
	l.key.RLock()
	defer l.key.RUnlock()

	if pos > uint(len(l.underlyer)) {
		return nil, false
	}
	return l.underlyer[pos], true
}

// IsEmpty tests to see if this List has any elements present.
func (l *List) IsEmpty() bool {
	l.key.RLock()
	defer l.key.RUnlock()
	return 0 == len(l.underlyer)
}

// Length returns the number of elements in the List.
func (l *List) Length() uint {
	l.key.RLock()
	defer l.key.RUnlock()
	return uint(len(l.underlyer))
}

// Remove retreives a value from this List and shifts all other values.
func (l *List) Remove(pos uint) (interface{}, bool) {
	l.key.Lock()
	defer l.key.Unlock()

	if pos > uint(len(l.underlyer)) {
		return nil, false
	}
	retval := l.underlyer[pos]
	l.underlyer = append(l.underlyer[:pos], l.underlyer[pos+1:]...)
	return retval, true
}

// Set updates the value stored at a given position in the List.
func (l *List) Set(pos uint, val interface{}) bool {
	l.key.Lock()
	defer l.key.Unlock()
	var retval bool
	count := uint(len(l.underlyer))
	if pos > count {
		retval = false
	} else {
		l.underlyer[pos] = val
		retval = true
	}
	return retval
}

// String generates a textual representation of the List for the sake of debugging.
func (l *List) String() string {
	l.key.RLock()
	defer l.key.RUnlock()

	builder := bytes.NewBufferString("[")

	for i, entry := range l.underlyer {
		if i >= 15 {
			builder.WriteString("... ")
			break
		}
		builder.WriteString(fmt.Sprintf("%v ", entry))
	}
	builder.Truncate(builder.Len() - 1)
	builder.WriteRune(']')
	return builder.String()
}

// Swap switches the values that are stored at positions `x` and `y`
func (l *List) Swap(x, y uint) bool {
	l.key.Lock()
	defer l.key.Unlock()
	return l.swap(x, y)
}

func (l *List) swap(x, y uint) bool {
	count := uint(len(l.underlyer))
	if x < count && y < count {
		temp := l.underlyer[x]
		l.underlyer[x] = l.underlyer[y]
		l.underlyer[y] = temp
		return true
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"syscall"
	"text/tabwriter"
	"time"

	"github.com/opencontainers/runc/libcontainer"
	"github.com/opencontainers/runc/libcontainer/user"
	"github.com/opencontainers/runc/libcontainer/utils"
	"github.com/urfave/cli"
)

const formatOptions = `table or json`

// containerState represents the platform agnostic pieces relating to a
// running container's status and state
type containerState struct {
	// Version is the OCI version for the container
	Version string `json:"ociVersion"`
	// ID is the container ID
	ID string `json:"id"`
	// InitProcessPid is the init process id in the parent namespace
	InitProcessPid int `json:"pid"`
	// Status is the current status of the container, running, paused, ...
	Status string `json:"status"`
	// Bundle is the path on the filesystem to the bundle
	Bundle string `json:"bundle"`
	// Rootfs is a path to a directory containing the container's root filesystem.
	Rootfs string `json:"rootfs"`
	// Created is the unix timestamp for the creation time of the container in UTC
	Created time.Time `json:"created"`
	// Annotations is the user defined annotations added to the config.
	Annotations map[string]string `json:"annotations,omitempty"`
	// The owner of the state directory (the owner of the container).
	Owner string `json:"owner"`
}

var listCommand = cli.Command{
	Name:  "list",
	Usage: "lists containers started by runc with the given root",
	ArgsUsage: `

Where the given root is specified via the global option "--root"
(default: "/run/runc").

EXAMPLE 1:
To list containers created via the default "--root":
       # runc list

EXAMPLE 2:
To list containers created using a non-default value for "--root":
       # runc --root value list`,
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "format, f",
			Value: "table",
			Usage: `select one of: ` + formatOptions,
		},
		cli.BoolFlag{
			Name:  "quiet, q",
			Usage: "display only container IDs",
		},
	},
	Action: func(context *cli.Context) error {
		if err := checkArgs(context, 0, exactArgs); err != nil {
			return err
		}
		s, err := getContainers(context)
		if err != nil {
			return err
		}

		if context.Bool("quiet") {
			for _, item := range s {
				fmt.Println(item.ID)
			}
			return nil
		}

		switch context.String("format") {
		case "table":
			w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0)
			fmt.Fprint(w, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\tOWNER\n")
			for _, item := range s {
				fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\n",
					item.ID,
					item.InitProcessPid,
					item.Status,
					item.Bundle,
					item.Created.Format(time.RFC3339Nano),
					item.Owner)
			}
			if err := w.Flush(); err != nil {
				return err
			}
		case "json":
			if err := json.NewEncoder(os.Stdout).Encode(s); err != nil {
				return err
			}
		default:
			return errors.New("invalid format option")
		}
		return nil
	},
}

func getContainers(context *cli.Context) ([]containerState, error) {
	factory, err := loadFactory(context)
	if err != nil {
		return nil, err
	}
	root := context.GlobalString("root")
	list, err := os.ReadDir(root)
	if err != nil {
		return nil, err
	}

	var s []containerState
	for _, item := range list {
		if !item.IsDir() {
			continue
		}
		st, err := item.Info()
		if err != nil {
			if errors.Is(err, os.ErrNotExist) {
				// Possible race with runc delete.
				continue
			}
			return nil, err
		}
		// This cast is safe on Linux.
		uid := st.Sys().(*syscall.Stat_t).Uid
		owner, err := user.LookupUid(int(uid))
		if err != nil {
			owner.Name = fmt.Sprintf("#%d", uid)
		}

		container, err := factory.Load(item.Name())
		if err != nil {
			fmt.Fprintf(os.Stderr, "load container %s: %v\n", item.Name(), err)
			continue
		}
		containerStatus, err := container.Status()
		if err != nil {
			fmt.Fprintf(os.Stderr, "status for %s: %v\n", item.Name(), err)
			continue
		}
		state, err := container.State()
		if err != nil {
			fmt.Fprintf(os.Stderr, "state for %s: %v\n", item.Name(), err)
			continue
		}
		pid := state.BaseState.InitProcessPid
		if containerStatus == libcontainer.Stopped {
			pid = 0
		}
		bundle, annotations := utils.Annotations(state.Config.Labels)
		s = append(s, containerState{
			Version:        state.BaseState.Config.Version,
			ID:             state.BaseState.ID,
			InitProcessPid: pid,
			Status:         containerStatus.String(),
			Bundle:         bundle,
			Rootfs:         state.BaseState.Config.Rootfs,
			Created:        state.BaseState.Created,
			Annotations:    annotations,
			Owner:          owner.Name,
		})
	}
	return s, nil
}
<commit_msg>list: report error when non-existent --root is specified<commit_after>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"syscall"
	"text/tabwriter"
	"time"

	"github.com/opencontainers/runc/libcontainer"
	"github.com/opencontainers/runc/libcontainer/user"
	"github.com/opencontainers/runc/libcontainer/utils"
	"github.com/urfave/cli"
)

const formatOptions = `table or json`

// containerState represents the platform agnostic pieces relating to a
// running container's status and state
type containerState struct {
	// Version is the OCI version for the container
	Version string `json:"ociVersion"`
	// ID is the container ID
	ID string `json:"id"`
	// InitProcessPid is the init process id in the parent namespace
	InitProcessPid int `json:"pid"`
	// Status is the current status of the container, running, paused, ...
	Status string `json:"status"`
	// Bundle is the path on the filesystem to the bundle
	Bundle string `json:"bundle"`
	// Rootfs is a path to a directory containing the container's root filesystem.
	Rootfs string `json:"rootfs"`
	// Created is the unix timestamp for the creation time of the container in UTC
	Created time.Time `json:"created"`
	// Annotations is the user defined annotations added to the config.
	Annotations map[string]string `json:"annotations,omitempty"`
	// The owner of the state directory (the owner of the container).
	Owner string `json:"owner"`
}

var listCommand = cli.Command{
	Name:  "list",
	Usage: "lists containers started by runc with the given root",
	ArgsUsage: `

Where the given root is specified via the global option "--root"
(default: "/run/runc").

EXAMPLE 1:
To list containers created via the default "--root":
       # runc list

EXAMPLE 2:
To list containers created using a non-default value for "--root":
       # runc --root value list`,
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "format, f",
			Value: "table",
			Usage: `select one of: ` + formatOptions,
		},
		cli.BoolFlag{
			Name:  "quiet, q",
			Usage: "display only container IDs",
		},
	},
	Action: func(context *cli.Context) error {
		if err := checkArgs(context, 0, exactArgs); err != nil {
			return err
		}
		s, err := getContainers(context)
		if err != nil {
			return err
		}

		if context.Bool("quiet") {
			for _, item := range s {
				fmt.Println(item.ID)
			}
			return nil
		}

		switch context.String("format") {
		case "table":
			w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0)
			fmt.Fprint(w, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\tOWNER\n")
			for _, item := range s {
				fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\n",
					item.ID,
					item.InitProcessPid,
					item.Status,
					item.Bundle,
					item.Created.Format(time.RFC3339Nano),
					item.Owner)
			}
			if err := w.Flush(); err != nil {
				return err
			}
		case "json":
			if err := json.NewEncoder(os.Stdout).Encode(s); err != nil {
				return err
			}
		default:
			return errors.New("invalid format option")
		}
		return nil
	},
}

func getContainers(context *cli.Context) ([]containerState, error) {
	root := context.GlobalString("root")
	list, err := os.ReadDir(root)
	if err != nil {
		if errors.Is(err, os.ErrNotExist) && context.IsSet("root") {
			// Ignore non-existing default root directory
			// (no containers created yet).
			return nil, nil
		}
		// Report other errors, including non-existent custom --root.
		return nil, err
	}

	factory, err := loadFactory(context)
	if err != nil {
		return nil, err
	}

	var s []containerState
	for _, item := range list {
		if !item.IsDir() {
			continue
		}
		st, err := item.Info()
		if err != nil {
			if errors.Is(err, os.ErrNotExist) {
				// Possible race with runc delete.
				continue
			}
			return nil, err
		}
		// This cast is safe on Linux.
		uid := st.Sys().(*syscall.Stat_t).Uid
		owner, err := user.LookupUid(int(uid))
		if err != nil {
			owner.Name = fmt.Sprintf("#%d", uid)
		}

		container, err := factory.Load(item.Name())
		if err != nil {
			fmt.Fprintf(os.Stderr, "load container %s: %v\n", item.Name(), err)
			continue
		}
		containerStatus, err := container.Status()
		if err != nil {
			fmt.Fprintf(os.Stderr, "status for %s: %v\n", item.Name(), err)
			continue
		}
		state, err := container.State()
		if err != nil {
			fmt.Fprintf(os.Stderr, "state for %s: %v\n", item.Name(), err)
			continue
		}
		pid := state.BaseState.InitProcessPid
		if containerStatus == libcontainer.Stopped {
			pid = 0
		}
		bundle, annotations := utils.Annotations(state.Config.Labels)
		s = append(s, containerState{
			Version:        state.BaseState.Config.Version,
			ID:             state.BaseState.ID,
			InitProcessPid: pid,
			Status:         containerStatus.String(),
			Bundle:         bundle,
			Rootfs:         state.BaseState.Config.Rootfs,
			Created:        state.BaseState.Created,
			Annotations:    annotations,
			Owner:          owner.Name,
		})
	}
	return s, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/codegangsta/cli"
	"github.com/koding/kite"
)

type kiteInfo struct {
	IP           string
	VMName       string
	Hostname     string
	MachineLabel string
	Mounts       []mountInfo
	Teams        []string

	// TODO: DEPRECATE
	MountedPaths []string
}

type mountInfo struct {
	RemotePath string `json:"remotePath"`
	LocalPath  string `json:"localPath"`
}

// ListCommand returns list of remote machines belonging to user or that can be
// accessed by the user.
func ListCommand(c *cli.Context) int {
	k, err := CreateKlientClient(NewKlientOptions())
	if err != nil {
		fmt.Println(defaultHealthChecker.CheckAllFailureOrMessagef(
			"Error connecting to %s: '%s'", KlientName, err,
		))
		return 1
	}

	if err := k.Dial(); err != nil {
		fmt.Println(defaultHealthChecker.CheckAllFailureOrMessagef(
			"Error connecting to %s: '%s'", KlientName, err,
		))
		return 1
	}

	infos, err := getListOfMachines(k)
	if err != nil {
		fmt.Print(err)
		return 1
	}

	w := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
	fmt.Fprintf(w, "\tTEAM\tLABEL\tIP\tALIAS\tMOUNTED PATHS\n")
	for i, info := range infos {
		// Join multiple teams into a single identifier
		team := strings.Join(info.Teams, ",")

		// For a more clear UX, replace the team name of the default Koding team,
		// with Koding.com
		if team == "Koding" {
			team = "koding.com"
		}

		// TODO: The UX for displaying multiple mounts is not decided, and
		// we only support a single mount for now anyway. So, listing will just default
		// to a single mount.
		var formattedMount string
		if len(info.Mounts) > 0 {
			// TODO: "fishify" the mount paths.
			formattedMount = fmt.Sprintf(
				"%s -> %s",
				FishifyPath(info.Mounts[0].LocalPath),
				FishifyPath(info.Mounts[0].RemotePath),
			)
		}

		fmt.Fprintf(w, "  %d.\t%s\t%s\t%s\t%s\t%s\n",
			i+1, team, info.MachineLabel, info.IP, info.VMName, formattedMount,
		)
	}
	w.Flush()

	return 0
}

func getListOfMachines(kite *kite.Client) ([]kiteInfo, error) {
	res, err := kite.Tell("remote.list")
	if err != nil {
		return nil, fmt.Errorf(defaultHealthChecker.CheckAllFailureOrMessagef(
			"Error fetching list of machines from %s: '%s'", KlientName, err,
		))
	}

	var infos []kiteInfo
	if err := res.Unmarshal(&infos); err != nil {
		return nil, fmt.Errorf(defaultHealthChecker.CheckAllFailureOrMessagef(
			"Error fetching list of machines from %s: '%s'", KlientName, err,
		))
	}

	return infos, nil
}

// FishifyPath takes a path and returnes a "Fish" like path.
// Example:
//
//     /foo/bar/baz/bat
//
// Becomes:
//
//     /foo/b/b/bat
//
// Note that this is different from Fish, in that it shows the root directory. This
// is done so that a mounted directory that has the same name as the remote directory
// is easier to distinguish.
func FishifyPath(p string) string {
	sep := string(os.PathSeparator)
	l := strings.Split(p, sep)

	first := true
	// premature optimize the end, since we'll need it on every iteration
	last := len(l) - 1

	for i, s := range l {
		if s == "" || i == last {
			continue
		}

		// If this is the first path segment, don't shorten it
		if first {
			first = false
			continue
		}

		l[i] = s[:1]
	}

	return strings.Join(l, sep)
}
<commit_msg>listen: Renamed FishifyPaths ShortenPaths<commit_after>package main

import (
	"fmt"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/codegangsta/cli"
	"github.com/koding/kite"
)

type kiteInfo struct {
	IP           string
	VMName       string
	Hostname     string
	MachineLabel string
	Mounts       []mountInfo
	Teams        []string

	// TODO: DEPRECATE
	MountedPaths []string
}

type mountInfo struct {
	RemotePath string `json:"remotePath"`
	LocalPath  string `json:"localPath"`
}

// ListCommand returns list of remote machines belonging to user or that can be
// accessed by the user.
func ListCommand(c *cli.Context) int {
	k, err := CreateKlientClient(NewKlientOptions())
	if err != nil {
		fmt.Println(defaultHealthChecker.CheckAllFailureOrMessagef(
			"Error connecting to %s: '%s'", KlientName, err,
		))
		return 1
	}

	if err := k.Dial(); err != nil {
		fmt.Println(defaultHealthChecker.CheckAllFailureOrMessagef(
			"Error connecting to %s: '%s'", KlientName, err,
		))
		return 1
	}

	infos, err := getListOfMachines(k)
	if err != nil {
		fmt.Print(err)
		return 1
	}

	w := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
	fmt.Fprintf(w, "\tTEAM\tLABEL\tIP\tALIAS\tMOUNTED PATHS\n")
	for i, info := range infos {
		// Join multiple teams into a single identifier
		team := strings.Join(info.Teams, ",")

		// For a more clear UX, replace the team name of the default Koding team,
		// with Koding.com
		if team == "Koding" {
			team = "koding.com"
		}

		// TODO: The UX for displaying multiple mounts is not decided, and
		// we only support a single mount for now anyway. So, listing will just default
		// to a single mount.
		var formattedMount string
		if len(info.Mounts) > 0 {
			// TODO: "fishify" the mount paths.
			formattedMount = fmt.Sprintf(
				"%s -> %s",
				shortenPath(info.Mounts[0].LocalPath),
				shortenPath(info.Mounts[0].RemotePath),
			)
		}

		fmt.Fprintf(w, "  %d.\t%s\t%s\t%s\t%s\t%s\n",
			i+1, team, info.MachineLabel, info.IP, info.VMName, formattedMount,
		)
	}
	w.Flush()

	return 0
}

func getListOfMachines(kite *kite.Client) ([]kiteInfo, error) {
	res, err := kite.Tell("remote.list")
	if err != nil {
		return nil, fmt.Errorf(defaultHealthChecker.CheckAllFailureOrMessagef(
			"Error fetching list of machines from %s: '%s'", KlientName, err,
		))
	}

	var infos []kiteInfo
	if err := res.Unmarshal(&infos); err != nil {
		return nil, fmt.Errorf(defaultHealthChecker.CheckAllFailureOrMessagef(
			"Error fetching list of machines from %s: '%s'", KlientName, err,
		))
	}

	return infos, nil
}

// shortenPath takes a path and returnes a "Fish" like path.
// Example:
//
//     /foo/bar/baz/bat
//
// Becomes:
//
//     /foo/b/b/bat
//
// Note that this is different from Fish, in that it shows the root directory. This
// is done so that a mounted directory that has the same name as the remote directory
// is easier to distinguish.
func shortenPath(p string) string {
	sep := string(os.PathSeparator)
	l := strings.Split(p, sep)

	first := true
	// premature optimize the end, since we'll need it on every iteration
	last := len(l) - 1

	for i, s := range l {
		if s == "" || i == last {
			continue
		}

		// If this is the first path segment, don't shorten it
		if first {
			first = false
			continue
		}

		l[i] = s[:1]
	}

	return strings.Join(l, sep)
}
<|endoftext|>


<commit_before>package lwgo

/*
#cgo LDFLAGS: -lwiringPi
#include <wiringPi.h>

#define byte unsigned char
#define bool int
#define true 1
#define false 0
static const byte nibbles[] = {0xF6, 0xEE, 0xED, 0xEB, 0xDE, 0xDD, 0xDB, 0xBE,
                               0xBD, 0xBB, 0xB7, 0x7E, 0x7D, 0x7B, 0x77, 0x6F};

static void sendBytes(int pin, int onval, int offval, int period,
                      int repeats, int translate,
                      byte b1, byte b2, byte b3, byte b4, byte b5,
                      byte b6, byte b7, byte b8, byte b9, byte b10)
{
    bool sending = true;
    const int buflen = 10;
    byte in_buf[] = {b1,b2,b3,b4,b5,b6,b7,b8,b9,b10};
    byte out_buf[10] = {0};

    // Should we translate the input bytes to nibbles? Probably yes.
    if (translate > 0) {
        byte i = 0;
        for (i = 0; i < buflen; i++) {
            out_buf[i] = nibbles[in_buf[i] & 0x0F];
        }
    } else {
        byte i = 0;
        for (i = 0; i < buflen; i++) {
            out_buf[i] = in_buf[i];
        }
    }

    int tx_low_count = 7;   // total number of ticks in a low (980 uSec)
    int tx_high_count = 4;  // total number of ticks in a high (560 uSec)
    int tx_trail_count = 2; //tick count to set line low (280 uSec)

    int tx_gap_count = 72; // Inter-message gap count (10.8 msec)
    //Gap multiplier byte is used to multiply gap if longer periods are needed for experimentation
    //If gap is 255 (35msec) then this to give a max of 9 seconds
    //Used with low repeat counts to find if device times out
    int tx_gap_multiplier = 0; //Gap extension byte

    int tx_repeat = 0; //counter for repeats
    int tx_toggle_count = 3;
    int tx_gap_repeat = 0;  //unsigned int

    typedef enum TxState_ {
        tx_state_idle = 0,
        tx_state_msgstart,
        tx_state_bytestart,
        tx_state_sendbyte,
        tx_state_msgend,
        tx_state_gapstart,
        tx_state_gapend
    } TxState;
    TxState tx_state = tx_state_idle;

    int tx_bit_mask = 0; // bit mask in current byte
    int tx_num_bytes = 0; // number of bytes sent

    while (sending == true)
    {
        //Set low after toggle count interrupts
        tx_toggle_count--;
        if (tx_toggle_count == tx_trail_count) {
            digitalWrite(pin, offval);
        } else if (tx_toggle_count == 0) {
            tx_toggle_count = tx_high_count; //default high pulse duration
            switch (tx_state) {
                case tx_state_idle:
                    if(sending) {
                        tx_repeat = 0;
                        tx_state = tx_state_msgstart;
                    }
                    break;
                case tx_state_msgstart:
                    digitalWrite(pin, onval);
                    tx_num_bytes = 0;
                    tx_state = tx_state_bytestart;
                    break;
                case tx_state_bytestart:
                    digitalWrite(pin, onval);
                    tx_bit_mask = 0x80;
                    tx_state = tx_state_sendbyte;
                    break;
                case tx_state_sendbyte:
                    if(out_buf[tx_num_bytes] & tx_bit_mask) {
                        digitalWrite(pin, onval);
                    } else {
                        // toggle count for the 0 pulse
                        tx_toggle_count = tx_low_count;
                    }
                    tx_bit_mask >>=1;
                    if(tx_bit_mask == 0) {
                        tx_num_bytes++;
                        if(tx_num_bytes >= buflen) {
                            tx_state = tx_state_msgend;
                        } else {
                            tx_state = tx_state_bytestart;
                        }
                    }
                    break;
                case tx_state_msgend:
                    digitalWrite(pin, onval);
                    tx_state = tx_state_gapstart;
                    tx_gap_repeat = tx_gap_multiplier;
                    break;
                case tx_state_gapstart:
                    tx_toggle_count = tx_gap_count;
                    if (tx_gap_repeat == 0) {
                        tx_state = tx_state_gapend;
                    } else {
                        tx_gap_repeat--;
                    }
                    break;
                case tx_state_gapend:
                    tx_repeat++;
                    if(tx_repeat >= repeats) {
                        //disable timer interrupt
                        //lw_timer_Stop();
                        sending = false;
                        tx_state = tx_state_idle;
                    } else {
                        tx_state = tx_state_msgstart;
                    }
                    break;
            } // end switch
        } // end if

        // Sleep for period (default 140 us)
        delayMicroseconds(period);
    } // end while (sending == true)
} // end func
*/
import "C"

import (
    "fmt"
    "errors"
)

func wiringPiSetup() error {
    if -1 == int(C.wiringPiSetup()) {
        return errors.New("lwgo::init: wiringPiSetup() failed to call")
    }
    err := C.piHiPri(C.int(99));
    if err < 0 {
        return errors.New("lwgo::init: piHiPri() failed to set thread priority")
    }
    return nil
}

func init() {
    err := wiringPiSetup()
    if err != nil {
        fmt.Println("lwgo::init: failed")
    }
}

type LwBuffer [10]byte

type LwCommand struct {
    parameter string
    device int
    command string
    address []byte
    room int
}

type LwTx struct {
    setup bool
    Pin int
    Repeats int
    Onval, Offval int
    Translate int
    Period int
}

func NewLwTx() *LwTx {
    // Apply defaults, allowing the user to change them afterwards if needed.
    return &LwTx{
        Pin: 3,
        Repeats: 10,
        Onval: 1,
        Offval: 0,
        Translate: 1,
        Period: 140,
    }
}

func (lw *LwTx) SetupPins() {
    C.pinMode(C.int(lw.Pin), C.OUTPUT)
    C.digitalWrite(C.int(lw.Pin), C.LOW)
    lw.setup = true
}

func (lw *LwTx) Send(buffer LwBuffer) {
    // Check that the transmitter is setup.
    if lw.setup == false {
        lw.SetupPins()
    }

    //fmt.Println("LwTx::Run: send:", buffer)

    // Send the message.
    C.sendBytes(C.int(lw.Pin), C.int(lw.Onval),
                C.int(lw.Offval), C.int(lw.Period),
                C.int(lw.Repeats), C.int(lw.Translate),
                C.byte(buffer[0]), C.byte(buffer[1]),
                C.byte(buffer[2]), C.byte(buffer[3]),
                C.byte(buffer[4]), C.byte(buffer[5]),
                C.byte(buffer[6]), C.byte(buffer[7]),
                C.byte(buffer[8]), C.byte(buffer[9]))
}

func (buf LwBuffer) Command() LwCommand {
    // parameter (2 [0,1])
    // device    (1 [2])
    // command   (1 [3])
    // address   (5 [4-8])
    // room      (1 [9])
    cmd := LwCommand{
        device: int(buf[2]),
        address: buf[4:8],
        room: int(buf[9]),
    }

    command := int(buf[3])
    param := int(buf[1])
    param += int(buf[0] << 4)

    // Get the parameter
    switch {
        // Command off
        case command == 0 && param >= 0 && param <= 127: {
            cmd.parameter = "off"
        }
        case command == 0 && param >= 128 && param <= 159: {
            cmd.parameter = fmt.Sprint("off with level:", param-128)
        }
        case command == 0 && param >= 160 && param <= 191: {
            cmd.parameter = "decrease brightness"
        }
        case command == 0 && param >= 192 && param <= 255: {
            cmd.parameter = "all off"
        }

        // Command on
        case command == 1 && param >= 0 && param <= 31: {
            cmd.parameter = "on to last level"
        }
        case command == 1 && param >= 32 && param <= 63: {
            cmd.parameter = fmt.Sprint("on with level:", param-32)
        }
        case command == 1 && param >= 64 && param <= 95: {
            cmd.parameter = fmt.Sprint("on with level:", param-64)
        }
        case command == 1 && param >= 96 && param <= 127: {
            cmd.parameter = fmt.Sprint("on with level:", param-96)
        }
        case command == 1 && param >= 128 && param <= 159: {
            cmd.parameter = fmt.Sprint("on with level:", param-128)
        }
        case command == 1 && param >= 160 && param <= 191: {
            cmd.parameter = "increase brightness"
        }
        case command == 1 && param >= 192 && param <= 223: {
            cmd.parameter = fmt.Sprint("set all to level:", param-192)
        }
        case command == 1 && param >= 224 && param <= 255: {
            cmd.parameter = fmt.Sprint("set all to level:", param-224)
        }

        // Command mood
        case command == 2 && param >= 130 && param <= 255: {
            cmd.parameter = fmt.Sprint("start mood:", param-129)
        }
        case command == 2 && param >= 2 && param <= 129: {
            cmd.parameter = fmt.Sprint("define mood:", param-1)
        }

        default: cmd.parameter = "unknown"
    }

    // Get the command
    switch command {
        case 0: cmd.command = "off"
        case 1: cmd.command = "on"
        case 2: cmd.command = "mood"
        default: cmd.command = "unknown"
    }

    return cmd
}

func (cmd LwCommand) String() string {
    return fmt.Sprint("Parameter: ", cmd.parameter,
                      ", Device: ", cmd.device,
                      ", Command: ", cmd.command,
                      ", Address: ", cmd.address,
                      ", Room: ", cmd.room)
}

func (buf LwBuffer) String() string {
    return fmt.Sprint(buf.Command().String())
}

func (buf LwBuffer) Raw() []byte {
    out := make([]byte, len(buf))
    for i, val := range buf {
        out[i] = val
    }
    return out
}
<commit_msg>add comments and have a shuffle<commit_after>/*
LightwaveRF library for the Raspberry Pi written in Go.

Basic usage:

    import "github.com/jimjibone/lwgo"

    func main() {
        lwtx := lwgo.NewLwTx()
        lightOn  := lwgo.LwBuffer{0x9,0xf,0x3,0x1,0x5,0x9,0x3,0x0,0x1,0x2}
        lwtx.Send(lightOn)
    }
 */
package lwgo

/*
#cgo LDFLAGS: -lwiringPi
#include <wiringPi.h>

#define byte unsigned char
#define bool int
#define true 1
#define false 0
static const byte nibbles[] = {0xF6, 0xEE, 0xED, 0xEB, 0xDE, 0xDD, 0xDB, 0xBE,
                               0xBD, 0xBB, 0xB7, 0x7E, 0x7D, 0x7B, 0x77, 0x6F};

static void sendBytes(int pin, int onval, int offval, int period,
                      int repeats, int translate,
                      byte b1, byte b2, byte b3, byte b4, byte b5,
                      byte b6, byte b7, byte b8, byte b9, byte b10)
{
    bool sending = true;
    const int buflen = 10;
    byte in_buf[] = {b1,b2,b3,b4,b5,b6,b7,b8,b9,b10};
    byte out_buf[10] = {0};

    // Should we translate the input bytes to nibbles? Probably yes.
    if (translate > 0) {
        byte i = 0;
        for (i = 0; i < buflen; i++) {
            out_buf[i] = nibbles[in_buf[i] & 0x0F];
        }
    } else {
        byte i = 0;
        for (i = 0; i < buflen; i++) {
            out_buf[i] = in_buf[i];
        }
    }

    int tx_low_count = 7;   // total number of ticks in a low (980 uSec)
    int tx_high_count = 4;  // total number of ticks in a high (560 uSec)
    int tx_trail_count = 2; //tick count to set line low (280 uSec)

    int tx_gap_count = 72; // Inter-message gap count (10.8 msec)
    //Gap multiplier byte is used to multiply gap if longer periods are needed for experimentation
    //If gap is 255 (35msec) then this to give a max of 9 seconds
    //Used with low repeat counts to find if device times out
    int tx_gap_multiplier = 0; //Gap extension byte

    int tx_repeat = 0; //counter for repeats
    int tx_toggle_count = 3;
    int tx_gap_repeat = 0;  //unsigned int

    typedef enum TxState_ {
        tx_state_idle = 0,
        tx_state_msgstart,
        tx_state_bytestart,
        tx_state_sendbyte,
        tx_state_msgend,
        tx_state_gapstart,
        tx_state_gapend
    } TxState;
    TxState tx_state = tx_state_idle;

    int tx_bit_mask = 0; // bit mask in current byte
    int tx_num_bytes = 0; // number of bytes sent

    while (sending == true)
    {
        //Set low after toggle count interrupts
        tx_toggle_count--;
        if (tx_toggle_count == tx_trail_count) {
            digitalWrite(pin, offval);
        } else if (tx_toggle_count == 0) {
            tx_toggle_count = tx_high_count; //default high pulse duration
            switch (tx_state) {
                case tx_state_idle:
                    if(sending) {
                        tx_repeat = 0;
                        tx_state = tx_state_msgstart;
                    }
                    break;
                case tx_state_msgstart:
                    digitalWrite(pin, onval);
                    tx_num_bytes = 0;
                    tx_state = tx_state_bytestart;
                    break;
                case tx_state_bytestart:
                    digitalWrite(pin, onval);
                    tx_bit_mask = 0x80;
                    tx_state = tx_state_sendbyte;
                    break;
                case tx_state_sendbyte:
                    if(out_buf[tx_num_bytes] & tx_bit_mask) {
                        digitalWrite(pin, onval);
                    } else {
                        // toggle count for the 0 pulse
                        tx_toggle_count = tx_low_count;
                    }
                    tx_bit_mask >>=1;
                    if(tx_bit_mask == 0) {
                        tx_num_bytes++;
                        if(tx_num_bytes >= buflen) {
                            tx_state = tx_state_msgend;
                        } else {
                            tx_state = tx_state_bytestart;
                        }
                    }
                    break;
                case tx_state_msgend:
                    digitalWrite(pin, onval);
                    tx_state = tx_state_gapstart;
                    tx_gap_repeat = tx_gap_multiplier;
                    break;
                case tx_state_gapstart:
                    tx_toggle_count = tx_gap_count;
                    if (tx_gap_repeat == 0) {
                        tx_state = tx_state_gapend;
                    } else {
                        tx_gap_repeat--;
                    }
                    break;
                case tx_state_gapend:
                    tx_repeat++;
                    if(tx_repeat >= repeats) {
                        //disable timer interrupt
                        //lw_timer_Stop();
                        sending = false;
                        tx_state = tx_state_idle;
                    } else {
                        tx_state = tx_state_msgstart;
                    }
                    break;
            } // end switch
        } // end if

        // Sleep for period (default 140 us)
        delayMicroseconds(period);
    } // end while (sending == true)
} // end func
*/
import "C"

import (
    "fmt"
    "errors"
)

func wiringPiSetup() error {
    if -1 == int(C.wiringPiSetup()) {
        return errors.New("lwgo::init: wiringPiSetup() failed to call")
    }
    err := C.piHiPri(C.int(99));
    if err < 0 {
        return errors.New("lwgo::init: piHiPri() failed to set thread priority")
    }
    return nil
}

func init() {
    err := wiringPiSetup()
    if err != nil {
        fmt.Println("lwgo::init: failed")
    }
}

func (lw *LwTx) setupPins() {
    C.pinMode(C.int(lw.Pin), C.OUTPUT)
    C.digitalWrite(C.int(lw.Pin), C.LOW)
    lw.setup = true
}

/*
Send LightwaveRF commands using this struct and its functions.
The best way to create this struct, with all appropriate defaults, is to do the
following e.g:
    lwtx := lwgo.NewLwTx()
 */
type LwTx struct {
    setup bool
    Pin int
    Repeats int
    Onval, Offval int
    Translate int
    Period int
}

// A 10-byte buffer containing the command you wish to send.
type LwBuffer [10]byte

// A helper struct to pull out the meaning of a LwBuffer, useful for logging.
type LwCommand struct {
    parameter string
    device int
    command string
    address []byte
    room int
}

// Get a pointer to a LwTx initialised with recommended defaults.
func NewLwTx() *LwTx {
    // Apply defaults, allowing the user to change them afterwards if needed.
    return &LwTx{
        Pin: 3,
        Repeats: 10,
        Onval: 1,
        Offval: 0,
        Translate: 1,
        Period: 140,
    }
}

// Send a constructed LwBuffer via the 433 MHz module.
func (lw *LwTx) Send(buffer LwBuffer) {
    // Check that the transmitter is setup.
    if lw.setup == false {
        lw.SetupPins()
    }

    //fmt.Println("LwTx::Run: send:", buffer)

    // Send the message.
    C.sendBytes(C.int(lw.Pin), C.int(lw.Onval),
                C.int(lw.Offval), C.int(lw.Period),
                C.int(lw.Repeats), C.int(lw.Translate),
                C.byte(buffer[0]), C.byte(buffer[1]),
                C.byte(buffer[2]), C.byte(buffer[3]),
                C.byte(buffer[4]), C.byte(buffer[5]),
                C.byte(buffer[6]), C.byte(buffer[7]),
                C.byte(buffer[8]), C.byte(buffer[9]))
}

// Convert the LwBuffer to a LwCommand.
func (buf LwBuffer) Command() LwCommand {
    // parameter (2 [0,1])
    // device    (1 [2])
    // command   (1 [3])
    // address   (5 [4-8])
    // room      (1 [9])
    cmd := LwCommand{
        device: int(buf[2]),
        address: buf[4:8],
        room: int(buf[9]),
    }

    command := int(buf[3])
    param := int(buf[1])
    param += int(buf[0] << 4)

    // Get the parameter
    switch {
        // Command off
        case command == 0 && param >= 0 && param <= 127: {
            cmd.parameter = "off"
        }
        case command == 0 && param >= 128 && param <= 159: {
            cmd.parameter = fmt.Sprint("off with level:", param-128)
        }
        case command == 0 && param >= 160 && param <= 191: {
            cmd.parameter = "decrease brightness"
        }
        case command == 0 && param >= 192 && param <= 255: {
            cmd.parameter = "all off"
        }

        // Command on
        case command == 1 && param >= 0 && param <= 31: {
            cmd.parameter = "on to last level"
        }
        case command == 1 && param >= 32 && param <= 63: {
            cmd.parameter = fmt.Sprint("on with level:", param-32)
        }
        case command == 1 && param >= 64 && param <= 95: {
            cmd.parameter = fmt.Sprint("on with level:", param-64)
        }
        case command == 1 && param >= 96 && param <= 127: {
            cmd.parameter = fmt.Sprint("on with level:", param-96)
        }
        case command == 1 && param >= 128 && param <= 159: {
            cmd.parameter = fmt.Sprint("on with level:", param-128)
        }
        case command == 1 && param >= 160 && param <= 191: {
            cmd.parameter = "increase brightness"
        }
        case command == 1 && param >= 192 && param <= 223: {
            cmd.parameter = fmt.Sprint("set all to level:", param-192)
        }
        case command == 1 && param >= 224 && param <= 255: {
            cmd.parameter = fmt.Sprint("set all to level:", param-224)
        }

        // Command mood
        case command == 2 && param >= 130 && param <= 255: {
            cmd.parameter = fmt.Sprint("start mood:", param-129)
        }
        case command == 2 && param >= 2 && param <= 129: {
            cmd.parameter = fmt.Sprint("define mood:", param-1)
        }

        default: cmd.parameter = "unknown"
    }

    // Get the command
    switch command {
        case 0: cmd.command = "off"
        case 1: cmd.command = "on"
        case 2: cmd.command = "mood"
        default: cmd.command = "unknown"
    }

    return cmd
}

// Get a string version of the LwCommand.
func (cmd LwCommand) String() string {
    return fmt.Sprint("Parameter: ", cmd.parameter,
                      ", Device: ", cmd.device,
                      ", Command: ", cmd.command,
                      ", Address: ", cmd.address,
                      ", Room: ", cmd.room)
}

// Get a nicely formatted string version of the LwBuffer.
func (buf LwBuffer) String() string {
    return fmt.Sprint(buf.Command().String())
}

// Get the raw byte buffer within the LwBuffer.
func (buf LwBuffer) Raw() []byte {
    out := make([]byte, len(buf))
    for i, val := range buf {
        out[i] = val
    }
    return out
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/howeyc/fsnotify"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

func md2conf(c *cli.Context) {
	arg := c.Args().First()
	cmd := exec.Command("markdown2confluence", arg)
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()

	if err != nil {
		log.Fatal(err)
	}

	ioutil.WriteFile(
		strings.TrimSuffix(arg, filepath.Ext(arg))+".wiki",
		out.Bytes(),
		0644,
	)
}

func main() {
	app := cli.NewApp()
	app.Name = "m2cw"
	app.Usage = "Convert markdown file to confluence style when save md file."
	app.Author = "Layzie <HIRAKI Satoru>"
	app.Email = "saruko313@gmail.com"
	app.Version = "0.0.1"
	app.Action = func(c *cli.Context) {
		arg := c.Args().First()

		fmt.Println("Start watching " + arg + ". <C-c> makes stop the command.")

		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			log.Fatal(err)
		}

		err = watcher.Watch("./")
		if err != nil {
			log.Fatal(err)
		}

		defer watcher.Close()

		for {
			select {
			case ev := <-watcher.Event:
				if ev.Name == c.Args().First() {
					md2conf(c)
					log.Println(
						"convert md to wiki ",
						ev.Name+" -> "+strings.TrimSuffix(arg, filepath.Ext(arg))+".wiki",
					)
				}
			case err := <-watcher.Error:
				log.Println("error:", err)
			}
		}
	}

	app.Run(os.Args)
}
<commit_msg>fix value<commit_after>package main

import (
	"bytes"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/howeyc/fsnotify"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

func md2conf(c *cli.Context) {
	arg := c.Args().First()
	cmd := exec.Command("markdown2confluence", arg)
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()

	if err != nil {
		log.Fatal(err)
	}

	ioutil.WriteFile(
		strings.TrimSuffix(arg, filepath.Ext(arg))+".wiki",
		out.Bytes(),
		0644,
	)
}

func main() {
	app := cli.NewApp()
	app.Name = "m2cw"
	app.Usage = "Convert markdown file to confluence style when save md file."
	app.Author = "Layzie <HIRAKI Satoru>"
	app.Email = "saruko313@gmail.com"
	app.Version = "0.0.1"
	app.Action = func(c *cli.Context) {
		arg := c.Args().First()

		fmt.Println("Start watching " + arg + ". <C-c> makes stop the command.")

		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			log.Fatal(err)
		}

		err = watcher.Watch("./")
		if err != nil {
			log.Fatal(err)
		}

		defer watcher.Close()

		for {
			select {
			case ev := <-watcher.Event:
				if ev.Name == arg {
					md2conf(c)
					log.Println(
						"convert md to wiki ",
						ev.Name+" -> "+strings.TrimSuffix(arg, filepath.Ext(arg))+".wiki",
					)
				}
			case err := <-watcher.Error:
				log.Println("error:", err)
			}
		}
	}

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


<commit_before>package main

import (
	"fmt"
	"github.com/c-14/grue/config"
	"github.com/jaytaylor/html2text"
	"github.com/mmcdole/gofeed"
	"gopkg.in/gomail.v2"
	"io"
	"os/exec"
	"strings"
	"time"
)

type Email struct {
	FromName    string
	FromAddress string
	Recipient   string
	Date        time.Time
	Subject     string
	ItemURI     string
	Body        string
}

func (email *Email) setFrom(feedName string, feedTitle string, account config.AccountConfig, conf *config.GrueConfig) {
	r := strings.NewReplacer("{name}", feedName, "{title}", feedTitle)
	if account.NameFormat != nil {
		email.FromName = r.Replace(*account.NameFormat)
	} else {
		email.FromName = r.Replace(conf.NameFormat)
	}
	email.FromAddress = conf.FromAddress
}

func (email *Email) Send() error {
	m := email.format()
	return gomail.Send(gomail.SendFunc(sendMail), m)
}

func (email *Email) format() *gomail.Message {
	var err error

	m := gomail.NewMessage()
	m.SetAddressHeader("From", email.FromAddress, email.FromName)
	m.SetHeader("To", email.Recipient)
	m.SetHeader("Subject", email.Subject)
	m.SetDateHeader("Date", email.Date)
	m.SetDateHeader("X-Date", time.Now())
	m.SetHeader("X-RSS-URI", email.ItemURI)
	bodyPlain, err := html2text.FromString(email.Body)
	if err != nil {
		fmt.Printf("Failed to parse text as HTML: %v", email.Subject)
		m.SetBody("text/html", email.Body)
	} else {
		m.SetBody("text/plain", bodyPlain)
	}
	return m
}

func createEmail(feedName string, feedTitle string, item *gofeed.Item, date time.Time, account config.AccountConfig, conf *config.GrueConfig) *Email {
	email := new(Email)
	email.setFrom(feedName, feedTitle, account, conf)
	email.Recipient = conf.Recipient
	email.Subject = item.Title
	email.Date = date
	email.ItemURI = item.Link
	email.Body = item.Description
	return email
}

func sendMail(from string, to []string, msg io.WriterTo) error {
	cmd := exec.Command("sendmail", "-oi", "-t")
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return err
	}
	err = cmd.Start()
	if err != nil {
		return err
	}
	_, err = msg.WriteTo(stdin)
	if err != nil {
		stdin.Close()
		return err
	}
	stdin.Close()
	return cmd.Wait()
}
<commit_msg>Set User-Agent e-mail header if UserAgent configured<commit_after>package main

import (
	"fmt"
	"github.com/c-14/grue/config"
	"github.com/jaytaylor/html2text"
	"github.com/mmcdole/gofeed"
	"gopkg.in/gomail.v2"
	"io"
	"os/exec"
	"strings"
	"time"
)

type Email struct {
	FromName    string
	FromAddress string
	Recipient   string
	Date        time.Time
	Subject     string
	UserAgent   string
	ItemURI     string
	Body        string
}

func (email *Email) setFrom(feedName string, feedTitle string, account config.AccountConfig, conf *config.GrueConfig) {
	r := strings.NewReplacer("{name}", feedName, "{title}", feedTitle)
	if account.NameFormat != nil {
		email.FromName = r.Replace(*account.NameFormat)
	} else {
		email.FromName = r.Replace(conf.NameFormat)
	}
	email.FromAddress = conf.FromAddress
}

func (email *Email) setUserAgent(conf *config.GrueConfig) {
	if conf.UserAgent != "" {
		r := strings.NewReplacer("{version}", version)
		email.UserAgent = r.Replace(conf.UserAgent)
	}
}

func (email *Email) Send() error {
	m := email.format()
	return gomail.Send(gomail.SendFunc(sendMail), m)
}

func (email *Email) format() *gomail.Message {
	var err error

	m := gomail.NewMessage()
	m.SetAddressHeader("From", email.FromAddress, email.FromName)
	m.SetHeader("To", email.Recipient)
	m.SetHeader("Subject", email.Subject)
	m.SetDateHeader("Date", email.Date)
	m.SetDateHeader("X-Date", time.Now())
	if email.UserAgent != "" {
		m.SetHeader("User-Agent", email.UserAgent)
	}
	m.SetHeader("X-RSS-URI", email.ItemURI)
	bodyPlain, err := html2text.FromString(email.Body)
	if err != nil {
		fmt.Printf("Failed to parse text as HTML: %v", email.Subject)
		m.SetBody("text/html", email.Body)
	} else {
		m.SetBody("text/plain", bodyPlain)
	}
	return m
}

func createEmail(feedName string, feedTitle string, item *gofeed.Item, date time.Time, account config.AccountConfig, conf *config.GrueConfig) *Email {
	email := new(Email)
	email.setFrom(feedName, feedTitle, account, conf)
	email.Recipient = conf.Recipient
	email.Subject = item.Title
	email.Date = date
	email.setUserAgent(conf)
	email.ItemURI = item.Link
	email.Body = item.Description
	return email
}

func sendMail(from string, to []string, msg io.WriterTo) error {
	cmd := exec.Command("sendmail", "-oi", "-t")
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return err
	}
	err = cmd.Start()
	if err != nil {
		return err
	}
	_, err = msg.WriteTo(stdin)
	if err != nil {
		stdin.Close()
		return err
	}
	stdin.Close()
	return cmd.Wait()
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// webui is a web-based user-interface for SysDB.
package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/user"

	"github.com/sysdb/go/client"
	"github.com/sysdb/webui/server"
)

var (
	addr     = flag.String("address", "/var/run/sysdbd.sock", "SysDB server address")
	username *string

	listen = flag.String("listen", ":8080", "address to listen for incoming connections")
	tmpl   = flag.String("template-path", "templates", "location of template files")
	static = flag.String("static-path", "static", "location of static files")
)

func init() {
	u, err := user.Current()
	var def string
	if err != nil {
		log.Printf("WARNING: Unable to determine current user: %v", err)
	} else {
		def = u.Username
	}

	username = flag.String("user", def, "SysDB user name")
}

func main() {
	flag.Parse()

	log.Printf("Connecting to SysDB at %s.", *addr)
	var conns []*client.Conn
	for i := 0; i < 10; i++ {
		conn, err := client.Connect(*addr, *username)
		if err != nil {
			fatalf("Failed to connect to SysDB at %q: %v", *addr, err)
		}
		conns = append(conns, conn)
	}

	srv, err := server.New(server.Config{
		Conns:        conns,
		TemplatePath: *tmpl,
		StaticPath:   *static,
	})
	if err != nil {
		fatalf("Failed to construct web-server: %v", err)
	}

	log.Printf("Listening on %s.", *listen)
	http.Handle("/", srv)
	err = http.ListenAndServe(*listen, nil)
	if err != nil {
		fatalf("Failed to set up HTTP server on address %q: %v", *listen, err)
	}
}

func fatalf(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
	fmt.Fprintln(os.Stderr)
	os.Exit(1)
}

// vim: set tw=78 sw=4 sw=4 noexpandtab :
<commit_msg>Log the remote server version on startup.<commit_after>//
// Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// webui is a web-based user-interface for SysDB.
package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/user"

	"github.com/sysdb/go/client"
	"github.com/sysdb/webui/server"
)

var (
	addr     = flag.String("address", "/var/run/sysdbd.sock", "SysDB server address")
	username *string

	listen = flag.String("listen", ":8080", "address to listen for incoming connections")
	tmpl   = flag.String("template-path", "templates", "location of template files")
	static = flag.String("static-path", "static", "location of static files")
)

func init() {
	u, err := user.Current()
	var def string
	if err != nil {
		log.Printf("WARNING: Unable to determine current user: %v", err)
	} else {
		def = u.Username
	}

	username = flag.String("user", def, "SysDB user name")
}

func main() {
	flag.Parse()

	log.Printf("Connecting to SysDB at %s.", *addr)
	var conns []*client.Conn
	for i := 0; i < 10; i++ {
		conn, err := client.Connect(*addr, *username)
		if err != nil {
			fatalf("Failed to connect to SysDB at %q: %v", *addr, err)
		}
		conns = append(conns, conn)
	}
	major, minor, patch, extra, err := conns[0].ServerVersion()
	if err != nil {
		fatalf("Failed to query server version: %v", err)
	}
	log.Printf("Connected to SysDB %d.%d.%d%s.", major, minor, patch, extra)

	srv, err := server.New(server.Config{
		Conns:        conns,
		TemplatePath: *tmpl,
		StaticPath:   *static,
	})
	if err != nil {
		fatalf("Failed to construct web-server: %v", err)
	}

	log.Printf("Listening on %s.", *listen)
	http.Handle("/", srv)
	err = http.ListenAndServe(*listen, nil)
	if err != nil {
		fatalf("Failed to set up HTTP server on address %q: %v", *listen, err)
	}
}

func fatalf(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
	fmt.Fprintln(os.Stderr)
	os.Exit(1)
}

// vim: set tw=78 sw=4 sw=4 noexpandtab :
<|endoftext|>


<commit_before>package main

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

type DNSRecord struct {
	Content   string
	Domain    string
	FQDN      string
	Priority  int64
	TTL       int64
	Subdomain string
	Record_id int64
	Type      string
}

type DNSRecords struct {
	Records []DNSRecord
	Success string
}

func PrintRecords(records []DNSRecord) {
	for _, record := range records {
		fmt.Printf(
			"%s %s %s\n",
			record.Subdomain,
			record.Type,
			record.Content,
		)
	}
}

func main() {
	pddTokenPtr := flag.String("pdd-token", "<auth token>", "PDD authenthication ticket.")
	domainPtr := flag.String("domain", "<domain>", "Domain name.")
	flag.Parse()

	client := &http.Client{}
	req, _ := http.NewRequest("GET", "https://pddimp.yandex.ru/api2/admin/dns/list", nil)
	req.Header.Set("PddToken", *pddTokenPtr)

	values := req.URL.Query()
	values.Add("domain", *domainPtr)
	req.URL.RawQuery = values.Encode()

	resp, err := client.Do(req)

	if err != nil {
		panic(err)
	}
	body, err := ioutil.ReadAll(resp.Body)

	var container DNSRecords
	err = json.Unmarshal(body, &container)
	PrintRecords(container.Records)

	defer resp.Body.Close()
}
<commit_msg>Changed formatting.<commit_after>package main

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

type DNSRecord struct {
	Content   string
	Domain    string
	FQDN      string
	Priority  int64
	TTL       int64
	Subdomain string
	Record_id int64
	Type      string
}

type DNSRecords struct {
	Records []DNSRecord
	Success string
}

func PrintRecords(records []DNSRecord) {
	fmt.Printf("Type\t\tSubdomain\tContent\n")
	fmt.Printf("-----\t\t--------\t-------\n")

	for _, record := range records {
		fmt.Printf(
			"%-12s\t%-12s\t%-12s\n",
			record.Type,
			record.Subdomain,
			record.Content,
		)
	}
}

func main() {
	pddTokenPtr := flag.String("pdd-token", "<auth token>", "PDD authenthication ticket.")
	domainPtr := flag.String("domain", "<domain>", "Domain name.")
	flag.Parse()

	client := &http.Client{}
	req, _ := http.NewRequest("GET", "https://pddimp.yandex.ru/api2/admin/dns/list", nil)
	req.Header.Set("PddToken", *pddTokenPtr)

	values := req.URL.Query()
	values.Add("domain", *domainPtr)
	req.URL.RawQuery = values.Encode()

	resp, err := client.Do(req)

	if err != nil {
		panic(err)
	}
	body, err := ioutil.ReadAll(resp.Body)

	var container DNSRecords
	err = json.Unmarshal(body, &container)
	PrintRecords(container.Records)

	defer resp.Body.Close()
}
<|endoftext|>