<commit_before>package data

import (
	"bytes"
	"github.com/viant/toolbox"
	"math"
	"strings"
)

const (
	eofToken     = -1
	invalidToken = iota
	beforeVarToken
	varToken
	incToken
	decrementToken
	shiftToken
	enclosedVarToken
	callToken
	idToken
	arrayIndexToken
	unmatchedToken
	keyIndexToken
	whitespace
	groupingToken
	operatorTojeb
	doubleQuoteEnclosedToken
	comaToken
)

var matchers = map[int]toolbox.Matcher{
	beforeVarToken:           toolbox.NewTerminatorMatcher("$"),
	varToken:                 toolbox.NewCharactersMatcher("$"),
	comaToken:                toolbox.NewTerminatorMatcher(","),
	idToken:                  toolbox.NewCustomIdMatcher("_"),
	incToken:                 toolbox.NewKeywordsMatcher(true, "++"),
	decrementToken:           toolbox.NewKeywordsMatcher(true, "--"),
	shiftToken:               toolbox.NewKeywordsMatcher(true, "<-"),
	arrayIndexToken:          toolbox.NewBodyMatcher("[", "]"),
	callToken:                toolbox.NewBodyMatcher("(", ")"),
	enclosedVarToken:         toolbox.NewBodyMatcher("{", "}"),
	doubleQuoteEnclosedToken: toolbox.NewBodyMatcher(`"`, `"`),
	keyIndexToken:            toolbox.NewCustomIdMatcher("."),
	unmatchedToken:           toolbox.NewRemainingSequenceMatcher(),
	groupingToken:            toolbox.NewBodyMatcher("(", ")"),
	operatorTojeb:            toolbox.NewTerminatorMatcher("+", "-", "*", "/", "^", "%"),
	whitespace:               toolbox.NewCharactersMatcher(" \t\n\r"),
}

//Parse parses expression
func Parse(expression string, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) interface{} {
	tokenizer := toolbox.NewTokenizer(expression, invalidToken, eofToken, matchers)
	var value interface{}
	var result = fragments{}
	var ok bool
	done := false
	for tokenizer.Index < len(expression) && !done {
		match := tokenizer.Nexts(beforeVarToken, varToken, unmatchedToken, eofToken)
		switch match.Token {
		case unmatchedToken:
			result.Append(match.Matched)
			done = true
			continue
		case eofToken:
			break
		case beforeVarToken:
			result.Append(match.Matched)
			continue

		case varToken:
			variable := "$"
			match = tokenizer.Nexts(idToken, enclosedVarToken, incToken, decrementToken, shiftToken)
			switch match.Token {
			case eofToken:
				result.Append(variable)
				continue
			case enclosedVarToken:

				expanded := expandEnclosed(match.Matched, handler)
				if toolbox.IsFloat(expanded) || toolbox.IsInt(expanded) {
					value = expanded
					result.Append(value)
					continue
				}
				expandedText := toolbox.AsString(expanded)
				if strings.HasSuffix(expandedText, ")") {
					value = Parse("$"+expandedText, handler)
					if textValue, ok := value.(string); ok && textValue == "$"+expandedText {
						value = "${" + expandedText + "}"
					}
					result.Append(value)
					continue
				}

				variable := "${" + expandedText + "}"
				if value, ok = handler(variable, false, ""); !ok {
					value = variable
				}
				result.Append(value)
				continue

			case incToken, decrementToken, shiftToken:
				variable += match.Matched
				match = tokenizer.Nexts(idToken) //enclosedVarToken, idToken ?
				if match.Token != idToken {
					result.Append(variable)
					continue
				}
				fallthrough

			case idToken:

				variable += match.Matched
				variable = expandVariable(tokenizer, variable, handler)
				match = tokenizer.Nexts(callToken, incToken, decrementToken, beforeVarToken, unmatchedToken, eofToken)
				switch match.Token {

				case callToken:
					arguments := string(match.Matched[1 : len(match.Matched)-1])
					if value, ok = handler(variable, true, arguments); !ok {
						value = variable + match.Matched
					}
					result.Append(value)
					continue
				case incToken, decrementToken:
					variable += match.Matched
					match.Matched = ""
					fallthrough

				case beforeVarToken, unmatchedToken, eofToken, invalidToken:
					if value, ok = handler(variable, false, ""); !ok {
						value = variable
					}
					result.Append(value)
					result.Append(match.Matched)
					continue
				}

			default:
				result.Append(variable)
			}
		}
	}
	return result.Get()
}

func expandVariable(tokenizer *toolbox.Tokenizer, variable string, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) string {
	match := tokenizer.Nexts(keyIndexToken, arrayIndexToken)
	switch match.Token {
	case keyIndexToken:
		variable = expandSubKey(variable, match, tokenizer, handler)
	case arrayIndexToken:
		variable = expandIndex(variable, match, handler, tokenizer)
	}
	return variable
}

func expandIndex(variable string, match *toolbox.Token, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool), tokenizer *toolbox.Tokenizer) string {
	variable += toolbox.AsString(Parse(match.Matched, handler))
	match = tokenizer.Nexts(arrayIndexToken, keyIndexToken)
	switch match.Token {
	case keyIndexToken:
		variable = expandSubKey(variable, match, tokenizer, handler)
	case arrayIndexToken:
		variable += toolbox.AsString(Parse(match.Matched, handler))
	}
	return variable
}

func expandSubKey(variable string, match *toolbox.Token, tokenizer *toolbox.Tokenizer, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) string {
	variable += match.Matched
	match = tokenizer.Nexts(idToken, enclosedVarToken, arrayIndexToken)
	switch match.Token {
	case idToken:
		variable += match.Matched
		variable = expandVariable(tokenizer, variable, handler)
	case enclosedVarToken:
		expanded := expandEnclosed(match.Matched, handler)
		variable += toolbox.AsString(expanded)
	case arrayIndexToken:
		variable = expandIndex(variable, match, handler, tokenizer)
	}
	return variable
}

func expandEnclosed(expr string, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) interface{} {
	if strings.HasPrefix(expr, "{") && strings.HasSuffix(expr, "}") {
		expr = string(expr[1 : len(expr)-1])

	}
	tokenizer := toolbox.NewTokenizer(expr, invalidToken, eofToken, matchers)
	match, err := toolbox.ExpectTokenOptionallyFollowedBy(tokenizer, whitespace, "expected operatorTojeb", groupingToken, operatorTojeb)
	if err != nil {
		return Parse(expr, handler)
	}
	switch match.Token {
	case groupingToken:
		groupExpr := string(match.Matched[1 : len(match.Matched)-1])
		result := expandEnclosed(groupExpr, handler)
		if !(toolbox.IsInt(result) || toolbox.IsFloat(result)) {
			return Parse(expr, handler)
		}
		expandedGroup := toolbox.AsString(result) + string(expr[tokenizer.Index:])
		return expandEnclosed(expandedGroup, handler)
	case operatorTojeb:
		leftOperand, leftOk := tryNumericOperand(match.Matched, handler).(float64)
		operator := string(expr[tokenizer.Index : tokenizer.Index+1])
		rightOperand, rightOk := tryNumericOperand(string(expr[tokenizer.Index+1:]), handler).(float64)
		if !leftOk || !rightOk {
			return Parse(expr, handler)
		}
		var floatResult float64
		switch operator {
		case "+":
			floatResult = leftOperand + rightOperand
		case "-":
			floatResult = leftOperand - rightOperand
		case "/":
			if rightOperand == 0 { //division by zero issue
				return Parse(expr, handler)
			}
			floatResult = leftOperand / rightOperand
		case "*":
			floatResult = leftOperand * rightOperand
		case "^":
			floatResult = math.Pow(leftOperand, rightOperand)
		case "%":
			floatResult = float64(int(leftOperand) % int(rightOperand))
		default:
			return Parse(expr, handler)
		}
		intResult := int(floatResult)
		if floatResult == float64(intResult) {
			return intResult
		}
		return floatResult
	}
	return Parse(expr, handler)
}

func tryNumericOperand(expression string, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) interface{} {
	expression = strings.TrimSpace(expression)
	if result, err := toolbox.ToFloat(expression); err == nil {
		return result
	}
	left := expandEnclosed(expression, handler)
	if result, err := toolbox.ToFloat(left); err == nil {
		return result
	}

	left = Parse("$"+expression, handler)
	if result, err := toolbox.ToFloat(left); err == nil {
		return result
	}
	return expression
}

func asExpandedText(source interface{}) string {
	if toolbox.IsSlice(source) || toolbox.IsMap(source) {
		buf := new(bytes.Buffer)
		err := toolbox.NewJSONEncoderFactory().Create(buf).Encode(source)
		if err == nil {
			return buf.String()
		}
	}
	return toolbox.AsString(source)
}

type fragments []interface{}

func (f *fragments) Append(item interface{}) {
	if text, ok := item.(string); ok {
		if text == "" {
			return
		}
	}
	*f = append(*f, item)
}

func (f fragments) Get() interface{} {
	count := len(f)
	if count == 0 {
		return ""
	}
	var emptyCount = 0
	var result interface{}
	for _, item := range f {
		if text, ok := item.(string); ok && strings.TrimSpace(text) == "" {
			emptyCount++
		} else {
			result = item
		}
	}
	if emptyCount == count-1 {
		return result
	}
	var textResult = ""
	for _, item := range f {
		textResult += asExpandedText(item)
	}
	return textResult
}
<commit_msg>added nil pointer check<commit_after>package data

import (
	"bytes"
	"github.com/viant/toolbox"
	"math"
	"strings"
)

const (
	eofToken     = -1
	invalidToken = iota
	beforeVarToken
	varToken
	incToken
	decrementToken
	shiftToken
	enclosedVarToken
	callToken
	idToken
	arrayIndexToken
	unmatchedToken
	keyIndexToken
	whitespace
	groupingToken
	operatorTojeb
	doubleQuoteEnclosedToken
	comaToken
)

var matchers = map[int]toolbox.Matcher{
	beforeVarToken:           toolbox.NewTerminatorMatcher("$"),
	varToken:                 toolbox.NewCharactersMatcher("$"),
	comaToken:                toolbox.NewTerminatorMatcher(","),
	idToken:                  toolbox.NewCustomIdMatcher("_"),
	incToken:                 toolbox.NewKeywordsMatcher(true, "++"),
	decrementToken:           toolbox.NewKeywordsMatcher(true, "--"),
	shiftToken:               toolbox.NewKeywordsMatcher(true, "<-"),
	arrayIndexToken:          toolbox.NewBodyMatcher("[", "]"),
	callToken:                toolbox.NewBodyMatcher("(", ")"),
	enclosedVarToken:         toolbox.NewBodyMatcher("{", "}"),
	doubleQuoteEnclosedToken: toolbox.NewBodyMatcher(`"`, `"`),
	keyIndexToken:            toolbox.NewCustomIdMatcher("."),
	unmatchedToken:           toolbox.NewRemainingSequenceMatcher(),
	groupingToken:            toolbox.NewBodyMatcher("(", ")"),
	operatorTojeb:            toolbox.NewTerminatorMatcher("+", "-", "*", "/", "^", "%"),
	whitespace:               toolbox.NewCharactersMatcher(" \t\n\r"),
}

