<commit_before>package types

import (
	"encoding/binary"
	"fmt"
	"io"
	"math/big"
	"sort"
	"time"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto/sha3"
	"github.com/ethereum/go-ethereum/rlp"
)

type Header struct {
	// Hash to the previous block
	ParentHash common.Hash
	// Uncles of this block
	UncleHash common.Hash
	// The coin base address
	Coinbase common.Address
	// Block Trie state
	Root common.Hash
	// Tx sha
	TxHash common.Hash
	// Receipt sha
	ReceiptHash common.Hash
	// Bloom
	Bloom Bloom
	// Difficulty for the current block
	Difficulty *big.Int
	// The block number
	Number *big.Int
	// Gas limit
	GasLimit *big.Int
	// Gas used
	GasUsed *big.Int
	// Creation time
	Time uint64
	// Extra data
	Extra []byte
	// Mix digest for quick checking to prevent DOS
	MixDigest common.Hash
	// Nonce
	Nonce [8]byte
}

func (self *Header) Hash() common.Hash {
	return rlpHash(self.rlpData(true))
}

func (self *Header) HashNoNonce() common.Hash {
	return rlpHash(self.rlpData(false))
}

func (self *Header) rlpData(withNonce bool) []interface{} {
	fields := []interface{}{
		self.ParentHash,
		self.UncleHash,
		self.Coinbase,
		self.Root,
		self.TxHash,
		self.ReceiptHash,
		self.Bloom,
		self.Difficulty,
		self.Number,
		self.GasLimit,
		self.GasUsed,
		self.Time,
		self.Extra,
	}
	if withNonce {
		fields = append(fields, self.MixDigest, self.Nonce)
	}
	return fields
}

func (self *Header) RlpData() interface{} {
	return self.rlpData(true)
}

func rlpHash(x interface{}) (h common.Hash) {
	hw := sha3.NewKeccak256()
	rlp.Encode(hw, x)
	hw.Sum(h[:0])
	return h
}

type Block struct {
	// Preset Hash for mock (Tests)
	HeaderHash       common.Hash
	ParentHeaderHash common.Hash
	// ^^^^ ignore ^^^^

	header       *Header
	uncles       []*Header
	transactions Transactions
	Td           *big.Int
	queued       bool // flag for blockpool to skip TD check

	receipts Receipts
}

// StorageBlock defines the RLP encoding of a Block stored in the
// state database. The StorageBlock encoding contains fields that
// would otherwise need to be recomputed.
type StorageBlock Block

// "external" block encoding. used for eth protocol, etc.
type extblock struct {
	Header *Header
	Txs    []*Transaction
	Uncles []*Header
}

// "storage" block encoding. used for database.
type storageblock struct {
	Header *Header
	Txs    []*Transaction
	Uncles []*Header
	TD     *big.Int
}

func NewBlock(parentHash common.Hash, coinbase common.Address, root common.Hash, difficulty *big.Int, nonce uint64, extra []byte) *Block {
	header := &Header{
		Root:       root,
		ParentHash: parentHash,
		Coinbase:   coinbase,
		Difficulty: difficulty,
		Time:       uint64(time.Now().Unix()),
		Extra:      extra,
		GasUsed:    new(big.Int),
		GasLimit:   new(big.Int),
		Number:     new(big.Int),
	}
	header.SetNonce(nonce)
	block := &Block{header: header}
	block.Td = new(big.Int)

	return block
}

func (self *Header) SetNonce(nonce uint64) {
	binary.BigEndian.PutUint64(self.Nonce[:], nonce)
}

func NewBlockWithHeader(header *Header) *Block {
	return &Block{header: header}
}

func (self *Block) ValidateFields() error {
	if self.header == nil {
		return fmt.Errorf("header is nil")
	}
	for i, transaction := range self.transactions {
		if transaction == nil {
			return fmt.Errorf("transaction %d is nil", i)
		}
	}
	for i, uncle := range self.uncles {
		if uncle == nil {
			return fmt.Errorf("uncle %d is nil", i)
		}
	}
	return nil
}

func (self *Block) DecodeRLP(s *rlp.Stream) error {
	var eb extblock
	if err := s.Decode(&eb); err != nil {
		return err
	}
	self.header, self.uncles, self.transactions = eb.Header, eb.Uncles, eb.Txs
	return nil
}

func (self Block) EncodeRLP(w io.Writer) error {
	return rlp.Encode(w, extblock{
		Header: self.header,
		Txs:    self.transactions,
		Uncles: self.uncles,
	})
}

func (self *StorageBlock) DecodeRLP(s *rlp.Stream) error {
	var sb storageblock
	if err := s.Decode(&sb); err != nil {
		return err
	}
	self.header, self.uncles, self.transactions, self.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
	return nil
}

func (self StorageBlock) EncodeRLP(w io.Writer) error {
	return rlp.Encode(w, storageblock{
		Header: self.header,
		Txs:    self.transactions,
		Uncles: self.uncles,
		TD:     self.Td,
	})
}

func (self *Block) Header() *Header {
	return self.header
}

func (self *Block) Uncles() []*Header {
	return self.uncles
}

func (self *Block) CalculateUnclesHash() common.Hash {
	return rlpHash(self.uncles)
}

func (self *Block) SetUncles(uncleHeaders []*Header) {
	self.uncles = uncleHeaders
	self.header.UncleHash = rlpHash(uncleHeaders)
}

func (self *Block) Transactions() Transactions {
	return self.transactions
}

func (self *Block) Transaction(hash common.Hash) *Transaction {
	for _, transaction := range self.transactions {
		if transaction.Hash() == hash {
			return transaction
		}
	}
	return nil
}

func (self *Block) SetTransactions(transactions Transactions) {
	self.transactions = transactions
	self.header.TxHash = DeriveSha(transactions)
}
func (self *Block) AddTransaction(transaction *Transaction) {
	self.transactions = append(self.transactions, transaction)
	self.SetTransactions(self.transactions)
}

func (self *Block) Receipts() Receipts {
	return self.receipts
}

func (self *Block) SetReceipts(receipts Receipts) {
	self.receipts = receipts
	self.header.ReceiptHash = DeriveSha(receipts)
	self.header.Bloom = CreateBloom(receipts)
}
func (self *Block) AddReceipt(receipt *Receipt) {
	self.receipts = append(self.receipts, receipt)
	self.SetReceipts(self.receipts)
}

func (self *Block) RlpData() interface{} {
	return []interface{}{self.header, self.transactions, self.uncles}
}

func (self *Block) RlpDataForStorage() interface{} {
	return []interface{}{self.header, self.transactions, self.uncles, self.Td /* TODO receipts */}
}

// Header accessors (add as you need them)
func (self *Block) Number() *big.Int       { return self.header.Number }
func (self *Block) NumberU64() uint64      { return self.header.Number.Uint64() }
func (self *Block) MixDigest() common.Hash { return self.header.MixDigest }
func (self *Block) Nonce() uint64 {
	return binary.BigEndian.Uint64(self.header.Nonce[:])
}
func (self *Block) SetNonce(nonce uint64) {
	self.header.SetNonce(nonce)
}

func (self *Block) Queued() bool     { return self.queued }
func (self *Block) SetQueued(q bool) { self.queued = q }

func (self *Block) Bloom() Bloom             { return self.header.Bloom }
func (self *Block) Coinbase() common.Address { return self.header.Coinbase }
func (self *Block) Time() int64              { return int64(self.header.Time) }
func (self *Block) GasLimit() *big.Int       { return self.header.GasLimit }
func (self *Block) GasUsed() *big.Int        { return self.header.GasUsed }
func (self *Block) Root() common.Hash        { return self.header.Root }
func (self *Block) SetRoot(root common.Hash) { self.header.Root = root }
func (self *Block) GetTransaction(i int) *Transaction {
	if len(self.transactions) > i {
		return self.transactions[i]
	}
	return nil
}
func (self *Block) GetUncle(i int) *Header {
	if len(self.uncles) > i {
		return self.uncles[i]
	}
	return nil
}

func (self *Block) Size() common.StorageSize {
	c := writeCounter(0)
	rlp.Encode(&c, self)
	return common.StorageSize(c)
}

type writeCounter common.StorageSize

func (c *writeCounter) Write(b []byte) (int, error) {
	*c += writeCounter(len(b))
	return len(b), nil
}

// Implement pow.Block
func (self *Block) Difficulty() *big.Int     { return self.header.Difficulty }
func (self *Block) HashNoNonce() common.Hash { return self.header.HashNoNonce() }

func (self *Block) Hash() common.Hash {
	if (self.HeaderHash != common.Hash{}) {
		return self.HeaderHash
	} else {
		return self.header.Hash()
	}
}

func (self *Block) ParentHash() common.Hash {
	if (self.ParentHeaderHash != common.Hash{}) {
		return self.ParentHeaderHash
	} else {
		return self.header.ParentHash
	}
}

func (self *Block) Copy() *Block {
	block := NewBlock(self.header.ParentHash, self.Coinbase(), self.Root(), new(big.Int), self.Nonce(), self.header.Extra)
	block.header.Bloom = self.header.Bloom
	block.header.TxHash = self.header.TxHash
	block.transactions = self.transactions
	block.header.UncleHash = self.header.UncleHash
	block.uncles = self.uncles
	block.header.GasLimit.Set(self.header.GasLimit)
	block.header.GasUsed.Set(self.header.GasUsed)
	block.header.ReceiptHash = self.header.ReceiptHash
	block.header.Difficulty.Set(self.header.Difficulty)
	block.header.Number.Set(self.header.Number)
	block.header.Time = self.header.Time
	block.header.MixDigest = self.header.MixDigest
	if self.Td != nil {
		block.Td.Set(self.Td)
	}

	return block
}

func (self *Block) String() string {
	return fmt.Sprintf(`Block(#%v): Size: %v TD: %v {
MinerHash: %x
%v
Transactions:
%v
Uncles:
%v
}
`, self.Number(), self.Size(), self.Td, self.header.HashNoNonce(), self.header, self.transactions, self.uncles)
}

func (self *Header) String() string {
	return fmt.Sprintf(`Header(%x):
[
	ParentHash:	    %x
	UncleHash:	    %x
	Coinbase:	    %x
	Root:		    %x
	TxSha		    %x
	ReceiptSha:	    %x
	Bloom:		    %x
	Difficulty:	    %v
	Number:		    %v
	GasLimit:	    %v
	GasUsed:	    %v
	Time:		    %v
	Extra:		    %s
	MixDigest:          %x
	Nonce:		    %x
]`, self.Hash(), self.ParentHash, self.UncleHash, self.Coinbase, self.Root, self.TxHash, self.ReceiptHash, self.Bloom, self.Difficulty, self.Number, self.GasLimit, self.GasUsed, self.Time, self.Extra, self.MixDigest, self.Nonce)
}

type Blocks []*Block

type BlockBy func(b1, b2 *Block) bool

func (self BlockBy) Sort(blocks Blocks) {
	bs := blockSorter{
		blocks: blocks,
		by:     self,
	}
	sort.Sort(bs)
}

type blockSorter struct {
	blocks Blocks
	by     func(b1, b2 *Block) bool
}

func (self blockSorter) Len() int { return len(self.blocks) }
func (self blockSorter) Swap(i, j int) {
	self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i]
}
func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }

func Number(b1, b2 *Block) bool { return b1.Header().Number.Cmp(b2.Header().Number) < 0 }
<commit_msg>core/types: added fake parent hash / hash to String() output<commit_after>package types

import (
	"encoding/binary"
	"fmt"
	"io"
	"math/big"
	"sort"
	"time"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto/sha3"
	"github.com/ethereum/go-ethereum/rlp"
)

type Header struct {
	// Hash to the previous block
	ParentHash common.Hash
	// Uncles of this block
	UncleHash common.Hash
	// The coin base address
	Coinbase common.Address
	// Block Trie state
	Root common.Hash
	// Tx sha
	TxHash common.Hash
	// Receipt sha
	ReceiptHash common.Hash
	// Bloom
	Bloom Bloom
	// Difficulty for the current block
	Difficulty *big.Int
	// The block number
	Number *big.Int
	// Gas limit
	GasLimit *big.Int
	// Gas used
	GasUsed *big.Int
	// Creation time
	Time uint64
	// Extra data
	Extra []byte
	// Mix digest for quick checking to prevent DOS
	MixDigest common.Hash
	// Nonce
	Nonce [8]byte
}

