<commit_before>package zerolog

import (
	"net"
	"sync"
	"time"
)

var arrayPool = &sync.Pool{
	New: func() interface{} {
		return &Array{
			buf: make([]byte, 0, 500),
		}
	},
}

// Array is used to prepopulate an array of items
// which can be re-used to add to log messages.
type Array struct {
	buf []byte
}

// Arr creates an array to be added to an Event or Context.
func Arr() *Array {
	a := arrayPool.Get().(*Array)
	a.buf = a.buf[:0]
	return a
}

// MarshalZerologArray method here is no-op - since data is
// already in the needed format.
func (*Array) MarshalZerologArray(*Array) {
}

func (a *Array) write(dst []byte) []byte {
	dst = enc.AppendArrayStart(dst)
	if len(a.buf) > 0 {
		dst = append(append(dst, a.buf...))
	}
	dst = enc.AppendArrayEnd(dst)
	arrayPool.Put(a)
	return dst
}

// Object marshals an object that implement the LogObjectMarshaler
// interface and Append it to the array.
func (a *Array) Object(obj LogObjectMarshaler) *Array {
	e := Dict()
	obj.MarshalZerologObject(e)
	e.buf = enc.AppendEndMarker(e.buf)
	a.buf = append(enc.AppendArrayDelim(a.buf), e.buf...)
	eventPool.Put(e)
	return a
}

// Str Append the val as a string to the array.
func (a *Array) Str(val string) *Array {
	a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), val)
	return a
}

// Bytes Append the val as a string to the array.
func (a *Array) Bytes(val []byte) *Array {
	a.buf = enc.AppendBytes(enc.AppendArrayDelim(a.buf), val)
	return a
}

// Hex Append the val as a hex string to the array.
func (a *Array) Hex(val []byte) *Array {
	a.buf = enc.AppendHex(enc.AppendArrayDelim(a.buf), val)
	return a
}

// Err Append the err as a string to the array.
func (a *Array) Err(err error) *Array {
	a.buf = enc.AppendError(enc.AppendArrayDelim(a.buf), err)
	return a
}

// Bool Append the val as a bool to the array.
func (a *Array) Bool(b bool) *Array {
	a.buf = enc.AppendBool(enc.AppendArrayDelim(a.buf), b)
	return a
}