//Parse parses expression
func Parse(expression string, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) interface{} {
	tokenizer := toolbox.NewTokenizer(expression, invalidToken, eofToken, matchers)
	var value interface{}
	var result = fragments{}
	var ok bool
	done := false
	for tokenizer.Index < len(expression) && !done {
		match := tokenizer.Nexts(beforeVarToken, varToken, unmatchedToken, eofToken)
		switch match.Token {
		case unmatchedToken:
			result.Append(match.Matched)
			done = true
			continue
		case eofToken:
			break
		case beforeVarToken:
			result.Append(match.Matched)
			continue

		case varToken:
			variable := "$"
			match = tokenizer.Nexts(idToken, enclosedVarToken, incToken, decrementToken, shiftToken)
			switch match.Token {
			case eofToken:
				result.Append(variable)
				continue
			case enclosedVarToken:

				expanded := expandEnclosed(match.Matched, handler)
				if toolbox.IsFloat(expanded) || toolbox.IsInt(expanded) {
					value = expanded
					result.Append(value)
					continue
				}
				expandedText := toolbox.AsString(expanded)
				if strings.HasSuffix(expandedText, ")") {
					value = Parse("$"+expandedText, handler)
					if textValue, ok := value.(string); ok && textValue == "$"+expandedText {
						value = "${" + expandedText + "}"
					}
					result.Append(value)
					continue
				}

				variable := "${" + expandedText + "}"
				if value, ok = handler(variable, false, ""); !ok {
					value = variable
				}
				result.Append(value)
				continue

			case incToken, decrementToken, shiftToken:
				variable += match.Matched
				match = tokenizer.Nexts(idToken) //enclosedVarToken, idToken ?
				if match.Token != idToken {
					result.Append(variable)
					continue
				}
				fallthrough

			case idToken:

				variable += match.Matched
				variable = expandVariable(tokenizer, variable, handler)
				match = tokenizer.Nexts(callToken, incToken, decrementToken, beforeVarToken, unmatchedToken, eofToken)
				switch match.Token {

				case callToken:
					arguments := string(match.Matched[1 : len(match.Matched)-1])
					if value, ok = handler(variable, true, arguments); !ok {
						value = variable + match.Matched
					}
					result.Append(value)
					continue
				case incToken, decrementToken:
					variable += match.Matched
					match.Matched = ""
					fallthrough

				case beforeVarToken, unmatchedToken, eofToken, invalidToken:
					if value, ok = handler(variable, false, ""); !ok {
						value = variable
					}
					result.Append(value)
					result.Append(match.Matched)
					continue
				}

			default:
				result.Append(variable)
			}
		}
	}
	return result.Get()
}

func expandVariable(tokenizer *toolbox.Tokenizer, variable string, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) string {
	match := tokenizer.Nexts(keyIndexToken, arrayIndexToken)
	switch match.Token {
	case keyIndexToken:
		variable = expandSubKey(variable, match, tokenizer, handler)
	case arrayIndexToken:
		variable = expandIndex(variable, match, handler, tokenizer)
	}
	return variable
}

func expandIndex(variable string, match *toolbox.Token, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool), tokenizer *toolbox.Tokenizer) string {
	variable += toolbox.AsString(Parse(match.Matched, handler))
	match = tokenizer.Nexts(arrayIndexToken, keyIndexToken)
	switch match.Token {
	case keyIndexToken:
		variable = expandSubKey(variable, match, tokenizer, handler)
	case arrayIndexToken:
		variable += toolbox.AsString(Parse(match.Matched, handler))
	}
	return variable
}

func expandSubKey(variable string, match *toolbox.Token, tokenizer *toolbox.Tokenizer, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) string {
	variable += match.Matched
	match = tokenizer.Nexts(idToken, enclosedVarToken, arrayIndexToken)
	switch match.Token {
	case idToken:
		variable += match.Matched
		variable = expandVariable(tokenizer, variable, handler)
	case enclosedVarToken:
		expanded := expandEnclosed(match.Matched, handler)
		variable += toolbox.AsString(expanded)
	case arrayIndexToken:
		variable = expandIndex(variable, match, handler, tokenizer)
	}
	return variable
}

func expandEnclosed(expr string, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) interface{} {
	if strings.HasPrefix(expr, "{") && strings.HasSuffix(expr, "}") {
		expr = string(expr[1 : len(expr)-1])

	}
	tokenizer := toolbox.NewTokenizer(expr, invalidToken, eofToken, matchers)
	match, err := toolbox.ExpectTokenOptionallyFollowedBy(tokenizer, whitespace, "expected operatorTojeb", groupingToken, operatorTojeb)
	if err != nil {
		return Parse(expr, handler)
	}
	switch match.Token {
	case groupingToken:
		groupExpr := string(match.Matched[1 : len(match.Matched)-1])
		result := expandEnclosed(groupExpr, handler)
		if !(toolbox.IsInt(result) || toolbox.IsFloat(result)) {
			return Parse(expr, handler)
		}
		expandedGroup := toolbox.AsString(result) + string(expr[tokenizer.Index:])
		return expandEnclosed(expandedGroup, handler)
	case operatorTojeb:
		leftOperand, leftOk := tryNumericOperand(match.Matched, handler).(float64)
		operator := string(expr[tokenizer.Index : tokenizer.Index+1])
		rightOperand, rightOk := tryNumericOperand(string(expr[tokenizer.Index+1:]), handler).(float64)
		if !leftOk || !rightOk {
			return Parse(expr, handler)
		}
		var floatResult float64
		switch operator {
		case "+":
			floatResult = leftOperand + rightOperand
		case "-":
			floatResult = leftOperand - rightOperand
		case "/":
			if rightOperand == 0 { //division by zero issue
				return Parse(expr, handler)
			}
			floatResult = leftOperand / rightOperand
		case "*":
			floatResult = leftOperand * rightOperand
		case "^":
			floatResult = math.Pow(leftOperand, rightOperand)
		case "%":
			floatResult = float64(int(leftOperand) % int(rightOperand))
		default:
			return Parse(expr, handler)
		}
		intResult := int(floatResult)
		if floatResult == float64(intResult) {
			return intResult
		}
		return floatResult
	}
	return Parse(expr, handler)
}

func tryNumericOperand(expression string, handler func(expression string, isUDF bool, argument interface{}) (interface{}, bool)) interface{} {
	expression = strings.TrimSpace(expression)
	if result, err := toolbox.ToFloat(expression); err == nil {
		return result
	}
	left := expandEnclosed(expression, handler)
	if result, err := toolbox.ToFloat(left); err == nil {
		return result
	}

	left = Parse("$"+expression, handler)
	if result, err := toolbox.ToFloat(left); err == nil {
		return result
	}
	return expression
}

func asExpandedText(source interface{}) string {
	if source != nil && (toolbox.IsSlice(source) || toolbox.IsMap(source)) {
		buf := new(bytes.Buffer)
		err := toolbox.NewJSONEncoderFactory().Create(buf).Encode(source)
		if err == nil {
			return buf.String()
		}
	}
	return toolbox.AsString(source)
}

type fragments []interface{}

func (f *fragments) Append(item interface{}) {
	if text, ok := item.(string); ok {
		if text == "" {
			return
		}
	}
	*f = append(*f, item)
}

func (f fragments) Get() interface{} {
	count := len(f)
	if count == 0 {
		return ""
	}
	var emptyCount = 0
	var result interface{}
	for _, item := range f {
		if text, ok := item.(string); ok && strings.TrimSpace(text) == "" {
			emptyCount++
		} else {
			result = item
		}
	}
	if emptyCount == count-1 {
		return result
	}
	var textResult = ""
	for _, item := range f {
		textResult += asExpandedText(item)
	}
	return textResult
}
<|endoftext|>


<commit_before>package imgmeta

import (
	"github.com/vanng822/imgscale/imagick"
)

func getMeta(filename string) map[string]string {
	img := imagick.NewMagickWand()
	img.ReadImage(filename)
	return img.GetImagePropertyValues("*")
}<commit_msg>Fix memory leak<commit_after>package imgmeta

import (
	"github.com/vanng822/imgscale/imagick"
)

func getMeta(filename string) map[string]string {
	img := imagick.NewMagickWand()
	img.ReadImage(filename)
	defer img.Destroy()
	return img.GetImagePropertyValues("*")
}<|endoftext|>


<commit_before>package wsapi

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"net/url"
	"strconv"
	"time"

	"github.com/FactomProject/FactomCode/factomapi"
	"github.com/FactomProject/FactomCode/factomchain/factoid"
	"github.com/FactomProject/FactomCode/notaryapi"
	"github.com/FactomProject/FactomCode/wallet"
	"github.com/FactomProject/gocoding"
	"github.com/hoisie/web"
)

// handle Submit Entry converts a json post to a factom.Entry then submits the
// entry to factom.
func handleSubmitEntry(ctx *web.Context) {
	log := serverLog
	log.Debug("handleSubmitEntry")

	switch ctx.Params["format"] {
	case "json":
		entry := new(notaryapi.Entry)
		reader := gocoding.ReadBytes([]byte(ctx.Params["entry"]))
		err := factomapi.SafeUnmarshal(reader, entry)
		if err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
			log.Error(err)
		}

		if err := factomapi.CommitEntry(entry); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
			log.Error(err)
		}

		time.Sleep(1 * time.Second)
		if err := factomapi.RevealEntry(entry); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
			log.Error(err)
		}
		fmt.Fprintln(ctx, "Entry Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

// handleSubmitChain converts a json post to a factomapi.Chain then submits the
// entry to factomapi.
func handleSubmitChain(ctx *web.Context) {
	log := serverLog
	log.Debug("handleSubmitChain")
	switch ctx.Params["format"] {
	case "json":
		reader := gocoding.ReadBytes([]byte(ctx.Params["chain"]))
		c := new(notaryapi.EChain)
		factomapi.SafeUnmarshal(reader, c)

		c.GenerateIDFromName()
		if c.FirstEntry == nil {
			fmt.Fprintln(ctx,
				"The first entry is required for submitting the chain:")
			log.Warning("The first entry is required for submitting the chain")
			return
		} else {
			c.FirstEntry.ChainID = *c.ChainID
		}

		log.Debug("c.ChainID:", c.ChainID.String())

		if err := factomapi.CommitChain(c); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the chain:", err)
			log.Error(err)
		}

		time.Sleep(1 * time.Second)

		if err := factomapi.RevealChain(c); err != nil {
			fmt.Println(err.Error())
			fmt.Fprintln(ctx,
				"there was a problem with submitting the chain:", err)
			log.Error(err)
		}

		fmt.Fprintln(ctx, "Chain Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

// handleBuyCredit will add entry credites to the specified key. Currently the
// entry credits are given without any factoid transactions occuring.
func handleBuyCredit(ctx *web.Context) {
	log := serverLog
	log.Debug("handleBuyCreditPost")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	var abortMessage, abortReturn string

	defer func() {
		if abortMessage != "" && abortReturn != "" {
			ctx.Header().Add("Location", fmt.Sprint("/failed?message=", abortMessage, "&return=", abortReturn))
			ctx.WriteHeader(303)
		}
	}()

	ecPubKey := new(notaryapi.Hash)
	if ctx.Params["to"] == "wallet" {
		ecPubKey.Bytes = (*wallet.ClientPublicKey().Key)[:]
	} else {
		ecPubKey.Bytes, _ = hex.DecodeString(ctx.Params["to"])
	}

	log.Info("handleBuyCreditPost using pubkey: ", ecPubKey, " requested", ctx.Params["to"])

	factoid, err := strconv.ParseFloat(ctx.Params["value"], 10)
	if err != nil {
		log.Error(err)
	}
	value := uint64(factoid * 1000000000)
	err = factomapi.BuyEntryCredit(1, ecPubKey, nil, value, 0, nil)
	if err != nil {
		abortMessage = fmt.Sprint("An error occured while submitting the buycredit request: ", err.Error())
		log.Error(err)
		return
	} else {
		fmt.Fprintln(ctx, "MsgGetCredit Submitted")
	}
}

func handleFactoidTx(ctx *web.Context) {
	log := serverLog
	log.Debug("handleFactoidTx")
	n, err := strconv.ParseInt(ctx.Params["amount"], 10, 32)
	if err != nil {
		log.Error(err)
	}
	amt := n
	var toaddress string
	if ctx.Params["to"] == "wallet" {
		toaddress = wallet.FactoidAddress()
	} else {
		toaddress = ctx.Params["to"]
	}

	addr, _, err := factoid.DecodeAddress(toaddress)
	if err != nil {
		log.Error(err)
	}

	log.Debug("factoid.NewTxFromInputToAddr")
	txm := factoid.NewTxFromInputToAddr(
		factoid.NewFaucetIn(),
		amt,
		addr)
	ds := wallet.DetachMarshalSign(txm.TxData)
	ss := factoid.NewSingleSignature(ds)
	factoid.AddSingleSigToTxMsg(txm, ss)

	wire := factoid.TxMsgToWire(txm)

	time.Sleep(1 * time.Second)
	if err := factomapi.SubmitFactoidTx(wire); err != nil {
		fmt.Fprintln(ctx,
			"there was a problem submitting the tx:", err.Error())
		log.Error(err)
	}

	log.Debug("MsgTx: ", wire)
}

// handleCreditBalance will return the current entry credit balance of the
// spesified pubKey
func handleCreditBalance(ctx *web.Context) {
	log := serverLog
	log.Debug("handleGetCreditBalance")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	ecPubKey := new(notaryapi.Hash)
	if ctx.Params["pubkey"] == "wallet" {
		ecPubKey.Bytes = (*wallet.ClientPublicKey().Key)[:]
	} else {
		p, err := hex.DecodeString(ctx.Params["pubkey"])
		if err != nil {
			log.Error(err)
		}
		ecPubKey.Bytes = p
	}

	log.Info("handleGetCreditBalance using pubkey: ", ecPubKey,
		" requested", ctx.Params["pubkey"])

	balance, err := factomapi.GetEntryCreditBalance(ecPubKey)
	if err != nil {
		log.Error(err)
	}

	ecBalance := new(notaryapi.ECBalance)
	ecBalance.Credits = balance
	ecBalance.PublicKey = ecPubKey

	log.Info("Balance for pubkey ", ctx.Params["pubkey"], " is: ", balance)

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, ecBalance)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request ")
		log.Error(err)
		return
	}
}

func handleDBlocksByRange(ctx *web.Context, fromHeightStr string,
	toHeightStr string) {
	log := serverLog
	log.Debug("handleDBlocksByRange")

	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	fromBlockHeight, err := strconv.Atoi(fromHeightStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad fromBlockHeight")
		log.Error(err)
		return
	}
	toBlockHeight, err := strconv.Atoi(toHeightStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad toBlockHeight")
		log.Error(err)
		return
	}

	dBlocks, err := factomapi.GetDirectoryBloks(uint64(fromBlockHeight), uint64(toBlockHeight))
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, dBlocks)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}
}

