<commit_before>/*
 * Mini Object Storage, (C) 2014 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package erasure

// #cgo CFLAGS: -O0
// #include <stdlib.h>
// #include "ec-code.h"
// #include "ec-common.h"
import "C"
import (
	"errors"
	"unsafe"
)

const (
	VANDERMONDE = iota
	CAUCHY
)

const (
	K = 10
	M = 3
)

// EncoderParams is a configuration set for building an encoder. It is created using ValidateParams.
type EncoderParams struct {
	K,
	M,
	Technique int // cauchy or vandermonde matrix (RS)
}

// Encoder is an object used to encode and decode data.
type Encoder struct {
	p *EncoderParams
	k,
	m C.int
	encode_matrix,
	encode_tbls,
	decode_matrix,
	decode_tbls *C.uint8_t
}

// ParseEncoderParams creates an EncoderParams object.
//
// k and m represent the matrix size, which corresponds to the protection level
// technique is the matrix type. Valid inputs are CAUCHY (recommended) or VANDERMONDE.
//
func ParseEncoderParams(k, m, technique int) (*EncoderParams, error) {
	if k < 1 {
		return nil, errors.New("k cannot be zero")
	}

	if m < 1 {
		return nil, errors.New("m cannot be zero")
	}

	if k+m > 255 {
		return nil, errors.New("(k + m) cannot be bigger than Galois field GF(2^8) - 1")
	}

	switch technique {
	case VANDERMONDE:
		break
	case CAUCHY:
		break
	default:
		return nil, errors.New("Technique can be either vandermonde or cauchy")
	}

	return &EncoderParams{
		K:         k,
		M:         m,
		Technique: technique,
	}, nil
}

// NewEncoder creates an encoder object with a given set of parameters.
func NewEncoder(ep *EncoderParams) *Encoder {
	var k = C.int(ep.K)
	var m = C.int(ep.M)

	var encode_matrix *C.uint8_t
	var encode_tbls *C.uint8_t

	C.minio_init_encoder(C.int(ep.Technique), k, m, &encode_matrix,
		&encode_tbls)

	return &Encoder{
		p:             ep,
		k:             k,
		m:             m,
		encode_matrix: encode_matrix,
		encode_tbls:   encode_tbls,
		decode_matrix: nil,
		decode_tbls:   nil,
	}
}

// Encode encodes a block of data. The input is the original data. The output
// is a 2 tuple containing (k + m) chunks of erasure encoded data and the
// length of the original object.
func (e *Encoder) Encode(block []byte) ([][]byte, int) {
	var block_len = len(block)

	chunk_size := int(C.minio_calc_chunk_size(e.k, C.uint32_t(block_len)))
	chunk_len := chunk_size * e.p.K
	pad_len := chunk_len - block_len

	if pad_len > 0 {
		s := make([]byte, pad_len)
		// Expand with new padded blocks to the byte array
		block = append(block, s...)
	}

	coded_len := chunk_size * e.p.M
	c := make([]byte, coded_len)
	block = append(block, c...)

	// Allocate chunks
	chunks := make([][]byte, e.p.K+e.p.M)
	pointers := make([]*byte, e.p.K+e.p.M)

	var i int
	// Add data blocks to chunks
	for i = 0; i < e.p.K; i++ {
		chunks[i] = block[i*chunk_size : (i+1)*chunk_size]
		pointers[i] = &chunks[i][0]
	}

	for i = e.p.K; i < (e.p.K + e.p.M); i++ {
		chunks[i] = make([]byte, chunk_size)
		pointers[i] = &chunks[i][0]
	}

	data := (**C.uint8_t)(unsafe.Pointer(&pointers[:e.p.K][0]))
	coding := (**C.uint8_t)(unsafe.Pointer(&pointers[e.p.K:][0]))

	C.ec_encode_data(C.int(chunk_size), e.k, e.m, e.encode_tbls, data,
		coding)
	return chunks, block_len
}
<commit_msg>Make K,M to be uint8 and Technique becomes its own type<commit_after>/*
 * Mini Object Storage, (C) 2014 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package erasure

// #cgo CFLAGS: -O0
// #include <stdlib.h>
// #include "ec-code.h"
// #include "ec-common.h"
import "C"
import (
	"errors"
	"unsafe"
)

type Technique int

const (
	VANDERMONDE Technique = iota
	CAUCHY
)

const (
	K = 10
	M = 3
)

// EncoderParams is a configuration set for building an encoder. It is created using ValidateParams.
type EncoderParams struct {
	K         uint8
	M         uint8
	Technique Technique // cauchy or vandermonde matrix (RS)
}

// Encoder is an object used to encode and decode data.
type Encoder struct {
	p *EncoderParams
	k,
	m C.int
	encode_matrix,
	encode_tbls,
	decode_matrix,
	decode_tbls *C.uint8_t
}

// ParseEncoderParams creates an EncoderParams object.
//
// k and m represent the matrix size, which corresponds to the protection level
// technique is the matrix type. Valid inputs are CAUCHY (recommended) or VANDERMONDE.
//
func ParseEncoderParams(k, m uint8, technique Technique) (*EncoderParams, error) {
	if k < 1 {
		return nil, errors.New("k cannot be zero")
	}

	if m < 1 {
		return nil, errors.New("m cannot be zero")
	}

	if k+m > 255 {
		return nil, errors.New("(k + m) cannot be bigger than Galois field GF(2^8) - 1")
	}

	switch technique {
	case VANDERMONDE:
		break
	case CAUCHY:
		break
	default:
		return nil, errors.New("Technique can be either vandermonde or cauchy")
	}

	return &EncoderParams{
		K:         k,
		M:         m,
		Technique: technique,
	}, nil
}

// NewEncoder creates an encoder object with a given set of parameters.
func NewEncoder(ep *EncoderParams) *Encoder {
	var k = C.int(ep.K)
	var m = C.int(ep.M)

	var encode_matrix *C.uint8_t
	var encode_tbls *C.uint8_t

	C.minio_init_encoder(C.int(ep.Technique), k, m, &encode_matrix,
		&encode_tbls)

	return &Encoder{
		p:             ep,
		k:             k,
		m:             m,
		encode_matrix: encode_matrix,
		encode_tbls:   encode_tbls,
		decode_matrix: nil,
		decode_tbls:   nil,
	}
}

// Encode encodes a block of data. The input is the original data. The output
// is a 2 tuple containing (k + m) chunks of erasure encoded data and the
// length of the original object.
func (e *Encoder) Encode(block []byte) ([][]byte, int) {
	var block_len = len(block)

	chunk_size := int(C.minio_calc_chunk_size(e.k, C.uint32_t(block_len)))
	chunk_len := chunk_size * int(e.p.K)
	pad_len := chunk_len - block_len

	if pad_len > 0 {
		s := make([]byte, pad_len)
		// Expand with new padded blocks to the byte array
		block = append(block, s...)
	}

	coded_len := chunk_size * int(e.p.M)
	c := make([]byte, coded_len)
	block = append(block, c...)

	// Allocate chunks
	chunks := make([][]byte, e.p.K+e.p.M)
	pointers := make([]*byte, e.p.K+e.p.M)

	var i int
	// Add data blocks to chunks
	for i = 0; i < int(e.p.K); i++ {
		chunks[i] = block[i*chunk_size : (i+1)*chunk_size]
		pointers[i] = &chunks[i][0]
	}

	for i = int(e.p.K); i < int(e.p.K+e.p.M); i++ {
		chunks[i] = make([]byte, chunk_size)
		pointers[i] = &chunks[i][0]
	}

	data := (**C.uint8_t)(unsafe.Pointer(&pointers[:e.p.K][0]))
	coding := (**C.uint8_t)(unsafe.Pointer(&pointers[e.p.K:][0]))

	C.ec_encode_data(C.int(chunk_size), e.k, e.m, e.encode_tbls, data,
		coding)
	return chunks, block_len
}
<|endoftext|>


<commit_before>package models

import (
	"time"
)

// IssueWatch is connection request for receiving issue notification.
type IssueWatch struct {
	ID          int64     `xorm:"pk autoincr"`
	UserID      int64     `xorm:"UNIQUE(watch) NOT NULL"`
	IssueID     int64     `xorm:"UNIQUE(watch) NOT NULL"`
	IsWatching  bool      `xorm:"NOT NULL"`
	Created     time.Time `xorm:"-"`
	CreatedUnix int64     `xorm:"NOT NULL"`
	Updated     time.Time `xorm:"-"`
	UpdatedUnix int64     `xorm:"NOT NULL"`
}

// BeforeInsert is invoked from XORM before inserting an object of this type.
func (iw *IssueWatch) BeforeInsert() {
	iw.Created = time.Now()
	iw.CreatedUnix = time.Now().Unix()
	iw.Updated = time.Now()
	iw.UpdatedUnix = time.Now().Unix()
}

func (iw *IssueWatch) BeforeUpdate() {
	iw.Updated = time.Now()
	iw.UpdatedUnix = time.Now().Unix()
}

// CreateOrUpdateIssueWatch set watching for a user and issue
func CreateOrUpdateIssueWatch(userID, issueID int64, isWatching bool) error {
	iw, exists, err := getIssueWatch(x, userID, issueID)
	if err != nil {
		return err
	}

	if !exists {
		iw = &IssueWatch{
			UserID:     userID,
			IssueID:    issueID,
			IsWatching: isWatching,
		}

		if _, err := x.Insert(iw); err != nil {
			return err
		}
	} else {
		iw.IsWatching = isWatching

		if _, err := x.Id(iw.ID).Cols("is_watching", "updated_unix").Update(iw); err != nil {
			return err
		}
	}
	return nil
}

// GetIssueWatch returns an issue watch by user and issue
func GetIssueWatch(userID, issueID int64) (iw *IssueWatch, exists bool, err error) {
	iw, exists, err = getIssueWatch(x, userID, issueID)
	return
}
func getIssueWatch(e Engine, userID, issueID int64) (iw *IssueWatch, exists bool, err error) {
	iw = new(IssueWatch)
	exists, err = e.
		Where("user_id = ?", userID).
		And("issue_id = ?", issueID).
		Get(iw)
	return
}

func GetIssueWatchers(issueID int64) ([]*IssueWatch, error) {
	return getIssueWatchers(x, issueID)
}
func getIssueWatchers(e Engine, issueID int64) (watches []*IssueWatch, err error) {
	err = e.
		Where("issue_id = ?", issueID).
		Find(&watches)
	return
}
<commit_msg>Fix lint<commit_after>package models

import (
	"time"
)

// IssueWatch is connection request for receiving issue notification.
type IssueWatch struct {
	ID          int64     `xorm:"pk autoincr"`
	UserID      int64     `xorm:"UNIQUE(watch) NOT NULL"`
	IssueID     int64     `xorm:"UNIQUE(watch) NOT NULL"`
	IsWatching  bool      `xorm:"NOT NULL"`
	Created     time.Time `xorm:"-"`
	CreatedUnix int64     `xorm:"NOT NULL"`
	Updated     time.Time `xorm:"-"`
	UpdatedUnix int64     `xorm:"NOT NULL"`
}

// BeforeInsert is invoked from XORM before inserting an object of this type.
func (iw *IssueWatch) BeforeInsert() {
	iw.Created = time.Now()
	iw.CreatedUnix = time.Now().Unix()
	iw.Updated = time.Now()
	iw.UpdatedUnix = time.Now().Unix()
}

// BeforeUpdate is invoked from XORM before updating an object of this type.
func (iw *IssueWatch) BeforeUpdate() {
	iw.Updated = time.Now()
	iw.UpdatedUnix = time.Now().Unix()
}

// CreateOrUpdateIssueWatch set watching for a user and issue
func CreateOrUpdateIssueWatch(userID, issueID int64, isWatching bool) error {
	iw, exists, err := getIssueWatch(x, userID, issueID)
	if err != nil {
		return err
	}

	if !exists {
		iw = &IssueWatch{
			UserID:     userID,
			IssueID:    issueID,
			IsWatching: isWatching,
		}

		if _, err := x.Insert(iw); err != nil {
			return err
		}
	} else {
		iw.IsWatching = isWatching

		if _, err := x.Id(iw.ID).Cols("is_watching", "updated_unix").Update(iw); err != nil {
			return err
		}
	}
	return nil
}

// GetIssueWatch returns an issue watch by user and issue
func GetIssueWatch(userID, issueID int64) (iw *IssueWatch, exists bool, err error) {
	iw, exists, err = getIssueWatch(x, userID, issueID)
	return
}
func getIssueWatch(e Engine, userID, issueID int64) (iw *IssueWatch, exists bool, err error) {
	iw = new(IssueWatch)
	exists, err = e.
		Where("user_id = ?", userID).
		And("issue_id = ?", issueID).
		Get(iw)
	return
}

// GetIssueWatchers returns watchers/unwatchers of a given issue
func GetIssueWatchers(issueID int64) ([]*IssueWatch, error) {
	return getIssueWatchers(x, issueID)
}
func getIssueWatchers(e Engine, issueID int64) (watches []*IssueWatch, err error) {
	err = e.
		Where("issue_id = ?", issueID).
		Find(&watches)
	return
}
<|endoftext|>


<commit_before>package cert

import (
	"fmt"
	"os"
	"path"
	"strconv"

	boshdir "github.com/cloudfoundry/bosh-agent/settings/directories"
	"github.com/cloudfoundry/bosh-utils/logger"
	boshsys "github.com/cloudfoundry/bosh-utils/system"
)

type windowsCertManager struct {
	fs          boshsys.FileSystem
	runner      boshsys.CmdRunner
	dirProvider boshdir.Provider
	logger      logger.Logger
	backupPath  string
}

const rootCertStore string = `Cert:\LocalMachine\Root`

func NewWindowsCertManager(fs boshsys.FileSystem, runner boshsys.CmdRunner, dirProvider boshdir.Provider, logger logger.Logger) Manager {
	return &windowsCertManager{
		fs:          fs,
		runner:      runner,
		dirProvider: dirProvider,
		logger:      logger,
		backupPath:  path.Join(dirProvider.TmpDir(), "rootCertBackup.sst"),
	}
}

func (c *windowsCertManager) createBackup() error {
	if _, err := os.Stat(c.backupPath); os.IsNotExist(err) {
		err = c.fs.MkdirAll(c.dirProvider.TmpDir(), os.FileMode(0777))
		if err != nil {
			return err
		}
		_, _, _, err := c.runner.RunCommand(
			"powershell",
			"-Command",
			fmt.Sprintf("Get-ChildItem %s | Select -Unique -Property Thumbprint, Subject | Export-Certificate -Type SST -FilePath %s", rootCertStore, c.backupPath),
		)
		if err != nil {
			return err
		}
	}
	return nil
}

func (c *windowsCertManager) resetCerts() error {
	_, _, _, err := c.runner.RunCommand(
		"powershell",
		"-Command",
		fmt.Sprintf(`Remove-Item %s\*`, rootCertStore),
	)
	if err != nil {
		return err
	}

	importCertsCmd := fmt.Sprintf("Import-Certificate -FilePath %s -CertStoreLocation %s", c.backupPath, rootCertStore)
	_, _, _, err = c.runner.RunCommand("powershell", "-Command", importCertsCmd)
	if err != nil {
		return err
	}
	return nil
}

func (c *windowsCertManager) UpdateCertificates(rawCerts string) error {
	err := c.createBackup()
	if err != nil {
		return err
	}

	err = c.resetCerts()
	if err != nil {
		return err
	}

	certs := splitCerts(rawCerts)
	tempCertDir, err := c.fs.TempDir("")
	if err != nil {
		return err
	}
	defer c.fs.RemoveAll(tempCertDir)

	for i, cert := range certs {
		filename := path.Join(tempCertDir, strconv.Itoa(i))
		err = c.fs.WriteFileString(filename, cert)
		if err != nil {
			return err
		}
		_, _, _, err = c.runner.RunCommand("powershell", "-Command",
			fmt.Sprintf("Import-Certificate -FilePath %s -CertStoreLocation %s", filename, rootCertStore))
		if err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Fix cert deduplication implementation<commit_after>package cert

import (
	"fmt"
	"os"
	"path"
	"strconv"

	boshdir "github.com/cloudfoundry/bosh-agent/settings/directories"
	"github.com/cloudfoundry/bosh-utils/logger"
	boshsys "github.com/cloudfoundry/bosh-utils/system"
)

type windowsCertManager struct {
	fs          boshsys.FileSystem
	runner      boshsys.CmdRunner
	dirProvider boshdir.Provider
	logger      logger.Logger
	backupPath  string
}

const rootCertStore string = `Cert:\LocalMachine\Root`

func NewWindowsCertManager(fs boshsys.FileSystem, runner boshsys.CmdRunner, dirProvider boshdir.Provider, logger logger.Logger) Manager {
	return &windowsCertManager{
		fs:          fs,
		runner:      runner,
		dirProvider: dirProvider,
		logger:      logger,
		backupPath:  path.Join(dirProvider.TmpDir(), "rootCertBackup.sst"),
	}
}

func (c *windowsCertManager) createBackup() error {
	if _, err := os.Stat(c.backupPath); os.IsNotExist(err) {
		err = c.fs.MkdirAll(c.dirProvider.TmpDir(), os.FileMode(0777))
		if err != nil {
			return err
		}
		_, _, _, err := c.runner.RunCommand(
			"powershell",
			"-Command",
			fmt.Sprintf("Get-ChildItem %s | Sort-Object -Property Thumbprint | Get-Unique | Export-Certificate -Type SST -FilePath %s", rootCertStore, c.backupPath),
		)
		if err != nil {
			return err
		}
	}
	return nil
}

func (c *windowsCertManager) resetCerts() error {
	_, _, _, err := c.runner.RunCommand(
		"powershell",
		"-Command",
		fmt.Sprintf(`Remove-Item %s\*`, rootCertStore),
	)
	if err != nil {
		return err
	}

	importCertsCmd := fmt.Sprintf("Import-Certificate -FilePath %s -CertStoreLocation %s", c.backupPath, rootCertStore)
	_, _, _, err = c.runner.RunCommand("powershell", "-Command", importCertsCmd)
	if err != nil {
		return err
	}
	return nil
}

func (c *windowsCertManager) UpdateCertificates(rawCerts string) error {
	err := c.createBackup()
	if err != nil {
		return err
	}

	err = c.resetCerts()
	if err != nil {
		return err
	}

	certs := splitCerts(rawCerts)
	tempCertDir, err := c.fs.TempDir("")
	if err != nil {
		return err
	}
	defer c.fs.RemoveAll(tempCertDir)

	for i, cert := range certs {
		filename := path.Join(tempCertDir, strconv.Itoa(i))
		err = c.fs.WriteFileString(filename, cert)
		if err != nil {
			return err
		}
		_, _, _, err = c.runner.RunCommand("powershell", "-Command",
			fmt.Sprintf("Import-Certificate -FilePath %s -CertStoreLocation %s", filename, rootCertStore))
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package ylog

import (
	"runtime"
	"time"

	"github.com/yeeuu/ylog/yjsonlog"
)

var gLogger *L

// Init 初始化全局日志
func Init(dir string) {
	l, err := New(dir)
	if err != nil {
		panic(err)
	}
	gLogger = l
}

// Close 关闭全局日志系统
func Close() {
	gLogger.Close()
}

// Info 在全局日志中输出信息
func Info(msg string, data ...interface{}) {
	gLogger.Info(msg, data...)
}

// Warning 在全局日志中输出警告信息
func Warning(msg string, data ...interface{}) {
	gLogger.Warning(msg, data...)
}

// Error 在全局日志中输出错误信息
func Error(msg string, data ...interface{}) {
	gLogger.Error(msg, data...)
}

// Debug 在全局日志中输出调试信息
func Debug(msg string, data ...interface{}) {
	gLogger.Debug(msg, data...)
}

// SetDebug 全局日志开启或关闭调试信息的输出
func SetDebug(debug bool) {
	gLogger.SetDebug(debug)
}

// M 日志数据
type M map[string]interface{}

// L 日志记录器
type L struct {
	l     *yjsonlog.L
	debug bool
}

// New 新建一个日志记录器
func New(dir string) (*L, error) {
	l, err := yjsonlog.New(yjsonlog.Config{
		Dir:      dir,
		Switcher: yjsonlog.DaySwitcher,
		FileType: ".log",
	})
	if err != nil {
		return nil, err
	}
	return &L{l, true}, nil
}

// Close 关闭日志系统
func (logger *L) Close() {
	logger.l.Close()
}

// Log 生成jsonlog
func (logger *L) Log(msg string, typ string, data ...interface{}) {
	_, file, line, _ := runtime.Caller(3)
	short := file
	for i := len(file) - 1; i > 0; i-- {
		if file[i] == '/' {
			short = file[i+1:]
			break
		}
	}
	file = short
	m := yjsonlog.M{
		"Time":    time.Now().Format("2006-01-02 15:04:05"),
		"Type":    typ,
		"File":    file,
		"Line":    line,
		"Message": msg,
	}
	if data != nil {
		m["Data"] = data
	}
	logger.l.Log(m)
}

// Info 在日志文件中输出信息
func (logger *L) Info(msg string, data ...interface{}) {
	logger.Log(msg, "info", data...)
}

// Warning 在日志文件中输出警告信息
func (logger *L) Warning(msg string, data ...interface{}) {
	logger.Log(msg, "warning", data...)
}

// Error 在日志文件中输出错误信息
func (logger *L) Error(msg string, data ...interface{}) {
	logger.Log(msg, "error", data...)
}

// Debug 在日志文件中输出调试信息
func (logger *L) Debug(msg string, data ...interface{}) {
	if logger.debug {
		logger.Log(msg, "debug", data...)
	}
}

// SetDebug 开启或关闭调试信息的输出
func (logger *L) SetDebug(debug bool) {
	logger.debug = debug
}
<commit_msg>修正未正常初始化时出现崩溃<commit_after>package ylog

import (
	"runtime"
	"time"

	"github.com/yeeuu/ylog/yjsonlog"
)

var gLogger *L

func init() {
	gLogger = nil
}

// Init 初始化全局日志
func Init(dir string) {
	l, err := New(dir)
	if err != nil {
		panic(err)
	}
	gLogger = l
}

// Close 关闭全局日志系统
func Close() {
	if gLogger != nil {
		gLogger.Close()
		gLogger = nil
	}
}

// Info 在全局日志中输出信息
func Info(msg string, data ...interface{}) {
	if gLogger != nil {
		gLogger.Info(msg, data...)
	}
}

// Warning 在全局日志中输出警告信息
func Warning(msg string, data ...interface{}) {
	if gLogger != nil {
		gLogger.Warning(msg, data...)
	}
}

// Error 在全局日志中输出错误信息
func Error(msg string, data ...interface{}) {
	if gLogger != nil {
		gLogger.Error(msg, data...)
	}
}

// Debug 在全局日志中输出调试信息
func Debug(msg string, data ...interface{}) {
	if gLogger != nil {
		gLogger.Debug(msg, data...)
	}
}

// SetDebug 全局日志开启或关闭调试信息的输出
func SetDebug(debug bool) {
	if gLogger != nil {
		gLogger.SetDebug(debug)
	}
}

// M 日志数据
type M map[string]interface{}

// L 日志记录器
type L struct {
	l     *yjsonlog.L
	debug bool
}

// New 新建一个日志记录器
func New(dir string) (*L, error) {
	l, err := yjsonlog.New(yjsonlog.Config{
		Dir:      dir,
		Switcher: yjsonlog.DaySwitcher,
		FileType: ".log",
	})
	if err != nil {
		return nil, err
	}
	return &L{l, true}, nil
}

// Close 关闭日志系统
func (logger *L) Close() {
	logger.l.Close()
}

// Log 生成jsonlog
func (logger *L) Log(msg string, typ string, data ...interface{}) {
	_, file, line, _ := runtime.Caller(3)
	short := file
	for i := len(file) - 1; i > 0; i-- {
		if file[i] == '/' {
			short = file[i+1:]
			break
		}
	}
	file = short
	m := yjsonlog.M{
		"Time":    time.Now().Format("2006-01-02 15:04:05"),
		"Type":    typ,
		"File":    file,
		"Line":    line,
		"Message": msg,
	}
	if data != nil {
		m["Data"] = data
	}
	logger.l.Log(m)
}

// Info 在日志文件中输出信息
func (logger *L) Info(msg string, data ...interface{}) {
	logger.Log(msg, "info", data...)
}

// Warning 在日志文件中输出警告信息
func (logger *L) Warning(msg string, data ...interface{}) {
	logger.Log(msg, "warning", data...)
}

// Error 在日志文件中输出错误信息
func (logger *L) Error(msg string, data ...interface{}) {
	logger.Log(msg, "error", data...)
}

// Debug 在日志文件中输出调试信息
func (logger *L) Debug(msg string, data ...interface{}) {
	if logger.debug {
		logger.Log(msg, "debug", data...)
	}
}

// SetDebug 开启或关闭调试信息的输出
func (logger *L) SetDebug(debug bool) {
	logger.debug = debug
}
<|endoftext|>


<commit_before>package zgok

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"
)

const (
	APP   = "zgok"
	MAJOR = 0
	MINOR = 0
	REV   = 1
)

// Get version string.
func Version() string {
	return fmt.Sprintf("%s-%d.%d.%d", APP, MAJOR, MINOR, REV)
}

// File system interface.
// Implements [net/http.FileSystem]
type FileSystem interface {
	AddFile(file File)
	GetFile(path string) (File, error)
	ReadFile(path string) ([]byte, error)
	ReadFileString(path string) (string, error)
	Paths() []string
	SubFileSystem(rootPath string) (FileSystem, error)
	Signature() Signature
	SetSignature(signature Signature)
	String() string
	Open(name string) (http.File, error) // Implements [net/http.FileSystem.Open]
}

// Zgok file system.
type zgokFileSystem struct {
	signature Signature
	rootPath  string
	fileMap   map[string]File
}

// Create a new file system.
func NewFileSystem() FileSystem {
	return &zgokFileSystem{
		signature: nil,
		rootPath:  APP,
		fileMap:   make(map[string]File),
	}
}

// Restore file system.
func RestoreFileSystem() (FileSystem, error) {
	// Get bytes of exe file.
	exeBytes, err := ioutil.ReadFile(os.Args[0])
	if err != nil {
		return nil, err
	}
	// Restore signature.
	sigOffset := len(exeBytes) - SIGNATURE_BYTE_SIZE
	sigBytes := exeBytes[sigOffset:]
	signature, err := RestoreSignature(sigBytes)
	if err != nil {
		return nil, err
	}
	// Unzip zip section.
	zipOffset := signature.ExeSize()
	zipBytes := exeBytes[zipOffset:sigOffset]
	unzipper := NewUnzipper(&zipBytes)
	zfs, err := unzipper.Unzip()
	if err != nil {
		return nil, err
	}
	// Set signature.
	zfs.SetSignature(signature)
	return zfs, nil
}

// Add file to file system.
func (zfs *zgokFileSystem) AddFile(file File) {
	key := filepath.ToSlash(file.FileInfo().Name())
	zfs.fileMap[key] = file
}

// Get file from file system.
func (zfs *zgokFileSystem) GetFile(path string) (File, error) {
	key := filepath.ToSlash(filepath.Join(zfs.rootPath, path))
	file, exists := zfs.fileMap[key]
	if !exists {
		return nil, errors.New("File doesn't exist.")
	}
	return file, nil
}

// Get the content of file in bytes from file system.
func (zfs *zgokFileSystem) ReadFile(path string) ([]byte, error) {
	file, err := zfs.GetFile(path)
	if err != nil {
		return []byte{}, nil
	}
	return file.Bytes(), nil
}

// Get the content of file in string from file system.
func (zfs *zgokFileSystem) ReadFileString(path string) (string, error) {
	bytes, err := zfs.ReadFile(path)
	if err != nil {
		return "", nil
	}
	str := string(bytes)
	return str, nil
}

// Get all the paths stored in the file system.
func (zfs *zgokFileSystem) Paths() []string {
	paths := []string{}
	prefix := zfs.rootPath + "/"
	for key := range zfs.fileMap {
		if strings.HasPrefix(key, prefix) {
			relPath := strings.TrimPrefix(key, prefix)
			paths = append(paths, relPath)
		}
	}
	return paths
}

// Get a sub file system.
func (zfs *zgokFileSystem) SubFileSystem(rootPath string) (FileSystem, error) {
	// Check root path.
	if strings.Contains(rootPath, "..") {
		return nil, errors.New("No double dots [..] are allowed in root path.")
	}
	// Initialize sub file system.
	newRootPath := filepath.ToSlash(filepath.Join(zfs.rootPath, rootPath))
	subFs := &zgokFileSystem{
		signature: zfs.signature,
		rootPath:  newRootPath,
		fileMap:   make(map[string]File),
	}
	// Add all the sets matching the new root path.
	for key, value := range zfs.fileMap {
		if key[0:len(newRootPath)] == newRootPath {
			subFs.fileMap[key] = value
		}
	}
	return subFs, nil
}

// Get signature.
func (zfs *zgokFileSystem) Signature() Signature {
	return zfs.signature
}

// Set signature.
func (zfs *zgokFileSystem) SetSignature(signature Signature) {
	zfs.signature = signature
}

// Get string.
func (zfs *zgokFileSystem) String() string {
	return zfs.Signature().String()
}

// Open the file.
// Implements [net/http.FileSystem.Open]
func (zfs *zgokFileSystem) Open(name string) (http.File, error) {
	path := strings.TrimLeft(name, "/")
	file, err := zfs.GetFile(path)
	if err != nil {
		// Return an abstract directory.
		dir := &zgokFile{
			fileInfo: zgokFileInfo{
				name: filepath.Base(path),
				mode: os.ModeDir | os.ModePerm,
			},
		}
		return dir, nil
	}
	// Set a new file reader
	file.SetNewReader()
	return file, nil
}

// File interface.
type File interface {
	SetFileInfo(fileInfo os.FileInfo)
	FileInfo() os.FileInfo
	SetBytes(content []byte)
	Bytes() []byte
	SetNewReader()
	Close() error                                 // Implements [net/http.File.Close]
	Read(p []byte) (int, error)                   // Implements [net/http.File.Read]
	Readdir(count int) ([]os.FileInfo, error)     // Implements [net/http.File.Readdir]
	Seek(offset int64, whence int) (int64, error) // Implements [net/http.File.Seek]
	Stat() (os.FileInfo, error)                   // Implements [net/http.File.Stat]
}

// Zgok file.
type zgokFile struct {
	fileInfo os.FileInfo
	content  []byte
	reader   *bytes.Reader
}

// Create a new zgok file.
func NewZgokFile() File {
	return &zgokFile{}
}

// Set file info to file.
func (zf *zgokFile) SetFileInfo(fileInfo os.FileInfo) {
	zf.fileInfo = fileInfo
}

// Get file info of file.
func (zf *zgokFile) FileInfo() os.FileInfo {
	return zf.fileInfo
}

// Set bytes to file.
func (zf *zgokFile) SetBytes(content []byte) {
	zf.content = content
}

// Get bytes from file.
func (zf *zgokFile) Bytes() []byte {
	return zf.content
}

// Set a new reader.
func (zf *zgokFile) SetNewReader() {
	reader := bytes.NewReader(zf.content)
	zf.reader = reader
}

// Close file.
// Implements [net/http.File.Close]
func (zf *zgokFile) Close() error {
	return nil
}

// Read file.
// Implements [net/http.File.Read]
func (zf *zgokFile) Read(p []byte) (int, error) {
	return zf.reader.Read(p)
}

// Read directories.
// Implements [net/http.File.Readdir]
func (zf *zgokFile) Readdir(count int) ([]os.FileInfo, error) {
	return nil, errors.New("Readdir is not allowed.")
}

// Seek file.
// Implements [net/http.File.Seek]
func (zf *zgokFile) Seek(offset int64, whence int) (int64, error) {
	return zf.reader.Seek(offset, whence)
}

// Get file info.
// Implements [net/http.File.Stat]
func (zf *zgokFile) Stat() (os.FileInfo, error) {
	return zf.fileInfo, nil
}

// Zgok file info.
// Implements [os.FileInfo]
type zgokFileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
}

// Get name.
// Implements [os.FileInfo.Name]
func (i zgokFileInfo) Name() string {
	return i.name
}

// Get size.
// Implements [os.FileInfo.Size]
func (i zgokFileInfo) Size() int64 {
	return i.size
}

// Get mode.
// Implements [os.FileInfo.Mode]
func (i zgokFileInfo) Mode() os.FileMode {
	return i.mode
}

// Get modified time.
// Implements [os.FileInfo.ModTime]
func (i zgokFileInfo) ModTime() time.Time {
	return i.modTime
}

// Check if it is a directory.
// Implements [os.FileInfo.IsDir]
func (i zgokFileInfo) IsDir() bool {
	return i.mode.IsDir()
}

// Get sys information. (Only returns nil.)
// Implements [os.FileInfo.Sys]
func (i zgokFileInfo) Sys() interface{} {
	return nil
}
<commit_msg>Fix Fixed Paths() function to sort file paths.<commit_after>package zgok

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"time"
)

const (
	APP   = "zgok"
	MAJOR = 0
	MINOR = 0
	REV   = 1
)

// Get version string.
func Version() string {
	return fmt.Sprintf("%s-%d.%d.%d", APP, MAJOR, MINOR, REV)
}

// File system interface.
// Implements [net/http.FileSystem]
type FileSystem interface {
	AddFile(file File)
	GetFile(path string) (File, error)
	ReadFile(path string) ([]byte, error)
	ReadFileString(path string) (string, error)
	Paths() []string
	SubFileSystem(rootPath string) (FileSystem, error)
	Signature() Signature
	SetSignature(signature Signature)
	String() string
	Open(name string) (http.File, error) // Implements [net/http.FileSystem.Open]
}

// Zgok file system.
type zgokFileSystem struct {
	signature Signature
	rootPath  string
	fileMap   map[string]File
}

// Create a new file system.
func NewFileSystem() FileSystem {
	return &zgokFileSystem{
		signature: nil,
		rootPath:  APP,
		fileMap:   make(map[string]File),
	}
}

// Restore file system.
func RestoreFileSystem() (FileSystem, error) {
	// Get bytes of exe file.
	exeBytes, err := ioutil.ReadFile(os.Args[0])
	if err != nil {
		return nil, err
	}
	// Restore signature.
	sigOffset := len(exeBytes) - SIGNATURE_BYTE_SIZE
	sigBytes := exeBytes[sigOffset:]
	signature, err := RestoreSignature(sigBytes)
	if err != nil {
		return nil, err
	}
	// Unzip zip section.
	zipOffset := signature.ExeSize()
	zipBytes := exeBytes[zipOffset:sigOffset]
	unzipper := NewUnzipper(&zipBytes)
	zfs, err := unzipper.Unzip()
	if err != nil {
		return nil, err
	}
	// Set signature.
	zfs.SetSignature(signature)
	return zfs, nil
}

// Add file to file system.
func (zfs *zgokFileSystem) AddFile(file File) {
	key := filepath.ToSlash(file.FileInfo().Name())
	zfs.fileMap[key] = file
}

// Get file from file system.
func (zfs *zgokFileSystem) GetFile(path string) (File, error) {
	key := filepath.ToSlash(filepath.Join(zfs.rootPath, path))
	file, exists := zfs.fileMap[key]
	if !exists {
		return nil, errors.New("File doesn't exist.")
	}
	return file, nil
}

// Get the content of file in bytes from file system.
func (zfs *zgokFileSystem) ReadFile(path string) ([]byte, error) {
	file, err := zfs.GetFile(path)
	if err != nil {
		return []byte{}, nil
	}
	return file.Bytes(), nil
}

// Get the content of file in string from file system.
func (zfs *zgokFileSystem) ReadFileString(path string) (string, error) {
	bytes, err := zfs.ReadFile(path)
	if err != nil {
		return "", nil
	}
	str := string(bytes)
	return str, nil
}

// Get all the paths stored in the file system.
func (zfs *zgokFileSystem) Paths() []string {
	paths := []string{}
	prefix := zfs.rootPath + "/"
	for key := range zfs.fileMap {
		if strings.HasPrefix(key, prefix) {
			relPath := strings.TrimPrefix(key, prefix)
			paths = append(paths, relPath)
		}
	}
	sort.Strings(paths)
	return paths
}

// Get a sub file system.
func (zfs *zgokFileSystem) SubFileSystem(rootPath string) (FileSystem, error) {
	// Check root path.
	if strings.Contains(rootPath, "..") {
		return nil, errors.New("No double dots [..] are allowed in root path.")
	}
	// Initialize sub file system.
	newRootPath := filepath.ToSlash(filepath.Join(zfs.rootPath, rootPath))
	subFs := &zgokFileSystem{
		signature: zfs.signature,
		rootPath:  newRootPath,
		fileMap:   make(map[string]File),
	}
	// Add all the sets matching the new root path.
	for key, value := range zfs.fileMap {
		if key[0:len(newRootPath)] == newRootPath {
			subFs.fileMap[key] = value
		}
	}
	return subFs, nil
}

// Get signature.
func (zfs *zgokFileSystem) Signature() Signature {
	return zfs.signature
}

// Set signature.
func (zfs *zgokFileSystem) SetSignature(signature Signature) {
	zfs.signature = signature
}

// Get string.
func (zfs *zgokFileSystem) String() string {
	return zfs.Signature().String()
}

// Open the file.
// Implements [net/http.FileSystem.Open]
func (zfs *zgokFileSystem) Open(name string) (http.File, error) {
	path := strings.TrimLeft(name, "/")
	file, err := zfs.GetFile(path)
	if err != nil {
		// Return an abstract directory.
		dir := &zgokFile{
			fileInfo: zgokFileInfo{
				name: filepath.Base(path),
				mode: os.ModeDir | os.ModePerm,
			},
		}
		return dir, nil
	}
	// Set a new file reader
	file.SetNewReader()
	return file, nil
}

// File interface.
type File interface {
	SetFileInfo(fileInfo os.FileInfo)
	FileInfo() os.FileInfo
	SetBytes(content []byte)
	Bytes() []byte
	SetNewReader()
	Close() error                                 // Implements [net/http.File.Close]
	Read(p []byte) (int, error)                   // Implements [net/http.File.Read]
	Readdir(count int) ([]os.FileInfo, error)     // Implements [net/http.File.Readdir]
	Seek(offset int64, whence int) (int64, error) // Implements [net/http.File.Seek]
	Stat() (os.FileInfo, error)                   // Implements [net/http.File.Stat]
}

// Zgok file.
type zgokFile struct {
	fileInfo os.FileInfo
	content  []byte
	reader   *bytes.Reader
}

// Create a new zgok file.
func NewZgokFile() File {
	return &zgokFile{}
}

// Set file info to file.
func (zf *zgokFile) SetFileInfo(fileInfo os.FileInfo) {
	zf.fileInfo = fileInfo
}

// Get file info of file.
func (zf *zgokFile) FileInfo() os.FileInfo {
	return zf.fileInfo
}

// Set bytes to file.
func (zf *zgokFile) SetBytes(content []byte) {
	zf.content = content
}

// Get bytes from file.
func (zf *zgokFile) Bytes() []byte {
	return zf.content
}

// Set a new reader.
func (zf *zgokFile) SetNewReader() {
	reader := bytes.NewReader(zf.content)
	zf.reader = reader
}

// Close file.
// Implements [net/http.File.Close]
func (zf *zgokFile) Close() error {
	return nil
}

// Read file.
// Implements [net/http.File.Read]
func (zf *zgokFile) Read(p []byte) (int, error) {
	return zf.reader.Read(p)
}

// Read directories.
// Implements [net/http.File.Readdir]
func (zf *zgokFile) Readdir(count int) ([]os.FileInfo, error) {
	return nil, errors.New("Readdir is not allowed.")
}

// Seek file.
// Implements [net/http.File.Seek]
func (zf *zgokFile) Seek(offset int64, whence int) (int64, error) {
	return zf.reader.Seek(offset, whence)
}

// Get file info.
// Implements [net/http.File.Stat]
func (zf *zgokFile) Stat() (os.FileInfo, error) {
	return zf.fileInfo, nil
}

// Zgok file info.
// Implements [os.FileInfo]
type zgokFileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
}

// Get name.
// Implements [os.FileInfo.Name]
func (i zgokFileInfo) Name() string {
	return i.name
}

// Get size.
// Implements [os.FileInfo.Size]
func (i zgokFileInfo) Size() int64 {
	return i.size
}

// Get mode.
// Implements [os.FileInfo.Mode]
func (i zgokFileInfo) Mode() os.FileMode {
	return i.mode
}

// Get modified time.
// Implements [os.FileInfo.ModTime]
func (i zgokFileInfo) ModTime() time.Time {
	return i.modTime
}

// Check if it is a directory.
// Implements [os.FileInfo.IsDir]
func (i zgokFileInfo) IsDir() bool {
	return i.mode.IsDir()
}

// Get sys information. (Only returns nil.)
// Implements [os.FileInfo.Sys]
func (i zgokFileInfo) Sys() interface{} {
	return nil
}
<|endoftext|>


<commit_before>package arn

// Genre ...
type Genre struct {
	ID        string   `json:"genre"`
	Name      string   `json:"-"`
	AnimeList []*Anime `json:"animeList"`
}

// GetGenre ...
func GetGenre(id string) (*Genre, error) {
	obj, err := DB.Get("Genre", id)

	if err != nil {
		return nil, err
	}

	return obj.(*Genre), nil
}
<commit_msg>Removed Genre<commit_after><|endoftext|>


<commit_before>package token

// This is a simple package for go that generates randomized base62 encoded tokens based on a single integer.
// It's ideal for shorturl services or for semi-secured randomized api primary keys.
//
// How it Works
//
// `Token` is an alias for `uint64`.
// Its `Token.Encode()` method interface returns a `Base62` encoded string based off of the number.
// Its implementation of the `encoding.TextMarshaler` and `encoding.TextUnmarshaler` interfaces encodes and
// decodes the `Token` when its being marshalled or unmarshalled as json or xml.
//
// Basically, the outside world will always address the token as its string equivolent and internally we can
// always be used as an `uint64` for fast, indexed, unique, lookups in various databases.
//
// **IMPORTANT:** Remember to always check for collisions when adding randomized tokens to a database

import (
	"bytes"
	"math"
	"math/rand"
	"time"
)

const (
	// Base62 is a string respresentation of every possible base62 character
	Base62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

	// MaxTokenLength is the largest possible character length of a token
	MaxTokenLength = 10

	// MinTokenLength is the smallest possible character length of a token
	MinTokenLength = 1

	// DefaultTokenLength is the default size of a token
	DefaultTokenLength = 9
)

var (
	base62Len = uint64(len(Base62))
)

// Token is an alias of an uint64 that is marshalled into a base62 encoded token
type Token uint64

// Encode encodes the token into a base62 string
func (t Token) Encode() string {
	bs, _ := t.MarshalText()
	return string(bs)
}

// UnmarshalText implements the `encoding.TextUnmarshaler` interface
func (t *Token) UnmarshalText(data []byte) error {

	number := uint64(0)
	idx := 0.0
	chars := []byte(Base62)

	charsLength := float64(len(chars))
	tokenLength := float64(len(data))

	if tokenLength > MaxTokenLength {
		return ErrTokenTooBig
	} else if tokenLength < MinTokenLength {
		return ErrTokenTooSmall
	}

	for _, c := range data {
		power := tokenLength - (idx + 1)
		index := bytes.IndexByte(chars, c)
		if index < 0 {
			return ErrInvalidCharacter
		}
		number += uint64(index) * uint64(math.Pow(charsLength, power))
		idx++
	}

	// the token was successfully decoded
	*t = Token(number)
	return nil
}

// MarshalText implements the `encoding.TextMarsheler` interface
func (t Token) MarshalText() ([]byte, error) {
	number := uint64(t)
	var chars []byte

	if number == 0 {
		return chars, nil
	}

	for number > 0 {
		result := number / base62Len
		remainder := number % base62Len
		chars = append(chars, Base62[remainder])
		number = result
	}

	for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
		chars[i], chars[j] = chars[j], chars[i]
	}

	return chars, nil
}

// New returns a `Base62` encoded `Token` of *up to* `DefaultTokenLength`
// if you pass in a `tokenLength` between `MinTokenLength` and `MaxTokenLength` this will return
// a `Token` of *up to* that length instead if you pass in a `tokenLength` that is out of range it will panic
func New(tokenLength ...int) Token {

	// calculate the max hash int based on the token length
	var max uint64
	if tokenLength == nil {
		max = maxHashInt(DefaultTokenLength)
	} else if tl := tokenLength[0]; tl < MinTokenLength {
		panic(ErrTokenTooSmall)
	} else if tl > MaxTokenLength {
		panic(ErrTokenTooBig)
	} else {
		max = maxHashInt(tl)
	}

	// generate a psuedo random token
	rand.Seed(time.Now().UTC().UnixNano())
	number := uint64(rand.Int63n(int64(max & math.MaxInt64)))

	return Token(number)
}

// Decode returns a token from a 1-12 character base62 encoded string
func Decode(token string) (Token, error) {
	var t Token
	err := (&t).UnmarshalText([]byte(token))
	return t, err
}

// maxHashInt returns the largest possible int that will yeild a base62 encoded token of the specified length
func maxHashInt(length int) uint64 {
	return uint64(math.Max(0, math.Min(math.MaxUint64, math.Pow(float64(base62Len), float64(length)))))
}
<commit_msg>changed initialization<commit_after>package token

// This is a simple package for go that generates randomized base62 encoded tokens based on a single integer.
// It's ideal for shorturl services or for semi-secured randomized api primary keys.
//
// How it Works
//
// `Token` is an alias for `uint64`.
// Its `Token.Encode()` method interface returns a `Base62` encoded string based off of the number.
// Its implementation of the `encoding.TextMarshaler` and `encoding.TextUnmarshaler` interfaces encodes and
// decodes the `Token` when its being marshalled or unmarshalled as json or xml.
//
// Basically, the outside world will always address the token as its string equivolent and internally we can
// always be used as an `uint64` for fast, indexed, unique, lookups in various databases.
//
// **IMPORTANT:** Remember to always check for collisions when adding randomized tokens to a database

import (
	"bytes"
	"math"
	"math/rand"
	"time"
)

const (
	// Base62 is a string respresentation of every possible base62 character
	Base62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

	// MaxTokenLength is the largest possible character length of a token
	MaxTokenLength = 10

	// MinTokenLength is the smallest possible character length of a token
	MinTokenLength = 1

	// DefaultTokenLength is the default size of a token
	DefaultTokenLength = 9
)

var (
	base62Len = uint64(len(Base62))
)

// init initializes the random number generator
func init() {
	rand.Seed(time.Now().UTC().UnixNano())
}

// Token is an alias of an uint64 that is marshalled into a base62 encoded token
type Token uint64

// Encode encodes the token into a base62 string
func (t Token) Encode() string {
	bs, _ := t.MarshalText()
	return string(bs)
}

// UnmarshalText implements the `encoding.TextUnmarshaler` interface
func (t *Token) UnmarshalText(data []byte) error {

	number := uint64(0)
	idx := 0.0
	chars := []byte(Base62)

	charsLength := float64(len(chars))
	tokenLength := float64(len(data))

	if tokenLength > MaxTokenLength {
		return ErrTokenTooBig
	} else if tokenLength < MinTokenLength {
		return ErrTokenTooSmall
	}

	for _, c := range data {
		power := tokenLength - (idx + 1)
		index := bytes.IndexByte(chars, c)
		if index < 0 {
			return ErrInvalidCharacter
		}
		number += uint64(index) * uint64(math.Pow(charsLength, power))
		idx++
	}

	// the token was successfully decoded
	*t = Token(number)
	return nil
}

// MarshalText implements the `encoding.TextMarsheler` interface
func (t Token) MarshalText() ([]byte, error) {
	number := uint64(t)
	var chars []byte

	if number == 0 {
		return chars, nil
	}

	for number > 0 {
		result := number / base62Len
		remainder := number % base62Len
		chars = append(chars, Base62[remainder])
		number = result
	}

	for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
		chars[i], chars[j] = chars[j], chars[i]
	}

	return chars, nil
}

// New returns a `Base62` encoded `Token` of *up to* `DefaultTokenLength`
// if you pass in a `tokenLength` between `MinTokenLength` and `MaxTokenLength` this will return
// a `Token` of *up to* that length instead if you pass in a `tokenLength` that is out of range it will panic
func New(tokenLength ...int) Token {

	// calculate the max hash int based on the token length
	var max uint64
	if tokenLength == nil {
		max = maxHashInt(DefaultTokenLength)
	} else if tl := tokenLength[0]; tl < MinTokenLength {
		panic(ErrTokenTooSmall)
	} else if tl > MaxTokenLength {
		panic(ErrTokenTooBig)
	} else {
		max = maxHashInt(tl)
	}

	// generate a psuedo random token
	number := uint64(rand.Int63n(int64(max & math.MaxInt64)))

	return Token(number)
}

// Decode returns a token from a 1-12 character base62 encoded string
func Decode(token string) (Token, error) {
	var t Token
	err := (&t).UnmarshalText([]byte(token))
	return t, err
}

// maxHashInt returns the largest possible int that will yeild a base62 encoded token of the specified length
func maxHashInt(length int) uint64 {
	return uint64(math.Max(0, math.Min(math.MaxUint64, math.Pow(float64(base62Len), float64(length)))))
}
<|endoftext|>


<commit_before>package microbrew

import (
  "encoding/json"
)

type Agent struct {
	producer *Producer
}

type MicrobrewAgent interface {
	Init(uri, exchange, exchangeType string) error
}

type Payload struct {
  Event string      `json:"event"`
  Data interface{}  `json:"data"`
}

func (a *Agent) Init(uri, exchange, exchangeType string) error {
	producer := &Producer{}
  err := producer.Init(uri, exchange, exchangeType)
	if err != nil {
		return err
	}

	a.producer = producer

  return nil
}

func (a *Agent) Signal(event string, data interface{}) error {
  payload := &Payload{
    Event: event,
    Data: data,
  }
  marshalled, _ := json.Marshal(payload)

  return a.producer.Publish("", marshalled)
}
<commit_msg>Adds Signal to Agent Interface<commit_after>package microbrew

import (
  "encoding/json"
)

type Agent struct {
	producer *Producer
}

type MicrobrewAgent interface {
	Init(uri, exchange, exchangeType string) error
  Signal(event string, data interface{}) error
}

type Payload struct {
  Event string      `json:"event"`
  Data interface{}  `json:"data"`
}

func (a *Agent) Init(uri, exchange, exchangeType string) error {
	producer := &Producer{}
  err := producer.Init(uri, exchange, exchangeType)
	if err != nil {
		return err
	}

	a.producer = producer

  return nil
}

func (a *Agent) Signal(event string, data interface{}) error {
  payload := &Payload{
    Event: event,
    Data: data,
  }
  marshalled, _ := json.Marshal(payload)

  return a.producer.Publish("", marshalled)
}
<|endoftext|>


<commit_before>package api

import (
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/unversioned"
)

const (
	ResourceKindElastic = "Elastic"
	ResourceNameElastic = "elastic"
	ResourceTypeElastic = "elastics"
)

// Elastic defines a Elasticsearch database.
type Elastic struct {
	unversioned.TypeMeta `json:",inline,omitempty"`
	api.ObjectMeta       `json:"metadata,omitempty"`
	Spec                 ElasticSpec   `json:"spec,omitempty"`
	Status               ElasticStatus `json:"status,omitempty"`
}

type ElasticSpec struct {
	// Version of Elasticsearch to be deployed.
	Version string `json:"version,omitempty"`
	// Number of instances to deploy for a Elasticsearch database.
	Replicas int32 `json:"replicas,omitempty"`
	// Storage spec to specify how storage shall be used.
	Storage *StorageSpec `json:"storage,omitempty"`
	// ServiceAccountName is the name of the ServiceAccount to use to run the
	// Prometheus Pods.
	ServiceAccountName string `json:"serviceAccountName,omitempty"`
	// NodeSelector is a selector which must be true for the pod to fit on a node
	// +optional
	NodeSelector map[string]string `json:"nodeSelector,omitempty"`
	// Init is used to initialize database
	// +optional
	Init *InitSpec `json:"init,omitempty"`
	// BackupSchedule spec to specify how database backup will be taken
	// +optional
	BackupSchedule *BackupScheduleSpec `json:"backupSchedule,omitempty"`
	// If DoNotDelete is true, controller will prevent to delete this Elastic object.
	// Controller will create same Elastic object and ignore other process.
	// +optional
	DoNotDelete bool `json:"doNotDelete,omitempty"`
}

type ElasticStatus struct {
	CreationTime *unversioned.Time `json:"creationTime,omitempty"`
	Phase        DatabasePhase     `json:"phase,omitempty"`
	Reason       string            `json:"reason,omitempty"`
}

type ElasticList struct {
	unversioned.TypeMeta `json:",inline"`
	unversioned.ListMeta `json:"metadata,omitempty"`
	// Items is a list of Elastic TPR objects
	Items []Elastic `json:"items,omitempty"`
}
<commit_msg>Rename ServiceAccountName in ElasticSpec<commit_after>package api

import (
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/unversioned"
)

const (
	ResourceKindElastic = "Elastic"
	ResourceNameElastic = "elastic"
	ResourceTypeElastic = "elastics"
)

// Elastic defines a Elasticsearch database.
type Elastic struct {
	unversioned.TypeMeta `json:",inline,omitempty"`
	api.ObjectMeta       `json:"metadata,omitempty"`
	Spec                 ElasticSpec   `json:"spec,omitempty"`
	Status               ElasticStatus `json:"status,omitempty"`
}

type ElasticSpec struct {
	// Version of Elasticsearch to be deployed.
	Version string `json:"version,omitempty"`
	// Number of instances to deploy for a Elasticsearch database.
	Replicas int32 `json:"replicas,omitempty"`
	// Storage spec to specify how storage shall be used.
	Storage *StorageSpec `json:"storage,omitempty"`
	// GoverningService is the name of Headless Service which is responsible for the network identity
	// of the Prometheus Pods.
	GoverningService string `json:"governingService,omitempty"`
	// NodeSelector is a selector which must be true for the pod to fit on a node
	// +optional
	NodeSelector map[string]string `json:"nodeSelector,omitempty"`
	// Init is used to initialize database
	// +optional
	Init *InitSpec `json:"init,omitempty"`
	// BackupSchedule spec to specify how database backup will be taken
	// +optional
	BackupSchedule *BackupScheduleSpec `json:"backupSchedule,omitempty"`
	// If DoNotDelete is true, controller will prevent to delete this Elastic object.
	// Controller will create same Elastic object and ignore other process.
	// +optional
	DoNotDelete bool `json:"doNotDelete,omitempty"`
}

type ElasticStatus struct {
	CreationTime *unversioned.Time `json:"creationTime,omitempty"`
	Phase        DatabasePhase     `json:"phase,omitempty"`
	Reason       string            `json:"reason,omitempty"`
}

type ElasticList struct {
	unversioned.TypeMeta `json:",inline"`
	unversioned.ListMeta `json:"metadata,omitempty"`
	// Items is a list of Elastic TPR objects
	Items []Elastic `json:"items,omitempty"`
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package sysctl

import (
	"io/ioutil"
	"path"
	"strconv"
	"strings"
)

const (
	sysctlBase = "/proc/sys"
	// VMOvercommitMemory refers to the sysctl variable responsible for defining
	// the memory over-commit policy used by kernel.
	VMOvercommitMemory = "vm/overcommit_memory"
	// VMPanicOnOOM refers to the sysctl variable responsible for defining
	// the OOM behavior used by kernel.
	VMPanicOnOOM = "vm/panic_on_oom"
	// KernelPanic refers to the sysctl variable responsible for defining
	// the timeout after a panic for the kernel to reboot.
	KernelPanic = "kernel/panic"
	// KernelPanicOnOops refers to the sysctl variable responsible for defining
	// the kernel behavior when an oops or BUG is encountered.
	KernelPanicOnOops = "kernel/panic_on_oops"
	// RootMaxKeys refers to the sysctl variable responsible for defining
	// the maximum number of keys that the root user (UID 0 in the root user namespace) may own.
	RootMaxKeys = "kernel/keys/root_maxkeys"
	// RootMaxBytes refers to the sysctl variable responsible for defining
	// the maximum number of bytes of data that the root user (UID 0 in the root user namespace)
	// can hold in the payloads of the keys owned by root.
	RootMaxBytes = "kernel/keys/root_maxbytes"

	// VMOvercommitMemoryAlways represents that kernel performs no memory over-commit handling.
	VMOvercommitMemoryAlways = 1
	// VMPanicOnOOMInvokeOOMKiller represents that kernel calls the oom_killer function when OOM occurs.
	VMPanicOnOOMInvokeOOMKiller = 0

	// KernelPanicOnOopsAlways represents that kernel panics on kernel oops.
	KernelPanicOnOopsAlways = 1
	// KernelPanicRebootTimeout is the timeout seconds after a panic for the kernel to reboot.
	KernelPanicRebootTimeout = 10

	// RootMaxKeysSetting is the maximum number of keys that the root user (UID 0 in the root user namespace) may own.
	// Needed since docker creates a new key per container.
	RootMaxKeysSetting = 1000000
	// RootMaxBytesSetting is the maximum number of bytes of data that the root user (UID 0 in the root user namespace)
	// can hold in the payloads of the keys owned by root.
	// Allocate 25 bytes per key * number of MaxKeys.
	RootMaxBytesSetting = RootMaxKeysSetting * 25
)

// Interface is an injectable interface for running sysctl commands.
type Interface interface {
	// GetSysctl returns the value for the specified sysctl setting
	GetSysctl(sysctl string) (int, error)
	// SetSysctl modifies the specified sysctl flag to the new value
	SetSysctl(sysctl string, newVal int) error
}

// New returns a new Interface for accessing sysctl
func New() Interface {
	return &procSysctl{}
}

// procSysctl implements Interface by reading and writing files under /proc/sys
type procSysctl struct {
}

// GetSysctl returns the value for the specified sysctl setting
func (*procSysctl) GetSysctl(sysctl string) (int, error) {
	data, err := ioutil.ReadFile(path.Join(sysctlBase, sysctl))
	if err != nil {
		return -1, err
	}
	val, err := strconv.Atoi(strings.Trim(string(data), " \n"))
	if err != nil {
		return -1, err
	}
	return val, nil
}

// SetSysctl modifies the specified sysctl flag to the new value
func (*procSysctl) SetSysctl(sysctl string, newVal int) error {
	return ioutil.WriteFile(path.Join(sysctlBase, sysctl), []byte(strconv.Itoa(newVal)), 0640)
}
<commit_msg>Remove ioutil from component-helpers<commit_after>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package sysctl

import (
	"os"
	"path"
	"strconv"
	"strings"
)

const (
	sysctlBase = "/proc/sys"
	// VMOvercommitMemory refers to the sysctl variable responsible for defining
	// the memory over-commit policy used by kernel.
	VMOvercommitMemory = "vm/overcommit_memory"
	// VMPanicOnOOM refers to the sysctl variable responsible for defining
	// the OOM behavior used by kernel.
	VMPanicOnOOM = "vm/panic_on_oom"
	// KernelPanic refers to the sysctl variable responsible for defining
	// the timeout after a panic for the kernel to reboot.
	KernelPanic = "kernel/panic"
	// KernelPanicOnOops refers to the sysctl variable responsible for defining
	// the kernel behavior when an oops or BUG is encountered.
	KernelPanicOnOops = "kernel/panic_on_oops"
	// RootMaxKeys refers to the sysctl variable responsible for defining
	// the maximum number of keys that the root user (UID 0 in the root user namespace) may own.
	RootMaxKeys = "kernel/keys/root_maxkeys"
	// RootMaxBytes refers to the sysctl variable responsible for defining
	// the maximum number of bytes of data that the root user (UID 0 in the root user namespace)
	// can hold in the payloads of the keys owned by root.
	RootMaxBytes = "kernel/keys/root_maxbytes"

	// VMOvercommitMemoryAlways represents that kernel performs no memory over-commit handling.
	VMOvercommitMemoryAlways = 1
	// VMPanicOnOOMInvokeOOMKiller represents that kernel calls the oom_killer function when OOM occurs.
	VMPanicOnOOMInvokeOOMKiller = 0

	// KernelPanicOnOopsAlways represents that kernel panics on kernel oops.
	KernelPanicOnOopsAlways = 1
	// KernelPanicRebootTimeout is the timeout seconds after a panic for the kernel to reboot.
	KernelPanicRebootTimeout = 10

	// RootMaxKeysSetting is the maximum number of keys that the root user (UID 0 in the root user namespace) may own.
	// Needed since docker creates a new key per container.
	RootMaxKeysSetting = 1000000
	// RootMaxBytesSetting is the maximum number of bytes of data that the root user (UID 0 in the root user namespace)
	// can hold in the payloads of the keys owned by root.
	// Allocate 25 bytes per key * number of MaxKeys.
	RootMaxBytesSetting = RootMaxKeysSetting * 25
)

// Interface is an injectable interface for running sysctl commands.
type Interface interface {
	// GetSysctl returns the value for the specified sysctl setting
	GetSysctl(sysctl string) (int, error)
	// SetSysctl modifies the specified sysctl flag to the new value
	SetSysctl(sysctl string, newVal int) error
}

// New returns a new Interface for accessing sysctl
func New() Interface {
	return &procSysctl{}
}

// procSysctl implements Interface by reading and writing files under /proc/sys
type procSysctl struct {
}

// GetSysctl returns the value for the specified sysctl setting
func (*procSysctl) GetSysctl(sysctl string) (int, error) {
	data, err := os.ReadFile(path.Join(sysctlBase, sysctl))
	if err != nil {
		return -1, err
	}
	val, err := strconv.Atoi(strings.Trim(string(data), " \n"))
	if err != nil {
		return -1, err
	}
	return val, nil
}

// SetSysctl modifies the specified sysctl flag to the new value
func (*procSysctl) SetSysctl(sysctl string, newVal int) error {
	return os.WriteFile(path.Join(sysctlBase, sysctl), []byte(strconv.Itoa(newVal)), 0640)
}
<|endoftext|>


<commit_before>package handlers

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/dom-bot/itchy-guacamole/deck"
	"github.com/dom-bot/itchy-guacamole/score"
	"github.com/dom-bot/itchy-guacamole/veto"
	"github.com/julienschmidt/httprouter"
)

var (
	rnd           = rand.New(rand.NewSource(time.Now().UnixNano()))
	availableSets deck.Sets
)

type makeDeckRequest struct {
	Sets            []deck.Set        `json:"sets"`
	MaxSetCount     uint              `json:"max_set_count"`
	Weights         score.Weights     `json:"weights"`
	VetoProbability *veto.Probability `json:"veto_probability,omitempty"`
}

type deckHardware struct {
	CoinTokens         bool `json:"coin_tokens"`
	VictoryTokens      bool `json:"victory_tokens"`
	MinusOneCardTokens bool `json:"minus_one_card_tokens"`
	MinusOneCoinTokens bool `json:"minus_one_coin_tokens"`
	JourneyTokens      bool `json:"journey_tokens"`
	TavernMats         bool `json:"tavern_mats"`
	TradeRouteMats     bool `json:"trade_route_mats"`
	NativeVillageMats  bool `json:"native_village_mats"`
}

type deckResponse struct {
	ID                   string       `json:"id"`
	Cards                []deck.Card  `json:"cards"`
	Events               []deck.Card  `json:"events"`
	ColoniesAndPlatinums bool         `json:"colonies_and_platinums"`
	Shelters             bool         `json:"shelters"`
	Potions              bool         `json:"potions"`
	Spoils               bool         `json:"spoils"`
	Ruins                bool         `json:"ruins"`
	Hardware             deckHardware `json:"hardware"`
}

func init() {
	setString := os.Getenv("SETS")
	if setString == "" {
		availableSets.Add(deck.Dominion)
	} else {
		exps := strings.Split(setString, `,`)

		for _, exp := range exps {
			availableSets.Add(deck.Set(exp))
		}
	}

	fmt.Printf("Using Sets: %+v\n", availableSets)
}

func getSets(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	sets := make([]string, 0, 10)

	setString := os.Getenv("SETS")
	if setString == "" {
		sets = append(sets, string(deck.Dominion))

	} else {
		sets = strings.Split(setString, `,`)
	}

	enc := json.NewEncoder(w)
	_ = enc.Encode(sets)

	w.Header().Set("Content-Type", "application/json")
}

func getDeck(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	idBase64 := ps.ByName("id")
	if idBase64 == "" {
		http.Error(w, "missing 'id'", http.StatusBadRequest)
		return
	}

	id, err := base64.URLEncoding.DecodeString(idBase64)
	if idBase64 == "" {
		http.Error(w, fmt.Sprintf("unable to decode ID: %s", err), http.StatusBadRequest)
		return
	}

	d, err := deck.NewDeckFromID(id)
	if idBase64 == "" {
		http.Error(w, fmt.Sprintf("unable to deserialize ID: %s", err), http.StatusBadRequest)
		return
	}

	resp := deckResponse{
		ID:                   base64.URLEncoding.EncodeToString(d.ID()),
		Cards:                d.Cards,
		Events:               d.Events,
		ColoniesAndPlatinums: d.ColoniesAndPlatinums,
		Shelters:             d.Shelters,
		Potions:              d.Potions(),
		Spoils:               d.Spoils(),
		Ruins:                d.Ruins(),
		Hardware: deckHardware{
			CoinTokens:         d.CoinTokens(),
			VictoryTokens:      d.VictoryTokens(),
			MinusOneCardTokens: d.MinusOneCardTokens(),
			MinusOneCoinTokens: d.MinusOneCoinTokens(),
			JourneyTokens:      d.JourneyTokens(),
			TavernMats:         d.TavernMats(),
			TradeRouteMats:     d.TradeRouteMats(),
			NativeVillageMats:  d.NativeVillageMats(),
		},
	}
	enc := json.NewEncoder(w)
	_ = enc.Encode(resp)

	w.Header().Set("Content-Type", "application/json")
}

func makeDeck(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var (
		sets            = availableSets
		requestedSets   deck.Sets
		vetoProbability veto.Probability
		req             makeDeckRequest
		maxSetCount     uint
		maxScore        uint
		d               deck.Deck
	)

	decoder := json.NewDecoder(r.Body)
	err := decoder.Decode(&req)
	if err != nil {
		http.Error(w, fmt.Sprintf("Error decoding JSON body: %s", err), http.StatusBadRequest)
		return
	}
	log.Printf("makeDeck(%+v)\n", req)

	for _, set := range req.Sets {
		requestedSets.Add(set)
	}
	if !requestedSets.Empty() {
		sets.Intersect(requestedSets)
	}
	if sets.Empty() {
		http.Error(w, "Can't generate a deck from no sets", http.StatusBadRequest)
		return
	}

	maxSetCount = req.MaxSetCount
	if maxSetCount == 0 {
		maxSetCount = 2
	}

	if req.VetoProbability == nil || (req.VetoProbability == &veto.Probability{}) {
		log.Println("Using default veto probs")
		// Defaults
		vetoProbability = veto.Probability{
			WhenTooExpensive:     0.90,
			WhenNoTrashing:       0.70,
			WhenTooManyMechanics: 0.85,
			WhenTooManyAttacks:   0.85,
		}
	} else {
		vetoProbability = *req.VetoProbability
	}

	decks := make([]deck.Deck, 0, 1000)
	count := 0
GenerateDeck:
	candidateDeck := deck.NewRandomDeck(maxSetCount, sets)
	if veto.TooExpensive(vetoProbability, candidateDeck) {
		goto GenerateDeck
	}
	if veto.NoTrashing(vetoProbability, candidateDeck) {
		goto GenerateDeck
	}
	if veto.TooManyMechanics(vetoProbability, candidateDeck) {
		goto GenerateDeck
	}
	if veto.TooManyAttacks(vetoProbability, candidateDeck) {
		goto GenerateDeck
	}
	count++

	decks = append(decks, candidateDeck)
	if len(decks) < cap(decks) {
		goto GenerateDeck
	}

	var totalCards uint
	cardCounts := make(map[deck.Card]uint, len(deck.Cards))
	for _, deck := range decks {
		for _, card := range deck.Cards {
			cardCounts[card]++
			totalCards++
		}
		for _, card := range deck.Events {
			cardCounts[card]++
			totalCards++
		}
	}
	cardProbs := make(map[deck.Card]float64, len(cardCounts))
	for card, count := range cardCounts {
		cardProbs[card] = float64(count) / float64(totalCards)
	}

	for _, candidateDeck := range decks {
		candidateScore := score.Evaluate(req.Weights, candidateDeck, cardProbs)
		if candidateScore > maxScore {
			d = candidateDeck
			maxScore = candidateScore
		}
	}

	resp := deckResponse{
		ID:                   base64.URLEncoding.EncodeToString(d.ID()),
		Cards:                d.Cards,
		Events:               d.Events,
		ColoniesAndPlatinums: d.ColoniesAndPlatinums,
		Shelters:             d.Shelters,
		Potions:              d.Potions(),
		Spoils:               d.Spoils(),
		Ruins:                d.Ruins(),
		Hardware: deckHardware{
			CoinTokens:         d.CoinTokens(),
			VictoryTokens:      d.VictoryTokens(),
			MinusOneCardTokens: d.MinusOneCardTokens(),
			MinusOneCoinTokens: d.MinusOneCoinTokens(),
			JourneyTokens:      d.JourneyTokens(),
			TavernMats:         d.TavernMats(),
			TradeRouteMats:     d.TradeRouteMats(),
			NativeVillageMats:  d.NativeVillageMats(),
		},
	}
	enc := json.NewEncoder(w)
	_ = enc.Encode(resp)

	w.Header().Set("Content-Type", "application/json")
}

func indexRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	contents, err := ioutil.ReadFile("app/public/index.html")
	if err != nil {
		log.Println(err)
	}

	fmt.Fprint(w, string(contents))
}
<commit_msg>Default to '5' across the board<commit_after>package handlers

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/dom-bot/itchy-guacamole/deck"
	"github.com/dom-bot/itchy-guacamole/score"
	"github.com/dom-bot/itchy-guacamole/veto"
	"github.com/julienschmidt/httprouter"
)

var (
	rnd           = rand.New(rand.NewSource(time.Now().UnixNano()))
	availableSets deck.Sets
)

type makeDeckRequest struct {
	Sets            []deck.Set        `json:"sets"`
	MaxSetCount     uint              `json:"max_set_count"`
	Weights         score.Weights     `json:"weights"`
	VetoProbability *veto.Probability `json:"veto_probability,omitempty"`
}

type deckHardware struct {
	CoinTokens         bool `json:"coin_tokens"`
	VictoryTokens      bool `json:"victory_tokens"`
	MinusOneCardTokens bool `json:"minus_one_card_tokens"`
	MinusOneCoinTokens bool `json:"minus_one_coin_tokens"`
	JourneyTokens      bool `json:"journey_tokens"`
	TavernMats         bool `json:"tavern_mats"`
	TradeRouteMats     bool `json:"trade_route_mats"`
	NativeVillageMats  bool `json:"native_village_mats"`
}

type deckResponse struct {
	ID                   string       `json:"id"`
	Cards                []deck.Card  `json:"cards"`
	Events               []deck.Card  `json:"events"`
	ColoniesAndPlatinums bool         `json:"colonies_and_platinums"`
	Shelters             bool         `json:"shelters"`
	Potions              bool         `json:"potions"`
	Spoils               bool         `json:"spoils"`
	Ruins                bool         `json:"ruins"`
	Hardware             deckHardware `json:"hardware"`
}

func init() {
	setString := os.Getenv("SETS")
	if setString == "" {
		availableSets.Add(deck.Dominion)
	} else {
		exps := strings.Split(setString, `,`)

		for _, exp := range exps {
			availableSets.Add(deck.Set(exp))
		}
	}

	fmt.Printf("Using Sets: %+v\n", availableSets)
}

func getSets(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	sets := make([]string, 0, 10)

	setString := os.Getenv("SETS")
	if setString == "" {
		sets = append(sets, string(deck.Dominion))

	} else {
		sets = strings.Split(setString, `,`)
	}

	enc := json.NewEncoder(w)
	_ = enc.Encode(sets)

	w.Header().Set("Content-Type", "application/json")
}

func getDeck(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	idBase64 := ps.ByName("id")
	if idBase64 == "" {
		http.Error(w, "missing 'id'", http.StatusBadRequest)
		return
	}

	id, err := base64.URLEncoding.DecodeString(idBase64)
	if idBase64 == "" {
		http.Error(w, fmt.Sprintf("unable to decode ID: %s", err), http.StatusBadRequest)
		return
	}

	d, err := deck.NewDeckFromID(id)
	if idBase64 == "" {
		http.Error(w, fmt.Sprintf("unable to deserialize ID: %s", err), http.StatusBadRequest)
		return
	}

	resp := deckResponse{
		ID:                   base64.URLEncoding.EncodeToString(d.ID()),
		Cards:                d.Cards,
		Events:               d.Events,
		ColoniesAndPlatinums: d.ColoniesAndPlatinums,
		Shelters:             d.Shelters,
		Potions:              d.Potions(),
		Spoils:               d.Spoils(),
		Ruins:                d.Ruins(),
		Hardware: deckHardware{
			CoinTokens:         d.CoinTokens(),
			VictoryTokens:      d.VictoryTokens(),
			MinusOneCardTokens: d.MinusOneCardTokens(),
			MinusOneCoinTokens: d.MinusOneCoinTokens(),
			JourneyTokens:      d.JourneyTokens(),
			TavernMats:         d.TavernMats(),
			TradeRouteMats:     d.TradeRouteMats(),
			NativeVillageMats:  d.NativeVillageMats(),
		},
	}
	enc := json.NewEncoder(w)
	_ = enc.Encode(resp)

	w.Header().Set("Content-Type", "application/json")
}

func makeDeck(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var (
		sets            = availableSets
		requestedSets   deck.Sets
		vetoProbability veto.Probability
		weights         score.Weights
		req             makeDeckRequest
		maxSetCount     uint
		maxScore        uint
		d               deck.Deck
	)

	decoder := json.NewDecoder(r.Body)
	err := decoder.Decode(&req)
	if err != nil {
		http.Error(w, fmt.Sprintf("Error decoding JSON body: %s", err), http.StatusBadRequest)
		return
	}
	log.Printf("makeDeck(%+v)\n", req)

	for _, set := range req.Sets {
		requestedSets.Add(set)
	}
	if !requestedSets.Empty() {
		sets.Intersect(requestedSets)
	}
	if sets.Empty() {
		http.Error(w, "Can't generate a deck from no sets", http.StatusBadRequest)
		return
	}

	maxSetCount = req.MaxSetCount
	if maxSetCount == 0 {
		maxSetCount = 2
	}

	if req.VetoProbability == nil || (req.VetoProbability == &veto.Probability{}) {
		log.Println("Using default veto probs")
		// Defaults
		vetoProbability = veto.Probability{
			WhenTooExpensive:     0.90,
			WhenNoTrashing:       0.70,
			WhenTooManyMechanics: 0.85,
			WhenTooManyAttacks:   0.85,
		}
	} else {
		vetoProbability = *req.VetoProbability
	}

	weights = req.Weights
	// Defaults
	if weights.Trashing == 0 {
		weights.Trashing = 5
	}
	if weights.Random == 0 {
		weights.Random = 5
	}
	if weights.Chaining == 0 {
		weights.Chaining = 5
	}
	if weights.CostSpread == 0 {
		weights.CostSpread = 5
	}
	if weights.SetCount == 0 {
		weights.SetCount = 5
	}
	if weights.MechanicCount == 0 {
		weights.MechanicCount = 5
	}
	if weights.Novelty == 0 {
		weights.Novelty = 5
	}

	decks := make([]deck.Deck, 0, 1000)
	count := 0
GenerateDeck:
	candidateDeck := deck.NewRandomDeck(maxSetCount, sets)
	if veto.TooExpensive(vetoProbability, candidateDeck) {
		goto GenerateDeck
	}
	if veto.NoTrashing(vetoProbability, candidateDeck) {
		goto GenerateDeck
	}
	if veto.TooManyMechanics(vetoProbability, candidateDeck) {
		goto GenerateDeck
	}
	if veto.TooManyAttacks(vetoProbability, candidateDeck) {
		goto GenerateDeck
	}
	count++

	decks = append(decks, candidateDeck)
	if len(decks) < cap(decks) {
		goto GenerateDeck
	}

	var totalCards uint
	cardCounts := make(map[deck.Card]uint, len(deck.Cards))
	for _, deck := range decks {
		for _, card := range deck.Cards {
			cardCounts[card]++
			totalCards++
		}
		for _, card := range deck.Events {
			cardCounts[card]++
			totalCards++
		}
	}
	cardProbs := make(map[deck.Card]float64, len(cardCounts))
	for card, count := range cardCounts {
		cardProbs[card] = float64(count) / float64(totalCards)
	}

	for _, candidateDeck := range decks {
		candidateScore := score.Evaluate(weights, candidateDeck, cardProbs)
		if candidateScore > maxScore {
			d = candidateDeck
			maxScore = candidateScore
		}
	}

	resp := deckResponse{
		ID:                   base64.URLEncoding.EncodeToString(d.ID()),
		Cards:                d.Cards,
		Events:               d.Events,
		ColoniesAndPlatinums: d.ColoniesAndPlatinums,
		Shelters:             d.Shelters,
		Potions:              d.Potions(),
		Spoils:               d.Spoils(),
		Ruins:                d.Ruins(),
		Hardware: deckHardware{
			CoinTokens:         d.CoinTokens(),
			VictoryTokens:      d.VictoryTokens(),
			MinusOneCardTokens: d.MinusOneCardTokens(),
			MinusOneCoinTokens: d.MinusOneCoinTokens(),
			JourneyTokens:      d.JourneyTokens(),
			TavernMats:         d.TavernMats(),
			TradeRouteMats:     d.TradeRouteMats(),
			NativeVillageMats:  d.NativeVillageMats(),
		},
	}
	enc := json.NewEncoder(w)
	_ = enc.Encode(resp)

	w.Header().Set("Content-Type", "application/json")
}

func indexRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	contents, err := ioutil.ReadFile("app/public/index.html")
	if err != nil {
		log.Println(err)
	}

	fmt.Fprint(w, string(contents))
}
<|endoftext|>


<commit_before>package pop

import (
	"fmt"
	stdlog "log"
	"os"

	"github.com/fatih/color"
	"github.com/gobuffalo/pop/logging"
)

type logger func(lvl logging.Level, s string, args ...interface{})
type legacyLogger func(s string, args ...interface{})

// Debug mode, to toggle verbose log traces
var Debug = false

// Color mode, to toggle colored logs
var Color = true

var log logger

var defaultStdLogger = stdlog.New(os.Stdout, "[POP] ", stdlog.LstdFlags)
var defaultLogger = func(lvl logging.Level, s string, args ...interface{}) {
	// Handle legacy logger
	if Log != nil {
		fmt.Println("Warning: Log is deprecated, and will be removed in a future version. Please use SetLogger instead.")
		Log(s, args...)
		return
	}
	if !Debug && lvl > logging.Debug {
		return
	}
	if lvl == logging.SQL {
		if len(args) > 0 {
			xargs := make([]string, len(args))
			for i, a := range args {
				switch a.(type) {
				case string:
					xargs[i] = fmt.Sprintf("%q", a)
				default:
					xargs[i] = fmt.Sprintf("%v", a)
				}
			}
			s = fmt.Sprintf("%s - %s | %s", lvl, s, xargs)
		} else {
			s = fmt.Sprintf("%s - %s", lvl, s)
		}
	} else {
		s = fmt.Sprintf(s, args...)
		s = fmt.Sprintf("%s - %s", lvl, s)
	}
	if Color {
		s = color.YellowString(s)
	}
	defaultStdLogger.Println(s)
}

// SetLogger overrides the default logger.
//
// The logger must implement the following interface:
// type logger func(lvl logging.Level, s string, args ...interface{})
func SetLogger(l logger) {
	log = l
}

// Log defines the pop logger. Override it to customize pop logs handling.
// Deprecated: use SetLogger instead
var Log legacyLogger
<commit_msg>Fix bad log filtering with default logger (#233)<commit_after>package pop

import (
	"fmt"
	stdlog "log"
	"os"

	"github.com/fatih/color"
	"github.com/gobuffalo/pop/logging"
)

type logger func(lvl logging.Level, s string, args ...interface{})
type legacyLogger func(s string, args ...interface{})

// Debug mode, to toggle verbose log traces
var Debug = false

// Color mode, to toggle colored logs
var Color = true

var log logger

var defaultStdLogger = stdlog.New(os.Stdout, "[POP] ", stdlog.LstdFlags)
var defaultLogger = func(lvl logging.Level, s string, args ...interface{}) {
	// Handle legacy logger
	if Log != nil {
		fmt.Println("Warning: Log is deprecated, and will be removed in a future version. Please use SetLogger instead.")
		Log(s, args...)
		return
	}
	if !Debug && lvl <= logging.Debug {
		return
	}
	if lvl == logging.SQL {
		if len(args) > 0 {
			xargs := make([]string, len(args))
			for i, a := range args {
				switch a.(type) {
				case string:
					xargs[i] = fmt.Sprintf("%q", a)
				default:
					xargs[i] = fmt.Sprintf("%v", a)
				}
			}
			s = fmt.Sprintf("%s - %s | %s", lvl, s, xargs)
		} else {
			s = fmt.Sprintf("%s - %s", lvl, s)
		}
	} else {
		s = fmt.Sprintf(s, args...)
		s = fmt.Sprintf("%s - %s", lvl, s)
	}
	if Color {
		s = color.YellowString(s)
	}
	defaultStdLogger.Println(s)
}

// SetLogger overrides the default logger.
//
// The logger must implement the following interface:
// type logger func(lvl logging.Level, s string, args ...interface{})
func SetLogger(l logger) {
	log = l
}

// Log defines the pop logger. Override it to customize pop logs handling.
// Deprecated: use SetLogger instead
var Log legacyLogger
<|endoftext|>


<commit_before>// Copyright 2013 Marc Weistroff. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package log

import (
	"fmt"
	"sync"
)

// A logger will log records transformed by the default processors to a collection of handlers
type Logger struct {
	mu         sync.Mutex
	Name       string
	handlers   []HandlerInterface
	processors []Processor
}

// Instanciates a new logger with specified name, handlers and processors
func NewLogger(name string) *Logger {
	return &Logger{Name: name, handlers: []HandlerInterface{}, processors: []Processor{}}
}

// Push a handler to the handlers stack
func (l *Logger) PushHandler(h HandlerInterface) {
	l.mu.Lock()
	defer l.mu.Unlock()
	handlers := make([]HandlerInterface, len(l.handlers))
	copy(handlers, l.handlers)

	l.handlers = []HandlerInterface{h}
	l.handlers = append(l.handlers, handlers...)
}

// Pop a handler from the handlers stack
func (l *Logger) PopHandler() {
	l.mu.Lock()
	defer l.mu.Unlock()
	if len(l.handlers) > 0 {
		l.handlers = l.handlers[1:len(l.handlers)]
		return
	}

	panic("Handlers stack is empty")
}

// Push a processor to the processor stack
func (l *Logger) PushProcessor(p Processor) {
	l.mu.Lock()
	defer l.mu.Unlock()
	processors := make([]Processor, len(l.processors))
	copy(processors, l.processors)

	l.processors = []Processor{p}
	l.processors = append(l.processors, processors...)
}

// Pop a processor from the processor stack
func (l *Logger) PopProcessor() {
	l.mu.Lock()
	defer l.mu.Unlock()
	if len(l.processors) > 0 {
		l.processors = l.processors[1:len(l.processors)]
		return
	}

	panic("Processors stack is empty")
}

// Log string with specified severity
func (l *Logger) AddRecord(level Severity, message string, context interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	r := newRecord(level, l.Name, message, context)

	if !l.S(level) {
		return
	}

	for k := range l.processors {
		l.processors[k].Process(r)
	}

	for k := range l.handlers {
		if l.handlers[k].S(level) {
			l.handlers[k].Handle(*r)
		}
	}
}

// Log string with the DEBUG level
func (l *Logger) AddDebug(message string, context interface{}) {
	l.AddRecord(DEBUG, message, context)
}

// Log string with the INFO level
func (l *Logger) AddInfo(message string, context interface{}) {
	l.AddRecord(INFO, message, context)
}

// Log string with the NOTICE level
func (l *Logger) AddNotice(message string, context interface{}) {
	l.AddRecord(NOTICE, message, context)
}

// Log string with the WARNING level
func (l *Logger) AddWarning(message string, context interface{}) {
	l.AddRecord(WARNING, message, context)
}

// Log string with the ERROR level
func (l *Logger) AddError(message string, context interface{}) {
	l.AddRecord(ERROR, message, context)
}

// Log string with the CRITICAL level
func (l *Logger) AddCritical(message string, context interface{}) {
	l.AddRecord(CRITICAL, message, context)
}

// Log string with the ALERT level
func (l *Logger) AddAlert(message string, context interface{}) {
	l.AddRecord(ALERT, message, context)
}

// Log string with the EMERGENCY level
func (l *Logger) AddEmergency(message string, context interface{}) {
	l.AddRecord(EMERGENCY, message, context)
}

// Log parameters with the DEBUG level
func (l *Logger) Debug(v ...interface{}) {
	l.AddDebug(fmt.Sprint(v...), nil)
}

// Log parameters with the INFO level
func (l *Logger) Info(v ...interface{}) {
	l.AddInfo(fmt.Sprint(v...), nil)
}

// Log parameters with the NOTICE level
func (l *Logger) Notice(v ...interface{}) {
	l.AddNotice(fmt.Sprint(v...), nil)
}

// Log parameters with the WARNING level
func (l *Logger) Warning(v ...interface{}) {
	l.AddWarning(fmt.Sprint(v...), nil)
}

// Log parameters with the ERROR level
func (l *Logger) Error(v ...interface{}) {
	l.AddError(fmt.Sprint(v...), nil)
}

// Log parameters with the CRITICAL level
func (l *Logger) Critical(v ...interface{}) {
	l.AddCritical(fmt.Sprint(v...), nil)
}

// Log parameters with the ALERT level
func (l *Logger) Alert(v ...interface{}) {
	l.AddAlert(fmt.Sprint(v...), nil)
}

// Log parameters with the EMERGENCY level
func (l *Logger) Emergency(v ...interface{}) {
	l.AddEmergency(fmt.Sprint(v...), nil)
}

// Returns true if a Handler can handle this severity level
func (l *Logger) S(level Severity) bool {
	for k := range l.handlers {
		if l.handlers[k].S(level) {
			return true
		}
	}

	return false
}
<commit_msg>Add fmt-like methods to logger<commit_after>// Copyright 2013 Marc Weistroff. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package log

import (
	"fmt"
	"sync"
)

// A logger will log records transformed by the default processors to a collection of handlers
type Logger struct {
	mu         sync.Mutex
	Name       string
	handlers   []HandlerInterface
	processors []Processor
}

// Instanciates a new logger with specified name, handlers and processors
func NewLogger(name string) *Logger {
	return &Logger{Name: name, handlers: []HandlerInterface{}, processors: []Processor{}}
}

// Push a handler to the handlers stack
func (l *Logger) PushHandler(h HandlerInterface) {
	l.mu.Lock()
	defer l.mu.Unlock()
	handlers := make([]HandlerInterface, len(l.handlers))
	copy(handlers, l.handlers)

	l.handlers = []HandlerInterface{h}
	l.handlers = append(l.handlers, handlers...)
}

// Pop a handler from the handlers stack
func (l *Logger) PopHandler() {
	l.mu.Lock()
	defer l.mu.Unlock()
	if len(l.handlers) > 0 {
		l.handlers = l.handlers[1:len(l.handlers)]
		return
	}

	panic("Handlers stack is empty")
}

// Push a processor to the processor stack
func (l *Logger) PushProcessor(p Processor) {
	l.mu.Lock()
	defer l.mu.Unlock()
	processors := make([]Processor, len(l.processors))
	copy(processors, l.processors)

	l.processors = []Processor{p}
	l.processors = append(l.processors, processors...)
}

// Pop a processor from the processor stack
func (l *Logger) PopProcessor() {
	l.mu.Lock()
	defer l.mu.Unlock()
	if len(l.processors) > 0 {
		l.processors = l.processors[1:len(l.processors)]
		return
	}

	panic("Processors stack is empty")
}

// Log string with specified severity
func (l *Logger) AddRecord(level Severity, message string, context interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	r := newRecord(level, l.Name, message, context)

	if !l.S(level) {
		return
	}

	for k := range l.processors {
		l.processors[k].Process(r)
	}

	for k := range l.handlers {
		if l.handlers[k].S(level) {
			l.handlers[k].Handle(*r)
		}
	}
}

// Log string with the DEBUG level
func (l *Logger) AddDebug(message string, context interface{}) {
	l.AddRecord(DEBUG, message, context)
}

// Log string with the INFO level
func (l *Logger) AddInfo(message string, context interface{}) {
	l.AddRecord(INFO, message, context)
}

// Log string with the NOTICE level
func (l *Logger) AddNotice(message string, context interface{}) {
	l.AddRecord(NOTICE, message, context)
}

// Log string with the WARNING level
func (l *Logger) AddWarning(message string, context interface{}) {
	l.AddRecord(WARNING, message, context)
}

// Log string with the ERROR level
func (l *Logger) AddError(message string, context interface{}) {
	l.AddRecord(ERROR, message, context)
}

// Log string with the CRITICAL level
func (l *Logger) AddCritical(message string, context interface{}) {
	l.AddRecord(CRITICAL, message, context)
}

// Log string with the ALERT level
func (l *Logger) AddAlert(message string, context interface{}) {
	l.AddRecord(ALERT, message, context)
}

// Log string with the EMERGENCY level
func (l *Logger) AddEmergency(message string, context interface{}) {
	l.AddRecord(EMERGENCY, message, context)
}

// Log parameters with the DEBUG level
func (l *Logger) Debug(v ...interface{}) {
	l.AddDebug(fmt.Sprint(v...), nil)
}

func (l *Logger) Debugf(format string, v ...interface{}) {
	l.AddDebug(fmt.Sprintf(format, v...), nil)
}

func (l *Logger) Debugln(v ...interface{}) {
	l.AddDebug(fmt.Sprintln(v...), nil)
}

// Log parameters with the INFO level
func (l *Logger) Info(v ...interface{}) {
	l.AddInfo(fmt.Sprint(v...), nil)
}

func (l *Logger) Infof(format string, v ...interface{}) {
	l.AddInfo(fmt.Sprintf(format, v...), nil)
}

func (l *Logger) Infoln(v ...interface{}) {
	l.AddInfo(fmt.Sprintln(v...), nil)
}

// Log parameters with the NOTICE level
func (l *Logger) Notice(v ...interface{}) {
	l.AddNotice(fmt.Sprint(v...), nil)
}

func (l *Logger) Noticef(format string, v ...interface{}) {
	l.AddNotice(fmt.Sprintf(format, v...), nil)
}

func (l *Logger) Noticeln(v ...interface{}) {
	l.AddNotice(fmt.Sprintln(v...), nil)
}

// Log parameters with the WARNING level
func (l *Logger) Warning(v ...interface{}) {
	l.AddWarning(fmt.Sprint(v...), nil)
}

func (l *Logger) Warningf(format string, v ...interface{}) {
	l.AddWarning(fmt.Sprintf(format, v...), nil)
}

func (l *Logger) Warningln(v ...interface{}) {
	l.AddWarning(fmt.Sprintln(v...), nil)
}

// Log parameters with the ERROR level
func (l *Logger) Error(v ...interface{}) {
	l.AddError(fmt.Sprint(v...), nil)
}

func (l *Logger) Errorf(format string, v ...interface{}) {
	l.AddError(fmt.Sprintf(format, v...), nil)
}

func (l *Logger) Errorln(v ...interface{}) {
	l.AddError(fmt.Sprintln(v...), nil)
}

// Log parameters with the CRITICAL level
func (l *Logger) Critical(v ...interface{}) {
	l.AddCritical(fmt.Sprint(v...), nil)
}

func (l *Logger) Criticalf(format string, v ...interface{}) {
	l.AddCritical(fmt.Sprintf(format, v...), nil)
}

func (l *Logger) Criticalln(v ...interface{}) {
	l.AddCritical(fmt.Sprintln(v...), nil)
}

// Log parameters with the ALERT level
func (l *Logger) Alert(v ...interface{}) {
	l.AddAlert(fmt.Sprint(v...), nil)
}

func (l *Logger) Alertf(format string, v ...interface{}) {
	l.AddAlert(fmt.Sprintf(format, v...), nil)
}

func (l *Logger) Alertln(v ...interface{}) {
	l.AddAlert(fmt.Sprintln(v...), nil)
}

// Log parameters with the EMERGENCY level
func (l *Logger) Emergency(v ...interface{}) {
	l.AddEmergency(fmt.Sprint(v...), nil)
}

func (l *Logger) Emergencyf(format string, v ...interface{}) {
	l.AddEmergency(fmt.Sprintf(format, v...), nil)
}

func (l *Logger) Emergencyln(v ...interface{}) {
	l.AddEmergency(fmt.Sprintln(v...), nil)
}

// Returns true if a Handler can handle this severity level
func (l *Logger) S(level Severity) bool {
	for k := range l.handlers {
		if l.handlers[k].S(level) {
			return true
		}
	}

	return false
}
<|endoftext|>


<commit_before>package dst

import (
	//"fmt"
	"log"
	"net/http"
	"time"
)

type response struct {
	res http.Response
}

func Logger(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		addr := r.Header.Get("X-Real-IP")
		if addr == "" {
			addr = r.Header.Get("X-Forwarded-For")
			if addr == "" {
				addr = r.RemoteAddr
			}
		}
		if next != nil {
			next.ServeHTTP(w, r)
		}
		/*status := w.Header().Get("Status")
		if status == "" {
			status = "200"
		}*/
		res := new(response)
		res.res = w
		status := res.res.StatusCode
		log.Printf("[%s] %s %v from %s in %v\n", r.Method, r.URL, status, addr, time.Since(start))
	}
	return http.HandlerFunc(fn)
}
<commit_msg>I'm baka<commit_after>package dst