// Int Append i as a int to the array.
func (a *Array) Int(i int) *Array {
	a.buf = enc.AppendInt(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Int8 Append i as a int8 to the array.
func (a *Array) Int8(i int8) *Array {
	a.buf = enc.AppendInt8(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Int16 Append i as a int16 to the array.
func (a *Array) Int16(i int16) *Array {
	a.buf = enc.AppendInt16(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Int32 Append i as a int32 to the array.
func (a *Array) Int32(i int32) *Array {
	a.buf = enc.AppendInt32(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Int64 Append i as a int64 to the array.
func (a *Array) Int64(i int64) *Array {
	a.buf = enc.AppendInt64(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint Append i as a uint to the array.
func (a *Array) Uint(i uint) *Array {
	a.buf = enc.AppendUint(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint8 Append i as a uint8 to the array.
func (a *Array) Uint8(i uint8) *Array {
	a.buf = enc.AppendUint8(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint16 Append i as a uint16 to the array.
func (a *Array) Uint16(i uint16) *Array {
	a.buf = enc.AppendUint16(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint32 Append i as a uint32 to the array.
func (a *Array) Uint32(i uint32) *Array {
	a.buf = enc.AppendUint32(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint64 Append i as a uint64 to the array.
func (a *Array) Uint64(i uint64) *Array {
	a.buf = enc.AppendUint64(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Float32 Append f as a float32 to the array.
func (a *Array) Float32(f float32) *Array {
	a.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f)
	return a
}

// Float64 Append f as a float64 to the array.
func (a *Array) Float64(f float64) *Array {
	a.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f)
	return a
}

// Time Append t formated as string using zerolog.TimeFieldFormat.
func (a *Array) Time(t time.Time) *Array {
	a.buf = enc.AppendTime(enc.AppendArrayDelim(a.buf), t, TimeFieldFormat)
	return a
}

// Dur Append d to the array.
func (a *Array) Dur(d time.Duration) *Array {
	a.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger)
	return a
}

// Interface Append i marshaled using reflection.
func (a *Array) Interface(i interface{}) *Array {
	if obj, ok := i.(LogObjectMarshaler); ok {
		return a.Object(obj)
	}
	a.buf = enc.AppendInterface(enc.AppendArrayDelim(a.buf), i)
	return a
}

// IPAddr adds IPv4 or IPv6 address to the array
func (a *Array) IPAddr(ip net.IP) *Array {
	a.buf = enc.AppendIPAddr(enc.AppendArrayDelim(a.buf), ip)
	return a
}

// IPPrefix adds IPv4 or IPv6 Prefix (IP + mask) to the array
func (a *Array) IPPrefix(pfx net.IPNet) *Array {
	a.buf = enc.AppendIPPrefix(enc.AppendArrayDelim(a.buf), pfx)
	return a
}

// MACAddr adds a MAC (Ethernet) address to the array
func (a *Array) MACAddr(ha net.HardwareAddr) *Array {
	a.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha)
	return a
}
<commit_msg>Fix comments (bis)<commit_after>package zerolog

import (
	"net"
	"sync"
	"time"
)

var arrayPool = &sync.Pool{
	New: func() interface{} {
		return &Array{
			buf: make([]byte, 0, 500),
		}
	},
}

// Array is used to prepopulate an array of items
// which can be re-used to add to log messages.
type Array struct {
	buf []byte
}

// Arr creates an array to be added to an Event or Context.
func Arr() *Array {
	a := arrayPool.Get().(*Array)
	a.buf = a.buf[:0]
	return a
}

// MarshalZerologArray method here is no-op - since data is
// already in the needed format.
func (*Array) MarshalZerologArray(*Array) {
}

func (a *Array) write(dst []byte) []byte {
	dst = enc.AppendArrayStart(dst)
	if len(a.buf) > 0 {
		dst = append(append(dst, a.buf...))
	}
	dst = enc.AppendArrayEnd(dst)
	arrayPool.Put(a)
	return dst
}

// Object marshals an object that implement the LogObjectMarshaler
// interface and append append it to the array.
func (a *Array) Object(obj LogObjectMarshaler) *Array {
	e := Dict()
	obj.MarshalZerologObject(e)
	e.buf = enc.AppendEndMarker(e.buf)
	a.buf = append(enc.AppendArrayDelim(a.buf), e.buf...)
	eventPool.Put(e)
	return a
}

// Str append append the val as a string to the array.
func (a *Array) Str(val string) *Array {
	a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), val)
	return a
}

// Bytes append append the val as a string to the array.
func (a *Array) Bytes(val []byte) *Array {
	a.buf = enc.AppendBytes(enc.AppendArrayDelim(a.buf), val)
	return a
}

// Hex append append the val as a hex string to the array.
func (a *Array) Hex(val []byte) *Array {
	a.buf = enc.AppendHex(enc.AppendArrayDelim(a.buf), val)
	return a
}

// Err append append the err as a string to the array.
func (a *Array) Err(err error) *Array {
	a.buf = enc.AppendError(enc.AppendArrayDelim(a.buf), err)
	return a
}

// Bool append append the val as a bool to the array.
func (a *Array) Bool(b bool) *Array {
	a.buf = enc.AppendBool(enc.AppendArrayDelim(a.buf), b)
	return a
}

// Int append append i as a int to the array.
func (a *Array) Int(i int) *Array {
	a.buf = enc.AppendInt(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Int8 append append i as a int8 to the array.
func (a *Array) Int8(i int8) *Array {
	a.buf = enc.AppendInt8(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Int16 append append i as a int16 to the array.
func (a *Array) Int16(i int16) *Array {
	a.buf = enc.AppendInt16(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Int32 append append i as a int32 to the array.
func (a *Array) Int32(i int32) *Array {
	a.buf = enc.AppendInt32(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Int64 append append i as a int64 to the array.
func (a *Array) Int64(i int64) *Array {
	a.buf = enc.AppendInt64(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint append append i as a uint to the array.
func (a *Array) Uint(i uint) *Array {
	a.buf = enc.AppendUint(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint8 append append i as a uint8 to the array.
func (a *Array) Uint8(i uint8) *Array {
	a.buf = enc.AppendUint8(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint16 append append i as a uint16 to the array.
func (a *Array) Uint16(i uint16) *Array {
	a.buf = enc.AppendUint16(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint32 append append i as a uint32 to the array.
func (a *Array) Uint32(i uint32) *Array {
	a.buf = enc.AppendUint32(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Uint64 append append i as a uint64 to the array.
func (a *Array) Uint64(i uint64) *Array {
	a.buf = enc.AppendUint64(enc.AppendArrayDelim(a.buf), i)
	return a
}

// Float32 append append f as a float32 to the array.
func (a *Array) Float32(f float32) *Array {
	a.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f)
	return a
}

// Float64 append append f as a float64 to the array.
func (a *Array) Float64(f float64) *Array {
	a.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f)
	return a
}

// Time append append t formated as string using zerolog.TimeFieldFormat.
func (a *Array) Time(t time.Time) *Array {
	a.buf = enc.AppendTime(enc.AppendArrayDelim(a.buf), t, TimeFieldFormat)
	return a
}

// Dur append append d to the array.
func (a *Array) Dur(d time.Duration) *Array {
	a.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger)
	return a
}

// Interface append append i marshaled using reflection.
func (a *Array) Interface(i interface{}) *Array {
	if obj, ok := i.(LogObjectMarshaler); ok {
		return a.Object(obj)
	}
	a.buf = enc.AppendInterface(enc.AppendArrayDelim(a.buf), i)
	return a
}

// IPAddr adds IPv4 or IPv6 address to the array
func (a *Array) IPAddr(ip net.IP) *Array {
	a.buf = enc.AppendIPAddr(enc.AppendArrayDelim(a.buf), ip)
	return a
}

// IPPrefix adds IPv4 or IPv6 Prefix (IP + mask) to the array
func (a *Array) IPPrefix(pfx net.IPNet) *Array {
	a.buf = enc.AppendIPPrefix(enc.AppendArrayDelim(a.buf), pfx)
	return a
}

// MACAddr adds a MAC (Ethernet) address to the array
func (a *Array) MACAddr(ha net.HardwareAddr) *Array {
	a.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha)
	return a
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp. 2016 All Rights Reserved.

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 main

//WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of
//calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has
//to be modified as well with the new ID of chaincode_example02.
//chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of
//hard-coding.

import (
	"errors"
	"fmt"
	"strconv"
	"encoding/json"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function == "delete" {
		// Deletes an entity from its state
		return t.delete(stub, args)
	}

	if function == "addTable" {
		// Deletes an entity from its state
		return t.addTable(stub, args)
	}

	if function == "getTable" {
		// Deletes an entity from its state
		return t.getTable(stub, args)
	}

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	if err != nil {
		return nil, errors.New("Invalid transaction amount, expecting a integer value")
	}
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) addTable(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	err := stub.CreateTable("Customer", []*shim.ColumnDefinition{
	&shim.ColumnDefinition{Name: "Customer_ID", Type: shim.ColumnDefinition_STRING, Key: true},
	&shim.ColumnDefinition{Name: "Customer_Name", Type: shim.ColumnDefinition_STRING, Key: false},
	&shim.ColumnDefinition{Name: "Customer_Gender", Type: shim.ColumnDefinition_STRING, Key: false},
	})

	if err != nil {
		return nil, err
	}

	success1, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1001"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Vivek"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Male"}},
	},
	})

	if !success1 {
		return nil, errors.New("Entity not found")
	}

	if err != nil {
		return nil, err
	}

	success2, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1002"}},
	&shim.Column{Value: &shim.Column_String_{String_: "John"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Male"}},
	},
	})

	if !success2 {
		return nil, errors.New("Entity not found")
	}
	if err != nil {
		return nil, err
	}

	success3, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1003"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Simone"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Female"}},
	},
	})

	if !success3 {
		return nil, errors.New("Entity not found")
	}
	if err != nil {
		return nil, err
	}
	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) getTable(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: "C1001"}}
	columns = append(columns, col1)

	row, err := stub.GetRow("Customer", columns)
	if err != nil {
		return nil, fmt.Errorf("getRows operation failed. %s", err)
	}

	jsonRow, err := json.Marshal(row)
		if err != nil {
			return nil, fmt.Errorf("getRows operation failed. Error marshaling JSON: %s", err)
		}
	fmt.Printf("Query Response Row:%s\n", jsonRow)

	cust := row.Columns[1].GetBytes()
	fmt.Printf("Customer = %d\n", cust)
	//myLogger.Debugf(" customer is [% x]",  cust)

	var columns2 []shim.Column
	col2 := shim.Column{Value: &shim.Column_String_{String_: "Male"}}
	columns = append(columns2, col2)

	rowChannel, err := stub.GetRows("Customer", columns)
	if err != nil {
		return nil, fmt.Errorf("getRows operation failed. %s", err)
	}
	var rows []shim.Row
		for {
			select {
			case row, ok := <-rowChannel:
				if !ok {
					rowChannel = nil
				} else {
					rows = append(rows, row)
				}
			}
			if rowChannel == nil {
				break
			}
		}

	jsonRows, err := json.Marshal(rows)
		if err != nil {
			return nil, fmt.Errorf("getRows operation failed. Error marshaling JSON: %s", err)
		}
	fmt.Printf("Query Response:%s\n", jsonRows)
	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function != "query" {
		return nil, errors.New("Invalid query function name. Expecting \"query\"")
	}
	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<commit_msg>Update accumshare.go<commit_after>/*
Copyright IBM Corp. 2016 All Rights Reserved.

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 main

//WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of
//calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has
//to be modified as well with the new ID of chaincode_example02.
//chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of
//hard-coding.

import (
	"errors"
	"fmt"
	"strconv"
	"encoding/json"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function == "delete" {
		// Deletes an entity from its state
		return t.delete(stub, args)
	}

	if function == "addTable" {
		// Deletes an entity from its state
		return t.addTable(stub, args)
	}

	if function == "getTable" {
		// Deletes an entity from its state
		return t.getTable(stub, args)
	}

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	if err != nil {
		return nil, errors.New("Invalid transaction amount, expecting a integer value")
	}
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) addTable(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	err := stub.CreateTable("Customer", []*shim.ColumnDefinition{
	&shim.ColumnDefinition{Name: "Customer_ID", Type: shim.ColumnDefinition_STRING, Key: true},
	&shim.ColumnDefinition{Name: "Customer_Name", Type: shim.ColumnDefinition_STRING, Key: false},
	&shim.ColumnDefinition{Name: "Customer_Gender", Type: shim.ColumnDefinition_STRING, Key: false},
	})

	if err != nil {
		return nil, err
	}

	success1, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1001"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Vivek"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Male"}},
	},
	})

	if !success1 {
		return nil, errors.New("Entity not found")
	}

	if err != nil {
		return nil, err
	}

	success2, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1002"}},
	&shim.Column{Value: &shim.Column_String_{String_: "John"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Male"}},
	},
	})

	if !success2 {
		return nil, errors.New("Entity not found")
	}
	if err != nil {
		return nil, err
	}

	success3, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1003"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Simone"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Female"}},
	},
	})

	if !success3 {
		return nil, errors.New("Entity not found")
	}
	if err != nil {
		return nil, err
	}
	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) getTable(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: "C1001"}}
	columns = append(columns, col1)

	row, err := stub.GetRow("Customer", columns)
	if err != nil {
		return nil, fmt.Errorf("getRows operation failed. %s", err)
	}

	//jsonRow, err := json.Marshal(row)
	//	if err != nil {
	//		return nil, fmt.Errorf("getRows operation failed. Error marshaling JSON: %s", err)
		}
	//fmt.Printf("Query Response Row:%s\n", jsonRow)

	cust := row.Columns[1].GetBytes()
	fmt.Printf("Customer = %d\n", cust)
	//myLogger.Debugf(" customer is [% x]",  cust)

	var columns2 []shim.Column
	col2 := shim.Column{Value: &shim.Column_String_{String_: "Male"}}
	columns = append(columns2, col2)

	rowChannel, err := stub.GetRows("Customer", columns2)
	if err != nil {
		return nil, fmt.Errorf("getRows operation failed. %s", err)
	}
	var rows []shim.Row
		for {
			select {
			case row, ok := <-rowChannel:
				if !ok {
					rowChannel = nil
				} else {
					rows = append(rows, row)
				}
			}
			if rowChannel == nil {
				break
			}
		}

	jsonRows, err := json.Marshal(rows)
		if err != nil {
			return nil, fmt.Errorf("getRows operation failed. Error marshaling JSON: %s", err)
		}
	fmt.Printf("Query Response:%s\n", jsonRows)
	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function != "query" {
		return nil, errors.New("Invalid query function name. Expecting \"query\"")
	}
	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<|endoftext|>


<commit_before>package flatmap

import (
	"reflect"
	"testing"
)

func TestExpand(t *testing.T) {
	cases := []struct {
		Map    map[string]string
		Key    string
		Output interface{}
	}{
		{
			Map: map[string]string{
				"foo": "bar",
				"bar": "baz",
			},
			Key:    "foo",
			Output: "bar",
		},

		{
			Map: map[string]string{
				"foo.#": "2",
				"foo.0": "one",
				"foo.1": "two",
			},
			Key: "foo",
			Output: []interface{}{
				"one",
				"two",
			},
		},

		{
			Map: map[string]string{
				"foo.#":         "1",
				"foo.0.name":    "bar",
				"foo.0.port":    "3000",
				"foo.0.enabled": "true",
			},
			Key: "foo",
			Output: []interface{}{
				map[string]interface{}{
					"name":    "bar",
					"port":    "3000",
					"enabled": true,
				},
			},
		},

		{
			Map: map[string]string{
				"foo.#":         "1",
				"foo.0.name":    "bar",
				"foo.0.ports.#": "2",
				"foo.0.ports.0": "1",
				"foo.0.ports.1": "2",
			},
			Key: "foo",
			Output: []interface{}{
				map[string]interface{}{
					"name": "bar",
					"ports": []interface{}{
						"1",
						"2",
					},
				},
			},
		},
	}

	for _, tc := range cases {
		actual := Expand(tc.Map, tc.Key)
		if !reflect.DeepEqual(actual, tc.Output) {
			t.Errorf(
				"Key: %v\nMap:\n\n%#v\n\nOutput:\n\n%#v\n\nExpected:\n\n%#v\n",
				tc.Key,
				tc.Map,
				actual,
				tc.Output)
		}
	}
}
<commit_msg>Add tests for nested structues in flatmap.Expand<commit_after>package flatmap

import (
	"reflect"
	"testing"
)

func TestExpand(t *testing.T) {
	cases := []struct {
		Map    map[string]string
		Key    string
		Output interface{}
	}{
		{
			Map: map[string]string{
				"foo": "bar",
				"bar": "baz",
			},
			Key:    "foo",
			Output: "bar",
		},

		{
			Map: map[string]string{
				"foo.#": "2",
				"foo.0": "one",
				"foo.1": "two",
			},
			Key: "foo",
			Output: []interface{}{
				"one",
				"two",
			},
		},

		{
			Map: map[string]string{
				"foo.#":         "1",
				"foo.0.name":    "bar",
				"foo.0.port":    "3000",
				"foo.0.enabled": "true",
			},
			Key: "foo",
			Output: []interface{}{
				map[string]interface{}{
					"name":    "bar",
					"port":    "3000",
					"enabled": true,
				},
			},
		},

		{
			Map: map[string]string{
				"foo.#":         "1",
				"foo.0.name":    "bar",
				"foo.0.ports.#": "2",
				"foo.0.ports.0": "1",
				"foo.0.ports.1": "2",
			},
			Key: "foo",
			Output: []interface{}{
				map[string]interface{}{
					"name": "bar",
					"ports": []interface{}{
						"1",
						"2",
					},
				},
			},
		},

		{
			Map: map[string]string{
				"list_of_map.#":   "2",
				"list_of_map.0.%": "1",
				"list_of_map.0.a": "1",
				"list_of_map.1.%": "2",
				"list_of_map.1.b": "2",
				"list_of_map.1.c": "3",
			},
			Key: "list_of_map",
			Output: []interface{}{
				map[string]interface{}{
					"a": "1",
				},
				map[string]interface{}{
					"b": "2",
					"c": "3",
				},
			},
		},

		{
			Map: map[string]string{
				"map_of_list.%":       "2",
				"map_of_list.list2.#": "1",
				"map_of_list.list2.0": "c",
				"map_of_list.list1.#": "2",
				"map_of_list.list1.0": "a",
				"map_of_list.list1.1": "b",
			},
			Key: "map_of_list",
			Output: map[string]interface{}{
				"list1": []interface{}{"a", "b"},
				"list2": []interface{}{"c"},
			},
		},
	}

	for _, tc := range cases {
		actual := Expand(tc.Map, tc.Key)
		if !reflect.DeepEqual(actual, tc.Output) {
			t.Errorf(
				"Key: %v\nMap:\n\n%#v\n\nOutput:\n\n%#v\n\nExpected:\n\n%#v\n",
				tc.Key,
				tc.Map,
				actual,
				tc.Output)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"io"
	"net/http"
	"os/exec"
	"regexp"

	"github.com/PuerkitoBio/goquery"
	"github.com/gorilla/mux"
	"go.skia.org/infra/go/baseapp"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

// flags
var (
	domain  = flag.String("domain", "dot.skia.org", "The domain this app is running on.")
	allowed = flag.String("allowed", `^https://(github.com/google/skia|skia.googlesource.com|(\w+.)?skia.org)`, "Regular expression that matches the URLs that are allowed to use this service.")
)

// The Graphviz formats we allow.
var validFormats = []string{"dot", "neato", "twopi", "circo", "fdp", "sfdp"}

// transformer is a func that transforms dot code into svg.
type transformer func(ctx context.Context, format string, dotCode string) (string, error)

// server implements base.App.
type server struct {
	client  *http.Client
	tx      transformer
	allowed *regexp.Regexp
}

func newServer() (baseapp.App, error) {
	return &server{
		client:  httputils.NewTimeoutClient(),
		tx:      transformToSVG,
		allowed: regexp.MustCompile(*allowed),
	}, nil
}

func (srv *server) indexHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	// TODO(jcgregorio) Fill in link to docs.
	_, err := w.Write([]byte(`<!DOCTYPE html>

  <title>Dot</title>

Dot

A service for transforming Graphviz data into SVG.

The Graphviz data must be formatted in a specific way:

<details>
  <summary>
    <object type="image/svg+xml" data="https://dot.skia.org/dot"></object>
  </summary>
  <pre>
    graph {
	  Hello -- World
    }
    </pre>
</details>

  Why this particular format? The details/summary allows for showing the summary,
  the generated SVG, while by default hiding the dot code, but in a way that makes
  it easy to view. We use an 'object' tag instead of an 'img' tag because that allows
  links in the SVG to be functional. The 'pre' tag makes it easy to grab the dot code
  and also formats the dot code nicely.

 Because <object> tags are treated like iframes, all links in Graphviz should specify
 a target, for example:

digraph {
	Jim [URL="https://www.google.com/" fillcolor="green4" style="filled" target="_blank"];
	Jim -> John;
	Jim -> Mary;
}

  If you have more that one diagram on a singe page then make the 'data' URLs
  unique by adding to the query parameters. For example:

  <object type="image/svg+xml" data="https://dot.skia.org/dot?first-diagram"></object>

  ...

  <object type="image/svg+xml" data="https://dot.skia.org/dot?second-diagram"></object>

	The service understands the following formats:

dot

neato

twopi

circo

fdp

sfdp

The format is specified via the path in the URL, for example to use neato:

<details>
<summary>
  <object type="image/svg+xml" data="https://dot.skia.org/neato"></object>
</summary>
<pre>
  graph {
	  Hello -- World
  }
</pre>
</details>

`))
	if err != nil {
		sklog.Errorf("Failed to render index page: %s", err)
	}
}

func transformToSVG(ctx context.Context, format, dotCode string) (string, error) {
	cmd := exec.CommandContext(ctx, format, "-Tsvg")
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return "", fmt.Errorf("Failed to create stdin pipe to dot: %s", err)
	}

	go func() {
		defer stdin.Close()
		_, err := io.WriteString(stdin, dotCode)
		if err != nil {
			sklog.Errorf("Failed to write to dot stdin: %s", err)
		}
	}()

	out, err := cmd.CombinedOutput()
	return string(out), err
}

func (srv *server) transformHandler(w http.ResponseWriter, r *http.Request) {
	// Strip off leading slash from path.
	format := r.URL.Path[1:]

	if !util.In(format, validFormats) {
		httputils.ReportError(w, fmt.Errorf("Unknown format: %q", format), "Unknown format.", http.StatusNotFound)
		return
	}

	sourceURL := r.Header.Get("Referer")
	if sourceURL == "" {
		httputils.ReportError(w, fmt.Errorf("Missing Referer header."), "Missing Referer header.", http.StatusNotFound)
		return
	}

	if !srv.allowed.MatchString(sourceURL) {
		httputils.ReportError(w, fmt.Errorf("Not an allowed domain: %q", sourceURL), "Not an allowed domain.", http.StatusNotFound)
		return
	}

	// Load the HTML document
	resp, err := srv.client.Get(sourceURL)
	if err != nil {
		httputils.ReportError(w, fmt.Errorf("Failed to fetch referring page: %s", err), "Failed to fetch referring page.", http.StatusNotFound)
		return
	}
	defer util.Close(resp.Body)
	if resp.StatusCode != 200 {
		httputils.ReportError(w, fmt.Errorf("Failed to get 200 fetching referring page: %d", resp.StatusCode), "Failed to get 200 fetching referring page.", http.StatusNotFound)
		return
	}

	// NOTE: If the service is too slow them implement caching by using md5
	// along with an lru in-memory cache. Also should use an HTTP caching client
	// to fetch pages.

	// Sometimes Host and Scheme are empty, fill them in so we can reconstuct
	// the requesting URL.
	if r.URL.Host == "" {
		r.URL.Host = *domain
	}
	if r.URL.Scheme == "" {
		r.URL.Scheme = "https"
	}
	requestedURL := r.URL.String()

	// We look for Graphviz data formatted in a specific way:
	//
	//
	//
	//          <object type="image/svg+xml" data="https://dot.skia.org/dot"></object>
	//
	//

	//      graph {
	//          Hello -- World
	//      }
	//

	//
	//
	// The details/summary allows for showing the summary, the generated SVG,
	// while hiding the dot code in a way that makes it easy to inspect it.
	//
	// We use an 'object' tag instead of an 'img' tag because that allows any
	// links in the SVG to be functional.
	//
	// The 'pre' tag makes it easy to grab the dot code and also formats the dot
	// code nicely.
	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
		httputils.ReportError(w, fmt.Errorf("Failed to parse HTML document: %s", err), "Failed to parse source page.", http.StatusNotFound)
		return
	}
	found := false // Only process the first matching response.
	doc.Find("object").Each(func(i int, s *goquery.Selection) {
		if found {
			return
		}
		if imgSrc, ok := s.Attr("data"); !ok || imgSrc != requestedURL {
			return
		}
		found = true
		dotCode := s.Parent().Parent().Find("pre").Text()
		svg, err := srv.tx(r.Context(), format, dotCode)
		if err != nil {
			httputils.ReportError(w, fmt.Errorf("Failed to transform: %s", err), "Failed to transform.", http.StatusNotFound)
			return
		}
		w.Header().Set("Content-Type", "image/svg+xml")
		// Make sure browsers don't cache the wrong value.
		w.Header().Set("Vary", "Referer")
		_, err = w.Write([]byte(svg))
		if err != nil {
			sklog.Errorf("Failed to write SVG: %s", err)
		}
		return
	})
	if !found {
		httputils.ReportError(w, fmt.Errorf("Couldn't find requested URL %q in source document %q", requestedURL, sourceURL), "Failed to find requester URL in source document.", http.StatusNotFound)
	}
}

// See baseapp.App.
func (srv *server) AddHandlers(r *mux.Router) {
	r.HandleFunc("/", srv.indexHandler)
	r.HandleFunc("/{[a-z]+}", srv.transformHandler)
}

// See baseapp.App.
func (srv *server) AddMiddleware() []mux.MiddlewareFunc {
	return []mux.MiddlewareFunc{}
}

func main() {
	baseapp.Serve(newServer, []string{*domain})
}
<commit_msg>[dot] Tidy up error handling<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"io"
	"net/http"
	"os/exec"
	"regexp"

	"github.com/PuerkitoBio/goquery"
	"github.com/gorilla/mux"
	"go.skia.org/infra/go/baseapp"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

// flags
var (
	domain  = flag.String("domain", "dot.skia.org", "The domain this app is running on.")
	allowed = flag.String("allowed", `^https://(github.com/google/skia|skia.googlesource.com|(\w+.)?skia.org)`, "Regular expression that matches the URLs that are allowed to use this service.")
)

// The Graphviz formats we allow.
var validFormats = []string{"dot", "neato", "twopi", "circo", "fdp", "sfdp"}

// transformer is a func that transforms dot code into svg.
type transformer func(ctx context.Context, format string, dotCode string) (string, error)

// server implements base.App.
type server struct {
	client  *http.Client
	tx      transformer
	allowed *regexp.Regexp
}

func newServer() (baseapp.App, error) {
	return &server{
		client:  httputils.NewTimeoutClient(),
		tx:      transformToSVG,
		allowed: regexp.MustCompile(*allowed),
	}, nil
}

func (srv *server) indexHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	// TODO(jcgregorio) Fill in link to docs.
	_, err := w.Write([]byte(`<!DOCTYPE html>

  <title>Dot</title>

Dot

A service for transforming Graphviz data into SVG.

The Graphviz data must be formatted in a specific way:

<details>
  <summary>
    <object type="image/svg+xml" data="https://dot.skia.org/dot"></object>
  </summary>
  <pre>
    graph {
	  Hello -- World
    }
    </pre>
</details>

  Why this particular format? The details/summary allows for showing the summary,
  the generated SVG, while by default hiding the dot code, but in a way that makes
  it easy to view. We use an 'object' tag instead of an 'img' tag because that allows
  links in the SVG to be functional. The 'pre' tag makes it easy to grab the dot code
  and also formats the dot code nicely.

 Because <object> tags are treated like iframes, all links in Graphviz should specify
 a target, for example:

digraph {
	Jim [URL="https://www.google.com/" fillcolor="green4" style="filled" target="_blank"];
	Jim -> John;
	Jim -> Mary;
}

  If you have more that one diagram on a singe page then make the 'data' URLs
  unique by adding to the query parameters. For example:

  <object type="image/svg+xml" data="https://dot.skia.org/dot?first-diagram"></object>

  ...

  <object type="image/svg+xml" data="https://dot.skia.org/dot?second-diagram"></object>

	The service understands the following formats:

dot

neato

twopi

circo

fdp

sfdp

The format is specified via the path in the URL, for example to use neato:

<details>
<summary>
  <object type="image/svg+xml" data="https://dot.skia.org/neato"></object>
</summary>
<pre>
  graph {
	  Hello -- World
  }
</pre>
</details>

`))
	if err != nil {
		sklog.Errorf("Failed to render index page: %s", err)
	}
}

func transformToSVG(ctx context.Context, format, dotCode string) (string, error) {
	cmd := exec.CommandContext(ctx, format, "-Tsvg")
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return "", fmt.Errorf("Failed to create stdin pipe to dot: %s", err)
	}

	go func() {
		if _, err := io.WriteString(stdin, dotCode); err != nil {
			_ = stdin.Close()
			sklog.Errorf("Failed to write to dot stdin: %s", err)
			return
		}
		if err := stdin.Close(); err != nil {
			sklog.Errorf("Failed to close dot stdin: %s", err)
		}
	}()

	out, err := cmd.CombinedOutput()
	return string(out), err
}

func (srv *server) transformHandler(w http.ResponseWriter, r *http.Request) {
	// Strip off leading slash from path.
	format := r.URL.Path[1:]

	if !util.In(format, validFormats) {
		httputils.ReportError(w, fmt.Errorf("Unknown format: %q", format), "Unknown format.", http.StatusNotFound)
		return
	}

	sourceURL := r.Header.Get("Referer")
	if sourceURL == "" {
		httputils.ReportError(w, fmt.Errorf("Missing Referer header."), "Missing Referer header.", http.StatusNotFound)
		return
	}

	if !srv.allowed.MatchString(sourceURL) {
		httputils.ReportError(w, fmt.Errorf("Not an allowed domain: %q", sourceURL), "Not an allowed domain.", http.StatusNotFound)
		return
	}

	// Load the HTML document
	resp, err := srv.client.Get(sourceURL)
	if err != nil {
		httputils.ReportError(w, fmt.Errorf("Failed to fetch referring page: %s", err), "Failed to fetch referring page.", http.StatusNotFound)
		return
	}
	defer util.Close(resp.Body)
	if resp.StatusCode != 200 {
		httputils.ReportError(w, fmt.Errorf("Failed to get 200 fetching referring page: %d", resp.StatusCode), "Failed to get 200 fetching referring page.", http.StatusNotFound)
		return
	}

	// NOTE: If the service is too slow them implement caching by using md5
	// along with an lru in-memory cache. Also should use an HTTP caching client
	// to fetch pages.

	// Sometimes Host and Scheme are empty, fill them in so we can reconstuct
	// the requesting URL.
	if r.URL.Host == "" {
		r.URL.Host = *domain
	}
	if r.URL.Scheme == "" {
		r.URL.Scheme = "https"
	}
	requestedURL := r.URL.String()

	// We look for Graphviz data formatted in a specific way:
	//
	//
	//
	//          <object type="image/svg+xml" data="https://dot.skia.org/dot"></object>
	//
	//

	//      graph {
	//          Hello -- World
	//      }
	//

	//
	//
	// The details/summary allows for showing the summary, the generated SVG,
	// while hiding the dot code in a way that makes it easy to inspect it.
	//
	// We use an 'object' tag instead of an 'img' tag because that allows any
	// links in the SVG to be functional.
	//
	// The 'pre' tag makes it easy to grab the dot code and also formats the dot
	// code nicely.
	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
		httputils.ReportError(w, fmt.Errorf("Failed to parse HTML document: %s", err), "Failed to parse source page.", http.StatusNotFound)
		return
	}
	found := false // Only process the first matching response.
	doc.Find("object").Each(func(i int, s *goquery.Selection) {
		if found {
			return
		}
		if imgSrc, ok := s.Attr("data"); !ok || imgSrc != requestedURL {
			return
		}
		found = true
		dotCode := s.Parent().Parent().Find("pre").Text()
		svg, err := srv.tx(r.Context(), format, dotCode)
		if err != nil {
			httputils.ReportError(w, fmt.Errorf("Failed to transform: %s", err), "Failed to transform.", http.StatusNotFound)
			return
		}
		w.Header().Set("Content-Type", "image/svg+xml")
		// Make sure browsers don't cache the wrong value.
		w.Header().Set("Vary", "Referer")
		_, err = w.Write([]byte(svg))
		if err != nil {
			sklog.Errorf("Failed to write SVG: %s", err)
		}
		return
	})
	if !found {
		httputils.ReportError(w, fmt.Errorf("Couldn't find requested URL %q in source document %q", requestedURL, sourceURL), "Failed to find requester URL in source document.", http.StatusNotFound)
	}
}

// See baseapp.App.
func (srv *server) AddHandlers(r *mux.Router) {
	r.HandleFunc("/", srv.indexHandler)
	r.HandleFunc("/{[a-z]+}", srv.transformHandler)
}

// See baseapp.App.
func (srv *server) AddMiddleware() []mux.MiddlewareFunc {
	return []mux.MiddlewareFunc{}
}

func main() {
	baseapp.Serve(newServer, []string{*domain})
}
<|endoftext|>


<commit_before>package downloader

import (
	//"errors"
	"github.com/nladuo/go-webcrawler/model"
	//"log"
	"net/http"
	netUrl "net/url"
	"time"
)

var (
	//default timeout
	proxyTimeOut time.Duration = 0 * time.Second
)

type Downloader interface {
	Download(tag string, task model.Task) *model.Result
	SetRetryTimes(times int)
}

func dowloadDirect(url string) (*http.Response, error) {
	return http.Get(url)
}

func dowloadWithProxy(url string, proxy *model.Proxy) (*http.Response, error) {
	request, _ := http.NewRequest("GET", url, nil)
	proxyStr := "http://" + proxy.IP + ":" + proxy.Port
	proxyUrl, err := netUrl.Parse(proxyStr)
	if err != nil {
		return nil, err
	}
	client := &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyURL(proxyUrl),
		},
	}

	if proxyTimeOut != 0*time.Second {
		client.Timeout = proxyTimeOut
	}

	return client.Do(request)
}

func SetProxyTimeOut(timeout time.Duration) {
	proxyTimeOut = timeout
}
<commit_msg>	modified:   downloader/downloader.go<commit_after>package downloader

import (
	//"errors"
	"github.com/nladuo/go-webcrawler/model"
	//"log"
	"net/http"
	netUrl "net/url"
	"time"
)

var (
	//default timeout
	proxyTimeOut time.Duration = 50 * time.Second
)

type Downloader interface {
	Download(tag string, task model.Task) *model.Result
	SetRetryTimes(times int)
}

func dowloadDirect(url string) (*http.Response, error) {
	return http.Get(url)
}

func dowloadWithProxy(url string, proxy *model.Proxy) (*http.Response, error) {
	request, _ := http.NewRequest("GET", url, nil)
	proxyStr := "http://" + proxy.IP + ":" + proxy.Port
	proxyUrl, err := netUrl.Parse(proxyStr)
	if err != nil {
		return nil, err
	}
	client := &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyURL(proxyUrl),
		},
	}

	client.Timeout = proxyTimeOut

	return client.Do(request)
}

func SetProxyTimeOut(timeout time.Duration) {
	proxyTimeOut = timeout
}
<|endoftext|>


<commit_before>// Package kitchen implements a driver based on Test Kitchen.
package kitchen

import (
	"errors"
	"fmt"
	"io/ioutil"
	"path"
	"strconv"

	"github.com/mlafeldt/chef-runner/log"
	"github.com/mlafeldt/chef-runner/openssh"
	"github.com/mlafeldt/chef-runner/rsync"
	"github.com/mlafeldt/chef-runner/util"
	"gopkg.in/yaml.v1"
)

// Driver is a driver based on Test Kitchen.
type Driver struct {
	Instance    string
	SSHClient   *openssh.Client
	RsyncClient *rsync.Client
}

type instanceConfig struct {
	Hostname string `yaml:"hostname"`
	Username string `yaml:"username"`
	SSHKey   string `yaml:"ssh_key"`
	Port     string `yaml:"port"`
}

func readInstanceConfig(instance string) (*instanceConfig, error) {
	configFile := path.Join(".kitchen", instance+".yml")
	log.Debugf("Kitchen config file = %s\n", configFile)

	data, err := ioutil.ReadFile(configFile)
	if err != nil {
		return nil, err
	}

	var config instanceConfig
	if err := yaml.Unmarshal(data, &config); err != nil {
		return nil, err
	}
	log.Debugf("Kitchen config = %+v\n", config)

	if config.Hostname == "" {
		return nil, errors.New(configFile + ": invalid `hostname`")
	}
	if config.Username == "" {
		return nil, errors.New(configFile + ": invalid `username`")
	}
	if config.SSHKey == "" {
		return nil, errors.New(configFile + ": invalid `ssh_key`")
	}
	if _, err := strconv.Atoi(config.Port); err != nil {
		return nil, errors.New(configFile + ": invalid `port`")
	}

	return &config, nil
}

// NewDriver creates a new Test Kitchen driver that communicates with the given
// Test Kitchen instance. Under the hood the instance's YAML configuration is
// parsed to get a working SSH configuration.
func NewDriver(instance string) (*Driver, error) {
	if !util.FileExist(".kitchen.yml") {
		return nil, errors.New("Kitchen YAML file not found")
	}

	config, err := readInstanceConfig(instance)
	if err != nil {
		return nil, err
	}

	// Test Kitchen stores the port as an string
	port, _ := strconv.Atoi(config.Port)

	// This is what `vagrant ssh` uses
	sshOpts := map[string]string{
		"UserKnownHostsFile":     "/dev/null",
		"StrictHostKeyChecking":  "no",
		"PasswordAuthentication": "no",
		"IdentitiesOnly":         "yes",
		"LogLevel":               "FATAL",
	}
	sshClient := &openssh.Client{
		Host:        config.Hostname,
		User:        config.Username,
		Port:        port,
		PrivateKeys: []string{config.SSHKey},
		Options:     sshOpts,
	}

	rsyncClient := *rsync.MirrorClient
	rsyncClient.RemoteHost = config.Hostname
	rsyncClient.RemoteShell = sshClient.Shell()

	return &Driver{instance, sshClient, &rsyncClient}, nil
}

// RunCommand runs the specified command on the Test Kitchen instance.
func (drv Driver) RunCommand(args []string) error {
	return drv.SSHClient.RunCommand(args)
}

// Upload copies files to the Test Kitchen instance.
func (drv Driver) Upload(dst string, src ...string) error {
	return drv.RsyncClient.Copy(dst, src...)
}

// String returns the driver's name.
func (drv Driver) String() string {
	return fmt.Sprintf("Test Kitchen driver (instance: %s)", drv.Instance)
}
<commit_msg>Update to yaml v2 package<commit_after>// Package kitchen implements a driver based on Test Kitchen.
package kitchen

import (
	"errors"
	"fmt"
	"io/ioutil"
	"path"
	"strconv"

	"github.com/mlafeldt/chef-runner/log"
	"github.com/mlafeldt/chef-runner/openssh"
	"github.com/mlafeldt/chef-runner/rsync"
	"github.com/mlafeldt/chef-runner/util"
	"gopkg.in/yaml.v2"
)

// Driver is a driver based on Test Kitchen.
type Driver struct {
	Instance    string
	SSHClient   *openssh.Client
	RsyncClient *rsync.Client
}

type instanceConfig struct {
	Hostname string `yaml:"hostname"`
	Username string `yaml:"username"`
	SSHKey   string `yaml:"ssh_key"`
	Port     string `yaml:"port"`
}

func readInstanceConfig(instance string) (*instanceConfig, error) {
	configFile := path.Join(".kitchen", instance+".yml")
	log.Debugf("Kitchen config file = %s\n", configFile)

	data, err := ioutil.ReadFile(configFile)
	if err != nil {
		return nil, err
	}

	var config instanceConfig
	if err := yaml.Unmarshal(data, &config); err != nil {
		return nil, err
	}
	log.Debugf("Kitchen config = %+v\n", config)

	if config.Hostname == "" {
		return nil, errors.New(configFile + ": invalid `hostname`")
	}
	if config.Username == "" {
		return nil, errors.New(configFile + ": invalid `username`")
	}
	if config.SSHKey == "" {
		return nil, errors.New(configFile + ": invalid `ssh_key`")
	}
	if _, err := strconv.Atoi(config.Port); err != nil {
		return nil, errors.New(configFile + ": invalid `port`")
	}

	return &config, nil
}

// NewDriver creates a new Test Kitchen driver that communicates with the given
// Test Kitchen instance. Under the hood the instance's YAML configuration is
// parsed to get a working SSH configuration.
func NewDriver(instance string) (*Driver, error) {
	if !util.FileExist(".kitchen.yml") {
		return nil, errors.New("Kitchen YAML file not found")
	}

	config, err := readInstanceConfig(instance)
	if err != nil {
		return nil, err
	}

	// Test Kitchen stores the port as an string
	port, _ := strconv.Atoi(config.Port)

	// This is what `vagrant ssh` uses
	sshOpts := map[string]string{
		"UserKnownHostsFile":     "/dev/null",
		"StrictHostKeyChecking":  "no",
		"PasswordAuthentication": "no",
		"IdentitiesOnly":         "yes",
		"LogLevel":               "FATAL",
	}
	sshClient := &openssh.Client{
		Host:        config.Hostname,
		User:        config.Username,
		Port:        port,
		PrivateKeys: []string{config.SSHKey},
		Options:     sshOpts,
	}

	rsyncClient := *rsync.MirrorClient
	rsyncClient.RemoteHost = config.Hostname
	rsyncClient.RemoteShell = sshClient.Shell()

	return &Driver{instance, sshClient, &rsyncClient}, nil
}

// RunCommand runs the specified command on the Test Kitchen instance.
func (drv Driver) RunCommand(args []string) error {
	return drv.SSHClient.RunCommand(args)
}

// Upload copies files to the Test Kitchen instance.
func (drv Driver) Upload(dst string, src ...string) error {
	return drv.RsyncClient.Copy(dst, src...)
}

// String returns the driver's name.
func (drv Driver) String() string {
	return fmt.Sprintf("Test Kitchen driver (instance: %s)", drv.Instance)
}
<|endoftext|>


<commit_before>package main

import (
	"math"
)

var Value [7]int = [7]int{
	0,
	1,
	3,
	3,
	5,
	9,
	0,
}

const INFINITY int = int(math.MaxInt32) // I win!

func Evaluate(board *Board) int {
	mate := Mated(board)
	if mate == -1 {
		return MaterialCount(board)
	} else {
		return mate
	}
}

/* Returns negative infinity if checkmate, zero if stalemate, -1 otherwise. */
func Mated(b *Board) int {
	moves := MoveGen(b)
	if len(moves) > 0 {
		return -1
	}
	var king byte
	if b.ToMove == BLACK {
		king = b.BlackKing
	} else {
		king = b.WhiteKing
	}
	if squareattacked(b, king, b.ToMove^BLACK) {
		return -INFINITY
	} else {
		return 0
	}
}

func MaterialCount(b *Board) int {
	var retval int
	for i := A1; i <= H8; i++ {
		if OnBoard(i) && GetPiece(b.Data[i]) != EMPTY {
			if GetSide(b.Data[i]) == b.ToMove {
				retval += Value[GetPiece(b.Data[i])]
			} else {
				retval -= Value[GetPiece(b.Data[i])]
			}
		}
	}
	return retval
}

func NegaMax(board *Board, depth int) int {
	best := -INFINITY
	if depth <= 0 {
		return Evaluate(board)
	}
	moves := MoveGen(board)
	for _, move := range moves {
		undo := MakeMove(board, &move)
		val := -NegaMax(board, depth-1)
		UnmakeMove(board, &move, undo)
		if val > best {
			best = val
		}
	}
	return best
}
<commit_msg>change minmax into alpha beta<commit_after>package main

import (
	"math"
)

var Value [7]int = [7]int{
	0,
	1,
	3,
	3,
	5,
	9,
	0,
}

const INFINITY int = int(math.MaxInt32) // I win!

func Evaluate(board *Board) int {
	mate := Mated(board)
	if mate == -1 {
		return MaterialCount(board)
	} else {
		return mate
	}
}

/* Returns negative infinity if checkmate, zero if stalemate, -1 otherwise. */
func Mated(b *Board) int {
	moves := MoveGen(b)
	if len(moves) > 0 {
		return -1
	}
	var king byte
	if b.ToMove == BLACK {
		king = b.BlackKing
	} else {
		king = b.WhiteKing
	}
	if squareattacked(b, king, b.ToMove^BLACK) {
		return -INFINITY
	} else {
		return 0
	}
}

func MaterialCount(b *Board) int {
	var retval int
	for i := A1; i <= H8; i++ {
		if OnBoard(i) && GetPiece(b.Data[i]) != EMPTY {
			if GetSide(b.Data[i]) == b.ToMove {
				retval += Value[GetPiece(b.Data[i])]
			} else {
				retval -= Value[GetPiece(b.Data[i])]
			}
		}
	}
	return retval
}

func AlphaBeta(board *Board, depth, alpha, beta int) int {
	if depth <= 0 {
		return Evaluate(board)
	}
	moves := MoveGen(board)
	for _, move := range moves {
		undo := MakeMove(board, &move)
		val := -AlphaBeta(board, depth-1, -beta, -alpha)
		UnmakeMove(board, &move, undo)
		if val >= beta {
			return beta
		}
		if val > alpha {
			alpha = val
		}
	}
	return alpha
}
<|endoftext|>


<commit_before>// 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 common

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

// DefaultServiceRoot is the default path to the Redfish service endpoint.
const DefaultServiceRoot = "/redfish/v1"

// Client is a connection to a Redfish service.
type Client interface {
	Get(url string) (*http.Response, error)
	// Post()
	// Patch()
	// Put()
	// Delete()
}

// Entity provides the common basis for all Redfish and Swordfish objects.
type Entity struct {
	ID     string `json:"Id"`
	Name   string `json:"Name"`
	Client Client
}

// SetClient sets the API client connection to use for accessing this
// entity.
func (e *Entity) SetClient(c Client) {
	e.Client = c
}

// Link is an OData link reference
type Link string

// UnmarshalJSON unmarshals a Link
func (l *Link) UnmarshalJSON(b []byte) error {
	var t struct {
		ODataID string `json:"@odata.id"`
	}

	err := json.Unmarshal(b, &t)
	if err != nil {
		*l = ""
	}

	*l = Link(t.ODataID)
	return nil
}

// Links are a collection of Link references
type Links []Link

// ToStrings converts a Link collection to a list of strings
func (l Links) ToStrings() []string {
	var result []string
	for _, link := range l {
		result = append(result, string(link))
	}
	return result
}

// LinksCollection contains links to other entities
type LinksCollection struct {
	Count   int   `json:"Member@odata.count"`
	Members Links `json:"Members"`
}

// ToStrings will extract the URI for all linked entities.
func (l LinksCollection) ToStrings() []string {
	return l.Members.ToStrings()
}

// Health indicates the health of a resource.
type Health string

const (
	// OKHealth indicates the health is normal.
	OKHealth Health = "OK"
	// WarningHealth indicates a condition exists that requires attention.
	WarningHealth Health = "Warning"
	// CriticalHealth indicates a critical condition exists that requires
	// immediate attention.
	CriticalHealth Health = "Critical"
)

// IndicatorLED represents LED indicator states
type IndicatorLED string

const (
	// UnknownIndicatorLED indicates the state of the Indicator LED cannot be
	// determined.
	UnknownIndicatorLED IndicatorLED = "Unknown"
	// LitIndicatorLED indicates the Indicator LED is lit.
	LitIndicatorLED IndicatorLED = "Lit"
	// BlinkingIndicatorLED indicates the Indicator LED is blinking.
	BlinkingIndicatorLED IndicatorLED = "Blinking"
	// OffIndicatorLED indicates the Indicator LED is off.
	OffIndicatorLED IndicatorLED = "Off"
)

// State indicates the known state of the resource, such as if it is enabled.
type State string

const (
	// EnabledState indicates this function or resource has been enabled.
	EnabledState State = "Enabled"
	// DisabledState Stateindicates this function or resource has been disabled.
	DisabledState State = "Disabled"
	// StandbyOfflineState indicates this function or resource is enabled,
	// but awaiting an external action to activate it.
	StandbyOfflineState State = "StandbyOffinline"
	// StandbySpareState indicates this function or resource is part of a
	// redundancy set and is awaiting a failover or other external action to
	// activate it.
	StandbySpareState State = "StandbySpare"
	// InTestState indicates this function or resource is undergoing testing.
	InTestState State = "InTest"
	// StartingState indicates this function or resource is starting.
	StartingState State = "Starting"
	// AbsentState indicates this function or resource is not present or not
	// detected.
	AbsentState State = "Absent"
	// UnavailableOfflineState indicates this function or resource is present
	// but cannot be used.
	UnavailableOfflineState State = "UnavailableOffline"
	// DeferringState indicates the element will not process any commands but
	// will queue new requests.
	DeferringState State = "Deferring"
	// QuiescedState indicates the element is enabled but only processes a
	// restricted set of commands.
	QuiescedState State = "Quiesced"
	// UpdatingState indicates the element is updating and may be unavailable
	// or degraded.
	UpdatingState State = "Updating"
)

// Status describes the status and health of a resource and its children.
type Status struct {
	Health Health `json:"Health"`
	State  State  `json:"State"`
}
<commit_msg>Correct collection Members@odata.count<commit_after>// 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 common

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

// DefaultServiceRoot is the default path to the Redfish service endpoint.
const DefaultServiceRoot = "/redfish/v1/"

// Client is a connection to a Redfish service.
type Client interface {
	Get(url string) (*http.Response, error)
	// Post()
	// Patch()
	// Put()
	// Delete()
}

// Entity provides the common basis for all Redfish and Swordfish objects.
type Entity struct {
	ID     string `json:"Id"`
	Name   string `json:"Name"`
	Client Client
}

// SetClient sets the API client connection to use for accessing this
// entity.
func (e *Entity) SetClient(c Client) {
	e.Client = c
}

// Link is an OData link reference
type Link string

// UnmarshalJSON unmarshals a Link
func (l *Link) UnmarshalJSON(b []byte) error {
	var t struct {
		ODataID string `json:"@odata.id"`
	}

	err := json.Unmarshal(b, &t)
	if err != nil {
		*l = ""
	}

	*l = Link(t.ODataID)
	return nil
}

// Links are a collection of Link references
type Links []Link

// ToStrings converts a Link collection to a list of strings
func (l Links) ToStrings() []string {
	var result []string
	for _, link := range l {
		result = append(result, string(link))
	}
	return result
}

// LinksCollection contains links to other entities
type LinksCollection struct {
	Count   int   `json:"Members@odata.count"`
	Members Links `json:"Members"`
}

// ToStrings will extract the URI for all linked entities.
func (l LinksCollection) ToStrings() []string {
	return l.Members.ToStrings()
}

// Health indicates the health of a resource.
type Health string

const (
	// OKHealth indicates the health is normal.
	OKHealth Health = "OK"
	// WarningHealth indicates a condition exists that requires attention.
	WarningHealth Health = "Warning"
	// CriticalHealth indicates a critical condition exists that requires
	// immediate attention.
	CriticalHealth Health = "Critical"
)

// IndicatorLED represents LED indicator states
type IndicatorLED string

const (
	// UnknownIndicatorLED indicates the state of the Indicator LED cannot be
	// determined.
	UnknownIndicatorLED IndicatorLED = "Unknown"
	// LitIndicatorLED indicates the Indicator LED is lit.
	LitIndicatorLED IndicatorLED = "Lit"
	// BlinkingIndicatorLED indicates the Indicator LED is blinking.
	BlinkingIndicatorLED IndicatorLED = "Blinking"
	// OffIndicatorLED indicates the Indicator LED is off.
	OffIndicatorLED IndicatorLED = "Off"
)

// State indicates the known state of the resource, such as if it is enabled.
type State string

const (
	// EnabledState indicates this function or resource has been enabled.
	EnabledState State = "Enabled"
	// DisabledState Stateindicates this function or resource has been disabled.
	DisabledState State = "Disabled"
	// StandbyOfflineState indicates this function or resource is enabled,
	// but awaiting an external action to activate it.
	StandbyOfflineState State = "StandbyOffinline"
	// StandbySpareState indicates this function or resource is part of a
	// redundancy set and is awaiting a failover or other external action to
	// activate it.
	StandbySpareState State = "StandbySpare"
	// InTestState indicates this function or resource is undergoing testing.
	InTestState State = "InTest"
	// StartingState indicates this function or resource is starting.
	StartingState State = "Starting"
	// AbsentState indicates this function or resource is not present or not
	// detected.
	AbsentState State = "Absent"
	// UnavailableOfflineState indicates this function or resource is present
	// but cannot be used.
	UnavailableOfflineState State = "UnavailableOffline"
	// DeferringState indicates the element will not process any commands but
	// will queue new requests.
	DeferringState State = "Deferring"
	// QuiescedState indicates the element is enabled but only processes a
	// restricted set of commands.
	QuiescedState State = "Quiesced"
	// UpdatingState indicates the element is updating and may be unavailable
	// or degraded.
	UpdatingState State = "Updating"
)

// Status describes the status and health of a resource and its children.
type Status struct {
	Health Health `json:"Health"`
	State  State  `json:"State"`
}
<|endoftext|>


<commit_before>package themekit

import (
	"encoding/base64"
	"errors"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

type Asset struct {
	Key        string `json:"key"`
	Value      string `json:"value,omitempty"`
	Attachment string `json:"attachment,omitempty"`
}

func (a Asset) String() string {
	return fmt.Sprintf("key: %s | value: %s | attachment: %s", a.Key, a.Value, a.Attachment)
}

func (a Asset) IsValid() bool {
	return len(a.Key) > 0 && (len(a.Value) > 0 || len(a.Attachment) > 0)
}

// Implementing sort.Interface
type ByAsset []Asset

func (assets ByAsset) Len() int {
	return len(assets)
}

func (assets ByAsset) Swap(i, j int) {
	assets[i], assets[j] = assets[j], assets[i]
}

func (assets ByAsset) Less(i, j int) bool {
	return assets[i].Key < assets[j].Key
}

func LoadAsset(root, filename string) (asset Asset, err error) {
	path := toSlash(fmt.Sprintf("%s/%s", root, filename))
	file, err := os.Open(path)
	info, err := os.Stat(path)
	if err != nil {
		return
	}

	if info.IsDir() {
		err = errors.New("File is a directory")
		return
	}

	buffer := make([]byte, info.Size())
	_, err = file.Read(buffer)
	if err != nil {
		return
	}

	asset = Asset{Key: toSlash(filename)}
	if contentTypeFor(buffer) == "text" {
		asset.Value = string(buffer)
	} else {
		asset.Attachment = encode64(buffer)
	}
	return
}

func toSlash(path string) string {
	newpath := filepath.ToSlash(path)
	if strings.Index(newpath, "\\") >= 0 {
		newpath = strings.Replace(newpath, "\\", "/", -1)
	}
	return newpath
}

func encode64(data []byte) string {
	return base64.StdEncoding.EncodeToString(data)
}

func contentTypeFor(data []byte) string {
	contentType := http.DetectContentType(data)
	if strings.Contains(contentType, "text") {
		return "text"
	} else {
		return "binary"
	}
}
<commit_msg>Fixes File Descriptor exhaustion<commit_after>package themekit

import (
	"encoding/base64"
	"errors"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

type Asset struct {
	Key        string `json:"key"`
	Value      string `json:"value,omitempty"`
	Attachment string `json:"attachment,omitempty"`
}

func (a Asset) String() string {
	return fmt.Sprintf("key: %s | value: %s | attachment: %s", a.Key, a.Value, a.Attachment)
}

func (a Asset) IsValid() bool {
	return len(a.Key) > 0 && (len(a.Value) > 0 || len(a.Attachment) > 0)
}

// Implementing sort.Interface
type ByAsset []Asset

func (assets ByAsset) Len() int {
	return len(assets)
}

func (assets ByAsset) Swap(i, j int) {
	assets[i], assets[j] = assets[j], assets[i]
}

func (assets ByAsset) Less(i, j int) bool {
	return assets[i].Key < assets[j].Key
}

func LoadAsset(root, filename string) (asset Asset, err error) {
	path := toSlash(fmt.Sprintf("%s/%s", root, filename))
	file, err := os.Open(path)
	info, err := os.Stat(path)
	if err != nil {
		return
	}
	defer file.Close()

	if info.IsDir() {
		err = errors.New("File is a directory")
		return
	}

	buffer := make([]byte, info.Size())
	_, err = file.Read(buffer)
	if err != nil {
		return
	}

	asset = Asset{Key: toSlash(filename)}
	if contentTypeFor(buffer) == "text" {
		asset.Value = string(buffer)
	} else {
		asset.Attachment = encode64(buffer)
	}
	return
}

func toSlash(path string) string {
	newpath := filepath.ToSlash(path)
	if strings.Index(newpath, "\\") >= 0 {
		newpath = strings.Replace(newpath, "\\", "/", -1)
	}
	return newpath
}

func encode64(data []byte) string {
	return base64.StdEncoding.EncodeToString(data)
}

func contentTypeFor(data []byte) string {
	contentType := http.DetectContentType(data)
	if strings.Contains(contentType, "text") {
		return "text"
	} else {
		return "binary"
	}
}
<|endoftext|>


<commit_before>// Copyright 2016-2020 The Libsacloud 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 naked

import (
	"encoding/json"
	"strings"
	"time"

	"github.com/sacloud/libsacloud/v2/sacloud/types"
)

// ProxyLB エンハンスドロードバランサ
type ProxyLB struct {
	ID           types.ID            `json:",omitempty" yaml:"id,omitempty" structs:",omitempty"`
	Name         string              `json:",omitempty" yaml:"name,omitempty" structs:",omitempty"`
	Description  string              `yaml:"description"`
	Tags         types.Tags          `yaml:"tags"`
	Icon         *Icon               `json:",omitempty" yaml:"icon,omitempty" structs:",omitempty"`
	CreatedAt    *time.Time          `json:",omitempty" yaml:"created_at,omitempty" structs:",omitempty"`
	ModifiedAt   *time.Time          `json:",omitempty" yaml:"modified_at,omitempty" structs:",omitempty"`
	Availability types.EAvailability `json:",omitempty" yaml:"availability,omitempty" structs:",omitempty"`
	Provider     *Provider           `json:",omitempty" yaml:"provider,omitempty" structs:",omitempty"`
	Settings     *ProxyLBSettings    `json:",omitempty" yaml:"settings,omitempty" structs:",omitempty"`
	SettingsHash string              `json:",omitempty" yaml:"settings_hash,omitempty" structs:",omitempty"`
	Status       *ProxyLBStatus      `json:",omitempty" yaml:"status,omitempty" structs:",omitempty"`

	// ServiceClass [HACK] プランはServiceClassとして文字列で表す必要がある。 詳細はtypes.EProxyLBPlanのコメント参照
	ServiceClass types.EProxyLBPlan `json:",omitempty" yaml:"service_class,omitempty" structs:",omitempty"`
}

// ProxyLBSettingsUpdate エンハンスドロードバランサ
type ProxyLBSettingsUpdate struct {
	Settings     *ProxyLBSettings `json:",omitempty" yaml:"settings,omitempty" structs:",omitempty"`
	SettingsHash string           `json:",omitempty" yaml:"settings_hash,omitempty" structs:",omitempty"`
}

// ProxyLBSettings エンハンスドロードバランサ設定
type ProxyLBSettings struct {
	ProxyLB *ProxyLBSetting `json:",omitempty" yaml:"proxy_lb,omitempty" structs:",omitempty"`
}

// ProxyLBSetting エンハンスドロードバランサ設定
type ProxyLBSetting struct {
	HealthCheck   ProxyLBHealthCheck   `yaml:"health_check"`                                                  // ヘルスチェック
	SorryServer   ProxyLBSorryServer   `yaml:"sorry_server"`                                                  // ソーリーサーバー
	BindPorts     []*ProxyLBBindPorts  `yaml:"bind_ports"`                                                    // プロキシ方式(プロトコル&ポート)
	Servers       []ProxyLBServer      `yaml:"servers"`                                                       // サーバー
	Rules         []ProxyLBRule        `yaml:"rules"`                                                         // 振り分けルール
	LetsEncrypt   *ProxyLBACMESetting  `json:",omitempty" yaml:"lets_encrypt,omitempty" structs:",omitempty"` // Let's encryptでの証明書取得設定
	StickySession ProxyLBStickySession `yaml:"sticky_session"`                                                // StickySession
	Timeout       ProxyLBTimeout       `json:",omitempty" yaml:"timeout,omitempty" structs:",omitempty"`      // タイムアウト
}

// MarshalJSON nullの場合に空配列を出力するための実装
func (s ProxyLBSetting) MarshalJSON() ([]byte, error) {
	if s.BindPorts == nil {
		s.BindPorts = make([]*ProxyLBBindPorts, 0)
	}
	if s.Servers == nil {
		s.Servers = make([]ProxyLBServer, 0)
	}
	if s.Rules == nil {
		s.Rules = make([]ProxyLBRule, 0)
	}

	type alias ProxyLBSetting
	tmp := alias(s)
	return json.Marshal(&tmp)
}

// ProxyLBHealthCheck ヘルスチェック
type ProxyLBHealthCheck struct {
	Protocol  types.EProxyLBHealthCheckProtocol `json:",omitempty" yaml:"protocol,omitempty" structs:",omitempty"`
	Path      string                            `json:",omitempty" yaml:"path,omitempty" structs:",omitempty"`
	Host      string                            `json:",omitempty" yaml:"host,omitempty" structs:",omitempty"`
	DelayLoop int                               `json:",omitempty" yaml:"delay_loop,omitempty" structs:",omitempty"`
}

// ProxyLBSorryServer ソーリーサーバ設定
type ProxyLBSorryServer struct {
	IPAddress string `yaml:"ip_address"`
	Port      *int   `yaml:"port"`
}

// ProxyLBBindPorts プロキシ方式
type ProxyLBBindPorts struct {
	ProxyMode         types.EProxyLBProxyMode  `json:",omitempty" yaml:"proxy_mode,omitempty" structs:",omitempty"`          // モード(プロトコル)
	Port              int                      `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"`                // ポート
	RedirectToHTTPS   bool                     `json:"RedirectToHttps" yaml:"redirect_to_https"`                             // HTTPSへのリダイレクト(モードがhttpの場合のみ)
	SupportHTTP2      bool                     `json:"SupportHttp2" yaml:"support_http2"`                                    // HTTP/2のサポート(モードがhttpsの場合のみ)
	AddResponseHeader []*ProxyLBResponseHeader `json:",omitempty" yaml:"add_response_header,omitempty" structs:",omitempty"` // レスポンスヘッダ
}

// ProxyLBResponseHeader ポートごとの追加レスポンスヘッダ
type ProxyLBResponseHeader struct {
	Header string // ヘッダ名称(英字, 数字, ハイフン)
	Value  string // 値(英字, 数字, 半角スペース, 一部記号（!#$%&'()*+,-./:;<=>?@[]^_`{|}~）)
}

// ProxyLBServer ProxyLB配下のサーバー
type ProxyLBServer struct {
	IPAddress   string `json:",omitempty" yaml:"ip_address,omitempty" structs:",omitempty"` // IPアドレス
	Port        int    `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"`       // ポート
	ServerGroup string `yaml:"server_group"`                                                // サーバグループ
	Enabled     bool   // 有効/無効
}

// ProxyLBRule ProxyLBの振り分けルール
type ProxyLBRule struct {
	Host        string `json:",omitempty" yaml:"host,omitempty" structs:",omitempty"` // ホストヘッダのパターン(ワイルドカードとして?と*が利用可能)
	Path        string `json:",omitempty" yaml:"path,omitempty" structs:",omitempty"` // パス
	ServerGroup string `yaml:"server_group"`
}

// ProxyLBACMESetting Let's Encryptでの証明書取得設定
type ProxyLBACMESetting struct {
	Enabled    bool
	CommonName string `json:",omitempty" yaml:",omitempty" structs:",omitempty"`
}

// ProxyLBStickySession セッション維持(Sticky session)設定
type ProxyLBStickySession struct {
	Enabled bool
	Method  string `json:",omitempty" yaml:"method,omitempty" structs:",omitempty"`
}

// ProxyLBTimeout 実サーバの通信タイムアウト
type ProxyLBTimeout struct {
	InactiveSec int `json:",omitempty" yaml:"inactive_sec" structs:",omitempty"` // 10から600まで1秒刻みで設定可
}

// ProxyLBStatus ステータス
type ProxyLBStatus struct {
	UseVIPFailover bool                 `yaml:"use_vip_failover"`
	Region         types.EProxyLBRegion `json:",omitempty" yaml:"region,omitempty" structs:",omitempty"`
	ProxyNetworks  []string             `json:",omitempty" yaml:"proxy_networks,omitempty" structs:",omitempty"`
	FQDN           string               `json:",omitempty" yaml:"fqdn,omitempty" structs:",omitempty"`
}

// ProxyLBAdditionalCerts additional certificates
type ProxyLBAdditionalCerts []*ProxyLBCertificate

// ProxyLBCertificates ProxyLBのSSL証明書
type ProxyLBCertificates struct {
	PrimaryCert     *ProxyLBCertificate    `yaml:"primary_cert"`
	AdditionalCerts ProxyLBAdditionalCerts `yaml:"additional_certs"`
}

// UnmarshalJSON UnmarshalJSON(AdditionalCertsが空の場合に空文字を返す問題への対応)
func (p *ProxyLBAdditionalCerts) UnmarshalJSON(data []byte) error {
	targetData := strings.Replace(strings.Replace(string(data), " ", "", -1), "\n", "", -1)
	if targetData == `` {
		return nil
	}

	var certs []*ProxyLBCertificate
	if err := json.Unmarshal(data, &certs); err != nil {
		return err
	}

	*p = certs
	return nil
}

// ProxyLBCertificate ProxyLBのSSL証明書詳細
type ProxyLBCertificate struct {
	ServerCertificate       string     `yaml:"server_certificate"`                                                       // サーバ証明書
	IntermediateCertificate string     `yaml:"intermediate_certificate"`                                                 // 中間証明書
	PrivateKey              string     `yaml:"private_key"`                                                              // 秘密鍵
	CertificateEndDate      *time.Time `json:",omitempty" yaml:"certificate_end_date,omitempty" structs:",omitempty"`    // 有効期限
	CertificateCommonName   string     `json:",omitempty" yaml:"certificate_common_name,omitempty" structs:",omitempty"` // CommonName
}

// UnmarshalJSON UnmarshalJSON(CertificateEndDateのtime.TimeへのUnmarshal対応)
func (p *ProxyLBCertificate) UnmarshalJSON(data []byte) error {
	var tmp map[string]interface{}
	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	p.ServerCertificate = tmp["ServerCertificate"].(string)
	p.IntermediateCertificate = tmp["IntermediateCertificate"].(string)
	p.PrivateKey = tmp["PrivateKey"].(string)
	p.CertificateCommonName = tmp["CertificateCommonName"].(string)
	endDate := tmp["CertificateEndDate"].(string)
	if endDate != "" {
		date, err := time.Parse("Jan _2 15:04:05 2006 MST", endDate)
		if err != nil {
			return err
		}
		p.CertificateEndDate = &date
	}

	return nil
}

// ProxyLBHealth ProxyLBのヘルスチェック戻り値
type ProxyLBHealth struct {
	ActiveConn int                    `json:",omitempty" yaml:"active_conn,omitempty" structs:",omitempty"` // アクティブなコネクション数
	CPS        int                    `json:",omitempty" yaml:"cps,omitempty" structs:",omitempty"`         // 秒あたりコネクション数
	Servers    []*ProxyLBHealthServer `json:",omitempty" yaml:"servers,omitempty" structs:",omitempty"`     // 実サーバのステータス
	CurrentVIP string                 `json:",omitempty" yaml:"current_vip,omitempty" structs:",omitempty"` // 現在のVIP
}

// ProxyLBHealthServer ProxyLBの実サーバのステータス
type ProxyLBHealthServer struct {
	ActiveConn int                         `json:",omitempty" yaml:"active_conn,omitempty" structs:",omitempty"` // アクティブなコネクション数
	Status     types.EServerInstanceStatus `json:",omitempty" yaml:"status,omitempty" structs:",omitempty"`      // ステータス(UP or DOWN)
	IPAddress  string                      `json:",omitempty" yaml:"ip_address,omitempty" structs:",omitempty"`  // IPアドレス
	Port       string                      `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"`        // ポート
	CPS        int                         `json:",omitempty" yaml:"cps,omitempty" structs:",omitempty"`         // 秒あたりコネクション数
}
<commit_msg>Add a VirtualIPAddress field to ProxyLB naked model<commit_after>// Copyright 2016-2020 The Libsacloud 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 naked

import (
	"encoding/json"
	"strings"
	"time"

	"github.com/sacloud/libsacloud/v2/sacloud/types"
)

// ProxyLB エンハンスドロードバランサ
type ProxyLB struct {
	ID           types.ID            `json:",omitempty" yaml:"id,omitempty" structs:",omitempty"`
	Name         string              `json:",omitempty" yaml:"name,omitempty" structs:",omitempty"`
	Description  string              `yaml:"description"`
	Tags         types.Tags          `yaml:"tags"`
	Icon         *Icon               `json:",omitempty" yaml:"icon,omitempty" structs:",omitempty"`
	CreatedAt    *time.Time          `json:",omitempty" yaml:"created_at,omitempty" structs:",omitempty"`
	ModifiedAt   *time.Time          `json:",omitempty" yaml:"modified_at,omitempty" structs:",omitempty"`
	Availability types.EAvailability `json:",omitempty" yaml:"availability,omitempty" structs:",omitempty"`
	Provider     *Provider           `json:",omitempty" yaml:"provider,omitempty" structs:",omitempty"`
	Settings     *ProxyLBSettings    `json:",omitempty" yaml:"settings,omitempty" structs:",omitempty"`
	SettingsHash string              `json:",omitempty" yaml:"settings_hash,omitempty" structs:",omitempty"`
	Status       *ProxyLBStatus      `json:",omitempty" yaml:"status,omitempty" structs:",omitempty"`

	// ServiceClass [HACK] プランはServiceClassとして文字列で表す必要がある。 詳細はtypes.EProxyLBPlanのコメント参照
	ServiceClass types.EProxyLBPlan `json:",omitempty" yaml:"service_class,omitempty" structs:",omitempty"`
}

// ProxyLBSettingsUpdate エンハンスドロードバランサ
type ProxyLBSettingsUpdate struct {
	Settings     *ProxyLBSettings `json:",omitempty" yaml:"settings,omitempty" structs:",omitempty"`
	SettingsHash string           `json:",omitempty" yaml:"settings_hash,omitempty" structs:",omitempty"`
}

// ProxyLBSettings エンハンスドロードバランサ設定
type ProxyLBSettings struct {
	ProxyLB *ProxyLBSetting `json:",omitempty" yaml:"proxy_lb,omitempty" structs:",omitempty"`
}

// ProxyLBSetting エンハンスドロードバランサ設定
type ProxyLBSetting struct {
	HealthCheck   ProxyLBHealthCheck   `yaml:"health_check"`                                                  // ヘルスチェック
	SorryServer   ProxyLBSorryServer   `yaml:"sorry_server"`                                                  // ソーリーサーバー
	BindPorts     []*ProxyLBBindPorts  `yaml:"bind_ports"`                                                    // プロキシ方式(プロトコル&ポート)
	Servers       []ProxyLBServer      `yaml:"servers"`                                                       // サーバー
	Rules         []ProxyLBRule        `yaml:"rules"`                                                         // 振り分けルール
	LetsEncrypt   *ProxyLBACMESetting  `json:",omitempty" yaml:"lets_encrypt,omitempty" structs:",omitempty"` // Let's encryptでの証明書取得設定
	StickySession ProxyLBStickySession `yaml:"sticky_session"`                                                // StickySession
	Timeout       ProxyLBTimeout       `json:",omitempty" yaml:"timeout,omitempty" structs:",omitempty"`      // タイムアウト
}

// MarshalJSON nullの場合に空配列を出力するための実装
func (s ProxyLBSetting) MarshalJSON() ([]byte, error) {
	if s.BindPorts == nil {
		s.BindPorts = make([]*ProxyLBBindPorts, 0)
	}
	if s.Servers == nil {
		s.Servers = make([]ProxyLBServer, 0)
	}
	if s.Rules == nil {
		s.Rules = make([]ProxyLBRule, 0)
	}

	type alias ProxyLBSetting
	tmp := alias(s)
	return json.Marshal(&tmp)
}

// ProxyLBHealthCheck ヘルスチェック
type ProxyLBHealthCheck struct {
	Protocol  types.EProxyLBHealthCheckProtocol `json:",omitempty" yaml:"protocol,omitempty" structs:",omitempty"`
	Path      string                            `json:",omitempty" yaml:"path,omitempty" structs:",omitempty"`
	Host      string                            `json:",omitempty" yaml:"host,omitempty" structs:",omitempty"`
	DelayLoop int                               `json:",omitempty" yaml:"delay_loop,omitempty" structs:",omitempty"`
}

// ProxyLBSorryServer ソーリーサーバ設定
type ProxyLBSorryServer struct {
	IPAddress string `yaml:"ip_address"`
	Port      *int   `yaml:"port"`
}

// ProxyLBBindPorts プロキシ方式
type ProxyLBBindPorts struct {
	ProxyMode         types.EProxyLBProxyMode  `json:",omitempty" yaml:"proxy_mode,omitempty" structs:",omitempty"`          // モード(プロトコル)
	Port              int                      `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"`                // ポート
	RedirectToHTTPS   bool                     `json:"RedirectToHttps" yaml:"redirect_to_https"`                             // HTTPSへのリダイレクト(モードがhttpの場合のみ)
	SupportHTTP2      bool                     `json:"SupportHttp2" yaml:"support_http2"`                                    // HTTP/2のサポート(モードがhttpsの場合のみ)
	AddResponseHeader []*ProxyLBResponseHeader `json:",omitempty" yaml:"add_response_header,omitempty" structs:",omitempty"` // レスポンスヘッダ
}

// ProxyLBResponseHeader ポートごとの追加レスポンスヘッダ
type ProxyLBResponseHeader struct {
	Header string // ヘッダ名称(英字, 数字, ハイフン)
	Value  string // 値(英字, 数字, 半角スペース, 一部記号（!#$%&'()*+,-./:;<=>?@[]^_`{|}~）)
}

// ProxyLBServer ProxyLB配下のサーバー
type ProxyLBServer struct {
	IPAddress   string `json:",omitempty" yaml:"ip_address,omitempty" structs:",omitempty"` // IPアドレス
	Port        int    `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"`       // ポート
	ServerGroup string `yaml:"server_group"`                                                // サーバグループ
	Enabled     bool   // 有効/無効
}

// ProxyLBRule ProxyLBの振り分けルール
type ProxyLBRule struct {
	Host        string `json:",omitempty" yaml:"host,omitempty" structs:",omitempty"` // ホストヘッダのパターン(ワイルドカードとして?と*が利用可能)
	Path        string `json:",omitempty" yaml:"path,omitempty" structs:",omitempty"` // パス
	ServerGroup string `yaml:"server_group"`
}

// ProxyLBACMESetting Let's Encryptでの証明書取得設定
type ProxyLBACMESetting struct {
	Enabled    bool
	CommonName string `json:",omitempty" yaml:",omitempty" structs:",omitempty"`
}

// ProxyLBStickySession セッション維持(Sticky session)設定
type ProxyLBStickySession struct {
	Enabled bool
	Method  string `json:",omitempty" yaml:"method,omitempty" structs:",omitempty"`
}

// ProxyLBTimeout 実サーバの通信タイムアウト
type ProxyLBTimeout struct {
	InactiveSec int `json:",omitempty" yaml:"inactive_sec" structs:",omitempty"` // 10から600まで1秒刻みで設定可
}

// ProxyLBStatus ステータス
type ProxyLBStatus struct {
	UseVIPFailover   bool                 `yaml:"use_vip_failover"`
	Region           types.EProxyLBRegion `json:",omitempty" yaml:"region,omitempty" structs:",omitempty"`
	ProxyNetworks    []string             `json:",omitempty" yaml:"proxy_networks,omitempty" structs:",omitempty"`
	FQDN             string               `json:",omitempty" yaml:"fqdn,omitempty" structs:",omitempty"`
	VirtualIPAddress string               `json:",omitempty" yaml:"virtual_ip_address,omitempty" structs:",omitempty"`
}

// ProxyLBAdditionalCerts additional certificates
type ProxyLBAdditionalCerts []*ProxyLBCertificate

// ProxyLBCertificates ProxyLBのSSL証明書
type ProxyLBCertificates struct {
	PrimaryCert     *ProxyLBCertificate    `yaml:"primary_cert"`
	AdditionalCerts ProxyLBAdditionalCerts `yaml:"additional_certs"`
}

// UnmarshalJSON UnmarshalJSON(AdditionalCertsが空の場合に空文字を返す問題への対応)
func (p *ProxyLBAdditionalCerts) UnmarshalJSON(data []byte) error {
	targetData := strings.Replace(strings.Replace(string(data), " ", "", -1), "\n", "", -1)
	if targetData == `` {
		return nil
	}

	var certs []*ProxyLBCertificate
	if err := json.Unmarshal(data, &certs); err != nil {
		return err
	}

	*p = certs
	return nil
}

// ProxyLBCertificate ProxyLBのSSL証明書詳細
type ProxyLBCertificate struct {
	ServerCertificate       string     `yaml:"server_certificate"`                                                       // サーバ証明書
	IntermediateCertificate string     `yaml:"intermediate_certificate"`                                                 // 中間証明書
	PrivateKey              string     `yaml:"private_key"`                                                              // 秘密鍵
	CertificateEndDate      *time.Time `json:",omitempty" yaml:"certificate_end_date,omitempty" structs:",omitempty"`    // 有効期限
	CertificateCommonName   string     `json:",omitempty" yaml:"certificate_common_name,omitempty" structs:",omitempty"` // CommonName
}

// UnmarshalJSON UnmarshalJSON(CertificateEndDateのtime.TimeへのUnmarshal対応)
func (p *ProxyLBCertificate) UnmarshalJSON(data []byte) error {
	var tmp map[string]interface{}
	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	p.ServerCertificate = tmp["ServerCertificate"].(string)
	p.IntermediateCertificate = tmp["IntermediateCertificate"].(string)
	p.PrivateKey = tmp["PrivateKey"].(string)
	p.CertificateCommonName = tmp["CertificateCommonName"].(string)
	endDate := tmp["CertificateEndDate"].(string)
	if endDate != "" {
		date, err := time.Parse("Jan _2 15:04:05 2006 MST", endDate)
		if err != nil {
			return err
		}
		p.CertificateEndDate = &date
	}

	return nil
}

// ProxyLBHealth ProxyLBのヘルスチェック戻り値
type ProxyLBHealth struct {
	ActiveConn int                    `json:",omitempty" yaml:"active_conn,omitempty" structs:",omitempty"` // アクティブなコネクション数
	CPS        int                    `json:",omitempty" yaml:"cps,omitempty" structs:",omitempty"`         // 秒あたりコネクション数
	Servers    []*ProxyLBHealthServer `json:",omitempty" yaml:"servers,omitempty" structs:",omitempty"`     // 実サーバのステータス
	CurrentVIP string                 `json:",omitempty" yaml:"current_vip,omitempty" structs:",omitempty"` // 現在のVIP
}

// ProxyLBHealthServer ProxyLBの実サーバのステータス
type ProxyLBHealthServer struct {
	ActiveConn int                         `json:",omitempty" yaml:"active_conn,omitempty" structs:",omitempty"` // アクティブなコネクション数
	Status     types.EServerInstanceStatus `json:",omitempty" yaml:"status,omitempty" structs:",omitempty"`      // ステータス(UP or DOWN)
	IPAddress  string                      `json:",omitempty" yaml:"ip_address,omitempty" structs:",omitempty"`  // IPアドレス
	Port       string                      `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"`        // ポート
	CPS        int                         `json:",omitempty" yaml:"cps,omitempty" structs:",omitempty"`         // 秒あたりコネクション数
}
<|endoftext|>


<commit_before>package teamsnap

import (
	"errors"
	"log"
	"github.com/centralmarinsoccer/teams/filesystem"
	"time"
	"github.com/centralmarinsoccer/teams/geocode"
	"github.com/centralmarinsoccer/teams/cache"
)

// ClubDataInterface provides a mechanism to retrieve club data
type ClubDataInterface interface {
	Get() ClubData
}

// TeamSnap provides a mechanism to configure and cache team data stored in TeamSnap.com website
type TeamSnap struct {
	root          teamSnapResult
	locations     map[string]TeamEventLocation
	clubData      ClubData
	configuration Configuration
}

// Configuration defines how TeamSnap information should be accessed
type Configuration struct {
	Token           string
	Division        int
	Geocoder	geocode.Geocoder
	FileSystem      filesystem.LocalDiskInterface
	TeamSnapServer  string
	DumpJSON        bool
}

// ClubData is the data returned from TeamSnap
type ClubData struct {
	LastUpdated time.Time `json:"last_updated"`
	Teams       Teams     `json:"teams"`
}

// Teams is an array of Team
type Teams []Team

// Team stores the details of a Team
type Team struct {
	ID       string       `json:"id"`
	Name     string       `json:"name"`
	Gender   string       `json:"gender"`
	Year     int          `json:"year"`
	Level    string       `json:"level"`
	PhotoURL string       `json:"image_url,omitempty"`
	Members  []TeamMember `json:"members,omitempty"`
	Events   []TeamEvent  `json:"events,omitempty"`
}

const memberTypePlayer = "player"
const memberTypeCoach = "coach"
const memberTypeManager = "manager"

// TeamMember holds the text and metadata for a team member
type TeamMember struct {
	Name       string `json:"name"`
	MemberType string `json:"type"`
}

// TeamEvent contains all of the data that makes up an event
type TeamEvent struct {
	Start     time.Time            `json:"start"`
	Opponent  string               `json:"opponent"`
	Duration  string               `json:"duration"`
	Location  TeamEventLocation    `json:"location"`
}

// TeamEventLocation contains all of the data that makes up an event location
type TeamEventLocation struct {
	Name    string    `json:"name"`
	Address string    `json:"address"`
	Latitude float64   `json:"latitude,omitempty"`
        Longitude float64  `json:"longitude,omitempty"`
}

const defaultServer = "https://api.teamsnap.com"
const defaultFilename = "teamsnap.json"

// TODO: Notify callers when data in cache has changed. Maybe hash our data struct so we can detect changes

// New creates a TeamSnap with the specified configuration
func New(configuration *Configuration) (*TeamSnap, error) {

	// Use defaults if variable not specified
	if configuration.FileSystem == nil {
		configuration.FileSystem = filesystem.OSFS{}
	}
	if configuration.TeamSnapServer == "" {
		configuration.TeamSnapServer = defaultServer
	}

	ts := &TeamSnap{
		configuration: *configuration,
		locations: make(map[string]TeamEventLocation),
	}

	// Check if the file exists
	var dataLoaded = false
	if err := cache.Load(defaultFilename, &ts.clubData); err == nil {
		dataLoaded = true
	}
	log.Printf("Data: %v\n", ts.clubData)

	if !dataLoaded {
		log.Printf("TeamSnap cache '%s' does not exist or failed to load. Building initial version\n", defaultFilename)
		dataLoaded = ts.loadTeamSnapData()
	}

	// Make sure we successfully loaded data
	if !dataLoaded {
		return &TeamSnap{}, errors.New("Failed to load TeamSnap data. Please check previous errors to determine cause.")
	}

	return ts, nil
}

func (ts *TeamSnap) loadTeamSnapData() bool {

	// Load data from TeamSnap web API
	teams, ok := ts.teams()
	if !ok {
		log.Println("Unable to retrieve data from TeamSnap. Check previous errors")
		return false
	}

	ts.clubData.Teams = teams
	ts.clubData.LastUpdated = time.Now()

	// Save our caches
	ts.configuration.Geocoder.SaveCache()
	cache.Save(defaultFilename, ts.clubData)

	return true
}

// Get returns club data
func (ts *TeamSnap) Get() ClubData {
	return ts.clubData
}

// Update reloads the club data from TeamSnap.com
func (ts *TeamSnap) Update() bool {
	return ts.loadTeamSnapData()
}

// Implement the Sort Interface

// Len provides the number of Teams
func (cd ClubData) Len() int { return len(cd.Teams) }

// Swap swaps two teams
func (cd ClubData) Swap(i, j int) { cd.Teams[i], cd.Teams[j] = cd.Teams[j], cd.Teams[i] }

// Sort teams by gender, year, and name
func (cd ClubData) Less(i, j int) bool {
	if cd.Teams[i].Gender == cd.Teams[j].Gender {
		if cd.Teams[i].Year == cd.Teams[j].Year {
			return cd.Teams[i].Name < cd.Teams[j].Name
		}
		return cd.Teams[i].Year > cd.Teams[j].Year
	}
	return cd.Teams[i].Gender < cd.Teams[j].Gender
}
<commit_msg>Removed extra logging<commit_after>package teamsnap

import (
	"errors"
	"log"
	"github.com/centralmarinsoccer/teams/filesystem"
	"time"
	"github.com/centralmarinsoccer/teams/geocode"
	"github.com/centralmarinsoccer/teams/cache"
)

// ClubDataInterface provides a mechanism to retrieve club data
type ClubDataInterface interface {
	Get() ClubData
}

// TeamSnap provides a mechanism to configure and cache team data stored in TeamSnap.com website
type TeamSnap struct {
	root          teamSnapResult
	locations     map[string]TeamEventLocation
	clubData      ClubData
	configuration Configuration
}

// Configuration defines how TeamSnap information should be accessed
type Configuration struct {
	Token           string
	Division        int
	Geocoder	geocode.Geocoder
	FileSystem      filesystem.LocalDiskInterface
	TeamSnapServer  string
	DumpJSON        bool
}

// ClubData is the data returned from TeamSnap
type ClubData struct {
	LastUpdated time.Time `json:"last_updated"`
	Teams       Teams     `json:"teams"`
}

// Teams is an array of Team
type Teams []Team

// Team stores the details of a Team
type Team struct {
	ID       string       `json:"id"`
	Name     string       `json:"name"`
	Gender   string       `json:"gender"`
	Year     int          `json:"year"`
	Level    string       `json:"level"`
	PhotoURL string       `json:"image_url,omitempty"`
	Members  []TeamMember `json:"members,omitempty"`
	Events   []TeamEvent  `json:"events,omitempty"`
}

const memberTypePlayer = "player"
const memberTypeCoach = "coach"
const memberTypeManager = "manager"

// TeamMember holds the text and metadata for a team member
type TeamMember struct {
	Name       string `json:"name"`
	MemberType string `json:"type"`
}

// TeamEvent contains all of the data that makes up an event
type TeamEvent struct {
	Start     time.Time            `json:"start"`
	Opponent  string               `json:"opponent"`
	Duration  string               `json:"duration"`
	Location  TeamEventLocation    `json:"location"`
}

// TeamEventLocation contains all of the data that makes up an event location
type TeamEventLocation struct {
	Name    string    `json:"name"`
	Address string    `json:"address"`
	Latitude float64   `json:"latitude,omitempty"`
        Longitude float64  `json:"longitude,omitempty"`
}

const defaultServer = "https://api.teamsnap.com"
const defaultFilename = "teamsnap.json"

// TODO: Notify callers when data in cache has changed. Maybe hash our data struct so we can detect changes

// New creates a TeamSnap with the specified configuration
func New(configuration *Configuration) (*TeamSnap, error) {

	// Use defaults if variable not specified
	if configuration.FileSystem == nil {
		configuration.FileSystem = filesystem.OSFS{}
	}
	if configuration.TeamSnapServer == "" {
		configuration.TeamSnapServer = defaultServer
	}

	ts := &TeamSnap{
		configuration: *configuration,
		locations: make(map[string]TeamEventLocation),
	}

	// Check if the file exists
	var dataLoaded = false
	if err := cache.Load(defaultFilename, &ts.clubData); err == nil {
		dataLoaded = true
	}

	if !dataLoaded {
		log.Printf("TeamSnap cache '%s' does not exist or failed to load. Building initial version\n", defaultFilename)
		dataLoaded = ts.loadTeamSnapData()
	}

	// Make sure we successfully loaded data
	if !dataLoaded {
		return &TeamSnap{}, errors.New("Failed to load TeamSnap data. Please check previous errors to determine cause.")
	}

	return ts, nil
}

func (ts *TeamSnap) loadTeamSnapData() bool {

	// Load data from TeamSnap web API
	teams, ok := ts.teams()
	if !ok {
		log.Println("Unable to retrieve data from TeamSnap. Check previous errors")
		return false
	}

	ts.clubData.Teams = teams
	ts.clubData.LastUpdated = time.Now()

	// Save our caches
	ts.configuration.Geocoder.SaveCache()
	cache.Save(defaultFilename, ts.clubData)

	return true
}

// Get returns club data
func (ts *TeamSnap) Get() ClubData {
	return ts.clubData
}

// Update reloads the club data from TeamSnap.com
func (ts *TeamSnap) Update() bool {
	return ts.loadTeamSnapData()
}

// Implement the Sort Interface

// Len provides the number of Teams
func (cd ClubData) Len() int { return len(cd.Teams) }

// Swap swaps two teams
func (cd ClubData) Swap(i, j int) { cd.Teams[i], cd.Teams[j] = cd.Teams[j], cd.Teams[i] }

// Sort teams by gender, year, and name
func (cd ClubData) Less(i, j int) bool {
	if cd.Teams[i].Gender == cd.Teams[j].Gender {
		if cd.Teams[i].Year == cd.Teams[j].Year {
			return cd.Teams[i].Name < cd.Teams[j].Name
		}
		return cd.Teams[i].Year > cd.Teams[j].Year
	}
	return cd.Teams[i].Gender < cd.Teams[j].Gender
}
<|endoftext|>