func handleDBlockByHash(ctx *web.Context, hashStr string) {
	log := serverLog
	log.Debug("handleDBlockByHash")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	dBlock, err := factomapi.GetDirectoryBlokByHashStr(hashStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad Request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, dBlock)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request ")
		log.Error(err)
		return
	}
}

func handleEBlockByHash(ctx *web.Context, hashStr string) {
	log := serverLog
	log.Debug("handleEBlockByHash")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	eBlock, err := factomapi.GetEntryBlokByHashStr(hashStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad Request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, eBlock)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}
}

func handleEBlockByMR(ctx *web.Context, mrStr string) {
	log := serverLog
	log.Debug("handleEBlockByMR")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()
	log.Info("mrstr:", mrStr)
	newstr, _ := url.QueryUnescape(mrStr)
	log.Info("newstr:", newstr)
	eBlock, err := factomapi.GetEntryBlokByMRStr(newstr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad Request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, eBlock)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}
}

func handleEntryByHash(ctx *web.Context, hashStr string) {
	log := serverLog
	log.Debug("handleEBlockByMR")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	entry, err := factomapi.GetEntryByHashStr(hashStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad Request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, entry)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}
}
<commit_msg>comments and formatting changes to code. hanlders now in alphabet order<commit_after>package wsapi

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"net/url"
	"strconv"
	"time"

	"github.com/FactomProject/FactomCode/factomapi"
	"github.com/FactomProject/FactomCode/factomchain/factoid"
	"github.com/FactomProject/FactomCode/notaryapi"
	"github.com/FactomProject/FactomCode/wallet"
	"github.com/FactomProject/gocoding"
	"github.com/hoisie/web"
)

// handleBuyCredit will add entry credites to the specified key. Currently the
// entry credits are given without any factoid transactions occuring.
func handleBuyCredit(ctx *web.Context) {
	log := serverLog
	log.Debug("handleBuyCreditPost")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	var abortMessage, abortReturn string

	defer func() {
		if abortMessage != "" && abortReturn != "" {
			ctx.Header().Add("Location", fmt.Sprint("/failed?message=",
				abortMessage, "&return=", abortReturn))
			ctx.WriteHeader(303)
		}
	}()

	ecPubKey := new(notaryapi.Hash)
	if ctx.Params["to"] == "wallet" {
		ecPubKey.Bytes = (*wallet.ClientPublicKey().Key)[:]
	} else {
		ecPubKey.Bytes, _ = hex.DecodeString(ctx.Params["to"])
	}

	log.Info("handleBuyCreditPost using pubkey: ", ecPubKey, " requested",
		ctx.Params["to"])

	factoid, err := strconv.ParseFloat(ctx.Params["value"], 10)
	if err != nil {
		log.Error(err)
	}
	value := uint64(factoid * 1000000000)
	err = factomapi.BuyEntryCredit(1, ecPubKey, nil, value, 0, nil)
	if err != nil {
		abortMessage = fmt.Sprint("An error occured while submitting the buycredit request: ", err.Error())
		log.Error(err)
		return
	} else {
		fmt.Fprintln(ctx, "MsgGetCredit Submitted")
	}
}

// handleCreditBalance will return the current entry credit balance of the
// spesified pubKey
func handleCreditBalance(ctx *web.Context) {
	log := serverLog
	log.Debug("handleGetCreditBalance")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	ecPubKey := new(notaryapi.Hash)
	if ctx.Params["pubkey"] == "wallet" {
		ecPubKey.Bytes = (*wallet.ClientPublicKey().Key)[:]
	} else {
		p, err := hex.DecodeString(ctx.Params["pubkey"])
		if err != nil {
			log.Error(err)
		}
		ecPubKey.Bytes = p
	}

	log.Info("handleGetCreditBalance using pubkey: ", ecPubKey,
		" requested", ctx.Params["pubkey"])

	balance, err := factomapi.GetEntryCreditBalance(ecPubKey)
	if err != nil {
		log.Error(err)
	}

	ecBalance := new(notaryapi.ECBalance)
	ecBalance.Credits = balance
	ecBalance.PublicKey = ecPubKey

	log.Info("Balance for pubkey ", ctx.Params["pubkey"], " is: ", balance)

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, ecBalance)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request ")
		log.Error(err)
		return
	}
}

// handleDBlockByHash will take a directory block hash and return the directory
// block information in json format.
func handleDBlockByHash(ctx *web.Context, hashStr string) {
	log := serverLog
	log.Debug("handleDBlockByHash")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	dBlock, err := factomapi.GetDirectoryBlokByHashStr(hashStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad Request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, dBlock)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request ")
		log.Error(err)
		return
	}
}

// handleDBlockByRange will get a block height range and return the information
// for all of the directory blocks within the range in json format.
func handleDBlocksByRange(ctx *web.Context, fromHeightStr string,
	toHeightStr string) {
	log := serverLog
	log.Debug("handleDBlocksByRange")

	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	fromBlockHeight, err := strconv.Atoi(fromHeightStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad fromBlockHeight")
		log.Error(err)
		return
	}
	toBlockHeight, err := strconv.Atoi(toHeightStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad toBlockHeight")
		log.Error(err)
		return
	}

	dBlocks, err := factomapi.GetDirectoryBloks(uint64(fromBlockHeight),
		uint64(toBlockHeight))
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, dBlocks)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}
}

func handleEBlockByHash(ctx *web.Context, hashStr string) {
	log := serverLog
	log.Debug("handleEBlockByHash")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	eBlock, err := factomapi.GetEntryBlokByHashStr(hashStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad Request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, eBlock)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}
}

func handleEBlockByMR(ctx *web.Context, mrStr string) {
	log := serverLog
	log.Debug("handleEBlockByMR")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()
	log.Info("mrstr:", mrStr)
	newstr, _ := url.QueryUnescape(mrStr)
	log.Info("newstr:", newstr)
	eBlock, err := factomapi.GetEntryBlokByMRStr(newstr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad Request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, eBlock)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}
}

func handleEntryByHash(ctx *web.Context, hashStr string) {
	log := serverLog
	log.Debug("handleEBlockByMR")
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	entry, err := factomapi.GetEntryByHashStr(hashStr)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad Request")
		log.Error(err)
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, entry)
	if err != nil {
		httpcode = 400
		buf.WriteString("Bad request")
		log.Error(err)
		return
	}
}

func handleFactoidTx(ctx *web.Context) {
	log := serverLog
	log.Debug("handleFactoidTx")
	n, err := strconv.ParseInt(ctx.Params["amount"], 10, 32)
	if err != nil {
		log.Error(err)
	}
	amt := n
	var toaddress string
	if ctx.Params["to"] == "wallet" {
		toaddress = wallet.FactoidAddress()
	} else {
		toaddress = ctx.Params["to"]
	}

	addr, _, err := factoid.DecodeAddress(toaddress)
	if err != nil {
		log.Error(err)
	}

	log.Debug("factoid.NewTxFromInputToAddr")
	txm := factoid.NewTxFromInputToAddr(
		factoid.NewFaucetIn(),
		amt,
		addr)
	ds := wallet.DetachMarshalSign(txm.TxData)
	ss := factoid.NewSingleSignature(ds)
	factoid.AddSingleSigToTxMsg(txm, ss)

	wire := factoid.TxMsgToWire(txm)

	time.Sleep(1 * time.Second)
	if err := factomapi.SubmitFactoidTx(wire); err != nil {
		fmt.Fprintln(ctx,
			"there was a problem submitting the tx:", err.Error())
		log.Error(err)
	}

	log.Debug("MsgTx: ", wire)
}

// handleSubmitChain converts a json post to a factomapi.Chain then submits the
// entry to factomapi.
func handleSubmitChain(ctx *web.Context) {
	log := serverLog
	log.Debug("handleSubmitChain")
	switch ctx.Params["format"] {
	case "json":
		reader := gocoding.ReadBytes([]byte(ctx.Params["chain"]))
		c := new(notaryapi.EChain)
		factomapi.SafeUnmarshal(reader, c)

		c.GenerateIDFromName()
		if c.FirstEntry == nil {
			fmt.Fprintln(ctx,
				"The first entry is required for submitting the chain:")
			log.Warning("The first entry is required for submitting the chain")
			return
		} else {
			c.FirstEntry.ChainID = *c.ChainID
		}

		log.Debug("c.ChainID:", c.ChainID.String())

		if err := factomapi.CommitChain(c); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the chain:", err)
			log.Error(err)
		}

		time.Sleep(1 * time.Second)

		if err := factomapi.RevealChain(c); err != nil {
			fmt.Println(err.Error())
			fmt.Fprintln(ctx,
				"there was a problem with submitting the chain:", err)
			log.Error(err)
		}

		fmt.Fprintln(ctx, "Chain Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

// handleSubmitEntry converts a json post to a factom.Entry then submits the
// entry to factom.
func handleSubmitEntry(ctx *web.Context) {
	log := serverLog
	log.Debug("handleSubmitEntry")

	switch ctx.Params["format"] {
	case "json":
		entry := new(notaryapi.Entry)
		reader := gocoding.ReadBytes([]byte(ctx.Params["entry"]))
		err := factomapi.SafeUnmarshal(reader, entry)
		if err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
			log.Error(err)
		}

		if err := factomapi.CommitEntry(entry); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
			log.Error(err)
		}

		time.Sleep(1 * time.Second)
		if err := factomapi.RevealEntry(entry); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
			log.Error(err)
		}
		fmt.Fprintln(ctx, "Entry Submitted")
	default:
		ctx.WriteHeader(403)
	}
}
<|endoftext|>


<commit_before>package gwr

import (
	"errors"
	"fmt"
	"io"
)

// DefaultDataSources is default data sources registry which data sources are
// added to by the module-level Add* functions.  It is used by all of the
// protocol servers if no data sources are provided.
var DefaultDataSources DataSources

func init() {
	DefaultDataSources.init()
}

// AddDataSource adds a data source to the default data sources registry.
func AddDataSource(ds DataSource) error {
	return DefaultDataSources.AddDataSource(ds)
}

// AddMarshaledDataSource adds a generically marshaled data source to the
// default data sources registry.
func AddMarshaledDataSource(gds GenericDataSource) error {
	return DefaultDataSources.AddMarshaledDataSource(gds)
}

// DataSource is the interface implemented by all
// data sources.
type DataSource interface {
	// NOTE: implementation is self encoding, but may abstract internally
	Info() DataSourceInfo
	Get(format string, w io.Writer) error
	Watch(format string, w io.Writer) error
}

var (
	// ErrUnsupportedFormat should be returned by DataSource.Get and
	// DataSource.Watch if the requested format is not supported.
	ErrUnsupportedFormat = errors.New("unsupported format")

	// ErrNotGetable should be returned by DataSource.Get if the data source
	// does not support get.
	ErrNotGetable = errors.New("get not supported, data source is watch-only")

	// ErrNotWatchable should be returned by DataSource.Get if the data source
	// does not support watch.
	ErrNotWatchable = errors.New("watch not supported, data source is get-only")
)