import (
	//"fmt"
	"log"
	"net/http"
	"time"
)

func Logger(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		addr := r.Header.Get("X-Real-IP")
		if addr == "" {
			addr = r.Header.Get("X-Forwarded-For")
			if addr == "" {
				addr = r.RemoteAddr
			}
		}
		if next != nil {
			next.ServeHTTP(w, r)
		}
		status := w.Header().Get("Status")
		if status == "" {
			status = "200"
		}
		log.Printf("[%s] %s %v from %s in %v\n", r.Method, r.URL, status, addr, time.Since(start))
	}
	return http.HandlerFunc(fn)
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2017 VMware, Inc. All Rights Reserved.

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

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

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

package simulator

import (
	"os"
	"path"

	"github.com/vmware/govmomi/vim25/methods"
	"github.com/vmware/govmomi/vim25/mo"
	"github.com/vmware/govmomi/vim25/soap"
	"github.com/vmware/govmomi/vim25/types"
)

type HostDatastoreSystem struct {
	mo.HostDatastoreSystem

	Host *mo.HostSystem
}

func (dss *HostDatastoreSystem) add(ds *Datastore) *soap.Fault {
	info := ds.Info.GetDatastoreInfo()

	info.Name = ds.Name

	if e := Map.FindByName(ds.Name, dss.Datastore); e != nil {
		return Fault(e.Reference().Value, &types.DuplicateName{
			Name:   ds.Name,
			Object: e.Reference(),
		})
	}

	fi, err := os.Stat(info.Url)
	if err == nil && !fi.IsDir() {
		err = os.ErrInvalid
	}

	if err != nil {
		switch {
		case os.IsNotExist(err):
			return Fault(err.Error(), &types.NotFound{})
		default:
			return Fault(err.Error(), &types.HostConfigFault{})
		}
	}

	folder := Map.getEntityFolder(dss.Host, "datastore")
	ds.Self.Type = typeName(ds)
	// Datastore is the only type where create methods do not include the parent (Folder in this case),
	// but we need the moref to be unique per DC/datastoreFolder, but not per-HostSystem.
	ds.Self.Value += "@" + folder.Self.Value
	// TODO: name should be made unique in the case of Local ds type

	ds.Summary.Datastore = &ds.Self
	ds.Summary.Name = ds.Name
	ds.Summary.Url = info.Url

	dss.Datastore = append(dss.Datastore, ds.Self)
	dss.Host.Datastore = dss.Datastore
	parent := hostParent(dss.Host)
	Map.AddReference(parent, &parent.Datastore, ds.Self)

	browser := &HostDatastoreBrowser{}
	browser.Datastore = dss.Datastore
	ds.Browser = Map.Put(browser).Reference()

	folder.putChild(ds)

	return nil
}