func (self *Header) Hash() common.Hash {
	return rlpHash(self.rlpData(true))
}

func (self *Header) HashNoNonce() common.Hash {
	return rlpHash(self.rlpData(false))
}

func (self *Header) rlpData(withNonce bool) []interface{} {
	fields := []interface{}{
		self.ParentHash,
		self.UncleHash,
		self.Coinbase,
		self.Root,
		self.TxHash,
		self.ReceiptHash,
		self.Bloom,
		self.Difficulty,
		self.Number,
		self.GasLimit,
		self.GasUsed,
		self.Time,
		self.Extra,
	}
	if withNonce {
		fields = append(fields, self.MixDigest, self.Nonce)
	}
	return fields
}

func (self *Header) RlpData() interface{} {
	return self.rlpData(true)
}

func rlpHash(x interface{}) (h common.Hash) {
	hw := sha3.NewKeccak256()
	rlp.Encode(hw, x)
	hw.Sum(h[:0])
	return h
}

type Block struct {
	// Preset Hash for mock (Tests)
	HeaderHash       common.Hash
	ParentHeaderHash common.Hash
	// ^^^^ ignore ^^^^

	header       *Header
	uncles       []*Header
	transactions Transactions
	Td           *big.Int
	queued       bool // flag for blockpool to skip TD check

	receipts Receipts
}

// StorageBlock defines the RLP encoding of a Block stored in the
// state database. The StorageBlock encoding contains fields that
// would otherwise need to be recomputed.
type StorageBlock Block

// "external" block encoding. used for eth protocol, etc.
type extblock struct {
	Header *Header
	Txs    []*Transaction
	Uncles []*Header
}

// "storage" block encoding. used for database.
type storageblock struct {
	Header *Header
	Txs    []*Transaction
	Uncles []*Header
	TD     *big.Int
}

func NewBlock(parentHash common.Hash, coinbase common.Address, root common.Hash, difficulty *big.Int, nonce uint64, extra []byte) *Block {
	header := &Header{
		Root:       root,
		ParentHash: parentHash,
		Coinbase:   coinbase,
		Difficulty: difficulty,
		Time:       uint64(time.Now().Unix()),
		Extra:      extra,
		GasUsed:    new(big.Int),
		GasLimit:   new(big.Int),
		Number:     new(big.Int),
	}
	header.SetNonce(nonce)
	block := &Block{header: header}
	block.Td = new(big.Int)

	return block
}

func (self *Header) SetNonce(nonce uint64) {
	binary.BigEndian.PutUint64(self.Nonce[:], nonce)
}

func NewBlockWithHeader(header *Header) *Block {
	return &Block{header: header}
}

func (self *Block) ValidateFields() error {
	if self.header == nil {
		return fmt.Errorf("header is nil")
	}
	for i, transaction := range self.transactions {
		if transaction == nil {
			return fmt.Errorf("transaction %d is nil", i)
		}
	}
	for i, uncle := range self.uncles {
		if uncle == nil {
			return fmt.Errorf("uncle %d is nil", i)
		}
	}
	return nil
}

func (self *Block) DecodeRLP(s *rlp.Stream) error {
	var eb extblock
	if err := s.Decode(&eb); err != nil {
		return err
	}
	self.header, self.uncles, self.transactions = eb.Header, eb.Uncles, eb.Txs
	return nil
}

func (self Block) EncodeRLP(w io.Writer) error {
	return rlp.Encode(w, extblock{
		Header: self.header,
		Txs:    self.transactions,
		Uncles: self.uncles,
	})
}

func (self *StorageBlock) DecodeRLP(s *rlp.Stream) error {
	var sb storageblock
	if err := s.Decode(&sb); err != nil {
		return err
	}
	self.header, self.uncles, self.transactions, self.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
	return nil
}

func (self StorageBlock) EncodeRLP(w io.Writer) error {
	return rlp.Encode(w, storageblock{
		Header: self.header,
		Txs:    self.transactions,
		Uncles: self.uncles,
		TD:     self.Td,
	})
}

func (self *Block) Header() *Header {
	return self.header
}

func (self *Block) Uncles() []*Header {
	return self.uncles
}

func (self *Block) CalculateUnclesHash() common.Hash {
	return rlpHash(self.uncles)
}

func (self *Block) SetUncles(uncleHeaders []*Header) {
	self.uncles = uncleHeaders
	self.header.UncleHash = rlpHash(uncleHeaders)
}

func (self *Block) Transactions() Transactions {
	return self.transactions
}

func (self *Block) Transaction(hash common.Hash) *Transaction {
	for _, transaction := range self.transactions {
		if transaction.Hash() == hash {
			return transaction
		}
	}
	return nil
}

func (self *Block) SetTransactions(transactions Transactions) {
	self.transactions = transactions
	self.header.TxHash = DeriveSha(transactions)
}
func (self *Block) AddTransaction(transaction *Transaction) {
	self.transactions = append(self.transactions, transaction)
	self.SetTransactions(self.transactions)
}

func (self *Block) Receipts() Receipts {
	return self.receipts
}

func (self *Block) SetReceipts(receipts Receipts) {
	self.receipts = receipts
	self.header.ReceiptHash = DeriveSha(receipts)
	self.header.Bloom = CreateBloom(receipts)
}
func (self *Block) AddReceipt(receipt *Receipt) {
	self.receipts = append(self.receipts, receipt)
	self.SetReceipts(self.receipts)
}

func (self *Block) RlpData() interface{} {
	return []interface{}{self.header, self.transactions, self.uncles}
}

func (self *Block) RlpDataForStorage() interface{} {
	return []interface{}{self.header, self.transactions, self.uncles, self.Td /* TODO receipts */}
}

// Header accessors (add as you need them)
func (self *Block) Number() *big.Int       { return self.header.Number }
func (self *Block) NumberU64() uint64      { return self.header.Number.Uint64() }
func (self *Block) MixDigest() common.Hash { return self.header.MixDigest }
func (self *Block) Nonce() uint64 {
	return binary.BigEndian.Uint64(self.header.Nonce[:])
}
func (self *Block) SetNonce(nonce uint64) {
	self.header.SetNonce(nonce)
}

func (self *Block) Queued() bool     { return self.queued }
func (self *Block) SetQueued(q bool) { self.queued = q }

func (self *Block) Bloom() Bloom             { return self.header.Bloom }
func (self *Block) Coinbase() common.Address { return self.header.Coinbase }
func (self *Block) Time() int64              { return int64(self.header.Time) }
func (self *Block) GasLimit() *big.Int       { return self.header.GasLimit }
func (self *Block) GasUsed() *big.Int        { return self.header.GasUsed }
func (self *Block) Root() common.Hash        { return self.header.Root }
func (self *Block) SetRoot(root common.Hash) { self.header.Root = root }
func (self *Block) GetTransaction(i int) *Transaction {
	if len(self.transactions) > i {
		return self.transactions[i]
	}
	return nil
}
func (self *Block) GetUncle(i int) *Header {
	if len(self.uncles) > i {
		return self.uncles[i]
	}
	return nil
}

func (self *Block) Size() common.StorageSize {
	c := writeCounter(0)
	rlp.Encode(&c, self)
	return common.StorageSize(c)
}

type writeCounter common.StorageSize

func (c *writeCounter) Write(b []byte) (int, error) {
	*c += writeCounter(len(b))
	return len(b), nil
}

// Implement pow.Block
func (self *Block) Difficulty() *big.Int     { return self.header.Difficulty }
func (self *Block) HashNoNonce() common.Hash { return self.header.HashNoNonce() }

func (self *Block) Hash() common.Hash {
	if (self.HeaderHash != common.Hash{}) {
		return self.HeaderHash
	} else {
		return self.header.Hash()
	}
}

func (self *Block) ParentHash() common.Hash {
	if (self.ParentHeaderHash != common.Hash{}) {
		return self.ParentHeaderHash
	} else {
		return self.header.ParentHash
	}
}

func (self *Block) Copy() *Block {
	block := NewBlock(self.header.ParentHash, self.Coinbase(), self.Root(), new(big.Int), self.Nonce(), self.header.Extra)
	block.header.Bloom = self.header.Bloom
	block.header.TxHash = self.header.TxHash
	block.transactions = self.transactions
	block.header.UncleHash = self.header.UncleHash
	block.uncles = self.uncles
	block.header.GasLimit.Set(self.header.GasLimit)
	block.header.GasUsed.Set(self.header.GasUsed)
	block.header.ReceiptHash = self.header.ReceiptHash
	block.header.Difficulty.Set(self.header.Difficulty)
	block.header.Number.Set(self.header.Number)
	block.header.Time = self.header.Time
	block.header.MixDigest = self.header.MixDigest
	if self.Td != nil {
		block.Td.Set(self.Td)
	}

	return block
}

func (self *Block) String() string {
	str := fmt.Sprintf(`Block(#%v): Size: %v TD: %v {
MinerHash: %x
%v
Transactions:
%v
Uncles:
%v
}
`, self.Number(), self.Size(), self.Td, self.header.HashNoNonce(), self.header, self.transactions, self.uncles)

	if (self.HeaderHash != common.Hash{}) {
		str += fmt.Sprintf("\nFake hash = %x", self.HeaderHash)
	}

	if (self.ParentHeaderHash != common.Hash{}) {
		str += fmt.Sprintf("\nFake parent hash = %x", self.ParentHeaderHash)
	}

	return str
}

func (self *Header) String() string {
	return fmt.Sprintf(`Header(%x):
[
	ParentHash:	    %x
	UncleHash:	    %x
	Coinbase:	    %x
	Root:		    %x
	TxSha		    %x
	ReceiptSha:	    %x
	Bloom:		    %x
	Difficulty:	    %v
	Number:		    %v
	GasLimit:	    %v
	GasUsed:	    %v
	Time:		    %v
	Extra:		    %s
	MixDigest:          %x
	Nonce:		    %x
]`, self.Hash(), self.ParentHash, self.UncleHash, self.Coinbase, self.Root, self.TxHash, self.ReceiptHash, self.Bloom, self.Difficulty, self.Number, self.GasLimit, self.GasUsed, self.Time, self.Extra, self.MixDigest, self.Nonce)
}

type Blocks []*Block

type BlockBy func(b1, b2 *Block) bool

func (self BlockBy) Sort(blocks Blocks) {
	bs := blockSorter{
		blocks: blocks,
		by:     self,
	}
	sort.Sort(bs)
}

type blockSorter struct {
	blocks Blocks
	by     func(b1, b2 *Block) bool
}

func (self blockSorter) Len() int { return len(self.blocks) }
func (self blockSorter) Swap(i, j int) {
	self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i]
}
func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }

func Number(b1, b2 *Block) bool { return b1.Header().Number.Cmp(b2.Header().Number) < 0 }
<|endoftext|>


<commit_before>package bubbles

import (
	"encoding/json"
	"fmt"
)

// ActionType is the type of the action.
type ActionType string

// The actiontypes and what they are called by ES.
const (
	Index  ActionType = "index"
	Create            = "create"
	Delete            = "delete"
	Update            = "update"
)

// Action is a single entry in a Bulk document. It might be re-send to different
// servers while there are errors. The 'Document' needs to be a valid JSON
// insert/update/&c document, but can't contain any newline. 'Document' is
// ignored for 'delete' actions.
type Action struct {
	Type     ActionType
	MetaData MetaData
	Document string // without any \n! // TODO: []byte ?
}

// MetaData tells ES how to deal with the document. Index and Type are
// required, the rest is not. See the ES documentation for what they mean.
type MetaData struct {
	Index string `json:"_index"`
	Type  string `json:"_type"`
	ID    string `json:"_id,omitempty"`
	// TODO: Check all these
	Refresh         bool `json:"refresh,omitempty"`
	RetryOnConflict int  `json:"retry_on_conflict,omitempty"`
	Timestamp       int  `json:"_timestamp,omitempty"`
	TTL             int  `json:"ttl,omitempty"`
}