// DataSourceInfo provides a description of each
// data source, such as name and supported formats.
type DataSourceInfo struct {
	Name    string                 `json:"name"`
	Formats []string               `json:"formats"`
	Attrs   map[string]interface{} `json:"attrs"`
}

// DataSources is a flat collection of DataSources
// with a meta introspection data source.
type DataSources struct {
	sources   map[string]DataSource
	metaNouns metaNounDataSource
}

// NewDataSources creates a DataSources structure
// an sets up its "/meta/nouns" data source.
func NewDataSources() *DataSources {
	dss := &DataSources{}
	dss.init()
	return dss
}

func (dss *DataSources) init() {
	dss.sources = make(map[string]DataSource, 2)
	dss.metaNouns.sources = dss
	dss.AddMarshaledDataSource(&dss.metaNouns)
}

// Get returns the named data source or nil if none is defined.
func (dss *DataSources) Get(name string) DataSource {
	source, ok := dss.sources[name]
	if ok {
		return source
	}
	return nil
}

// Info returns a map of all DataSource.Info() data
func (dss *DataSources) Info() map[string]DataSourceInfo {
	info := make(map[string]DataSourceInfo, len(dss.sources))
	for name, ds := range dss.sources {
		info[name] = ds.Info()
	}
	return info
}

// AddMarshaledDataSource adds a generically-marshaled data source. It is a
// convenience for AddDataSource(NewMarshaledDataSource(gds, nil))
func (dss *DataSources) AddMarshaledDataSource(gds GenericDataSource) error {
	mds := NewMarshaledDataSource(gds, nil)
	// TODO: useful to return mds?
	return dss.AddDataSource(mds)
}

// AddDataSource adds a DataSource, if none is
// already defined for the given name.
func (dss *DataSources) AddDataSource(ds DataSource) error {
	info := ds.Info()
	_, ok := dss.sources[info.Name]
	if ok {
		return fmt.Errorf("data source already defined")
	}
	dss.sources[info.Name] = ds
	dss.metaNouns.dataSourceAdded(ds)
	return nil
}

// TODO: do we really need to support removing data sources?  I can see the
// case for intermediaries perhaps, and suspect that is needed... but punting
// for now.
<commit_msg>DataSource: expand interface documentation<commit_after>package gwr

import (
	"errors"
	"fmt"
	"io"
)

// DefaultDataSources is default data sources registry which data sources are
// added to by the module-level Add* functions.  It is used by all of the
// protocol servers if no data sources are provided.
var DefaultDataSources DataSources

func init() {
	DefaultDataSources.init()
}

// AddDataSource adds a data source to the default data sources registry.
func AddDataSource(ds DataSource) error {
	return DefaultDataSources.AddDataSource(ds)
}

// AddMarshaledDataSource adds a generically marshaled data source to the
// default data sources registry.
func AddMarshaledDataSource(gds GenericDataSource) error {
	return DefaultDataSources.AddMarshaledDataSource(gds)
}

// DataSource is the low-level interface implemented by all data sources.
//
// On formats, implementanions:
// - must implement format == "json"
// - should implement format == "text"
// - may implement any other formats that make sense for them
//
// Further implementation requirements are listed within the interface
// functions' documentation.
type DataSource interface {
	// Info returns a struct describing the formats and other capabilities of
	// this data source.  All implemented formats must be listed in
	// Info().Formats.  At least "json" should be in Info().Formats.
	Info() DataSourceInfo

	// Get implementations:
	// - may return ErrNotGetable if get is not supported by the data source
	// - if the format is not support then ErrUnsupportedFormat must be returned
	// - must format and write any available data to the supplied io.Writer
	// - should return any write error
	Get(format string, w io.Writer) error

	// Watch implementations:
	// - may return ErrNotWatchable if watch is not supported by the data
	//   source
	// - if the format is not support then ErrUnsupportedFormat must be returned
	// - may format and write initial data to the supplied io.Writer; any
	//   initial write error must be returned
	// - may retain and write to the supplied io.Writer indefinately until it
	//   returns a write error
	//
	// Note that at this level, data sources are responsible for both item
	// marshalling and stream framing.
	//
	// Framing for the required "json" format is as follows:
	// - JSON must be encoded in compact (no intermediate whitespace) form
	// - each JSON record must be separated by a newline "\n"
	//
	// Framing for the required "text" format is as follows:
	// - any initial stream data should be followed by a blank line (double new
	//   line "\n\n")
	// - items should be separated by newlines
	// - if an item's text form takes up multiple lines, it should either use
	//   indentation or a double blank line to separate itself from siblings
	Watch(format string, w io.Writer) error
}

var (
	// ErrUnsupportedFormat should be returned by DataSource.Get and
	// DataSource.Watch if the requested format is not supported.
	ErrUnsupportedFormat = errors.New("unsupported format")

	// ErrNotGetable should be returned by DataSource.Get if the data source
	// does not support get.
	ErrNotGetable = errors.New("get not supported, data source is watch-only")

	// ErrNotWatchable should be returned by DataSource.Get if the data source
	// does not support watch.
	ErrNotWatchable = errors.New("watch not supported, data source is get-only")
)

// DataSourceInfo provides a description of each
// data source, such as name and supported formats.
type DataSourceInfo struct {
	Name    string                 `json:"name"`
	Formats []string               `json:"formats"`
	Attrs   map[string]interface{} `json:"attrs"`
}

// DataSources is a flat collection of DataSources
// with a meta introspection data source.
type DataSources struct {
	sources   map[string]DataSource
	metaNouns metaNounDataSource
}

// NewDataSources creates a DataSources structure
// an sets up its "/meta/nouns" data source.
func NewDataSources() *DataSources {
	dss := &DataSources{}
	dss.init()
	return dss
}

func (dss *DataSources) init() {
	dss.sources = make(map[string]DataSource, 2)
	dss.metaNouns.sources = dss
	dss.AddMarshaledDataSource(&dss.metaNouns)
}

// Get returns the named data source or nil if none is defined.
func (dss *DataSources) Get(name string) DataSource {
	source, ok := dss.sources[name]
	if ok {
		return source
	}
	return nil
}

// Info returns a map of all DataSource.Info() data
func (dss *DataSources) Info() map[string]DataSourceInfo {
	info := make(map[string]DataSourceInfo, len(dss.sources))
	for name, ds := range dss.sources {
		info[name] = ds.Info()
	}
	return info
}

// AddMarshaledDataSource adds a generically-marshaled data source. It is a
// convenience for AddDataSource(NewMarshaledDataSource(gds, nil))
func (dss *DataSources) AddMarshaledDataSource(gds GenericDataSource) error {
	mds := NewMarshaledDataSource(gds, nil)
	// TODO: useful to return mds?
	return dss.AddDataSource(mds)
}

// AddDataSource adds a DataSource, if none is
// already defined for the given name.
func (dss *DataSources) AddDataSource(ds DataSource) error {
	info := ds.Info()
	_, ok := dss.sources[info.Name]
	if ok {
		return fmt.Errorf("data source already defined")
	}
	dss.sources[info.Name] = ds
	dss.metaNouns.dataSourceAdded(ds)
	return nil
}

// TODO: do we really need to support removing data sources?  I can see the
// case for intermediaries perhaps, and suspect that is needed... but punting
// for now.
<|endoftext|>


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

package wav

import (
	"bytes"
	"io/ioutil"
	"os"
	"testing"

	"azul3d.org/audio.v1"
)

type decodeTest struct {
	file         string
	samplesTotal int
	audio.Config
	start audio.Slice
}

func testDecode(t *testing.T, tst decodeTest) {
	// Open the file.
	file, err := os.Open(tst.file)
	if err != nil {
		t.Fatal(err)
	}

	// Create a decoder for the audio source
	decoder, format, err := audio.NewDecoder(file)
	if err != nil {
		t.Fatal(err)
	}

	// Check for a valid format identifier.
	if format != "wav" {
		t.Fatalf(`Incorrect format, want "wav" got %q\n`, format)
	}

	// Ensure the decoder's configuration is correct.
	config := decoder.Config()
	if config != tst.Config {
		t.Fatalf("Incorrect configuration, expected %+v, got %+v\n", tst.Config, config)
	}

	// Create a slice large enough to hold 1 second of audio samples.
	bufSize := 1 * config.SampleRate * config.Channels
	buf := tst.start.Make(bufSize, bufSize)

	// Read audio samples until there are no more.
	first := true
	var samplesTotal int
	for {
		read, err := decoder.Read(buf)
		samplesTotal += read
		if first {
			// Validate the audio samples.
			first = false
			for i := 0; i < tst.start.Len(); i++ {
				if buf.At(i) != tst.start.At(i) {
					t.Log("got", buf.Slice(0, tst.start.Len()))
					t.Log("want", tst.start)
					t.Fatal("Bad sample data.")
				}
			}
		}
		if err == audio.EOS {
			break
		}
		if err != nil {
			t.Fatal(err)
		}
	}

	// Ensure that we read the correct number of samples.
	if samplesTotal != tst.samplesTotal {
		t.Fatalf("Read %d audio samples, expected %d.\n", samplesTotal, tst.samplesTotal)
	}
}

func TestDecodeFloat32(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_float32.wav",
		samplesTotal: 993566,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.F32Samples{0, 0, 9.682657e-08, 3.3106906e-10, 9.845178e-07, 3.9564156e-09, 3.711236e-06, 1.869304e-08, 8.562939e-06, 5.7355663e-08, 1.4786613e-05, 1.3752022e-07, 2.1342606e-05, 2.8124632e-07, 2.7840168e-05},
	})
}

func TestDecodeFloat64(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_float64.wav",
		samplesTotal: 993577,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.F64Samples{0, 0, 9.682656809673063e-08, 3.31069061054734e-10, 9.845177828537999e-07, 3.9564156395499595e-09, 3.7112361042090924e-06, 1.8693040004791328e-08, 8.56293900142191e-06, 5.7355663329872186e-08, 1.4786613064643461e-05, 1.375202174358492e-07, 2.134260648745112e-05, 2.812463151258271e-07, 2.7840167604153976e-05},
	})
}

func TestDecodeUInt8(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_uint8.wav",
		samplesTotal: 993544,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.PCM8Samples{128, 128, 128, 128, 127, 128, 127, 128, 128, 127, 128, 128, 127, 128, 127},
	})
}

func TestDecodeInt16(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_int16.wav",
		samplesTotal: 993566,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.PCM16Samples{0, 0, 0, -1, 2, -2, 3, -3, 2, -1, 1, 0, 2, -3, 4},
	})
}

func TestDecodeInt24(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_int24.wav",
		samplesTotal: 993573,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.PCM32Samples{0, 0, 0, 0, 8, 0, 31, 0, 71, 0, 124, 1, 179, 2, 233},
	})
}

func TestDecodeInt32(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_int32.wav",
		samplesTotal: 993577,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.PCM32Samples{0, 0, 208, 1, 2114, 8, 7970, 40, 18389, 123, 31754, 295, 45833, 604, 59786},
	})
}

func TestDecodeALaw(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_alaw.wav",
		samplesTotal: 993530,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.ALawSamples{213, 213, 85, 213, 85, 213, 85, 213, 85, 213, 85, 213, 213, 213, 213},
	})
}

func TestDecodeMuLaw(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_mulaw.wav",
		samplesTotal: 993530,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.MuLawSamples{255, 255, 255, 255, 255, 255, 127, 255, 255, 127, 255, 255, 127, 255, 127},
	})
}

func benchDecode(b *testing.B, fmt audio.Slice, path string) {
	// Read the file into memory so we are strictly benchmarking the decoder,
	// avoiding disk read performance.
	data, err := ioutil.ReadFile("testdata/tune_stereo_44100hz_int24.wav")
	if err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()

	// Create a new decoder for the audio source to retrieve the configuration.
	decoder, _, err := audio.NewDecoder(bytes.NewReader(data))
	if err != nil {
		b.Fatal(err)
	}
	config := decoder.Config()

	// Create a slice of type fmt large enough to hold 1 second of audio
	// samples.
	bufSize := 1 * config.SampleRate * config.Channels
	buf := fmt.Make(bufSize, bufSize)

	// Decode the entire file b.N times.
	for i := 0; i < b.N; i++ {
		// Create a new decoder for the audio source
		decoder, _, err := audio.NewDecoder(bytes.NewReader(data))
		if err != nil {
			b.Fatal(err)
		}

		// Read audio samples until there are no more.
		for {
			_, err := decoder.Read(buf)
			if err == audio.EOS {
				break
			}
			if err != nil {
				b.Fatal(err)
			}
		}
	}
}