func (dss *HostDatastoreSystem) CreateLocalDatastore(c *types.CreateLocalDatastore) soap.HasFault {
	r := &methods.CreateLocalDatastoreBody{}

	ds := &Datastore{}
	ds.Name = c.Name
	ds.Self.Value = c.Path

	ds.Info = &types.LocalDatastoreInfo{
		DatastoreInfo: types.DatastoreInfo{
			Name: c.Name,
			Url:  c.Path,
		},
		Path: c.Path,
	}

	ds.Summary.Type = "local"

	if err := dss.add(ds); err != nil {
		r.Fault_ = err
		return r
	}

	ds.Host = append(ds.Host, types.DatastoreHostMount{
		Key: dss.Host.Reference(),
		MountInfo: types.HostMountInfo{
			AccessMode: string(types.HostMountModeReadWrite),
			Mounted:    types.NewBool(true),
			Accessible: types.NewBool(true),
		},
	})

	_ = ds.RefreshDatastore(&types.RefreshDatastore{This: ds.Self})

	r.Res = &types.CreateLocalDatastoreResponse{
		Returnval: ds.Self,
	}

	return r
}

func (dss *HostDatastoreSystem) CreateNasDatastore(c *types.CreateNasDatastore) soap.HasFault {
	r := &methods.CreateNasDatastoreBody{}

	ds := &Datastore{}
	ds.Name = path.Base(c.Spec.LocalPath)
	ds.Self.Value = c.Spec.RemoteHost + ":" + c.Spec.RemotePath

	ds.Info = &types.NasDatastoreInfo{
		DatastoreInfo: types.DatastoreInfo{
			Url: c.Spec.LocalPath,
		},
		Nas: &types.HostNasVolume{
			HostFileSystemVolume: types.HostFileSystemVolume{
				Name: c.Spec.LocalPath,
				Type: c.Spec.Type,
			},
			RemoteHost: c.Spec.RemoteHost,
			RemotePath: c.Spec.RemotePath,
		},
	}

	ds.Summary.Type = c.Spec.Type

	if err := dss.add(ds); err != nil {
		r.Fault_ = err
		return r
	}

	_ = ds.RefreshDatastore(&types.RefreshDatastore{This: ds.Self})

	r.Res = &types.CreateNasDatastoreResponse{
		Returnval: ds.Self,
	}

	return r
}
<commit_msg>Report local Datastore back as type OTHER<commit_after>/*
Copyright (c) 2017 VMware, Inc. All Rights Reserved.

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

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

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

package simulator

import (
	"os"
	"path"

	"github.com/vmware/govmomi/vim25/methods"
	"github.com/vmware/govmomi/vim25/mo"
	"github.com/vmware/govmomi/vim25/soap"
	"github.com/vmware/govmomi/vim25/types"
)

type HostDatastoreSystem struct {
	mo.HostDatastoreSystem

	Host *mo.HostSystem
}

func (dss *HostDatastoreSystem) add(ds *Datastore) *soap.Fault {
	info := ds.Info.GetDatastoreInfo()

	info.Name = ds.Name

	if e := Map.FindByName(ds.Name, dss.Datastore); e != nil {
		return Fault(e.Reference().Value, &types.DuplicateName{
			Name:   ds.Name,
			Object: e.Reference(),
		})
	}

	fi, err := os.Stat(info.Url)
	if err == nil && !fi.IsDir() {
		err = os.ErrInvalid
	}

	if err != nil {
		switch {
		case os.IsNotExist(err):
			return Fault(err.Error(), &types.NotFound{})
		default:
			return Fault(err.Error(), &types.HostConfigFault{})
		}
	}

	folder := Map.getEntityFolder(dss.Host, "datastore")
	ds.Self.Type = typeName(ds)
	// Datastore is the only type where create methods do not include the parent (Folder in this case),
	// but we need the moref to be unique per DC/datastoreFolder, but not per-HostSystem.
	ds.Self.Value += "@" + folder.Self.Value
	// TODO: name should be made unique in the case of Local ds type

	ds.Summary.Datastore = &ds.Self
	ds.Summary.Name = ds.Name
	ds.Summary.Url = info.Url

	dss.Datastore = append(dss.Datastore, ds.Self)
	dss.Host.Datastore = dss.Datastore
	parent := hostParent(dss.Host)
	Map.AddReference(parent, &parent.Datastore, ds.Self)

	browser := &HostDatastoreBrowser{}
	browser.Datastore = dss.Datastore
	ds.Browser = Map.Put(browser).Reference()

	folder.putChild(ds)

	return nil
}

func (dss *HostDatastoreSystem) CreateLocalDatastore(c *types.CreateLocalDatastore) soap.HasFault {
	r := &methods.CreateLocalDatastoreBody{}

	ds := &Datastore{}
	ds.Name = c.Name
	ds.Self.Value = c.Path

	ds.Info = &types.LocalDatastoreInfo{
		DatastoreInfo: types.DatastoreInfo{
			Name: c.Name,
			Url:  c.Path,
		},
		Path: c.Path,
	}

	ds.Summary.Type = string(types.HostFileSystemVolumeFileSystemTypeOTHER)

	if err := dss.add(ds); err != nil {
		r.Fault_ = err
		return r
	}

	ds.Host = append(ds.Host, types.DatastoreHostMount{
		Key: dss.Host.Reference(),
		MountInfo: types.HostMountInfo{
			AccessMode: string(types.HostMountModeReadWrite),
			Mounted:    types.NewBool(true),
			Accessible: types.NewBool(true),
		},
	})

	_ = ds.RefreshDatastore(&types.RefreshDatastore{This: ds.Self})

	r.Res = &types.CreateLocalDatastoreResponse{
		Returnval: ds.Self,
	}

	return r
}

func (dss *HostDatastoreSystem) CreateNasDatastore(c *types.CreateNasDatastore) soap.HasFault {
	r := &methods.CreateNasDatastoreBody{}

	ds := &Datastore{}
	ds.Name = path.Base(c.Spec.LocalPath)
	ds.Self.Value = c.Spec.RemoteHost + ":" + c.Spec.RemotePath

	ds.Info = &types.NasDatastoreInfo{
		DatastoreInfo: types.DatastoreInfo{
			Url: c.Spec.LocalPath,
		},
		Nas: &types.HostNasVolume{
			HostFileSystemVolume: types.HostFileSystemVolume{
				Name: c.Spec.LocalPath,
				Type: c.Spec.Type,
			},
			RemoteHost: c.Spec.RemoteHost,
			RemotePath: c.Spec.RemotePath,
		},
	}

	ds.Summary.Type = c.Spec.Type

	if err := dss.add(ds); err != nil {
		r.Fault_ = err
		return r
	}

	_ = ds.RefreshDatastore(&types.RefreshDatastore{This: ds.Self})

	r.Res = &types.CreateNasDatastoreResponse{
		Returnval: ds.Self,
	}

	return r
}
<|endoftext|>


<commit_before>package stores

import (
	"sync"

	"github.com/Everlane/evan/common"
)

// Stores deployments in the process's local memory.
type ProcessLocalStore struct {
	// Two-level map: first is application repository canonical name, second
	// is environment.
	applications map[string]map[string]common.Deployment
	mutex sync.Mutex
}

func NewProcessLocalStore() *ProcessLocalStore {
	return &ProcessLocalStore{
		applications: make(map[string]map[string]common.Deployment),
	}
}

func (store *ProcessLocalStore) SaveDeployment(deployment common.Deployment) error {
	application := store.keyForApplication(deployment.Application())
	environment := deployment.Environment()

	store.mutex.Lock()
	defer store.mutex.Unlock()

	if store.applications[application] == nil {
		store.applications[application] = make(map[string]common.Deployment)
	}
	store.applications[application][environment] = deployment
	return nil
}

func (store *ProcessLocalStore) FindDeployment(app common.Application, environment string) (common.Deployment, error) {
	application := store.keyForApplication(app)

	store.mutex.Lock()
	defer store.mutex.Unlock()

	return store.applications[application][environment], nil
}

func (store *ProcessLocalStore) HasActiveDeployment(app common.Application, environment string) (bool, error) {
	deployment, err := store.FindDeployment(app, environment)
	if err != nil {
		return false, err
	}
	if deployment == nil {
		return false, nil
	}

	switch deployment.Status().State {
	case common.DEPLOYMENT_PENDING:
	case common.RUNNING_PRECONDITIONS:
	case common.RUNNING_PHASE:
		return true, nil
	}
	return false, nil
}

func (store *ProcessLocalStore) keyForApplication(application common.Application) string {
	return common.CanonicalNameForRepository(application.Repository())
}
<commit_msg>Run `gofmt` on stores package<commit_after>package stores

import (
	"sync"

	"github.com/Everlane/evan/common"
)

// Stores deployments in the process's local memory.
type ProcessLocalStore struct {
	// Two-level map: first is application repository canonical name, second
	// is environment.
	applications map[string]map[string]common.Deployment
	mutex        sync.Mutex
}

func NewProcessLocalStore() *ProcessLocalStore {
	return &ProcessLocalStore{
		applications: make(map[string]map[string]common.Deployment),
	}
}

func (store *ProcessLocalStore) SaveDeployment(deployment common.Deployment) error {
	application := store.keyForApplication(deployment.Application())
	environment := deployment.Environment()

	store.mutex.Lock()
	defer store.mutex.Unlock()

	if store.applications[application] == nil {
		store.applications[application] = make(map[string]common.Deployment)
	}
	store.applications[application][environment] = deployment
	return nil
}

func (store *ProcessLocalStore) FindDeployment(app common.Application, environment string) (common.Deployment, error) {
	application := store.keyForApplication(app)

	store.mutex.Lock()
	defer store.mutex.Unlock()

	return store.applications[application][environment], nil
}

func (store *ProcessLocalStore) HasActiveDeployment(app common.Application, environment string) (bool, error) {
	deployment, err := store.FindDeployment(app, environment)
	if err != nil {
		return false, err
	}
	if deployment == nil {
		return false, nil
	}

	switch deployment.Status().State {
	case common.DEPLOYMENT_PENDING:
	case common.RUNNING_PRECONDITIONS:
	case common.RUNNING_PHASE:
		return true, nil
	}
	return false, nil
}

func (store *ProcessLocalStore) keyForApplication(application common.Application) string {
	return common.CanonicalNameForRepository(application.Repository())
}
<|endoftext|>