// Buf returns the command ready for the ES bulk buffer
func (a *Action) Buf() []byte {
	switch a.Type {
	default:
		panic("what's this?")
	case Index, Create, Update:
		md, err := json.Marshal(a.MetaData)
		if err != nil {
			panic(err.Error())
		}
		return []byte(fmt.Sprintf("{\"%s\": %s}\n%s\n", a.Type, md, a.Document))
	case Delete:
		md, err := json.Marshal(a.MetaData)
		if err != nil {
			panic(err.Error())
		}
		return []byte(fmt.Sprintf("{\"%s\": %s}\n", a.Type, md))
	}
}
<commit_msg>'consistency' field.<commit_after>package bubbles

import (
	"encoding/json"
	"fmt"
)

// ActionType is the type of the action.
type ActionType string

// The actiontypes and what they are called by ES.
const (
	Index  ActionType = "index"
	Create            = "create"
	Delete            = "delete"
	Update            = "update"
)

// Action is a single entry in a Bulk document. It might be re-send to different
// servers while there are errors. The 'Document' needs to be a valid JSON
// insert/update/&c document, but can't contain any newline. 'Document' is
// ignored for 'delete' actions.
type Action struct {
	Type     ActionType
	MetaData MetaData
	Document string // without any \n! // TODO: []byte ?
}

// MetaData tells ES how to deal with the document. Index and Type are
// required, the rest is not. See the ES documentation for what they mean.
type MetaData struct {
	Index string `json:"_index"`
	Type  string `json:"_type"`
	ID    string `json:"_id,omitempty"`
	// TODO: Check all these
	Refresh         bool   `json:"refresh,omitempty"`
	RetryOnConflict int    `json:"retry_on_conflict,omitempty"`
	Timestamp       int    `json:"_timestamp,omitempty"`
	TTL             int    `json:"ttl,omitempty"`
	Consistency     string `json:"consistency,omitempty"`
}

// Buf returns the command ready for the ES bulk buffer
func (a *Action) Buf() []byte {
	switch a.Type {
	default:
		panic("what's this?")
	case Index, Create, Update:
		md, err := json.Marshal(a.MetaData)
		if err != nil {
			panic(err.Error())
		}
		return []byte(fmt.Sprintf("{\"%s\": %s}\n%s\n", a.Type, md, a.Document))
	case Delete:
		md, err := json.Marshal(a.MetaData)
		if err != nil {
			panic(err.Error())
		}
		return []byte(fmt.Sprintf("{\"%s\": %s}\n", a.Type, md))
	}
}
<|endoftext|>


<commit_before>package fetcher

import (
	"fmt"
	"testing"
)

func TestGetArticle(t *testing.T) {
	a, err := GetArticle("https://www.yasuhisay.info/entry/20090516/1242480413")
	if err != nil {
		t.Error(err.Error())
	}

	if a.Title == "" {
		t.Error("Title must not be empty")
	}
	if a.Description == "" {
		t.Error("Description must not be empty")
	}
	if a.OgType != "article" {
		t.Error("OgType must be article")
	}
	if a.StatusCode != 200 {
		t.Error("StatusCode must be 200")
	}
}

func TestGetArticleNotFound(t *testing.T) {
	_, err := GetArticle("https://www.yasuhisay.info/entry/NOT_FOUND")
	if err == nil {
		t.Error("Error should occur")
	}
}

func TestGetArticleWithInvalidEncoding(t *testing.T) {
	url := "http://www.atmarkit.co.jp/ait/articles/1702/20/news021.html"
	_, err := GetArticle(url)
	if err == nil {
		t.Error(fmt.Sprintf("Error must occur for this url: %s", url))
	}
}

func TestRemoveUtmParams(t *testing.T) {
	before := "https://techplay.jp/event/698349?utm_source=event_698349"
	after, err := removeUtmParams(before)
	if err != nil {
		t.Error(fmt.Sprintf("Error must occur for this url: %s", before))
	}
	expected := "https://techplay.jp/event/698349"
	if expected != after {
		t.Errorf("url should be %s, but %s", expected, after)
	}
	a, err := GetArticle(before)
	if expected != a.Url {
		t.Errorf("url should be %s, but %s", expected, a.Url)
	}
}

func TestFavicon(t *testing.T) {
	url := "https://twitter.com/facebookai/status/1057764513582215168"
	a, err := GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath := "https://abs.twimg.com/favicons/twitter.ico"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://arxiv.org/abs/1810.08403"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://static.arxiv.org/static/browse/0.3.2/images/icons/favicon.ico"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://www.lifehacker.jp/2018/11/amazon-impact-absorption-case.html"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://www.lifehacker.jp/assets/common/img/favicon.ico"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://peterroelants.github.io/"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://peterroelants.github.io/images/favicon/apple-icon-57x57.png"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://www.getrevue.co/profile/icoxfog417/issues/weekly-machine-learning-79-121292"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://d3jbm9h03wxzi9.cloudfront.net/assets/favicon-84fc7f228d52c2410eb7aa839e279caeaa491588c7c75229ed33e1c7f69fe75d.ico"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://ai.googleblog.com/2018/11/open-sourcing-bert-state-of-art-pre.html"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://ai.googleblog.com/favicon.ico"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}
}

func TestGetPublishDate(t *testing.T) {
	a, err := GetArticle("https://www.yasuhisay.info/entry/2019/11/18/153000")
	if err != nil {
		t.Error("Error should not occur")
	}
	if a.PublishDate == nil {
		t.Error("PublishDate must not be nil")
	}
}
<commit_msg>定期的にpathが変わるものをテストから省く<commit_after>package fetcher

import (
	"fmt"
	"testing"
)

func TestGetArticle(t *testing.T) {
	a, err := GetArticle("https://www.yasuhisay.info/entry/20090516/1242480413")
	if err != nil {
		t.Error(err.Error())
	}

	if a.Title == "" {
		t.Error("Title must not be empty")
	}
	if a.Description == "" {
		t.Error("Description must not be empty")
	}
	if a.OgType != "article" {
		t.Error("OgType must be article")
	}
	if a.StatusCode != 200 {
		t.Error("StatusCode must be 200")
	}
}

func TestGetArticleNotFound(t *testing.T) {
	_, err := GetArticle("https://www.yasuhisay.info/entry/NOT_FOUND")
	if err == nil {
		t.Error("Error should occur")
	}
}

func TestGetArticleWithInvalidEncoding(t *testing.T) {
	url := "http://www.atmarkit.co.jp/ait/articles/1702/20/news021.html"
	_, err := GetArticle(url)
	if err == nil {
		t.Error(fmt.Sprintf("Error must occur for this url: %s", url))
	}
}

func TestRemoveUtmParams(t *testing.T) {
	before := "https://techplay.jp/event/698349?utm_source=event_698349"
	after, err := removeUtmParams(before)
	if err != nil {
		t.Error(fmt.Sprintf("Error must occur for this url: %s", before))
	}
	expected := "https://techplay.jp/event/698349"
	if expected != after {
		t.Errorf("url should be %s, but %s", expected, after)
	}
	a, err := GetArticle(before)
	if expected != a.Url {
		t.Errorf("url should be %s, but %s", expected, a.Url)
	}
}

func TestFavicon(t *testing.T) {
	url := "https://www.yasuhisay.info/entry/2020/11/22/190000"
	a, err := GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath := "https://www.yasuhisay.info/icon/favicon"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://www.lifehacker.jp/2018/11/amazon-impact-absorption-case.html"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://www.lifehacker.jp/assets/common/img/favicon.ico"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://peterroelants.github.io/"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://peterroelants.github.io/images/favicon/apple-icon-57x57.png"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://www.getrevue.co/profile/icoxfog417/issues/weekly-machine-learning-79-121292"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://d3jbm9h03wxzi9.cloudfront.net/assets/favicon-84fc7f228d52c2410eb7aa839e279caeaa491588c7c75229ed33e1c7f69fe75d.ico"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}

	url = "https://ai.googleblog.com/2018/11/open-sourcing-bert-state-of-art-pre.html"
	a, err = GetArticle(url)
	if err != nil {
		t.Error(fmt.Sprintf("Error must not occur for this url: %s", url))
	}
	expectedFaviconPath = "https://ai.googleblog.com/favicon.ico"
	if expectedFaviconPath != a.Favicon {
		t.Errorf("Favicon: %s should be %s", a.Favicon, expectedFaviconPath)
	}
}

func TestGetPublishDate(t *testing.T) {
	a, err := GetArticle("https://www.yasuhisay.info/entry/2019/11/18/153000")
	if err != nil {
		t.Error("Error should not occur")
	}
	if a.PublishDate == nil {
		t.Error("PublishDate must not be nil")
	}
}
<|endoftext|>


<commit_before>package openzwave

// #cgo LDFLAGS: -lopenzwave -Lgo/src/github.com/ninjasphere/go-openzwave/openzwave
// #cgo CPPFLAGS: -Iopenzwave/cpp/src/platform -Iopenzwave/cpp/src -Iopenzwave/cpp/src/value_classes
//
// #include "api.h"
import "C"

import (
	"fmt"

	"github.com/ninjasphere/go-openzwave/CODE"
	"github.com/ninjasphere/go-openzwave/NT"
	"github.com/ninjasphere/go-openzwave/VT"
)

// The type of notifications received via the API's Notifications() channel.
type Notification struct {
	inC *C.Notification
}

// Converts the notification into a string representation.
func (self Notification) String() string {
	return fmt.Sprintf(
		"Notification["+
			"node=0x%08x:0x%02x, "+
			"notificationType=%s/%s, "+
			"valueType=%s, "+
			"valueId=0x%08x]",
		self.inC.nodeId.homeId,
		self.inC.nodeId.nodeId,
		NT.ToEnum(int(self.inC.notificationType)),
		CODE.ToEnum(int(self.inC.notificationCode)),
		VT.ToEnum(int(self.inC.valueId.valueType)),
		self.inC.valueId.id)
}

func (self api) FreeNotification(apiNotification Notification) {
	C.freeNotification(apiNotification.inC)
}

}

<commit_msg>Add accessor methods ValueID and Value types.<commit_after>package openzwave

// #cgo LDFLAGS: -lopenzwave -Lgo/src/github.com/ninjasphere/go-openzwave/openzwave
// #cgo CPPFLAGS: -Iopenzwave/cpp/src/platform -Iopenzwave/cpp/src -Iopenzwave/cpp/src/value_classes
//
// #include "api.h"
import "C"

import (
	"fmt"

	"github.com/ninjasphere/go-openzwave/CODE"
	"github.com/ninjasphere/go-openzwave/NT"
	"github.com/ninjasphere/go-openzwave/VT"
)

// The type of notifications received via the API's Notifications() channel.
type Notification struct {
	inC *C.Notification
}

// Converts the notification into a string representation.
func (self Notification) String() string {
	return fmt.Sprintf(
		"Notification["+
			"node=0x%08x:0x%02x, "+
			"notificationType=%s/%s, "+
			"valueType=%s, "+
			"valueId=0x%08x]",
		self.inC.nodeId.homeId,
		self.inC.nodeId.nodeId,
		NT.ToEnum(int(self.inC.notificationType)),
		CODE.ToEnum(int(self.inC.notificationCode)),
		VT.ToEnum(int(self.inC.valueId.valueType)),
		self.inC.valueId.id)
}

func (self api) FreeNotification(apiNotification Notification) {
	C.freeNotification(apiNotification.inC)
}

func (notification *Notification) GetValueID() *ValueID {
	return &ValueID{notification.inC.valueId};
}

func (notification *Notification) GetValue() *Value {
	return &Value{notification.inC.value};
}

<|endoftext|>


<commit_before>package notificator

import (
	"fmt"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
)

type Options struct {
	DefaultIcon string
	AppName     string
}

const (
	UR_NORMAL   = "normal"
	UR_CRITICAL = "critical"
)

type notifier interface {
	push(title string, text string, iconPath string) *exec.Cmd
	pushCritical(title string, text string, iconPath string) *exec.Cmd
}

type Notificator struct {
	notifier    notifier
	defaultIcon string
}

func (n Notificator) Push(title string, text string, iconPath string, urgency string) error {
	icon := n.defaultIcon

	if iconPath != "" {
		icon = iconPath
	}

	if urgency == UR_CRITICAL {
		return n.notifier.pushCritical(title, text, icon).Run()
	}

	return n.notifier.push(title, text, icon).Run()

}