func BenchmarkDecodeFloat32(b *testing.B) {
	benchDecode(b, audio.F32Samples{}, "testdata/tune_stereo_44100hz_float32.wav")
}

func BenchmarkDecodeFloat64(b *testing.B) {
	benchDecode(b, audio.F64Samples{}, "testdata/tune_stereo_44100hz_float64.wav")
}

func BenchmarkDecodeUint8(b *testing.B) {
	benchDecode(b, audio.PCM8Samples{}, "testdata/tune_stereo_44100hz_uint8.wav")
}

func BenchmarkDecodeInt16(b *testing.B) {
	benchDecode(b, audio.PCM16Samples{}, "testdata/tune_stereo_44100hz_int16.wav")
}

func BenchmarkDecodeInt24(b *testing.B) {
	benchDecode(b, audio.PCM32Samples{}, "testdata/tune_stereo_44100hz_int24.wav")
}

func BenchmarkDecodeInt32(b *testing.B) {
	benchDecode(b, audio.PCM32Samples{}, "testdata/tune_stereo_44100hz_int32.wav")
}

func BenchmarkDecodeALaw(b *testing.B) {
	benchDecode(b, audio.PCM8Samples{}, "testdata/tune_stereo_44100hz_alaw.wav")
}

func BenchmarkDecodeMuLaw(b *testing.B) {
	benchDecode(b, audio.MuLawSamples{}, "testdata/tune_stereo_44100hz_mulaw.wav")
}
<commit_msg>Fix incorrect file path in decode benchmark.<commit_after>// Copyright 2014 The Azul3D Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package wav

import (
	"bytes"
	"io/ioutil"
	"os"
	"testing"

	"azul3d.org/audio.v1"
)

type decodeTest struct {
	file         string
	samplesTotal int
	audio.Config
	start audio.Slice
}

func testDecode(t *testing.T, tst decodeTest) {
	// Open the file.
	file, err := os.Open(tst.file)
	if err != nil {
		t.Fatal(err)
	}

	// Create a decoder for the audio source
	decoder, format, err := audio.NewDecoder(file)
	if err != nil {
		t.Fatal(err)
	}

	// Check for a valid format identifier.
	if format != "wav" {
		t.Fatalf(`Incorrect format, want "wav" got %q\n`, format)
	}

	// Ensure the decoder's configuration is correct.
	config := decoder.Config()
	if config != tst.Config {
		t.Fatalf("Incorrect configuration, expected %+v, got %+v\n", tst.Config, config)
	}

	// Create a slice large enough to hold 1 second of audio samples.
	bufSize := 1 * config.SampleRate * config.Channels
	buf := tst.start.Make(bufSize, bufSize)

	// Read audio samples until there are no more.
	first := true
	var samplesTotal int
	for {
		read, err := decoder.Read(buf)
		samplesTotal += read
		if first {
			// Validate the audio samples.
			first = false
			for i := 0; i < tst.start.Len(); i++ {
				if buf.At(i) != tst.start.At(i) {
					t.Log("got", buf.Slice(0, tst.start.Len()))
					t.Log("want", tst.start)
					t.Fatal("Bad sample data.")
				}
			}
		}
		if err == audio.EOS {
			break
		}
		if err != nil {
			t.Fatal(err)
		}
	}

	// Ensure that we read the correct number of samples.
	if samplesTotal != tst.samplesTotal {
		t.Fatalf("Read %d audio samples, expected %d.\n", samplesTotal, tst.samplesTotal)
	}
}

func TestDecodeFloat32(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_float32.wav",
		samplesTotal: 993566,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.F32Samples{0, 0, 9.682657e-08, 3.3106906e-10, 9.845178e-07, 3.9564156e-09, 3.711236e-06, 1.869304e-08, 8.562939e-06, 5.7355663e-08, 1.4786613e-05, 1.3752022e-07, 2.1342606e-05, 2.8124632e-07, 2.7840168e-05},
	})
}

func TestDecodeFloat64(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_float64.wav",
		samplesTotal: 993577,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.F64Samples{0, 0, 9.682656809673063e-08, 3.31069061054734e-10, 9.845177828537999e-07, 3.9564156395499595e-09, 3.7112361042090924e-06, 1.8693040004791328e-08, 8.56293900142191e-06, 5.7355663329872186e-08, 1.4786613064643461e-05, 1.375202174358492e-07, 2.134260648745112e-05, 2.812463151258271e-07, 2.7840167604153976e-05},
	})
}

func TestDecodeUInt8(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_uint8.wav",
		samplesTotal: 993544,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.PCM8Samples{128, 128, 128, 128, 127, 128, 127, 128, 128, 127, 128, 128, 127, 128, 127},
	})
}

func TestDecodeInt16(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_int16.wav",
		samplesTotal: 993566,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.PCM16Samples{0, 0, 0, -1, 2, -2, 3, -3, 2, -1, 1, 0, 2, -3, 4},
	})
}

func TestDecodeInt24(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_int24.wav",
		samplesTotal: 993573,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.PCM32Samples{0, 0, 0, 0, 8, 0, 31, 0, 71, 0, 124, 1, 179, 2, 233},
	})
}

func TestDecodeInt32(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_int32.wav",
		samplesTotal: 993577,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.PCM32Samples{0, 0, 208, 1, 2114, 8, 7970, 40, 18389, 123, 31754, 295, 45833, 604, 59786},
	})
}

func TestDecodeALaw(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_alaw.wav",
		samplesTotal: 993530,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.ALawSamples{213, 213, 85, 213, 85, 213, 85, 213, 85, 213, 85, 213, 213, 213, 213},
	})
}

func TestDecodeMuLaw(t *testing.T) {
	testDecode(t, decodeTest{
		file:         "testdata/tune_stereo_44100hz_mulaw.wav",
		samplesTotal: 993530,
		Config: audio.Config{
			SampleRate: 44100,
			Channels:   2,
		},
		start: audio.MuLawSamples{255, 255, 255, 255, 255, 255, 127, 255, 255, 127, 255, 255, 127, 255, 127},
	})
}

func benchDecode(b *testing.B, fmt audio.Slice, path string) {
	// Read the file into memory so we are strictly benchmarking the decoder,
	// avoiding disk read performance.
	data, err := ioutil.ReadFile(path)
	if err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()

	// Create a new decoder for the audio source to retrieve the configuration.
	decoder, _, err := audio.NewDecoder(bytes.NewReader(data))
	if err != nil {
		b.Fatal(err)
	}
	config := decoder.Config()

	// Create a slice of type fmt large enough to hold 1 second of audio
	// samples.
	bufSize := 1 * config.SampleRate * config.Channels
	buf := fmt.Make(bufSize, bufSize)

	// Decode the entire file b.N times.
	for i := 0; i < b.N; i++ {
		// Create a new decoder for the audio source
		decoder, _, err := audio.NewDecoder(bytes.NewReader(data))
		if err != nil {
			b.Fatal(err)
		}

		// Read audio samples until there are no more.
		for {
			_, err := decoder.Read(buf)
			if err == audio.EOS {
				break
			}
			if err != nil {
				b.Fatal(err)
			}
		}
	}
}

func BenchmarkDecodeFloat32(b *testing.B) {
	benchDecode(b, audio.F32Samples{}, "testdata/tune_stereo_44100hz_float32.wav")
}

func BenchmarkDecodeFloat64(b *testing.B) {
	benchDecode(b, audio.F64Samples{}, "testdata/tune_stereo_44100hz_float64.wav")
}

func BenchmarkDecodeUint8(b *testing.B) {
	benchDecode(b, audio.PCM8Samples{}, "testdata/tune_stereo_44100hz_uint8.wav")
}

func BenchmarkDecodeInt16(b *testing.B) {
	benchDecode(b, audio.PCM16Samples{}, "testdata/tune_stereo_44100hz_int16.wav")
}

func BenchmarkDecodeInt24(b *testing.B) {
	benchDecode(b, audio.PCM32Samples{}, "testdata/tune_stereo_44100hz_int24.wav")
}

func BenchmarkDecodeInt32(b *testing.B) {
	benchDecode(b, audio.PCM32Samples{}, "testdata/tune_stereo_44100hz_int32.wav")
}

func BenchmarkDecodeALaw(b *testing.B) {
	benchDecode(b, audio.PCM8Samples{}, "testdata/tune_stereo_44100hz_alaw.wav")
}