type osxNotificator struct {
	AppName string
}

func (o osxNotificator) push(title string, text string, iconPath string) *exec.Cmd {

	// Checks if terminal-notifier exists, and is accessible.

	term_notif := CheckTermNotif()
	os_version_check := CheckMacOSVersion()

	// if terminal-notifier exists, use it.
	// else, fall back to osascript. (Mavericks and later.)

	if term_notif == true {
		return exec.Command("terminal-notifier", "-title", o.AppName, "-message", text, "-subtitle", title, "-appIcon", iconPath)
	} else if os_version_check == true {
		notification := fmt.Sprintf("display notification \"%s\" with title \"%s\" subtitle \"%s\"", text, o.AppName, title)
		return exec.Command("osascript", "-e", notification)
	}

	// finally falls back to growlnotify.

	return exec.Command("growlnotify", "-n", o.AppName, "--image", iconPath, "-m", title)
}

// Causes the notification to stick around until clicked.
func (o osxNotificator) pushCritical(title string, text string, iconPath string) *exec.Cmd {

	// same function as above...

	term_notif := CheckTermNotif()
	os_version_check := CheckMacOSVersion()

	if term_notif == true {
		// timeout set to 30 seconds, to show the importance of the notification
		return exec.Command("terminal-notifier", "-title", o.AppName, "-message", text, "-subtitle", title, "-timeout", "30")
	} else if os_version_check == true {
		notification := fmt.Sprintf("display notification \"%s\" with title \"%s\" subtitle \"%s\"", text, o.AppName, title)
		return exec.Command("osascript", "-e", notification)
	}

	return exec.Command("growlnotify", "-n", o.AppName, "--image", iconPath, "-m", title)

}

type linuxNotificator struct{}

func (l linuxNotificator) push(title string, text string, iconPath string) *exec.Cmd {
	return exec.Command("notify-send", "-i", iconPath, title, text)
}

// Causes the notification to stick around until clicked.
func (l linuxNotificator) pushCritical(title string, text string, iconPath string) *exec.Cmd {
	return exec.Command("notify-send", "-i", iconPath, title, text, "-u", "critical")
}

type windowsNotificator struct{}

func (w windowsNotificator) push(title string, text string, iconPath string) *exec.Cmd {
	return exec.Command("growlnotify", "/i:", iconPath, "/t:", title, text)
}

// Causes the notification to stick around until clicked.
func (w windowsNotificator) pushCritical(title string, text string, iconPath string) *exec.Cmd {
	return exec.Command("notify-send", "-i", iconPath, title, text, "/s", "true", "/p", "2")
}

func New(o Options) *Notificator {

	var Notifier notifier

	switch runtime.GOOS {

	case "darwin":
		Notifier = osxNotificator{AppName: o.AppName}
	case "linux":
		Notifier = linuxNotificator{}
	case "windows":
		Notifier = windowsNotificator{}

	}

	return &Notificator{notifier: Notifier, defaultIcon: o.DefaultIcon}
}

// Helper function for macOS

func CheckTermNotif() bool {
	// Checks if terminal-notifier exists, and is accessible.

	check_term_notif := exec.Command("which", "terminal-notifier")
	err := check_term_notif.Start()

	if err != nil {
		return false
	} else {
		err = check_term_notif.Wait()
		if err != nil {
			return false
		}
	}
	// no error, so return true. (terminal-notifier exists)
	return true
}

func CheckMacOSVersion() bool {
	// Checks if the version of macOS is 10.9 or Higher (osascript support for notifications.)

	cmd := exec.Command("sw_vers", "-productVersion")
	check, _ := cmd.Output()

	version := strings.Split(string(check), ".")

	// semantic versioning of macOS

	major, _ := strconv.Atoi(version[0])
	minor, _ := strconv.Atoi(version[1])

	if major < 10 {
		return false
	} else if major == 10 && minor < 9 {
		return false
	} else {
		return true
	}
}
<commit_msg>Make terminal notifier check shorter<commit_after>package notificator

import (
	"fmt"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
)

type Options struct {
	DefaultIcon string
	AppName     string
}

const (
	UR_NORMAL   = "normal"
	UR_CRITICAL = "critical"
)

type notifier interface {
	push(title string, text string, iconPath string) *exec.Cmd
	pushCritical(title string, text string, iconPath string) *exec.Cmd
}

type Notificator struct {
	notifier    notifier
	defaultIcon string
}

func (n Notificator) Push(title string, text string, iconPath string, urgency string) error {
	icon := n.defaultIcon

	if iconPath != "" {
		icon = iconPath
	}

	if urgency == UR_CRITICAL {
		return n.notifier.pushCritical(title, text, icon).Run()
	}

	return n.notifier.push(title, text, icon).Run()

}

type osxNotificator struct {
	AppName string
}

func (o osxNotificator) push(title string, text string, iconPath string) *exec.Cmd {

	// Checks if terminal-notifier exists, and is accessible.

	term_notif := CheckTermNotif()
	os_version_check := CheckMacOSVersion()

	// if terminal-notifier exists, use it.
	// else, fall back to osascript. (Mavericks and later.)

	if term_notif == true {
		return exec.Command("terminal-notifier", "-title", o.AppName, "-message", text, "-subtitle", title, "-appIcon", iconPath)
	} else if os_version_check == true {
		notification := fmt.Sprintf("display notification \"%s\" with title \"%s\" subtitle \"%s\"", text, o.AppName, title)
		return exec.Command("osascript", "-e", notification)
	}

	// finally falls back to growlnotify.

	return exec.Command("growlnotify", "-n", o.AppName, "--image", iconPath, "-m", title)
}

// Causes the notification to stick around until clicked.
func (o osxNotificator) pushCritical(title string, text string, iconPath string) *exec.Cmd {

	// same function as above...

	term_notif := CheckTermNotif()
	os_version_check := CheckMacOSVersion()

	if term_notif == true {
		// timeout set to 30 seconds, to show the importance of the notification
		return exec.Command("terminal-notifier", "-title", o.AppName, "-message", text, "-subtitle", title, "-timeout", "30")
	} else if os_version_check == true {
		notification := fmt.Sprintf("display notification \"%s\" with title \"%s\" subtitle \"%s\"", text, o.AppName, title)
		return exec.Command("osascript", "-e", notification)
	}

	return exec.Command("growlnotify", "-n", o.AppName, "--image", iconPath, "-m", title)

}

type linuxNotificator struct{}

func (l linuxNotificator) push(title string, text string, iconPath string) *exec.Cmd {
	return exec.Command("notify-send", "-i", iconPath, title, text)
}

// Causes the notification to stick around until clicked.
func (l linuxNotificator) pushCritical(title string, text string, iconPath string) *exec.Cmd {
	return exec.Command("notify-send", "-i", iconPath, title, text, "-u", "critical")
}

type windowsNotificator struct{}

func (w windowsNotificator) push(title string, text string, iconPath string) *exec.Cmd {
	return exec.Command("growlnotify", "/i:", iconPath, "/t:", title, text)
}

// Causes the notification to stick around until clicked.
func (w windowsNotificator) pushCritical(title string, text string, iconPath string) *exec.Cmd {
	return exec.Command("notify-send", "-i", iconPath, title, text, "/s", "true", "/p", "2")
}

func New(o Options) *Notificator {

	var Notifier notifier

	switch runtime.GOOS {

	case "darwin":
		Notifier = osxNotificator{AppName: o.AppName}
	case "linux":
		Notifier = linuxNotificator{}
	case "windows":
		Notifier = windowsNotificator{}

	}

	return &Notificator{notifier: Notifier, defaultIcon: o.DefaultIcon}
}

// Helper function for macOS

func CheckTermNotif() bool {
	// Checks if terminal-notifier exists, and is accessible.
	if err := exec.Command("which", "terminal-notifier").Run(); err != nil {
		return false
	}
	// no error, so return true. (terminal-notifier exists)
	return true
}

func CheckMacOSVersion() bool {
	// Checks if the version of macOS is 10.9 or Higher (osascript support for notifications.)

	cmd := exec.Command("sw_vers", "-productVersion")
	check, _ := cmd.Output()

	version := strings.Split(string(check), ".")

	// semantic versioning of macOS

	major, _ := strconv.Atoi(version[0])
	minor, _ := strconv.Atoi(version[1])

	if major < 10 {
		return false
	} else if major == 10 && minor < 9 {
		return false
	} else {
		return true
	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
)

func CheckMAC(message, messageMAC, key []byte) bool {
	mac := hmac.New(sha1.New, key)
	mac.Write(message)
	expectedMAC := mac.Sum(nil)
	return hmac.Equal(messageMAC, expectedMAC)
}

var secretKey []byte

func githubnotify(w http.ResponseWriter, r *http.Request) {
	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	event := r.Header.Get("X-Github-Event")
	sig := r.Header.Get("X-Hub-Signature")

	payload := GithubPayload{}
	err = json.Unmarshal(data, &payload)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if strings.HasPrefix(sig, "sha1=") {
		sigBytes, err := hex.DecodeString(sig[len("sha1="):])
		if err != nil {
			http.Error(w, "Invalid X-Hub-Signature: "+err.Error(), http.StatusBadRequest)
			return
		}

		if !CheckMAC(data, sigBytes, secretKey) {
			http.Error(w, "", http.StatusUnauthorized)
			return
		}
	} else {
		http.Error(w, "Invalid X-Hub-Signature", http.StatusBadRequest)
		return
	}

	name := payload.Repository.Description
	url := payload.Repository.URL

	fmt.Println(event, sig, name, url)
}

func main() {
	secretKey = []byte(os.Getenv("GITHUBSECRET"))
	if len(secretKey) == 0 {
		panic("GITHUBSECRET environment variable not set")
	}

	http.HandleFunc("/githubnotify/", githubnotify)
	http.ListenAndServe(":8080", nil)
}
<commit_msg>code tidy up<commit_after>package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	//	"strings"
)

var secretKey []byte

func verifyHMAC(w http.ResponseWriter, r *http.Request, body []byte) bool {
	sig := r.Header.Get("X-Hub-Signature")

	mac := hmac.New(sha1.New, secretKey)
	mac.Write(body)
	expectedMAC := "sha1=" + hex.EncodeToString(mac.Sum(nil))
	equal := hmac.Equal([]byte(sig), []byte(expectedMAC))

	if !equal {
		http.Error(w, "X-Hub-Signature Mismatch", http.StatusUnauthorized)
	}

	return equal
}

func githubnotify(w http.ResponseWriter, r *http.Request) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if r.Header.Get("X-Github-Event") != "push" {
		return
	}

	if !verifyHMAC(w, r, body) {
		return
	}

	payload := GithubPayload{}
	err = json.Unmarshal(body, &payload)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	name := payload.Repository.Description
	url := payload.Repository.URL
	fmt.Println(name, url)

}

func main() {
	secretKey = []byte(os.Getenv("GITHUBSECRET"))
	if len(secretKey) == 0 {
		panic("GITHUBSECRET environment variable not set")
	}

	http.HandleFunc("/githubnotify/", githubnotify)
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"github.com/oschwald/geoip2-golang"
	"log"
	"net"
	"net/http"
	"os"
	"strconv"
	"strings"
)

var db *sql.DB
var visitorsStmt *sql.Stmt
var visitStmt *sql.Stmt

type Visit struct {
	timse    string
	location string
	ip       string
}

func handler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" || r.Method == "" {
		get(w)
	} else if r.Method == "POST" {
		post(w, r)
	}
}

func get(w http.ResponseWriter) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	rows, err := db.Query("select count(id), strftime(\"%Y-%m-%d %H:00:00\", datetime(time, 'localtime')) from visits where time > datetime('now', '-500 hours') group by strftime(\"%Y%j%H\", time);")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	result := map[string][]map[string]string{}
	counts := []map[string]string{}
	for rows.Next() {
		var count string
		var time string

		rows.Scan(&count, &time)
		counts = append(counts, map[string]string{
			"time":  time,
			"count": count,
		})
	}
	result["counts"] = counts

	lrows, err := db.Query("select count(city), city, country, iso from visitors natural join visits where visits.time > datetime('now', '-500 hours') group by city, iso;")
	if err != nil {
		log.Fatal(err)
	}
	defer lrows.Close()
	locations := []map[string]string{}
	for lrows.Next() {
		var count string
		var city string
		var country string
		var iso string

		lrows.Scan(&count, &city, &country, &iso)
		locations = append(locations, map[string]string{
			"city":    city,
			"country": country,
			"iso":     iso,
			"count":   count,
		})
	}
	result["locations"] = locations

	b, _ := json.Marshal(result)
	fmt.Fprintf(w, string(b))

	rows.Close()
}

func post(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	if strings.Contains(r.UserAgent(), "Googlebot") {
		return
	}

	if r.FormValue("action") == "enter" {
		var id int64
		avid := r.FormValue("avid")

		if avid == "" {
			host, _, _ := net.SplitHostPort(r.RemoteAddr)
			if host != "" {
				gr := geo(host)
				result, err := visitorsStmt.Exec(gr["city"], gr["country"], gr["iso"], host, r.UserAgent())

				if err != nil {
					log.Print(err)
					return
				}

				id, _ = result.LastInsertId()
				response := map[string]string{}
				response["vid"] = strconv.FormatInt(id, 10)

				rj, _ := json.Marshal(response)
				fmt.Fprintf(w, string(rj))
			}
		} else {
			id_s, _ := strconv.Atoi(avid)
			id = int64(id_s)
		}

		_, err := visitStmt.Exec(r.FormValue("url"), r.FormValue("referrer"), id)

		if err != nil {
			log.Print(err)
			return
		}
	}
}

func geo(ipstring string) map[string]string {
	db, err := geoip2.Open("GeoLite2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	ip := net.ParseIP(ipstring)
	if ip != nil {
		record, err := db.City(ip)
		if err != nil {
			log.Fatal(err)
		}
		return map[string]string{
			"city":    record.City.Names["en"],
			"country": record.Country.Names["en"],
			"iso":     record.Country.IsoCode,
		}
	}

	return map[string]string{
		"city":    "",
		"country": "",
		"iso":     "",
	}
}

func main() {
	isNew := false

	_, err := os.Open("./alight.db")
	if err != nil {
		isNew = true
	}

	db, err = sql.Open("sqlite3", "./alight.db")
	defer db.Close()

	if isNew {
		sqlStmt := `
		create table visits (id integer primary key, url text, time integer, referrer text, vid integer references visitors);
		create table visitors (vid integer primary key, city text, country text, iso text, ip text, ua text);
		`

		_, err = db.Exec(sqlStmt)
		if err != nil {
			os.Remove("./alight.db")
			log.Printf("%q: %s\n", err, sqlStmt)
			return
		}
	}

	db.Exec("pragma synchronous = OFF")

	visitorsStmt, err = db.Prepare("insert into visitors values (null, ?, ?, ?, ?, ?)")
	if err != nil {
		log.Fatal(err)
	}
	visitStmt, err = db.Prepare("insert into visits values (null, ?, datetime('now'), ?, ?);")
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/", handler)
	http.ListenAndServe(":8000", nil)
}
<commit_msg>count distinct vid<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"github.com/oschwald/geoip2-golang"
	"log"
	"net"
	"net/http"
	"os"
	"strconv"
	"strings"
)

var db *sql.DB
var visitorsStmt *sql.Stmt
var visitStmt *sql.Stmt

type Visit struct {
	timse    string
	location string
	ip       string
}

func handler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" || r.Method == "" {
		get(w)
	} else if r.Method == "POST" {
		post(w, r)
	}
}

func get(w http.ResponseWriter) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	rows, err := db.Query("select count(id), strftime(\"%Y-%m-%d %H:00:00\", datetime(time, 'localtime')) from visits where time > datetime('now', '-500 hours') group by strftime(\"%Y%j%H\", time);")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	result := map[string][]map[string]string{}
	counts := []map[string]string{}
	for rows.Next() {
		var count string
		var time string

		rows.Scan(&count, &time)
		counts = append(counts, map[string]string{
			"time":  time,
			"count": count,
		})
	}
	result["counts"] = counts

	lrows, err := db.Query("select count(distinct vid), city, country, iso from visitors natural join visits where visits.time > datetime('now', '-500 hours') group by city, iso;")
	if err != nil {
		log.Fatal(err)
	}
	defer lrows.Close()
	locations := []map[string]string{}
	for lrows.Next() {
		var count string
		var city string
		var country string
		var iso string

		lrows.Scan(&count, &city, &country, &iso)
		locations = append(locations, map[string]string{
			"city":    city,
			"country": country,
			"iso":     iso,
			"count":   count,
		})
	}
	result["locations"] = locations

	b, _ := json.Marshal(result)
	fmt.Fprintf(w, string(b))

	rows.Close()
}

func post(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	if strings.Contains(r.UserAgent(), "Googlebot") {
		return
	}

	if r.FormValue("action") == "enter" {
		var id int64
		avid := r.FormValue("avid")

		if avid == "" {
			host, _, _ := net.SplitHostPort(r.RemoteAddr)
			if host != "" {
				gr := geo(host)
				result, err := visitorsStmt.Exec(gr["city"], gr["country"], gr["iso"], host, r.UserAgent())

				if err != nil {
					log.Print(err)
					return
				}

				id, _ = result.LastInsertId()
				response := map[string]string{}
				response["vid"] = strconv.FormatInt(id, 10)

				rj, _ := json.Marshal(response)
				fmt.Fprintf(w, string(rj))
			}
		} else {
			id_s, _ := strconv.Atoi(avid)
			id = int64(id_s)
		}

		_, err := visitStmt.Exec(r.FormValue("url"), r.FormValue("referrer"), id)

		if err != nil {
			log.Print(err)
			return
		}
	}
}

func geo(ipstring string) map[string]string {
	db, err := geoip2.Open("GeoLite2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	ip := net.ParseIP(ipstring)
	if ip != nil {
		record, err := db.City(ip)
		if err != nil {
			log.Fatal(err)
		}
		return map[string]string{
			"city":    record.City.Names["en"],
			"country": record.Country.Names["en"],
			"iso":     record.Country.IsoCode,
		}
	}

	return map[string]string{
		"city":    "",
		"country": "",
		"iso":     "",
	}
}

func main() {
	isNew := false

	_, err := os.Open("./alight.db")
	if err != nil {
		isNew = true
	}

	db, err = sql.Open("sqlite3", "./alight.db")
	defer db.Close()

	if isNew {
		sqlStmt := `
		create table visits (id integer primary key, url text, time integer, referrer text, vid integer references visitors);
		create table visitors (vid integer primary key, city text, country text, iso text, ip text, ua text);
		`

		_, err = db.Exec(sqlStmt)
		if err != nil {
			os.Remove("./alight.db")
			log.Printf("%q: %s\n", err, sqlStmt)
			return
		}
	}

	db.Exec("pragma synchronous = OFF")

	visitorsStmt, err = db.Prepare("insert into visitors values (null, ?, ?, ?, ?, ?)")
	if err != nil {
		log.Fatal(err)
	}
	visitStmt, err = db.Prepare("insert into visits values (null, ?, datetime('now'), ?, ?);")
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/", handler)
	http.ListenAndServe(":8000", nil)
}
<|endoftext|>


<commit_before>package config

import (
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/discovery"
	"github.com/docker/docker/pkg/plugingetter"
	"github.com/docker/go-connections/tlsconfig"
	"github.com/docker/libkv/store"
	"github.com/docker/libnetwork/cluster"
	"github.com/docker/libnetwork/datastore"
	"github.com/docker/libnetwork/netlabel"
	"github.com/docker/libnetwork/osl"
)

// Config encapsulates configurations of various Libnetwork components
type Config struct {
	Daemon          DaemonCfg
	Cluster         ClusterCfg
	Scopes          map[string]*datastore.ScopeCfg
	ActiveSandboxes map[string]interface{}
	PluginGetter    plugingetter.PluginGetter
}

// DaemonCfg represents libnetwork core configuration
type DaemonCfg struct {
	Debug                  bool
	Experimental           bool
	DataDir                string
	DefaultNetwork         string
	DefaultDriver          string
	Labels                 []string
	DriverCfg              map[string]interface{}
	ClusterProvider        cluster.Provider
	NetworkControlPlaneMTU int
}

// ClusterCfg represents cluster configuration
type ClusterCfg struct {
	Watcher   discovery.Watcher
	Address   string
	Discovery string
	Heartbeat uint64
}

// LoadDefaultScopes loads default scope configs for scopes which
// doesn't have explicit user specified configs.
func (c *Config) LoadDefaultScopes(dataDir string) {
	for k, v := range datastore.DefaultScopes(dataDir) {
		if _, ok := c.Scopes[k]; !ok {
			c.Scopes[k] = v
		}
	}
}

// ParseConfig parses the libnetwork configuration file
func ParseConfig(tomlCfgFile string) (*Config, error) {
	cfg := &Config{
		Scopes: map[string]*datastore.ScopeCfg{},
	}

	if _, err := toml.DecodeFile(tomlCfgFile, cfg); err != nil {
		return nil, err
	}

	cfg.LoadDefaultScopes(cfg.Daemon.DataDir)
	return cfg, nil
}

// ParseConfigOptions parses the configuration options and returns
// a reference to the corresponding Config structure
func ParseConfigOptions(cfgOptions ...Option) *Config {
	cfg := &Config{
		Daemon: DaemonCfg{
			DriverCfg: make(map[string]interface{}),
		},
		Scopes: make(map[string]*datastore.ScopeCfg),
	}

	cfg.ProcessOptions(cfgOptions...)
	cfg.LoadDefaultScopes(cfg.Daemon.DataDir)

	return cfg
}

// Option is an option setter function type used to pass various configurations
// to the controller
type Option func(c *Config)

// OptionDefaultNetwork function returns an option setter for a default network
func OptionDefaultNetwork(dn string) Option {
	return func(c *Config) {
		logrus.Debugf("Option DefaultNetwork: %s", dn)
		c.Daemon.DefaultNetwork = strings.TrimSpace(dn)
	}
}

// OptionDefaultDriver function returns an option setter for default driver
func OptionDefaultDriver(dd string) Option {
	return func(c *Config) {
		logrus.Debugf("Option DefaultDriver: %s", dd)
		c.Daemon.DefaultDriver = strings.TrimSpace(dd)
	}
}

// OptionDriverConfig returns an option setter for driver configuration.
func OptionDriverConfig(networkType string, config map[string]interface{}) Option {
	return func(c *Config) {
		c.Daemon.DriverCfg[networkType] = config
	}
}

// OptionLabels function returns an option setter for labels
func OptionLabels(labels []string) Option {
	return func(c *Config) {
		for _, label := range labels {
			if strings.HasPrefix(label, netlabel.Prefix) {
				c.Daemon.Labels = append(c.Daemon.Labels, label)
			}
		}
	}
}

// OptionKVProvider function returns an option setter for kvstore provider
func OptionKVProvider(provider string) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionKVProvider: %s", provider)
		if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
			c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.GlobalScope].Client.Provider = strings.TrimSpace(provider)
	}
}

// OptionKVProviderURL function returns an option setter for kvstore url
func OptionKVProviderURL(url string) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionKVProviderURL: %s", url)
		if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
			c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.GlobalScope].Client.Address = strings.TrimSpace(url)
	}
}

// OptionKVOpts function returns an option setter for kvstore options
func OptionKVOpts(opts map[string]string) Option {
	return func(c *Config) {
		if opts["kv.cacertfile"] != "" && opts["kv.certfile"] != "" && opts["kv.keyfile"] != "" {
			logrus.Info("Option Initializing KV with TLS")
			tlsConfig, err := tlsconfig.Client(tlsconfig.Options{
				CAFile:   opts["kv.cacertfile"],
				CertFile: opts["kv.certfile"],
				KeyFile:  opts["kv.keyfile"],
			})
			if err != nil {
				logrus.Errorf("Unable to set up TLS: %s", err)
				return
			}
			if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
				c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{}
			}
			if c.Scopes[datastore.GlobalScope].Client.Config == nil {
				c.Scopes[datastore.GlobalScope].Client.Config = &store.Config{TLS: tlsConfig}
			} else {
				c.Scopes[datastore.GlobalScope].Client.Config.TLS = tlsConfig
			}
			// Workaround libkv/etcd bug for https
			c.Scopes[datastore.GlobalScope].Client.Config.ClientTLS = &store.ClientTLSConfig{
				CACertFile: opts["kv.cacertfile"],
				CertFile:   opts["kv.certfile"],
				KeyFile:    opts["kv.keyfile"],
			}
		} else {
			logrus.Info("Option Initializing KV without TLS")
		}
	}
}