func BenchmarkDecodeMuLaw(b *testing.B) {
	benchDecode(b, audio.MuLawSamples{}, "testdata/tune_stereo_44100hz_mulaw.wav")
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/rand"
	"crypto/tls"
	"fmt"
	"time"

	MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

var MaxClientIdLen = 8

type MQTTClient struct {
	Client *MQTT.MqttClient
	Opts   *MQTT.ClientOptions
}

// Connects connect to the MQTT broker with Options.
func (m *MQTTClient) Connect() (*MQTT.MqttClient, error) {
	m.Client = MQTT.NewClient(m.Opts)
	_, err := m.Client.Start()
	if err != nil {
		return nil, err
	}
	return m.Client, nil
}

func (m *MQTTClient) Publish(topic string, payload []byte, qos int, retain bool) error {
	mqttmsg := MQTT.NewMessage(payload)
	// FIXME: validate qos number
	mqttmsg.SetQoS(MQTT.QoS(qos))
	mqttmsg.SetRetainedFlag(retain)

	receipt := m.Client.PublishMessage(topic, mqttmsg)
	<-receipt

	return nil
}

func onMessageReceived(client *MQTT.MqttClient, message MQTT.Message) {
	log.Infof("topic:%s  / msg:%s", message.Topic(), message.Payload())
	fmt.Println(string(message.Payload()))
}

func (m *MQTTClient) Subscribe(topic string, qos int) error {
	topicFilter, err := MQTT.NewTopicFilter(topic, byte(qos))
	if err != nil {
		return err
	}
	_, err = m.Client.StartSubscription(onMessageReceived, topicFilter)
	if err != nil {
		return err
	}

	for {
		time.Sleep(1 * time.Second)
	}
	return nil
}

// getRandomClientId returns randomized ClientId.
func getRandomClientId() string {
	const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
	var bytes = make([]byte, MaxClientIdLen)
	rand.Read(bytes)
	for i, b := range bytes {
		bytes[i] = alphanum[b%byte(len(alphanum))]
	}
	return "mqttcli-" + string(bytes)
}

// NewOption returns ClientOptions via parsing command line options.
func NewOption(c *cli.Context) *MQTT.ClientOptions {
	opts := MQTT.NewClientOptions()

	host := c.String("host")
	port := c.Int("p")

	if host == "" && port == 0 {
		getSettingsFromFile(c.String("conf"), opts)
	}

	clientId := c.String("i")
	if clientId == "" {
		clientId = getRandomClientId()
	}
	opts.SetClientId(clientId)

	cafile := c.String("cafile")
	scheme := "tcp"
	if cafile != "" {
		scheme = "ssl"
	}
	insecure := true
	if insecure {
		tlsConfig := &tls.Config{InsecureSkipVerify: true}
		opts.SetTlsConfig(tlsConfig)
	}

	user := c.String("u")
	if user != "" {
		opts.SetUsername(user)
	}
	password := c.String("P")
	if password != "" {
		opts.SetPassword(password)
	}

	if host != "" {
		brokerUri := fmt.Sprintf("%s://%s:%d", scheme, host, port)
		log.Infof("Broker URI: %s", brokerUri)

		opts.AddBroker(brokerUri)
	}
	return opts
}
<commit_msg>fix not reading from config file.<commit_after>package main

import (
	"crypto/rand"
	"crypto/tls"
	"fmt"
	"time"

	MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

var MaxClientIdLen = 8

type MQTTClient struct {
	Client *MQTT.MqttClient
	Opts   *MQTT.ClientOptions
}

// Connects connect to the MQTT broker with Options.
func (m *MQTTClient) Connect() (*MQTT.MqttClient, error) {
	m.Client = MQTT.NewClient(m.Opts)
	_, err := m.Client.Start()
	if err != nil {
		return nil, err
	}
	return m.Client, nil
}

func (m *MQTTClient) Publish(topic string, payload []byte, qos int, retain bool) error {
	mqttmsg := MQTT.NewMessage(payload)
	// FIXME: validate qos number
	mqttmsg.SetQoS(MQTT.QoS(qos))
	mqttmsg.SetRetainedFlag(retain)

	receipt := m.Client.PublishMessage(topic, mqttmsg)
	<-receipt

	return nil
}

func onMessageReceived(client *MQTT.MqttClient, message MQTT.Message) {
	log.Infof("topic:%s  / msg:%s", message.Topic(), message.Payload())
	fmt.Println(string(message.Payload()))
}

func (m *MQTTClient) Subscribe(topic string, qos int) error {
	topicFilter, err := MQTT.NewTopicFilter(topic, byte(qos))
	if err != nil {
		return err
	}
	_, err = m.Client.StartSubscription(onMessageReceived, topicFilter)
	if err != nil {
		return err
	}

	for {
		time.Sleep(1 * time.Second)
	}
	return nil
}

// getRandomClientId returns randomized ClientId.
func getRandomClientId() string {
	const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
	var bytes = make([]byte, MaxClientIdLen)
	rand.Read(bytes)
	for i, b := range bytes {
		bytes[i] = alphanum[b%byte(len(alphanum))]
	}
	return "mqttcli-" + string(bytes)
}

// NewOption returns ClientOptions via parsing command line options.
func NewOption(c *cli.Context) *MQTT.ClientOptions {
	opts := MQTT.NewClientOptions()

	host := c.String("host")
	port := c.Int("p")

	if host == "" {
		getSettingsFromFile(c.String("conf"), opts)
	}

	clientId := c.String("i")
	if clientId == "" {
		clientId = getRandomClientId()
	}
	opts.SetClientId(clientId)

	cafile := c.String("cafile")
	scheme := "tcp"
	if cafile != "" {
		scheme = "ssl"
	}
	insecure := true
	if insecure {
		tlsConfig := &tls.Config{InsecureSkipVerify: true}
		opts.SetTlsConfig(tlsConfig)
	}

	user := c.String("u")
	if user != "" {
		opts.SetUsername(user)
	}
	password := c.String("P")
	if password != "" {
		opts.SetPassword(password)
	}

	if host != "" {
		brokerUri := fmt.Sprintf("%s://%s:%d", scheme, host, port)
		log.Infof("Broker URI: %s", brokerUri)

		opts.AddBroker(brokerUri)
	}
	return opts
}
<|endoftext|>


<commit_before>// 5 october 2014
package main

import (
	"os"
	"path/filepath"
	"strings"
	"sort"
	"github.com/andlabs/ohv/mshi"
//	"github.com/davecheney/profile"
)

type MSHI struct {
	dir			string
	containers	[][]*mshi.ContainerPath
	assets		[][]*mshi.AssetData
	topics		map[string]*MSHITopic
	books		[]Topic
	orphans		[]Topic
}

func (m *MSHI) Name() string {
	return "All Microsoft Help Viewer-format documentation"
}

func (m *MSHI) Books() []Topic {
	return m.books
}

func (m *MSHI) Orphans() []Topic {
	return m.orphans
}

// TODO adorn errors
func OpenMSHI(dir string) (*MSHI, error) {
	m := new(MSHI)
	m.dir = dir

	// first read all indices
	err := m.readAllIndices()
	if err != nil {
		return nil, err
	}

	// then produce a map that goes from ID -> topic
	m.collectTopics()

	// now figure out the hierarchy, books, and orphans
	m.buildHierarchy()

	// now sort all children
	m.sortAllChildren()

	return m, nil
}

func (m *MSHI) readAllIndices() error {
	return filepath.Walk(m.dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		// TODO subdirectories
		if strings.ToLower(filepath.Ext(path)) != ".mshi" {
			return nil
		}
		of, err := os.Open(path)
		if err != nil {
			return err
		}
		f := mshi.Open(of)
		if f.Err() != nil {
			return f.Err()
		}
		c := f.ReadContainerPaths()
		if f.Err() != nil {
			return f.Err()
		}
		a := f.ReadAssetDatas()
		if f.Err() != nil {
			return f.Err()
		}
		of.Close()
		m.containers = append(m.containers, c)
		m.assets = append(m.assets, a)
		return nil
	})
}

func (m *MSHI) collectTopics() {
	// TODO deal with versions sensibly
	m.topics = make(map[string]*MSHITopic)
	for container, aa := range m.assets {
		for _, a := range aa {
			if m.topics[a.ID] != nil && m.topics[a.ID].asset.Version > a.Version {
				continue
			}
			m.topics[a.ID] = &MSHITopic{
				containers:	m.containers[container],
				asset:		a,
			}
		}
	}
}

func (m *MSHI) buildHierarchy() {
	all := make([]*MSHITopic, 0, len(m.topics))
	for _, v := range m.topics {
		all = append(all, v)
	}
	i := 0
	for i < len(all) {
		if all[i].asset.ParentID == "-1" {		// is top-level
			m.books = append(m.books, all[i])
			all = append(all[:i], all[i + 1:]...)
			continue
		}
		parent, ok := m.topics[all[i].asset.ParentID]
		if ok {			// has parent
			parent.children = append(parent.children, all[i])
			all = append(all[:i], all[i + 1:]...)
			continue
		}
		i++		// parent elsewhere or missing
	}
	for _, v := range all {
		m.orphans = append(m.orphans, v)
	}
}

func (m *MSHI) sortAllChildren() {
	for _, t := range m.topics {
		sort.Sort(TopicSorter(t.children))
	}
}

type MSHITopic struct {
	containers	[]*mshi.ContainerPath
	asset			*mshi.AssetData
	children		[]Topic
}

func (m *MSHITopic) Name() string {
	return m.asset.Title
}

func (m *MSHITopic) Prepare() (string, error) {
	// TODO
	return "", nil
}

func (m *MSHITopic) Children() []Topic {
	return m.children
}

func (m *MSHITopic) Less(t Topic) bool {
	tt := t.(*MSHITopic)
	return m.asset.Order < tt.asset.Order
}

func main() {
//	defer profile.Start(profile.CPUProfile).Stop()
	m, err := OpenMSHI(os.Args[1])
	if err != nil { panic(err) }
	println("books:")
	for _, b := range m.Books() {
		println(b.Name())
	}
	println("orphans:", len(m.Orphans()))
}
<commit_msg>Removed unnecessary copying in the hierarchy generator.<commit_after>// 5 october 2014
package main

import (
	"os"
	"path/filepath"
	"strings"
	"sort"
	"github.com/andlabs/ohv/mshi"
//	"github.com/davecheney/profile"
)

type MSHI struct {
	dir			string
	containers	[][]*mshi.ContainerPath
	assets		[][]*mshi.AssetData
	topics		map[string]*MSHITopic
	books		[]Topic
	orphans		[]Topic
}

func (m *MSHI) Name() string {
	return "All Microsoft Help Viewer-format documentation"
}

func (m *MSHI) Books() []Topic {
	return m.books
}

func (m *MSHI) Orphans() []Topic {
	return m.orphans
}

// TODO adorn errors
func OpenMSHI(dir string) (*MSHI, error) {
	m := new(MSHI)
	m.dir = dir

	// first read all indices
	err := m.readAllIndices()
	if err != nil {
		return nil, err
	}

	// then produce a map that goes from ID -> topic
	m.collectTopics()

	// now figure out the hierarchy, books, and orphans
	m.buildHierarchy()

	// now sort all children
	m.sortAllChildren()

	return m, nil
}

func (m *MSHI) readAllIndices() error {
	return filepath.Walk(m.dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		// TODO subdirectories
		if strings.ToLower(filepath.Ext(path)) != ".mshi" {
			return nil
		}
		of, err := os.Open(path)
		if err != nil {
			return err
		}
		f := mshi.Open(of)
		if f.Err() != nil {
			return f.Err()
		}
		c := f.ReadContainerPaths()
		if f.Err() != nil {
			return f.Err()
		}
		a := f.ReadAssetDatas()
		if f.Err() != nil {
			return f.Err()
		}
		of.Close()
		m.containers = append(m.containers, c)
		m.assets = append(m.assets, a)
		return nil
	})
}

func (m *MSHI) collectTopics() {
	// TODO deal with versions sensibly
	m.topics = make(map[string]*MSHITopic)
	for container, aa := range m.assets {
		for _, a := range aa {
			if m.topics[a.ID] != nil && m.topics[a.ID].asset.Version > a.Version {
				continue
			}
			m.topics[a.ID] = &MSHITopic{
				containers:	m.containers[container],
				asset:		a,
			}
		}
	}
}

func (m *MSHI) buildHierarchy() {
	for _, v := range m.topics {
		if v.asset.ParentID == "-1" {		// is top-level
			m.books = append(m.books, v)
			continue
		}
		parent, ok := m.topics[v.asset.ParentID]
		if ok {			// has parent
			parent.children = append(parent.children, v)
			continue
		}
		m.orphans = append(m.orphans, v)			// parent elsewhere or missing
	}
}

func (m *MSHI) sortAllChildren() {
	for _, t := range m.topics {
		sort.Sort(TopicSorter(t.children))
	}
}

type MSHITopic struct {
	containers	[]*mshi.ContainerPath
	asset			*mshi.AssetData
	children		[]Topic
}

func (m *MSHITopic) Name() string {
	return m.asset.Title
}

func (m *MSHITopic) Prepare() (string, error) {
	// TODO
	return "", nil
}

func (m *MSHITopic) Children() []Topic {
	return m.children
}

func (m *MSHITopic) Less(t Topic) bool {
	tt := t.(*MSHITopic)
	return m.asset.Order < tt.asset.Order
}

func main() {
//	defer profile.Start(profile.CPUProfile).Stop()
	m, err := OpenMSHI(os.Args[1])
	if err != nil { panic(err) }
	println("books:")
	for _, b := range m.Books() {
		println(b.Name())
	}
	println("orphans:", len(m.Orphans()))
}
<|endoftext|>


<commit_before>// myLG is command line looking glass that written with Go language
// it tries from its own icmp and external looking glasses tools
package main

import (
	"errors"
	"github.com/briandowns/spinner"
	"net"
	"regexp"
	"strings"
	"time"

	"github.com/mehrdadrad/mylg/cli"
	"github.com/mehrdadrad/mylg/icmp"
	"github.com/mehrdadrad/mylg/lg"
	"github.com/mehrdadrad/mylg/ns"
	"github.com/mehrdadrad/mylg/peeringdb"
	"github.com/mehrdadrad/mylg/ripe"
)

// Provider is a interface to accessing lg
type Provider interface {
	Set(host, version string)
	GetDefaultNode() string
	GetNodes() []string
	ChangeNode(node string)
	Ping() (string, error)
}

type Whois interface {
	Set(r string)
	GetData() bool
	PrettyPrint()
}

var (
	// register looking glass hosts
	providers = map[string]Provider{"telia": new(lg.Telia), "level3": new(lg.Level3), "cogent": new(lg.Cogent)}
	whois     = map[string]Whois{"asn": new(ripe.ASN), "prefix": new(ripe.Prefix)}
	pNames    = providerNames()
	nsr       *ns.Request
)

func providerNames() []string {
	pNames := []string{}
	for p := range providers {
		pNames = append(pNames, p)
	}
	return pNames
}

func validateProvider(p string) (string, error) {
	pNames := []string{}
	match, _ := regexp.MatchString("("+strings.Join(pNames, "|")+")", p)
	p = strings.ToLower(p)
	if match {
		return p, nil
	}
	return "", errors.New("provider not support")

}
func init() {
	// Initialize name server data
	nsr = ns.NewRequest()
	go nsr.Init()
}