// OptionDiscoveryWatcher function returns an option setter for discovery watcher
func OptionDiscoveryWatcher(watcher discovery.Watcher) Option {
	return func(c *Config) {
		c.Cluster.Watcher = watcher
	}
}

// OptionDiscoveryAddress function returns an option setter for self discovery address
func OptionDiscoveryAddress(address string) Option {
	return func(c *Config) {
		c.Cluster.Address = address
	}
}

// OptionDataDir function returns an option setter for data folder
func OptionDataDir(dataDir string) Option {
	return func(c *Config) {
		c.Daemon.DataDir = dataDir
	}
}

// OptionExecRoot function returns an option setter for exec root folder
func OptionExecRoot(execRoot string) Option {
	return func(c *Config) {
		osl.SetBasePath(execRoot)
	}
}

// OptionPluginGetter returns a plugingetter for remote drivers.
func OptionPluginGetter(pg plugingetter.PluginGetter) Option {
	return func(c *Config) {
		c.PluginGetter = pg
	}
}

// OptionExperimental function returns an option setter for experimental daemon
func OptionExperimental(exp bool) Option {
	return func(c *Config) {
		logrus.Debugf("Option Experimental: %v", exp)
		c.Daemon.Experimental = exp
	}
}

// OptionNetworkControlPlaneMTU function returns an option setter for control plane MTU
func OptionNetworkControlPlaneMTU(exp int) Option {
	return func(c *Config) {
		logrus.Debugf("Network Control Plane MTU: %d", exp)
		if exp < 1500 {
			// if exp == 0 the value won't be used
			logrus.Warnf("Received a MTU of %d, this value is very low,",
				"the network control plane can misbehave", exp)
		}
		c.Daemon.NetworkControlPlaneMTU = exp
	}
}

// ProcessOptions processes options and stores it in config
func (c *Config) ProcessOptions(options ...Option) {
	for _, opt := range options {
		if opt != nil {
			opt(c)
		}
	}
}

// IsValidName validates configuration objects supported by libnetwork
func IsValidName(name string) bool {
	return strings.TrimSpace(name) != ""
}

// OptionLocalKVProvider function returns an option setter for kvstore provider
func OptionLocalKVProvider(provider string) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionLocalKVProvider: %s", provider)
		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.LocalScope].Client.Provider = strings.TrimSpace(provider)
	}
}

// OptionLocalKVProviderURL function returns an option setter for kvstore url
func OptionLocalKVProviderURL(url string) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionLocalKVProviderURL: %s", url)
		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.LocalScope].Client.Address = strings.TrimSpace(url)
	}
}

// OptionLocalKVProviderConfig function returns an option setter for kvstore config
func OptionLocalKVProviderConfig(config *store.Config) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionLocalKVProviderConfig: %v", config)
		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.LocalScope].Client.Config = config
	}
}

// OptionActiveSandboxes function returns an option setter for passing the sandboxes
// which were active during previous daemon life
func OptionActiveSandboxes(sandboxes map[string]interface{}) Option {
	return func(c *Config) {
		c.ActiveSandboxes = sandboxes
	}
}
<commit_msg>Fix warn log<commit_after>package config

import (
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/discovery"
	"github.com/docker/docker/pkg/plugingetter"
	"github.com/docker/go-connections/tlsconfig"
	"github.com/docker/libkv/store"
	"github.com/docker/libnetwork/cluster"
	"github.com/docker/libnetwork/datastore"
	"github.com/docker/libnetwork/netlabel"
	"github.com/docker/libnetwork/osl"
)

// Config encapsulates configurations of various Libnetwork components
type Config struct {
	Daemon          DaemonCfg
	Cluster         ClusterCfg
	Scopes          map[string]*datastore.ScopeCfg
	ActiveSandboxes map[string]interface{}
	PluginGetter    plugingetter.PluginGetter
}

// DaemonCfg represents libnetwork core configuration
type DaemonCfg struct {
	Debug                  bool
	Experimental           bool
	DataDir                string
	DefaultNetwork         string
	DefaultDriver          string
	Labels                 []string
	DriverCfg              map[string]interface{}
	ClusterProvider        cluster.Provider
	NetworkControlPlaneMTU int
}

// ClusterCfg represents cluster configuration
type ClusterCfg struct {
	Watcher   discovery.Watcher
	Address   string
	Discovery string
	Heartbeat uint64
}

// LoadDefaultScopes loads default scope configs for scopes which
// doesn't have explicit user specified configs.
func (c *Config) LoadDefaultScopes(dataDir string) {
	for k, v := range datastore.DefaultScopes(dataDir) {
		if _, ok := c.Scopes[k]; !ok {
			c.Scopes[k] = v
		}
	}
}

// ParseConfig parses the libnetwork configuration file
func ParseConfig(tomlCfgFile string) (*Config, error) {
	cfg := &Config{
		Scopes: map[string]*datastore.ScopeCfg{},
	}

	if _, err := toml.DecodeFile(tomlCfgFile, cfg); err != nil {
		return nil, err
	}

	cfg.LoadDefaultScopes(cfg.Daemon.DataDir)
	return cfg, nil
}

// ParseConfigOptions parses the configuration options and returns
// a reference to the corresponding Config structure
func ParseConfigOptions(cfgOptions ...Option) *Config {
	cfg := &Config{
		Daemon: DaemonCfg{
			DriverCfg: make(map[string]interface{}),
		},
		Scopes: make(map[string]*datastore.ScopeCfg),
	}

	cfg.ProcessOptions(cfgOptions...)
	cfg.LoadDefaultScopes(cfg.Daemon.DataDir)

	return cfg
}

// Option is an option setter function type used to pass various configurations
// to the controller
type Option func(c *Config)

// OptionDefaultNetwork function returns an option setter for a default network
func OptionDefaultNetwork(dn string) Option {
	return func(c *Config) {
		logrus.Debugf("Option DefaultNetwork: %s", dn)
		c.Daemon.DefaultNetwork = strings.TrimSpace(dn)
	}
}

// OptionDefaultDriver function returns an option setter for default driver
func OptionDefaultDriver(dd string) Option {
	return func(c *Config) {
		logrus.Debugf("Option DefaultDriver: %s", dd)
		c.Daemon.DefaultDriver = strings.TrimSpace(dd)
	}
}

// OptionDriverConfig returns an option setter for driver configuration.
func OptionDriverConfig(networkType string, config map[string]interface{}) Option {
	return func(c *Config) {
		c.Daemon.DriverCfg[networkType] = config
	}
}

// OptionLabels function returns an option setter for labels
func OptionLabels(labels []string) Option {
	return func(c *Config) {
		for _, label := range labels {
			if strings.HasPrefix(label, netlabel.Prefix) {
				c.Daemon.Labels = append(c.Daemon.Labels, label)
			}
		}
	}
}

// OptionKVProvider function returns an option setter for kvstore provider
func OptionKVProvider(provider string) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionKVProvider: %s", provider)
		if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
			c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.GlobalScope].Client.Provider = strings.TrimSpace(provider)
	}
}

// OptionKVProviderURL function returns an option setter for kvstore url
func OptionKVProviderURL(url string) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionKVProviderURL: %s", url)
		if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
			c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.GlobalScope].Client.Address = strings.TrimSpace(url)
	}
}

// OptionKVOpts function returns an option setter for kvstore options
func OptionKVOpts(opts map[string]string) Option {
	return func(c *Config) {
		if opts["kv.cacertfile"] != "" && opts["kv.certfile"] != "" && opts["kv.keyfile"] != "" {
			logrus.Info("Option Initializing KV with TLS")
			tlsConfig, err := tlsconfig.Client(tlsconfig.Options{
				CAFile:   opts["kv.cacertfile"],
				CertFile: opts["kv.certfile"],
				KeyFile:  opts["kv.keyfile"],
			})
			if err != nil {
				logrus.Errorf("Unable to set up TLS: %s", err)
				return
			}
			if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
				c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{}
			}
			if c.Scopes[datastore.GlobalScope].Client.Config == nil {
				c.Scopes[datastore.GlobalScope].Client.Config = &store.Config{TLS: tlsConfig}
			} else {
				c.Scopes[datastore.GlobalScope].Client.Config.TLS = tlsConfig
			}
			// Workaround libkv/etcd bug for https
			c.Scopes[datastore.GlobalScope].Client.Config.ClientTLS = &store.ClientTLSConfig{
				CACertFile: opts["kv.cacertfile"],
				CertFile:   opts["kv.certfile"],
				KeyFile:    opts["kv.keyfile"],
			}
		} else {
			logrus.Info("Option Initializing KV without TLS")
		}
	}
}

// OptionDiscoveryWatcher function returns an option setter for discovery watcher
func OptionDiscoveryWatcher(watcher discovery.Watcher) Option {
	return func(c *Config) {
		c.Cluster.Watcher = watcher
	}
}

// OptionDiscoveryAddress function returns an option setter for self discovery address
func OptionDiscoveryAddress(address string) Option {
	return func(c *Config) {
		c.Cluster.Address = address
	}
}

// OptionDataDir function returns an option setter for data folder
func OptionDataDir(dataDir string) Option {
	return func(c *Config) {
		c.Daemon.DataDir = dataDir
	}
}

// OptionExecRoot function returns an option setter for exec root folder
func OptionExecRoot(execRoot string) Option {
	return func(c *Config) {
		osl.SetBasePath(execRoot)
	}
}

// OptionPluginGetter returns a plugingetter for remote drivers.
func OptionPluginGetter(pg plugingetter.PluginGetter) Option {
	return func(c *Config) {
		c.PluginGetter = pg
	}
}

// OptionExperimental function returns an option setter for experimental daemon
func OptionExperimental(exp bool) Option {
	return func(c *Config) {
		logrus.Debugf("Option Experimental: %v", exp)
		c.Daemon.Experimental = exp
	}
}

// OptionNetworkControlPlaneMTU function returns an option setter for control plane MTU
func OptionNetworkControlPlaneMTU(exp int) Option {
	return func(c *Config) {
		logrus.Debugf("Network Control Plane MTU: %d", exp)
		if exp < 1500 {
			// if exp == 0 the value won't be used
			logrus.Warnf("Received a MTU of %d, this value is very low, the network control plane can misbehave", exp)
		}
		c.Daemon.NetworkControlPlaneMTU = exp
	}
}

// ProcessOptions processes options and stores it in config
func (c *Config) ProcessOptions(options ...Option) {
	for _, opt := range options {
		if opt != nil {
			opt(c)
		}
	}
}

// IsValidName validates configuration objects supported by libnetwork
func IsValidName(name string) bool {
	return strings.TrimSpace(name) != ""
}

// OptionLocalKVProvider function returns an option setter for kvstore provider
func OptionLocalKVProvider(provider string) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionLocalKVProvider: %s", provider)
		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.LocalScope].Client.Provider = strings.TrimSpace(provider)
	}
}

// OptionLocalKVProviderURL function returns an option setter for kvstore url
func OptionLocalKVProviderURL(url string) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionLocalKVProviderURL: %s", url)
		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.LocalScope].Client.Address = strings.TrimSpace(url)
	}
}

// OptionLocalKVProviderConfig function returns an option setter for kvstore config
func OptionLocalKVProviderConfig(config *store.Config) Option {
	return func(c *Config) {
		logrus.Debugf("Option OptionLocalKVProviderConfig: %v", config)
		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
		}
		c.Scopes[datastore.LocalScope].Client.Config = config
	}
}

// OptionActiveSandboxes function returns an option setter for passing the sandboxes
// which were active during previous daemon life
func OptionActiveSandboxes(sandboxes map[string]interface{}) Option {
	return func(c *Config) {
		c.ActiveSandboxes = sandboxes
	}
}
<|endoftext|>


<commit_before><commit_msg>Fix log directory access<commit_after><|endoftext|>


<commit_before>package opds2