func main() {
	var (
		err     error
		request string
		loop    = true
		cPName  = "local"
	)

	rep := make(chan string, 1)
	req := make(chan string, 1)
	nxt := make(chan struct{}, 1)

	c := cli.Init("local")
	go c.Run(req, nxt)

	r, _ := regexp.Compile(`(ping|trace|lg|ns|dig|whois|peering|connect|node|local|mode|help|exit|quit)\s{0,1}(.*)`)
	s := spinner.New(spinner.CharSets[26], 220*time.Millisecond)

	for loop {
		select {
		case request, loop = <-req:
			if !loop {
				break
			}
			if len(request) < 1 {
				c.Next()
				continue
			}
			subReq := r.FindStringSubmatch(request)
			if len(subReq) == 0 {
				println("syntax error")
				c.Next()
				continue
			}
			prompt := c.GetPrompt()
			cmd := strings.TrimSpace(subReq[1])
			args := strings.TrimSpace(subReq[2])
			switch {
			case cmd == "ping" && cPName == "local":
				p := icmp.NewPing()
				ra, err := net.ResolveIPAddr("ip", args)
				if err != nil {
					println("cannot resolve", args, ": Unknown host")
					c.Next()
					continue
				}
				p.IP(ra.String())
				for n := 0; n < 4; n++ {
					p.Ping(rep)
					println(<-rep)
				}
				c.Next()
			case cmd == "ping":
				s.Prefix = "please wait "
				s.Start()
				providers[cPName].Set(args, "ipv4")
				m, _ := providers[cPName].Ping()
				s.Stop()
				println(m)
				c.Next()
			case cmd == "trace":
				trace := icmp.Trace{}
				trace.Run(args)
				c.Next()
			case cmd == "dig":
				nsr.Dig(args)
				c.Next()
			case cmd == "node":
				switch {
				case strings.HasPrefix(prompt, "lg"):
					if _, ok := providers[cPName]; ok {
						providers[cPName].ChangeNode(args)
						c.UpdatePromptN(args, 3)
					} else {
						println("the specified node doesn't support")
					}
				case strings.HasPrefix(prompt, "ns"):
					if !nsr.ChkNode(args) {
						println("error: argument is not valid")
						continue
					}
					c.UpdatePromptN(args, 3)
				}
				c.Next()
			case cmd == "local":
				cPName = "local"
				c.SetPrompt(cPName)
				c.Next()
			case cmd == "lg":
				c.SetPrompt("lg")
				c.UpdateCompleter("connect", pNames)
				c.Next()
			case cmd == "connect":
				switch {
				case strings.HasPrefix(prompt, "lg"):
					var pName string
					if pName, err = validateProvider(args); err != nil {
						println("provider not available")
						c.Next()
						continue
					}
					cPName = pName
					if _, ok := providers[cPName]; ok {
						c.UpdatePromptN(cPName+"/"+providers[cPName].GetDefaultNode(), 2)
						go func() {
							c.UpdateCompleter("node", providers[cPName].GetNodes())
						}()
					} else {
						println("it doesn't support")
					}
				case strings.HasPrefix(prompt, "ns"):
					if !nsr.ChkCountry(args) {
						println("error: argument is not valid")
						continue
					}
					c.SetPrompt("ns/" + args)
					nsr.SetNodeList(c)

				}
				c.Next()
			case cmd == "ns":
				nsr.SetCountryList(c)
				c.SetPrompt("ns")
				c.Next()
			case cmd == "whois":
				if ripe.IsASN(args) {
					whois["asn"].Set(args)
					whois["asn"].GetData()
					whois["asn"].PrettyPrint()
				} else {
					whois["prefix"].Set(args)
					whois["prefix"].GetData()
					whois["prefix"].PrettyPrint()
				}
				c.Next()
			case cmd == "peering":
				peeringdb.Search(args)
				c.Next()
			case cmd == "mode":
				if args == "vim" {
					c.SetVim()
				} else if args == "emacs" {
					c.SetEmacs()
				} else {
					println("the request mode doesn't support")
				}
				c.Next()
			case cmd == "help":
				c.Help()
				c.Next()
			case cmd == "exit", cmd == "quit":
				c.Close(nxt)
				close(req)
				// todo
			}
		}
	}
}
<commit_msg>added lg.trace, resetnodelist and init local<commit_after>// myLG is command line looking glass that written with Go language
// it tries from its own icmp and external looking glasses tools
package main

import (
	"errors"
	"github.com/briandowns/spinner"
	"net"
	"regexp"
	"strings"
	"time"

	"github.com/mehrdadrad/mylg/cli"
	"github.com/mehrdadrad/mylg/icmp"
	"github.com/mehrdadrad/mylg/lg"
	"github.com/mehrdadrad/mylg/ns"
	"github.com/mehrdadrad/mylg/peeringdb"
	"github.com/mehrdadrad/mylg/ripe"
)

// Provider is a interface to accessing lg
type Provider interface {
	Set(host, version string)
	GetDefaultNode() string
	GetNodes() []string
	ChangeNode(node string)
	Ping() (string, error)
	Trace() chan string
}

type Whois interface {
	Set(r string)
	GetData() bool
	PrettyPrint()
}

var (
	// register looking glass hosts
	providers = map[string]Provider{"telia": new(lg.Telia), "level3": new(lg.Level3), "cogent": new(lg.Cogent)}
	whois     = map[string]Whois{"asn": new(ripe.ASN), "prefix": new(ripe.Prefix)}
	pNames    = providerNames()
	nsr       *ns.Request
)

func providerNames() []string {
	pNames := []string{}
	for p := range providers {
		pNames = append(pNames, p)
	}
	return pNames
}

func validateProvider(p string) (string, error) {
	pNames := []string{}
	match, _ := regexp.MatchString("("+strings.Join(pNames, "|")+")", p)
	p = strings.ToLower(p)
	if match {
		return p, nil
	}
	return "", errors.New("provider not support")

}
func init() {
	// Initialize name server data
	nsr = ns.NewRequest()
	go nsr.Init()
}

func main() {
	var (
		err     error
		request string
		loop    = true
		cPName  = "local"
	)

	rep := make(chan string, 1)
	req := make(chan string, 1)
	nxt := make(chan struct{}, 1)

	c := cli.Init("local")
	go c.Run(req, nxt)

	r, _ := regexp.Compile(`(ping|trace|lg|ns|dig|whois|peering|connect|node|local|mode|help|exit|quit)\s{0,1}(.*)`)
	s := spinner.New(spinner.CharSets[26], 220*time.Millisecond)

	for loop {
		select {
		case request, loop = <-req:
			if !loop {
				break
			}
			if len(request) < 1 {
				c.Next()
				continue
			}
			subReq := r.FindStringSubmatch(request)
			if len(subReq) == 0 {
				println("syntax error")
				c.Next()
				continue
			}
			prompt := c.GetPrompt()
			cmd := strings.TrimSpace(subReq[1])
			args := strings.TrimSpace(subReq[2])
			switch {
			case cmd == "ping" && cPName == "local":
				p := icmp.NewPing()
				ra, err := net.ResolveIPAddr("ip", args)
				if err != nil {
					println("cannot resolve", args, ": Unknown host")
					c.Next()
					continue
				}
				p.IP(ra.String())
				for n := 0; n < 4; n++ {
					p.Ping(rep)
					println(<-rep)
				}
				c.Next()
			case cmd == "ping":
				s.Prefix = "please wait "
				s.Start()
				providers[cPName].Set(args, "ipv4")
				m, _ := providers[cPName].Ping()
				s.Stop()
				println(m)
				c.Next()
			case cmd == "trace":
				switch {
				case strings.HasPrefix(prompt, "local"):
					trace := icmp.Trace{}
					trace.Run(args)
				case strings.HasPrefix(prompt, "lg"):
					providers[cPName].Set(args, "ipv4")
					for l := range providers[cPName].Trace() {
						println(l)
					}
				}
				c.Next()
			case cmd == "dig":
				nsr.Dig(args)
				c.Next()
			case cmd == "node":
				switch {
				case strings.HasPrefix(prompt, "lg"):
					if _, ok := providers[cPName]; ok {
						providers[cPName].ChangeNode(args)
						c.UpdatePromptN(args, 3)
					} else {
						println("the specified node doesn't support")
					}
				case strings.HasPrefix(prompt, "ns"):
					if !nsr.ChkNode(args) {
						println("error: argument is not valid")
						continue
					}
					c.UpdatePromptN(args, 3)
				}
				c.Next()
			case cmd == "local":
				nsr.Local()
				cPName = "local"
				c.SetPrompt(cPName)
				c.Next()
			case cmd == "lg":
				c.SetPrompt("lg")
				c.UpdateCompleter("connect", pNames)
				c.Next()
			case cmd == "connect":
				switch {
				case strings.HasPrefix(prompt, "lg"):
					var pName string
					if pName, err = validateProvider(args); err != nil {
						println("provider not available")
						c.Next()
						continue
					}
					cPName = pName
					if _, ok := providers[cPName]; ok {
						c.UpdatePromptN(cPName+"/"+providers[cPName].GetDefaultNode(), 2)
						go func() {
							c.UpdateCompleter("node", providers[cPName].GetNodes())
						}()
					} else {
						println("it doesn't support")
					}
				case strings.HasPrefix(prompt, "ns"):
					if !nsr.ChkCountry(args) {
						println("error: argument is not valid")
						continue
					}
					c.SetPrompt("ns/" + args)
					nsr.SetNodeList(c)

				}
				c.Next()
			case cmd == "ns":
				nsr.SetCountryList(c)
				nsr.ResetNodeList(c)
				c.SetPrompt("ns")
				c.Next()
			case cmd == "whois":
				if ripe.IsASN(args) {
					whois["asn"].Set(args)
					whois["asn"].GetData()
					whois["asn"].PrettyPrint()
				} else {
					whois["prefix"].Set(args)
					whois["prefix"].GetData()
					whois["prefix"].PrettyPrint()
				}
				c.Next()
			case cmd == "peering":
				peeringdb.Search(args)
				c.Next()
			case cmd == "mode":
				if args == "vim" {
					c.SetVim()
				} else if args == "emacs" {
					c.SetEmacs()
				} else {
					println("the request mode doesn't support")
				}
				c.Next()
			case cmd == "help":
				c.Help()
				c.Next()
			case cmd == "exit", cmd == "quit":
				c.Close(nxt)
				close(req)
				// todo
			}
		}
	}
}
<|endoftext|>


<commit_before>package kite

import (
	"archive/tar"
	"compress/gzip"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"koding/newKite/kd/util"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

type Install struct{}

func NewInstall() *Install {
	return &Install{}
}

func (*Install) Definition() string {
	return "Install kite from Koding repository"
}

const s3URL = "http://koding-kites.s3.amazonaws.com/"

func (*Install) Exec() error {
	flag.Parse()
	if flag.NArg() != 1 {
		return errors.New("You should give a kite name")
	}

	// Generate download URL
	kiteFullName := flag.Arg(0)
	kiteName, kiteVersion, err := splitVersion(kiteFullName, true)
	if err != nil {
		kiteName, kiteVersion = kiteFullName, "latest"
	}
	kiteURL := s3URL + kiteName + "-" + kiteVersion + ".kite.tar.gz"
	log.Println(kiteURL)

	// Make download request
	fmt.Println("Downloading...")
	res, err := http.Get(kiteURL)
	if err != nil {
		return err
	}
	defer res.Body.Close()
	if res.StatusCode == 404 {
		return errors.New("Package is not found on the server.")
	}
	if res.StatusCode != 200 {
		return fmt.Errorf("Unexpected response from server: %d", res.StatusCode)
	}

	// Extract gzip
	gz, err := gzip.NewReader(res.Body)
	if err != nil {
		return err
	}
	defer gz.Close()

	// Extract tar
	tempKitePath, err := ioutil.TempDir("", "kd-kite-install-")
	log.Println("Created temp dir:", tempKitePath)
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempKitePath)
	err = extractTar(gz, tempKitePath)
	if err != nil {
		return err
	}

	// Move kite from tmp to kites folder (~/.kd/kites)
	dirs, err := ioutil.ReadDir(tempKitePath)
	if err != nil {
		return err
	}
	if len(dirs) != 1 {
		return errors.New("Invalid package: Package must contain only one directory.")
	}
	// found prefix means we got it from extracted tar.
	// We should assert that they are expected.
	foundKiteBundleName := dirs[0].Name() // Example: asdf-1.2.3.kite
	if !strings.HasSuffix(foundKiteBundleName, ".kite") {
		return errors.New("Invalid package: Direcory name must end with \".kite\".")
	}
	foundKiteFullName := strings.TrimSuffix(foundKiteBundleName, ".kite") // Example: asdf-1.2.3
	foundKiteName, foundKiteVersion, err := splitVersion(foundKiteFullName, false)
	if err != nil {
		return errors.New("Invalid package: No version number in Kite bundle")
	}
	tempKitePath = filepath.Join(tempKitePath, foundKiteBundleName)
	kitesPath := filepath.Join(util.GetKdPath(), "kites")
	os.MkdirAll(kitesPath, 0700)
	kitePath := filepath.Join(kitesPath, foundKiteBundleName)
	log.Println("Moving from:", tempKitePath, "to:", kitePath)
	err = os.Rename(tempKitePath, kitePath)
	if err != nil {
		return err
	}

	fmt.Println("Installed successfully:", foundKiteName+"-"+foundKiteVersion)
	return nil
}