// AddLink add a new link in feed information
// at minimum the self link
func (feed *Feed) AddLink(href string, rel string, typeLink string, templated bool) {
	var l Link

	l.Href = href
	l.Rel = append(l.Rel, rel)
	l.TypeLink = typeLink
	if templated == true {
		l.Templated = true
	}

	feed.Links = append(feed.Links, l)
}

// AddImage add a image link to Publication
func (publication *Publication) AddImage(href string, typeImage string, height int, width int) {
	var i Link

	i.Href = href
	i.TypeLink = typeImage
	if height > 0 {
		i.Height = height
	}
	if width > 0 {
		i.Width = width
	}

	publication.Images = append(publication.Images, i)
}

// AddLink add a new link to the publication
func (publication *Publication) AddLink(href string, typeLink string, rel string, title string) {
	var l Link

	l.Href = href
	l.TypeLink = typeLink
	if rel != "" {
		l.Rel = append(l.Rel, rel)
	}
	if title != "" {
		l.Title = title
	}

	publication.Links = append(publication.Links, l)
}

// AddAuthor add author to publication with all parameters mostly optional
func (publication *Publication) AddAuthor(name string, identifier string, sortAs string, href string, typeLink string) {
	var c Contributor
	var l Link

	c.Name.SingleString = name
	if identifier != "" {
		c.Identifier = identifier
	}
	if sortAs != "" {
		c.SortAs = sortAs
	}
	if href != "" {
		l.Href = href
	}
	if typeLink != "" {
		l.TypeLink = typeLink
	}

	if l.Href != "" {
		c.Links = append(c.Links, l)
	}

	publication.Metadata.Author = append(publication.Metadata.Author, c)
}

// AddSerie add serie to publication
func (publication *Publication) AddSerie(name string, position float32, href string, typeLink string) {
	var c Collection
	var l Link

	c.Name = name
	c.Position = position

	if publication.Metadata.BelongsTo == nil {
		publication.Metadata.BelongsTo = &BelongsTo{}
	}

	if typeLink != "" {
		l.TypeLink = typeLink
	}

	if l.Href != "" {
		c.Links = append(c.Links, l)
	}

	publication.Metadata.BelongsTo.Series = append(publication.Metadata.BelongsTo.Series, c)
}

// AddPublisher add publisher to publication
func (publication *Publication) AddPublisher(name string, href string, typeLink string) {
	var c Contributor
	var l Link

	c.Name.SingleString = name

	if typeLink != "" {
		l.TypeLink = typeLink
	}

	if l.Href != "" {
		c.Links = append(c.Links, l)
	}

	publication.Metadata.Publisher = append(publication.Metadata.Publisher, c)
}

// AddNavigation add navigation element in feed
func (feed *Feed) AddNavigation(title string, href string, rel string, typeLink string) {
	var l Link

	l.Href = href
	l.TypeLink = typeLink
	l.Rel = append(l.Rel, rel)
	if title != "" {
		l.Title = title
	}

	feed.Navigation = append(feed.Navigation, l)
}

// AddPagination add pagination and link information in feed
func (feed *Feed) AddPagination(numberItems int, itemsPerPage int, currentPage int, nextLink string, prevLink string, firstLink string, lastLink string) {

	feed.Metadata.CurrentPage = currentPage
	feed.Metadata.ItemsPerPage = itemsPerPage
	feed.Metadata.NumberOfItems = numberItems

	if nextLink != "" {
		feed.AddLink(nextLink, "next", "application/opds+json", false)
	}
	if prevLink != "" {
		feed.AddLink(prevLink, "previous", "application/opds+json", false)
	}
	if firstLink != "" {
		feed.AddLink(firstLink, "first", "application/opds+json", false)
	}
	if lastLink != "" {
		feed.AddLink(lastLink, "last", "application/opds+json", false)
	}
}

// AddFacet add link to facet handler multiple add
func (feed *Feed) AddFacet(link Link, group string) {
	var facet Facet

	for i, f := range feed.Facets {
		if f.Metadata.Title == group {
			feed.Facets[i].Links = append(feed.Facets[i].Links, link)
			return
		}
	}

	facet.Metadata.Title = group
	facet.Links = append(facet.Links, link)
	feed.Facets = append(feed.Facets, facet)
}

// AddPublicationInGroup smart adding of publication in Group
func (feed *Feed) AddPublicationInGroup(publication Publication, collLink Link) {
	var group Group

	for i, g := range feed.Groups {
		for _, l := range g.Links {
			if l.Href == collLink.Href {
				feed.Groups[i].Publications = append(feed.Groups[i].Publications, publication)
				return
			}
		}
	}

	group.Metadata.Title = collLink.Title
	group.Publications = append(group.Publications, publication)
	group.Links = append(group.Links, Link{Rel: []string{"self"}, Title: collLink.Title, Href: collLink.Href})
	feed.Groups = append(feed.Groups, group)
}

// AddNavigationInGroup add a navigation link to Group
func (feed *Feed) AddNavigationInGroup(link Link, collLink Link) {
	var group Group

	for i, g := range feed.Groups {
		for _, l := range g.Links {
			if l.Href == collLink.Href {
				feed.Groups[i].Navigation = append(feed.Groups[i].Navigation, link)
				return
			}
		}
	}

	group.Metadata.Title = collLink.Title
	group.Navigation = append(group.Navigation, link)
	group.Links = append(group.Links, Link{Rel: []string{"self"}, Title: collLink.Title, Href: collLink.Href})
	feed.Groups = append(feed.Groups, group)
}
<commit_msg>add missing code for helper<commit_after>package opds2

// AddLink add a new link in feed information
// at minimum the self link
func (feed *Feed) AddLink(href string, rel string, typeLink string, templated bool) {
	var l Link

	l.Href = href
	l.Rel = append(l.Rel, rel)
	l.TypeLink = typeLink
	if templated == true {
		l.Templated = true
	}

	feed.Links = append(feed.Links, l)
}

// AddImage add a image link to Publication
func (publication *Publication) AddImage(href string, typeImage string, height int, width int) {
	var i Link

	i.Href = href
	i.TypeLink = typeImage
	if height > 0 {
		i.Height = height
	}
	if width > 0 {
		i.Width = width
	}

	publication.Images = append(publication.Images, i)
}

// AddLink add a new link to the publication
func (publication *Publication) AddLink(href string, typeLink string, rel string, title string) {
	var l Link

	l.Href = href
	l.TypeLink = typeLink
	if rel != "" {
		l.Rel = append(l.Rel, rel)
	}
	if title != "" {
		l.Title = title
	}

	publication.Links = append(publication.Links, l)
}

// AddAuthor add author to publication with all parameters mostly optional
func (publication *Publication) AddAuthor(name string, identifier string, sortAs string, href string, typeLink string) {
	var c Contributor
	var l Link

	c.Name.SingleString = name
	if identifier != "" {
		c.Identifier = identifier
	}
	if sortAs != "" {
		c.SortAs = sortAs
	}
	if href != "" {
		l.Href = href
	}
	if typeLink != "" {
		l.TypeLink = typeLink
	}

	if l.Href != "" {
		c.Links = append(c.Links, l)
	}

	publication.Metadata.Author = append(publication.Metadata.Author, c)
}

// AddSerie add serie to publication
func (publication *Publication) AddSerie(name string, position float32, href string, typeLink string) {
	var c Collection
	var l Link

	c.Name = name
	c.Position = position

	if publication.Metadata.BelongsTo == nil {
		publication.Metadata.BelongsTo = &BelongsTo{}
	}

	if typeLink != "" {
		l.TypeLink = typeLink
	}

	if href != "" {
		l.Href = href
	}

	if l.Href != "" {
		c.Links = append(c.Links, l)
	}

	publication.Metadata.BelongsTo.Series = append(publication.Metadata.BelongsTo.Series, c)
}

// AddPublisher add publisher to publication
func (publication *Publication) AddPublisher(name string, href string, typeLink string) {
	var c Contributor
	var l Link

	c.Name.SingleString = name

	if typeLink != "" {
		l.TypeLink = typeLink
	}

	if href != "" {
		l.Href = href
	}

	if l.Href != "" {
		c.Links = append(c.Links, l)
	}

	publication.Metadata.Publisher = append(publication.Metadata.Publisher, c)
}

// AddNavigation add navigation element in feed
func (feed *Feed) AddNavigation(title string, href string, rel string, typeLink string) {
	var l Link

	l.Href = href
	l.TypeLink = typeLink
	l.Rel = append(l.Rel, rel)
	if title != "" {
		l.Title = title
	}

	feed.Navigation = append(feed.Navigation, l)
}

// AddPagination add pagination and link information in feed
func (feed *Feed) AddPagination(numberItems int, itemsPerPage int, currentPage int, nextLink string, prevLink string, firstLink string, lastLink string) {

	feed.Metadata.CurrentPage = currentPage
	feed.Metadata.ItemsPerPage = itemsPerPage
	feed.Metadata.NumberOfItems = numberItems

	if nextLink != "" {
		feed.AddLink(nextLink, "next", "application/opds+json", false)
	}
	if prevLink != "" {
		feed.AddLink(prevLink, "previous", "application/opds+json", false)
	}
	if firstLink != "" {
		feed.AddLink(firstLink, "first", "application/opds+json", false)
	}
	if lastLink != "" {
		feed.AddLink(lastLink, "last", "application/opds+json", false)
	}
}

// AddFacet add link to facet handler multiple add
func (feed *Feed) AddFacet(link Link, group string) {
	var facet Facet

	for i, f := range feed.Facets {
		if f.Metadata.Title == group {
			feed.Facets[i].Links = append(feed.Facets[i].Links, link)
			return
		}
	}

	facet.Metadata.Title = group
	facet.Links = append(facet.Links, link)
	feed.Facets = append(feed.Facets, facet)
}

// AddPublicationInGroup smart adding of publication in Group
func (feed *Feed) AddPublicationInGroup(publication Publication, collLink Link) {
	var group Group

	for i, g := range feed.Groups {
		for _, l := range g.Links {
			if l.Href == collLink.Href {
				feed.Groups[i].Publications = append(feed.Groups[i].Publications, publication)
				return
			}
		}
	}

	group.Metadata.Title = collLink.Title
	group.Publications = append(group.Publications, publication)
	group.Links = append(group.Links, Link{Rel: []string{"self"}, Title: collLink.Title, Href: collLink.Href})
	feed.Groups = append(feed.Groups, group)
}

// AddNavigationInGroup add a navigation link to Group
func (feed *Feed) AddNavigationInGroup(link Link, collLink Link) {
	var group Group

	for i, g := range feed.Groups {
		for _, l := range g.Links {
			if l.Href == collLink.Href {
				feed.Groups[i].Navigation = append(feed.Groups[i].Navigation, link)
				return
			}
		}
	}

	group.Metadata.Title = collLink.Title
	group.Navigation = append(group.Navigation, link)
	group.Links = append(group.Links, Link{Rel: []string{"self"}, Title: collLink.Title, Href: collLink.Href})
	feed.Groups = append(feed.Groups, group)
}
<|endoftext|>


<commit_before>package p2p

import (
	"sync"
)

// IPeerSet has a (immutable) subset of the methods of PeerSet.
type IPeerSet interface {
	Has(key string) bool
	Get(key string) *Peer
	List() []*Peer
	Size() int
}

//-----------------------------------------------------------------------------

// PeerSet is a special structure for keeping a table of peers.
// Iteration over the peers is super fast and thread-safe.
type PeerSet struct {
	mtx    sync.Mutex
	lookup map[string]*peerSetItem
	list   []*Peer
}

type peerSetItem struct {
	peer  *Peer
	index int
}

func NewPeerSet() *PeerSet {
	return &PeerSet{
		lookup: make(map[string]*peerSetItem),
		list:   make([]*Peer, 0, 256),
	}
}

// Returns false if peer with key (PubKeyEd25519) is already set
func (ps *PeerSet) Add(peer *Peer) error {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	if ps.lookup[peer.Key] != nil {
		return ErrDuplicatePeer
	}

	index := len(ps.list)
	// Appending is safe even with other goroutines
	// iterating over the ps.list slice.
	ps.list = append(ps.list, peer)
	ps.lookup[peer.Key] = &peerSetItem{peer, index}
	return nil
}

func (ps *PeerSet) Has(peerKey string) bool {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	_, ok := ps.lookup[peerKey]
	return ok
}

func (ps *PeerSet) Get(peerKey string) *Peer {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	item, ok := ps.lookup[peerKey]
	if ok {
		return item.peer
	} else {
		return nil
	}
}

func (ps *PeerSet) Remove(peer *Peer) {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	item := ps.lookup[peer.Key]
	if item == nil {
		return
	}

	index := item.index
	// Copy the list but without the last element.
	// (we must copy because we're mutating the list)
	newList := make([]*Peer, len(ps.list)-1)
	copy(newList, ps.list)
	// If it's the last peer, that's an easy special case.
	if index == len(ps.list)-1 {
		ps.list = newList
		delete(ps.lookup, peer.Key)
		return
	}

	// Move the last item from ps.list to "index" in list.
	lastPeer := ps.list[len(ps.list)-1]
	lastPeerKey := lastPeer.Key
	lastPeerItem := ps.lookup[lastPeerKey]
	newList[index] = lastPeer
	lastPeerItem.index = index
	ps.list = newList
	delete(ps.lookup, peer.Key)

}

func (ps *PeerSet) Size() int {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	return len(ps.list)
}

// threadsafe list of peers.
func (ps *PeerSet) List() []*Peer {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	return ps.list
}
<commit_msg>Add p2p/peer_set function comments<commit_after>package p2p

import (
	"sync"
)

// IPeerSet has a (immutable) subset of the methods of PeerSet.
type IPeerSet interface {
	Has(key string) bool
	Get(key string) *Peer
	List() []*Peer
	Size() int
}

//-----------------------------------------------------------------------------

// PeerSet is a special structure for keeping a table of peers.
// Iteration over the peers is super fast and thread-safe.
type PeerSet struct {
	mtx    sync.Mutex
	lookup map[string]*peerSetItem
	list   []*Peer
}

type peerSetItem struct {
	peer  *Peer
	index int
}

// NewPeerSet creates a new peerSet with a list of initial capacity of 256 items.
func NewPeerSet() *PeerSet {
	return &PeerSet{
		lookup: make(map[string]*peerSetItem),
		list:   make([]*Peer, 0, 256),
	}
}

// Add adds the peer to the PeerSet.
// Returns false if peer with key (PubKeyEd25519) is already set
func (ps *PeerSet) Add(peer *Peer) error {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	if ps.lookup[peer.Key] != nil {
		return ErrDuplicatePeer
	}

	index := len(ps.list)
	// Appending is safe even with other goroutines
	// iterating over the ps.list slice.
	ps.list = append(ps.list, peer)
	ps.lookup[peer.Key] = &peerSetItem{peer, index}
	return nil
}

// Has returns true if the PeerSet contains
// the peer referred to by this peerKey.
func (ps *PeerSet) Has(peerKey string) bool {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	_, ok := ps.lookup[peerKey]
	return ok
}

// Get looks up a peer by the provided peerKey.
func (ps *PeerSet) Get(peerKey string) *Peer {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	item, ok := ps.lookup[peerKey]
	if ok {
		return item.peer
	}
	return nil
}

// Remove discards peer if the peer was previously memoized.
func (ps *PeerSet) Remove(peer *Peer) {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	item := ps.lookup[peer.Key]
	if item == nil {
		return
	}

	index := item.index
	// Copy the list but without the last element.
	// (we must copy because we're mutating the list)
	newList := make([]*Peer, len(ps.list)-1)
	copy(newList, ps.list)
	// If it's the last peer, that's an easy special case.
	if index == len(ps.list)-1 {
		ps.list = newList
		delete(ps.lookup, peer.Key)
		return
	}

	// Move the last item from ps.list to "index" in list.
	lastPeer := ps.list[len(ps.list)-1]
	lastPeerKey := lastPeer.Key
	lastPeerItem := ps.lookup[lastPeerKey]
	newList[index] = lastPeer
	lastPeerItem.index = index
	ps.list = newList
	delete(ps.lookup, peer.Key)

}

// Size returns the number of unique items in the peerSet.
func (ps *PeerSet) Size() int {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	return len(ps.list)
}

// threadsafe list of peers.
func (ps *PeerSet) List() []*Peer {
	ps.mtx.Lock()
	defer ps.mtx.Unlock()
	return ps.list
}
<|endoftext|>


<commit_before>package packing

import (
	"testing"
	"math/rand"
	"io/ioutil"
	"strconv"
	"bytes"
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"encoding/json"
)

func createImage(width int, height int, color color.RGBA) *image.RGBA {
	r := image.Rect(0, 0, width, height);
	eleImg := image.NewRGBA(r);
	for y := eleImg.Rect.Min.Y; y < eleImg.Rect.Max.Y; y++ {
		for x := eleImg.Rect.Min.X; x < eleImg.Rect.Max.X; x++ {
			eleImg.Set(x, y, color)
		}
	}

	return eleImg;
}

func createMeta(presults []*Result, names []string) ([]byte, error) {
	type frame struct {
		FileID string `json:"fileId"`
		X      int    `json:"x"`
		Y      int    `json:"y"`
		Width  int    `json:"width"`
		Height int    `json:"height"`
		Rotate bool   `json:"rotate"`
	}
	obj := make(map[string][]*frame)
	for i, presult := range presults {
		var frames []*frame
		for fileID, rect := range presult.Rects {
			f := &frame{}
			f.FileID = fileID
			f.X = rect.Min.X
			f.Y = rect.Min.Y
			f.Height = rect.Max.Y - rect.Min.Y
			f.Width = rect.Max.X - rect.Min.X
			f.Rotate = presult.IsRotated(fileID)
			frames = append(frames, f)
		}
		obj[names[i]] = frames
	}
	jsonb, err := json.MarshalIndent(&obj, "", " ")
	if err != nil {
		return nil, err
	}
	return jsonb, nil
}

func TestOK_Pack(t *testing.T) {
	// create packing infomation
	pinfo := CreatePackingInfo(512, 512)
	for i := 0; i < 10; i++ {
		randR := uint8(rand.Intn(255));
		randG := uint8(rand.Intn(255));
		randB := uint8(rand.Intn(255));
		pinfo.AddImage(strconv.FormatUint(uint64(i), 10), createImage(rand.Intn(255), rand.Intn(255), color.RGBA{randR,randG,randB,0x88}))
	}

	// pack
	presults, err := Pack(*pinfo)
	if err != nil {
		t.Error(err)
	}

	// draw images into txatlas
	imgNum := len(presults)
	pimgs := make([][]byte, imgNum, imgNum)
	for i := 0; i < imgNum; i++ {
		presult := presults[i]
		img := image.NewRGBA(presult.BaseRect)
		for y := img.Rect.Min.Y; y < img.Rect.Max.Y; y++ {
			for x := img.Rect.Min.X; x < img.Rect.Max.X; x++ {
				img.Set(x, y, color.RGBA{0x00, 0x00, 0x00, 0x00})
			}
		}
		for id, rect := range presult.Rects {
			eleImg := pinfo.GetImage(id)
			draw.Draw(img, rect, eleImg, image.Pt(0, 0), draw.Over)
		}

		buff := &bytes.Buffer{} //empty buffer
		png.Encode(buff, img)

		pimgs[i] = buff.Bytes()
	}

	// output image file
	var names []string
	for i, v := range pimgs {
		var name = strconv.FormatUint(uint64(i), 10) + ".png"
		err = ioutil.WriteFile("output/" + name, v, 0777)
		if err != nil {
			t.Error(err)
		}
		names = append(names, name)
	}

	// output meta file
	jsonb, err := createMeta(presults, names)
	err = ioutil.WriteFile("output/meta.json", jsonb, 0777)
	if err != nil {
		t.Error(err)
	}

}

func TestOK_PadToPow2_Up(t *testing.T) {
	// test data
	x := 999
	expected := 1024

	result := PadToPow2(x)

	if result != expected {
		t.Errorf("result(%d) is invalid. expected = %d", result, expected)
	}
}

func TestOK_PadToPow2_Same(t *testing.T) {
	// test data
	x := 512
	expected := 512

	result := PadToPow2(x)

	if result != expected {
		t.Errorf("result(%d) is invalid. expected = %d", result, expected)
	}
}<commit_msg>Refactor<commit_after>package packing

import (
	"testing"
	"math/rand"
	"io/ioutil"
	"strconv"
	"bytes"
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"encoding/json"
)

func createImage(width int, height int, color color.RGBA) *image.RGBA {
	r := image.Rect(0, 0, width, height);
	eleImg := image.NewRGBA(r);
	for y := eleImg.Rect.Min.Y; y < eleImg.Rect.Max.Y; y++ {
		for x := eleImg.Rect.Min.X; x < eleImg.Rect.Max.X; x++ {
			eleImg.Set(x, y, color)
		}
	}

	return eleImg;
}

func createMeta(presults []*Result, names []string) ([]byte, error) {
	type frame struct {
		FileID string `json:"fileId"`
		X      int    `json:"x"`
		Y      int    `json:"y"`
		Width  int    `json:"width"`
		Height int    `json:"height"`
		Rotate bool   `json:"rotate"`
	}
	obj := make(map[string][]*frame)
	for i, presult := range presults {
		var frames []*frame
		for fileID, rect := range presult.Rects {
			f := &frame{}
			f.FileID = fileID
			f.X = rect.Min.X
			f.Y = rect.Min.Y
			f.Height = rect.Max.Y - rect.Min.Y
			f.Width = rect.Max.X - rect.Min.X
			f.Rotate = presult.IsRotated(fileID)
			frames = append(frames, f)
		}
		obj[names[i]] = frames
	}
	jsonb, err := json.MarshalIndent(&obj, "", " ")
	if err != nil {
		return nil, err
	}
	return jsonb, nil
}

func TestOK_Pack(t *testing.T) {
	// create packing infomation
	pinfo := CreatePackingInfo(512, 512)
	for i := 0; i < 10; i++ {
		fileID := "img_" + strconv.FormatUint(uint64(i), 10) + ".png"
		randR := uint8(rand.Intn(255));
		randG := uint8(rand.Intn(255));
		randB := uint8(rand.Intn(255));
		pinfo.AddImage(fileID, createImage(rand.Intn(255), rand.Intn(255), color.RGBA{randR,randG,randB,0x88}))
	}

	// pack
	presults, err := Pack(*pinfo)
	if err != nil {
		t.Error(err)
	}

	// draw images into txatlas
	imgNum := len(presults)
	pimgs := make([][]byte, imgNum, imgNum)
	for i := 0; i < imgNum; i++ {
		presult := presults[i]
		img := image.NewRGBA(presult.BaseRect)
		for y := img.Rect.Min.Y; y < img.Rect.Max.Y; y++ {
			for x := img.Rect.Min.X; x < img.Rect.Max.X; x++ {
				img.Set(x, y, color.RGBA{0x00, 0x00, 0x00, 0x00})
			}
		}
		for id, rect := range presult.Rects {
			eleImg := pinfo.GetImage(id)
			draw.Draw(img, rect, eleImg, image.Pt(0, 0), draw.Over)
		}

		buff := &bytes.Buffer{} //empty buffer
		png.Encode(buff, img)

		pimgs[i] = buff.Bytes()
	}

	// output image file
	var names []string
	for i, v := range pimgs {
		var name = "txatlas_" + strconv.FormatUint(uint64(i), 10) + ".png"
		err = ioutil.WriteFile("output/" + name, v, 0777)
		if err != nil {
			t.Error(err)
		}
		names = append(names, name)
	}

	// output meta file
	jsonb, err := createMeta(presults, names)
	err = ioutil.WriteFile("output/meta.json", jsonb, 0777)
	if err != nil {
		t.Error(err)
	}

}

func TestOK_PadToPow2_Up(t *testing.T) {
	// test data
	x := 999
	expected := 1024

	result := PadToPow2(x)

	if result != expected {
		t.Errorf("result(%d) is invalid. expected = %d", result, expected)
	}
}

func TestOK_PadToPow2_Same(t *testing.T) {
	// test data
	x := 512
	expected := 512

	result := PadToPow2(x)

	if result != expected {
		t.Errorf("result(%d) is invalid. expected = %d", result, expected)
	}
}<|endoftext|>