// extractTar reads from the io.Reader and writes the files into the directory.
func extractTar(r io.Reader, dir string) error {
	tr := tar.NewReader(r)
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			// end of tar archive
			break
		}
		if err != nil {
			return err
		}

		fi := hdr.FileInfo()
		name := fi.Name()
		path := filepath.Join(dir, name)

		// TODO make the binary under /bin executable

		if fi.IsDir() {
			os.MkdirAll(path, 0700)
		} else {
			f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
			if err != nil {
				return err
			}

			if _, err := io.Copy(f, tr); err != nil {
				return err
			}
		}
	}
	return nil
}

// splitVersion takes a name like "asdf-1.2.3" and
// returns the name "asdf" and version "1.2.3" seperately.
// If allowLatest is true, then the version must not be numeric and can be "latest".
func splitVersion(fullname string, allowLatest bool) (name, version string, err error) {
	notFound := errors.New("name does not contain a version number")

	parts := strings.Split(fullname, "-")
	n := len(parts)
	if n < 2 {
		return "", "", notFound
	}

	name = strings.Join(parts[:n-1], "-")
	version = parts[n-1]

	if allowLatest && version == "latest" {
		return name, version, nil
	}

	versionParts := strings.Split(version, ".")
	for _, v := range versionParts {
		if _, err := strconv.ParseUint(v, 10, 64); err != nil {
			return "", "", notFound
		}
	}

	return name, version, nil
}
<commit_msg>extra assertion<commit_after>package kite

import (
	"archive/tar"
	"compress/gzip"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"koding/newKite/kd/util"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

type Install struct{}

func NewInstall() *Install {
	return &Install{}
}

func (*Install) Definition() string {
	return "Install kite from Koding repository"
}

const s3URL = "http://koding-kites.s3.amazonaws.com/"

func (*Install) Exec() error {
	flag.Parse()
	if flag.NArg() != 1 {
		return errors.New("You should give a kite name")
	}

	// Generate download URL
	kiteFullName := flag.Arg(0)
	kiteName, kiteVersion, err := splitVersion(kiteFullName, true)
	if err != nil {
		kiteName, kiteVersion = kiteFullName, "latest"
	}
	kiteURL := s3URL + kiteName + "-" + kiteVersion + ".kite.tar.gz"
	log.Println(kiteURL)

	// Make download request
	fmt.Println("Downloading...")
	res, err := http.Get(kiteURL)
	if err != nil {
		return err
	}
	defer res.Body.Close()
	if res.StatusCode == 404 {
		return errors.New("Package is not found on the server.")
	}
	if res.StatusCode != 200 {
		return fmt.Errorf("Unexpected response from server: %d", res.StatusCode)
	}

	// Extract gzip
	gz, err := gzip.NewReader(res.Body)
	if err != nil {
		return err
	}
	defer gz.Close()

	// Extract tar
	tempKitePath, err := ioutil.TempDir("", "kd-kite-install-")
	log.Println("Created temp dir:", tempKitePath)
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempKitePath)
	err = extractTar(gz, tempKitePath)
	if err != nil {
		return err
	}

	// Move kite from tmp to kites folder (~/.kd/kites)
	dirs, err := ioutil.ReadDir(tempKitePath)
	if err != nil {
		return err
	}
	if len(dirs) != 1 {
		return errors.New("Invalid package: Package must contain only one directory.")
	}
	// found prefix means we got it from extracted tar.
	// We should assert that they are expected.
	foundKiteBundleName := dirs[0].Name() // Example: asdf-1.2.3.kite
	if !strings.HasSuffix(foundKiteBundleName, ".kite") {
		return errors.New("Invalid package: Direcory name must end with \".kite\".")
	}
	foundKiteFullName := strings.TrimSuffix(foundKiteBundleName, ".kite") // Example: asdf-1.2.3
	foundKiteName, foundKiteVersion, err := splitVersion(foundKiteFullName, false)
	if err != nil {
		return errors.New("Invalid package: No version number in Kite bundle")
	}
	if foundKiteName != kiteName {
		return fmt.Errorf("Invalid package: Bundle name does not match with package name: %s != %s", foundKiteName, kiteName)
	}
	tempKitePath = filepath.Join(tempKitePath, foundKiteBundleName)
	kitesPath := filepath.Join(util.GetKdPath(), "kites")
	os.MkdirAll(kitesPath, 0700)
	kitePath := filepath.Join(kitesPath, foundKiteBundleName)
	log.Println("Moving from:", tempKitePath, "to:", kitePath)
	err = os.Rename(tempKitePath, kitePath)
	if err != nil {
		return err
	}

	fmt.Println("Installed successfully:", foundKiteName+"-"+foundKiteVersion)
	return nil
}

// extractTar reads from the io.Reader and writes the files into the directory.
func extractTar(r io.Reader, dir string) error {
	tr := tar.NewReader(r)
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			// end of tar archive
			break
		}
		if err != nil {
			return err
		}

		fi := hdr.FileInfo()
		name := fi.Name()
		path := filepath.Join(dir, name)

		// TODO make the binary under /bin executable

		if fi.IsDir() {
			os.MkdirAll(path, 0700)
		} else {
			f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
			if err != nil {
				return err
			}

			if _, err := io.Copy(f, tr); err != nil {
				return err
			}
		}
	}
	return nil
}

// splitVersion takes a name like "asdf-1.2.3" and
// returns the name "asdf" and version "1.2.3" seperately.
// If allowLatest is true, then the version must not be numeric and can be "latest".
func splitVersion(fullname string, allowLatest bool) (name, version string, err error) {
	notFound := errors.New("name does not contain a version number")

	parts := strings.Split(fullname, "-")
	n := len(parts)
	if n < 2 {
		return "", "", notFound
	}

	name = strings.Join(parts[:n-1], "-")
	version = parts[n-1]

	if allowLatest && version == "latest" {
		return name, version, nil
	}

	versionParts := strings.Split(version, ".")
	for _, v := range versionParts {
		if _, err := strconv.ParseUint(v, 10, 64); err != nil {
			return "", "", notFound
		}
	}

	return name, version, nil
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package rewrite

import (
	extensions "k8s.io/api/extensions/v1beta1"

	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
	"k8s.io/ingress-nginx/internal/ingress/resolver"
)

// Config describes the per location redirect config
type Config struct {
	// Target URI where the traffic must be redirected
	Target string `json:"target"`
	// AddBaseURL indicates if is required to add a base tag in the head
	// of the responses from the upstream servers
	AddBaseURL bool `json:"addBaseUrl"`
	// BaseURLScheme override for the scheme passed to the base tag
	BaseURLScheme string `json:"baseUrlScheme"`
	// SSLRedirect indicates if the location section is accessible SSL only
	SSLRedirect bool `json:"sslRedirect"`
	// ForceSSLRedirect indicates if the location section is accessible SSL only
	ForceSSLRedirect bool `json:"forceSSLRedirect"`
	// AppRoot defines the Application Root that the Controller must redirect if it's in '/' context
	AppRoot string `json:"appRoot"`
	// UseRegex indicates whether or not the locations use regex paths
	UseRegex bool `json:"useRegex"`
}

// Equal tests for equality between two Redirect types
func (r1 *Config) Equal(r2 *Config) bool {
	if r1 == r2 {
		return true
	}
	if r1 == nil || r2 == nil {
		return false
	}
	if r1.Target != r2.Target {
		return false
	}
	if r1.AddBaseURL != r2.AddBaseURL {
		return false
	}
	if r1.BaseURLScheme != r2.BaseURLScheme {
		return false
	}
	if r1.SSLRedirect != r2.SSLRedirect {
		return false
	}
	if r1.ForceSSLRedirect != r2.ForceSSLRedirect {
		return false
	}
	if r1.AppRoot != r2.AppRoot {
		return false
	}
	if r1.UseRegex != r2.UseRegex {
		return false
	}

	return true
}

type rewrite struct {
	r resolver.Resolver
}

// NewParser creates a new reqrite annotation parser
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
	return rewrite{r}
}

// ParseAnnotations parses the annotations contained in the ingress
// rule used to rewrite the defined paths
func (a rewrite) Parse(ing *extensions.Ingress) (interface{}, error) {
	rt, _ := parser.GetStringAnnotation("rewrite-target", ing)
	sslRe, err := parser.GetBoolAnnotation("ssl-redirect", ing)
	if err != nil {
		sslRe = a.r.GetDefaultBackend().SSLRedirect
	}
	fSslRe, err := parser.GetBoolAnnotation("force-ssl-redirect", ing)
	if err != nil {
		fSslRe = a.r.GetDefaultBackend().ForceSSLRedirect
	}
	abu, _ := parser.GetBoolAnnotation("add-base-url", ing)
	bus, _ := parser.GetStringAnnotation("base-url-scheme", ing)
	ar, _ := parser.GetStringAnnotation("app-root", ing)
	ur, _ := parser.GetBoolAnnotation("use-regex", ing)

	return &Config{
		Target:           rt,
		AddBaseURL:       abu,
		BaseURLScheme:    bus,
		SSLRedirect:      sslRe,
		ForceSSLRedirect: fSslRe,
		AppRoot:          ar,
		UseRegex:         ur,
	}, nil
}
<commit_msg>Fix typos: reqrite -> rewrite<commit_after>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package rewrite

import (
	extensions "k8s.io/api/extensions/v1beta1"

	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
	"k8s.io/ingress-nginx/internal/ingress/resolver"
)

// Config describes the per location redirect config
type Config struct {
	// Target URI where the traffic must be redirected
	Target string `json:"target"`
	// AddBaseURL indicates if is required to add a base tag in the head
	// of the responses from the upstream servers
	AddBaseURL bool `json:"addBaseUrl"`
	// BaseURLScheme override for the scheme passed to the base tag
	BaseURLScheme string `json:"baseUrlScheme"`
	// SSLRedirect indicates if the location section is accessible SSL only
	SSLRedirect bool `json:"sslRedirect"`
	// ForceSSLRedirect indicates if the location section is accessible SSL only
	ForceSSLRedirect bool `json:"forceSSLRedirect"`
	// AppRoot defines the Application Root that the Controller must redirect if it's in '/' context
	AppRoot string `json:"appRoot"`
	// UseRegex indicates whether or not the locations use regex paths
	UseRegex bool `json:"useRegex"`
}

// Equal tests for equality between two Redirect types
func (r1 *Config) Equal(r2 *Config) bool {
	if r1 == r2 {
		return true
	}
	if r1 == nil || r2 == nil {
		return false
	}
	if r1.Target != r2.Target {
		return false
	}
	if r1.AddBaseURL != r2.AddBaseURL {
		return false
	}
	if r1.BaseURLScheme != r2.BaseURLScheme {
		return false
	}
	if r1.SSLRedirect != r2.SSLRedirect {
		return false
	}
	if r1.ForceSSLRedirect != r2.ForceSSLRedirect {
		return false
	}
	if r1.AppRoot != r2.AppRoot {
		return false
	}
	if r1.UseRegex != r2.UseRegex {
		return false
	}

	return true
}

type rewrite struct {
	r resolver.Resolver
}

// NewParser creates a new rewrite annotation parser
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
	return rewrite{r}
}

// ParseAnnotations parses the annotations contained in the ingress
// rule used to rewrite the defined paths
func (a rewrite) Parse(ing *extensions.Ingress) (interface{}, error) {
	rt, _ := parser.GetStringAnnotation("rewrite-target", ing)
	sslRe, err := parser.GetBoolAnnotation("ssl-redirect", ing)
	if err != nil {
		sslRe = a.r.GetDefaultBackend().SSLRedirect
	}
	fSslRe, err := parser.GetBoolAnnotation("force-ssl-redirect", ing)
	if err != nil {
		fSslRe = a.r.GetDefaultBackend().ForceSSLRedirect
	}
	abu, _ := parser.GetBoolAnnotation("add-base-url", ing)
	bus, _ := parser.GetStringAnnotation("base-url-scheme", ing)
	ar, _ := parser.GetStringAnnotation("app-root", ing)
	ur, _ := parser.GetBoolAnnotation("use-regex", ing)

	return &Config{
		Target:           rt,
		AddBaseURL:       abu,
		BaseURLScheme:    bus,
		SSLRedirect:      sslRe,
		ForceSSLRedirect: fSslRe,
		AppRoot:          ar,
		UseRegex:         ur,
	}, nil
}
<|endoftext|>