<commit_before>package upperio

import (
	"fmt"
	"github.com/gorilla/context"
	"net/http"
	"upper.io/db"
)

// Upper is the general registry to be used
// in database session management for upperio database
var defs map[string]Def

const upperCtxKey = "gourd/kit/store/upperio/"

func init() {
	defs = make(map[string]Def)
}

// Def contains the definition of a database source
// Has all the parameters needed by db.Database.Open()
type Def struct {
	Adapter string
	URL     db.ConnectionURL
}

// Define a database source with name
func Define(name, adapter string, conn db.ConnectionURL) {
	defs[name] = Def{
		Adapter: adapter,
		URL:     conn,
	}
}

// Open a database from existing definitions and error if there is problem
// or retrieve the previously openned database session
func Open(r *http.Request, name string) (d db.Database, err error) {

	// try getting from context
	if cv, ok := context.GetOk(r, upperCtxKey+name); ok {
		if d, ok = cv.(db.Database); ok {
			return
		}
	}

	// find definition
	if def, ok := defs[name]; ok {
		// connect
		d, err = db.Open(def.Adapter, def.URL)
		if err != nil {
			// remember the database in context
			context.Set(r, upperCtxKey+name, d)
		}
		return
	}

	// tell user that the definition doesn't exists
	err = fmt.Errorf(
		"Definition for upper.io source \"%s\" not exists", name)
	return
}

// Close down an existing database connection
func Close(r *http.Request, name string) error {
	var d db.Database

	// try getting from context
	if cv, ok := context.GetOk(r, upperCtxKey+name); ok {
		if d, ok = cv.(db.Database); ok {
			// disconnect
			return d.Close()
		}
	}

	// if connection doesn't exists, quit scilently
	return nil
}

// MustOpen equals to open except it return only the database and not error.
// It will panic when encountering error
func MustOpen(r *http.Request, name string) (d db.Database) {
	d, err := Open(r, name)
	if err != nil {
		panic(err.Error())
	}
	return
}
<commit_msg>[store/upperio] Update context key pattern<commit_after>package upperio

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

	"github.com/gorilla/context"
	gourdctx "github.com/gourd/kit/context"
	"upper.io/db"
)

// Upper is the general registry to be used
// in database session management for upperio database
var defs map[string]Def

type ctxKey string

func init() {
	defs = make(map[string]Def)
}

// Def contains the definition of a database source
// Has all the parameters needed by db.Database.Open()
type Def struct {
	Adapter string
	URL     db.ConnectionURL
}

// Define a database source with name
func Define(name, adapter string, conn db.ConnectionURL) {
	defs[name] = Def{
		Adapter: adapter,
		URL:     conn,
	}
}

// Open a database from existing definitions and error if there is problem
// or retrieve the previously openned database session
func Open(r *http.Request, name string) (d db.Database, err error) {

	id := gourdctx.GetRequestID(r)
	log.Printf("[%s] upperio.Open()", id)

	// try getting from context
	if cv, ok := context.GetOk(r, ctxKey(name)); ok {
		if d, ok = cv.(db.Database); ok {
			return
		}
	}

	// find definition
	if def, ok := defs[name]; ok {
		// connect
		d, err = db.Open(def.Adapter, def.URL)
		if err != nil {
			// remember the database in context
			context.Set(r, ctxKey(name), d)
		}
		return
	}

	// tell user that the definition doesn't exists
	err = fmt.Errorf(
		"Definition for upper.io source \"%s\" not exists", name)
	return
}

// Close down an existing database connection
func Close(r *http.Request, name string) error {
	var d db.Database

	// try getting from context
	if cv, ok := context.GetOk(r, ctxKey(name)); ok {
		if d, ok = cv.(db.Database); ok {
			// disconnect
			return d.Close()
		}
	}

	// if connection doesn't exists, quit scilently
	return nil
}

// MustOpen equals to open except it return only the database and not error.
// It will panic when encountering error
func MustOpen(r *http.Request, name string) (d db.Database) {
	d, err := Open(r, name)
	if err != nil {
		panic(err.Error())
	}
	return
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 pkg

import (
	"bytes"
	"crypto/sha1"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	log "github.com/Sirupsen/logrus"

	"mynewt.apache.org/newt/newt/interfaces"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/newt/repo"
	"mynewt.apache.org/newt/util"
	"mynewt.apache.org/newt/viper"
	"mynewt.apache.org/newt/yaml"
)

var PackageHashIgnoreDirs = map[string]bool{
	"obj": true,
	"bin": true,
	".":   true,
}

var LocalPackageSpecialNames = map[string]bool{
	"src":     true,
	"include": true,
	"bin":     true,
}

type LocalPackage struct {
	repo        *repo.Repo
	name        string
	basePath    string
	packageType interfaces.PackageType

	// General information about the package
	desc *PackageDesc
	// Dependencies for this package
	deps []*Dependency
	// APIs that this package exports
	apis []string
	// APIs that this package requires
	reqApis []string

	// This is only used for top-level packages, but make no distinction
	// and always read it in.
	featureBlackList map[string]interface{}
	featureWhiteList map[string]interface{}

	// Pointer to pkg.yml configuration structure
	Viper *viper.Viper

	// Names of all source yml files; used to determine if rebuild required.
	cfgFilenames []string
}

func NewLocalPackage(r *repo.Repo, pkgDir string) *LocalPackage {
	pkg := &LocalPackage{
		desc: &PackageDesc{},
		// XXX: Initialize viper object; clients should not need to check for
		// nil pointer.
	}
	pkg.Init(r, pkgDir)
	return pkg
}

func (pkg *LocalPackage) Name() string {
	return pkg.name
}

func (pkg *LocalPackage) FullName() string {
	r := pkg.Repo()
	if r.IsLocal() {
		return pkg.Name()
	} else {
		return newtutil.BuildPackageString(r.Name(), pkg.Name())
	}
}

func (pkg *LocalPackage) BasePath() string {
	return pkg.basePath
}

func (pkg *LocalPackage) Type() interfaces.PackageType {
	return pkg.packageType
}

func (pkg *LocalPackage) Repo() interfaces.RepoInterface {
	return pkg.repo
}

func (pkg *LocalPackage) Desc() *PackageDesc {
	return pkg.desc
}

func (pkg *LocalPackage) SetName(name string) {
	pkg.name = name
	// XXX: Also set "pkg.name" in viper object (possibly just remove cached
	// variable from code entirely).
}

func (pkg *LocalPackage) SetBasePath(basePath string) {
	pkg.basePath = basePath
}

func (pkg *LocalPackage) SetType(packageType interfaces.PackageType) {
	pkg.packageType = packageType
	// XXX: Also set "pkg.type" in viper object (possibly just remove cached
	// variable from code entirely).
}

func (pkg *LocalPackage) SetDesc(desc *PackageDesc) {
	pkg.desc = desc
	// XXX: Also set desc fields in viper object (possibly just remove cached
	// variable from code entirely).
}

func (pkg *LocalPackage) SetRepo(r *repo.Repo) {
	pkg.repo = r
}

func (pkg *LocalPackage) Hash() (string, error) {
	hash := sha1.New()

	err := filepath.Walk(pkg.basePath,
		func(path string, info os.FileInfo, err error) error {
			name := info.Name()
			if PackageHashIgnoreDirs[name] {
				return filepath.SkipDir
			}

			if info.IsDir() {
				// SHA the directory name into the hash
				hash.Write([]byte(name))
			} else {
				// SHA the file name & contents into the hash
				contents, err := ioutil.ReadFile(path)
				if err != nil {
					return err
				}
				hash.Write(contents)
			}
			return nil
		})
	if err != nil && err != filepath.SkipDir {
		return "", util.NewNewtError(err.Error())
	}

	hashStr := fmt.Sprintf("%x", hash.Sum(nil))

	return hashStr, nil
}

func (pkg *LocalPackage) CfgFilenames() []string {
	return pkg.cfgFilenames
}

func (pkg *LocalPackage) AddCfgFilename(cfgFilename string) {
	pkg.cfgFilenames = append(pkg.cfgFilenames, cfgFilename)
}

func (pkg *LocalPackage) HasDep(searchDep *Dependency) bool {
	for _, dep := range pkg.deps {
		if dep.String() == searchDep.String() {
			return true
		}
	}
	return false
}

func (pkg *LocalPackage) AddDep(dep *Dependency) {
	// Remember the name of the configuration file so that it can be specified
	// as a dependency to the compiler.
	pkg.deps = append(pkg.deps, dep)
}

func (pkg *LocalPackage) Deps() []*Dependency {
	return pkg.deps
}

func (pkg *LocalPackage) AddApi(api string) {
	pkg.apis = append(pkg.apis, api)
}

func (pkg *LocalPackage) Apis() []string {
	return pkg.apis
}

func (pkg *LocalPackage) AddReqApi(api string) {
	pkg.reqApis = append(pkg.reqApis, api)
}

func (pkg *LocalPackage) ReqApis() []string {
	return pkg.reqApis
}

func (pkg *LocalPackage) readDesc(v *viper.Viper) (*PackageDesc, error) {
	pdesc := &PackageDesc{}

	pdesc.Author = v.GetString("pkg.author")
	pdesc.Homepage = v.GetString("pkg.homepage")
	pdesc.Description = v.GetString("pkg.description")
	pdesc.Keywords = v.GetStringSlice("pkg.keywords")

	return pdesc, nil
}

func (pkg *LocalPackage) Init(repo *repo.Repo, pkgDir string) {
	pkg.repo = repo
	pkg.basePath = filepath.Clean(pkgDir) + "/"
}

func (pkg *LocalPackage) sequenceString(key string) string {
	var buffer bytes.Buffer

	if pkg.Viper != nil {
		for _, f := range pkg.Viper.GetStringSlice(key) {
			buffer.WriteString("    - " + yaml.EscapeString(f) + "\n")
		}
	}

	if buffer.Len() == 0 {
		return ""
	} else {
		return key + ":\n" + buffer.String()
	}
}

// Saves the package's pkg.yml file.
// NOTE: This does not save every field in the package.  Only the fields
// necessary for creating a new target get saved.
func (pkg *LocalPackage) Save() error {
	dirpath := pkg.BasePath()
	if err := os.MkdirAll(dirpath, 0755); err != nil {
		return util.NewNewtError(err.Error())
	}

	filepath := dirpath + "/" + PACKAGE_FILE_NAME
	file, err := os.Create(filepath)
	if err != nil {
		return util.NewNewtError(err.Error())
	}
	defer file.Close()

	file.WriteString("### Package: " + pkg.Name() + "\n")

	// XXX: Just iterate viper object's settings rather than calling out
	// cached settings individually.
	file.WriteString("pkg.name: " + yaml.EscapeString(pkg.Name()) + "\n")
	file.WriteString("pkg.type: " +
		yaml.EscapeString(PackageTypeNames[pkg.Type()]) + "\n")
	file.WriteString("pkg.description: " +
		yaml.EscapeString(pkg.Desc().Description) + "\n")
	file.WriteString("pkg.author: " +
		yaml.EscapeString(pkg.Desc().Author) + "\n")
	file.WriteString("pkg.homepage: " +
		yaml.EscapeString(pkg.Desc().Homepage) + "\n")

	file.WriteString("\n")

	file.WriteString(pkg.sequenceString("pkg.aflags"))
	file.WriteString(pkg.sequenceString("pkg.cflags"))
	file.WriteString(pkg.sequenceString("pkg.features"))
	file.WriteString(pkg.sequenceString("pkg.lflags"))

	return nil
}

// Load reads everything that isn't identity specific into the
// package
func (pkg *LocalPackage) Load() error {
	// Load configuration
	log.Debugf("Loading configuration for package %s", pkg.basePath)

	v, err := util.ReadConfig(pkg.basePath,
		strings.TrimSuffix(PACKAGE_FILE_NAME, ".yml"))
	if err != nil {
		return err
	}
	pkg.Viper = v

	// Set package name from the package
	pkg.name = v.GetString("pkg.name")

	typeString := v.GetString("pkg.type")
	pkg.packageType = PACKAGE_TYPE_LIB
	for t, n := range PackageTypeNames {
		if typeString == n {
			pkg.packageType = t
			break
		}
	}

	pkg.featureBlackList = v.GetStringMap("pkg.feature_blacklist")
	pkg.featureWhiteList = v.GetStringMap("pkg.feature_whitelist")

	// Read the package description from the file
	pkg.desc, err = pkg.readDesc(v)
	if err != nil {
		return err
	}

	pkg.AddCfgFilename(pkg.basePath + PACKAGE_FILE_NAME)

	return nil
}

func (pkg *LocalPackage) FeatureBlackList() map[string]interface{} {
	return pkg.featureBlackList
}

func (pkg *LocalPackage) FeatureWhiteList() map[string]interface{} {
	return pkg.featureWhiteList
}

func (pkg *LocalPackage) Clone(newRepo *repo.Repo,
	newName string) *LocalPackage {

	// XXX: Validate name.

	// Copy the package.
	newPkg := *pkg
	newPkg.repo = newRepo
	newPkg.name = newName
	newPkg.basePath = newRepo.Path() + "/" + newPkg.name

	// Insert the clone into the global package map.
	proj := interfaces.GetProject()
	pMap := proj.PackageList()
	(*pMap[newRepo.Name()])[newPkg.name] = &newPkg

	return &newPkg
}

func LoadLocalPackage(repo *repo.Repo, pkgDir string) (*LocalPackage, error) {
	pkg := &LocalPackage{}
	pkg.Init(repo, pkgDir)
	err := pkg.Load()
	return pkg, err
}

func LocalPackageSpecialName(dirName string) bool {
	_, ok := LocalPackageSpecialNames[dirName]
	return ok
}

func ReadLocalPackageRecursive(repo *repo.Repo,
	pkgList map[string]interfaces.PackageInterface, basePath string,
	pkgName string) error {

	dirList, err := ioutil.ReadDir(basePath + "/" + pkgName)
	if err != nil {
		return util.NewNewtError(err.Error())
	}

	for _, dirEnt := range dirList {
		if !dirEnt.IsDir() {
			continue
		}

		name := dirEnt.Name()
		if LocalPackageSpecialName(name) || strings.HasPrefix(name, ".") {
			continue
		}

		if err := ReadLocalPackageRecursive(repo, pkgList, basePath,
			pkgName+"/"+name); err != nil {
			return err
		}
	}

	if util.NodeNotExist(basePath + "/" + pkgName + "/" + PACKAGE_FILE_NAME) {
		return nil
	}

	pkg, err := LoadLocalPackage(repo, basePath+"/"+pkgName)
	if err != nil {
		return err
	}

	if oldPkg, ok := pkgList[pkg.Name()]; ok {
		errStr := fmt.Sprintf("Multiple packages with same pkg.name=%s in repo %s\n",
			oldPkg.FullName(), repo.Name())
		return util.NewNewtError(errStr)
	}

	pkgList[pkg.Name()] = pkg

	return nil
}

func ReadLocalPackages(repo *repo.Repo, basePath string,
	searchPaths []string) (*map[string]interfaces.PackageInterface, error) {

	pkgList := map[string]interfaces.PackageInterface{}

	for _, path := range searchPaths {
		pkgDir := basePath + "/" + path

		if util.NodeNotExist(pkgDir) {
			continue
		}

		dirList, err := ioutil.ReadDir(pkgDir)
		if err != nil {
			return nil, util.NewNewtError(err.Error())
		}

		for _, subDir := range dirList {
			name := subDir.Name()
			if filepath.HasPrefix(name, ".") || filepath.HasPrefix(name, "..") {
				continue
			}

			if !subDir.IsDir() {
				continue
			}

			if err := ReadLocalPackageRecursive(repo, pkgList, pkgDir,
				name); err != nil {
				return nil, util.NewNewtError(err.Error())
			}
		}
	}

	return &pkgList, nil
}
<commit_msg>newt - Put paths of conflicting packages in error.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 pkg

import (
	"bytes"
	"crypto/sha1"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	log "github.com/Sirupsen/logrus"

	"mynewt.apache.org/newt/newt/interfaces"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/newt/repo"
	"mynewt.apache.org/newt/util"
	"mynewt.apache.org/newt/viper"
	"mynewt.apache.org/newt/yaml"
)

var PackageHashIgnoreDirs = map[string]bool{
	"obj": true,
	"bin": true,
	".":   true,
}

var LocalPackageSpecialNames = map[string]bool{
	"src":     true,
	"include": true,
	"bin":     true,
}

type LocalPackage struct {
	repo        *repo.Repo
	name        string
	basePath    string
	packageType interfaces.PackageType

	// General information about the package
	desc *PackageDesc
	// Dependencies for this package
	deps []*Dependency
	// APIs that this package exports
	apis []string
	// APIs that this package requires
	reqApis []string

	// This is only used for top-level packages, but make no distinction
	// and always read it in.
	featureBlackList map[string]interface{}
	featureWhiteList map[string]interface{}

	// Pointer to pkg.yml configuration structure
	Viper *viper.Viper

	// Names of all source yml files; used to determine if rebuild required.
	cfgFilenames []string
}

func NewLocalPackage(r *repo.Repo, pkgDir string) *LocalPackage {
	pkg := &LocalPackage{
		desc: &PackageDesc{},
		// XXX: Initialize viper object; clients should not need to check for
		// nil pointer.
	}
	pkg.Init(r, pkgDir)
	return pkg
}

func (pkg *LocalPackage) Name() string {
	return pkg.name
}

func (pkg *LocalPackage) FullName() string {
	r := pkg.Repo()
	if r.IsLocal() {
		return pkg.Name()
	} else {
		return newtutil.BuildPackageString(r.Name(), pkg.Name())
	}
}

func (pkg *LocalPackage) BasePath() string {
	return pkg.basePath
}

func (pkg *LocalPackage) Type() interfaces.PackageType {
	return pkg.packageType
}

func (pkg *LocalPackage) Repo() interfaces.RepoInterface {
	return pkg.repo
}

func (pkg *LocalPackage) Desc() *PackageDesc {
	return pkg.desc
}

func (pkg *LocalPackage) SetName(name string) {
	pkg.name = name
	// XXX: Also set "pkg.name" in viper object (possibly just remove cached
	// variable from code entirely).
}

func (pkg *LocalPackage) SetBasePath(basePath string) {
	pkg.basePath = basePath
}

func (pkg *LocalPackage) SetType(packageType interfaces.PackageType) {
	pkg.packageType = packageType
	// XXX: Also set "pkg.type" in viper object (possibly just remove cached
	// variable from code entirely).
}

func (pkg *LocalPackage) SetDesc(desc *PackageDesc) {
	pkg.desc = desc
	// XXX: Also set desc fields in viper object (possibly just remove cached
	// variable from code entirely).
}

func (pkg *LocalPackage) SetRepo(r *repo.Repo) {
	pkg.repo = r
}

func (pkg *LocalPackage) Hash() (string, error) {
	hash := sha1.New()

	err := filepath.Walk(pkg.basePath,
		func(path string, info os.FileInfo, err error) error {
			name := info.Name()
			if PackageHashIgnoreDirs[name] {
				return filepath.SkipDir
			}

			if info.IsDir() {
				// SHA the directory name into the hash
				hash.Write([]byte(name))
			} else {
				// SHA the file name & contents into the hash
				contents, err := ioutil.ReadFile(path)
				if err != nil {
					return err
				}
				hash.Write(contents)
			}
			return nil
		})
	if err != nil && err != filepath.SkipDir {
		return "", util.NewNewtError(err.Error())
	}

	hashStr := fmt.Sprintf("%x", hash.Sum(nil))

	return hashStr, nil
}

func (pkg *LocalPackage) CfgFilenames() []string {
	return pkg.cfgFilenames
}

func (pkg *LocalPackage) AddCfgFilename(cfgFilename string) {
	pkg.cfgFilenames = append(pkg.cfgFilenames, cfgFilename)
}

func (pkg *LocalPackage) HasDep(searchDep *Dependency) bool {
	for _, dep := range pkg.deps {
		if dep.String() == searchDep.String() {
			return true
		}
	}
	return false
}

func (pkg *LocalPackage) AddDep(dep *Dependency) {
	// Remember the name of the configuration file so that it can be specified
	// as a dependency to the compiler.
	pkg.deps = append(pkg.deps, dep)
}

func (pkg *LocalPackage) Deps() []*Dependency {
	return pkg.deps
}

func (pkg *LocalPackage) AddApi(api string) {
	pkg.apis = append(pkg.apis, api)
}

func (pkg *LocalPackage) Apis() []string {
	return pkg.apis
}

func (pkg *LocalPackage) AddReqApi(api string) {
	pkg.reqApis = append(pkg.reqApis, api)
}

func (pkg *LocalPackage) ReqApis() []string {
	return pkg.reqApis
}

func (pkg *LocalPackage) readDesc(v *viper.Viper) (*PackageDesc, error) {
	pdesc := &PackageDesc{}

	pdesc.Author = v.GetString("pkg.author")
	pdesc.Homepage = v.GetString("pkg.homepage")
	pdesc.Description = v.GetString("pkg.description")
	pdesc.Keywords = v.GetStringSlice("pkg.keywords")

	return pdesc, nil
}

func (pkg *LocalPackage) Init(repo *repo.Repo, pkgDir string) {
	pkg.repo = repo
	pkg.basePath = filepath.Clean(pkgDir) + "/"
}

func (pkg *LocalPackage) sequenceString(key string) string {
	var buffer bytes.Buffer

	if pkg.Viper != nil {
		for _, f := range pkg.Viper.GetStringSlice(key) {
			buffer.WriteString("    - " + yaml.EscapeString(f) + "\n")
		}
	}

	if buffer.Len() == 0 {
		return ""
	} else {
		return key + ":\n" + buffer.String()
	}
}

// Saves the package's pkg.yml file.
// NOTE: This does not save every field in the package.  Only the fields
// necessary for creating a new target get saved.
func (pkg *LocalPackage) Save() error {
	dirpath := pkg.BasePath()
	if err := os.MkdirAll(dirpath, 0755); err != nil {
		return util.NewNewtError(err.Error())
	}

	filepath := dirpath + "/" + PACKAGE_FILE_NAME
	file, err := os.Create(filepath)
	if err != nil {
		return util.NewNewtError(err.Error())
	}
	defer file.Close()

	file.WriteString("### Package: " + pkg.Name() + "\n")

	// XXX: Just iterate viper object's settings rather than calling out
	// cached settings individually.
	file.WriteString("pkg.name: " + yaml.EscapeString(pkg.Name()) + "\n")
	file.WriteString("pkg.type: " +
		yaml.EscapeString(PackageTypeNames[pkg.Type()]) + "\n")
	file.WriteString("pkg.description: " +
		yaml.EscapeString(pkg.Desc().Description) + "\n")
	file.WriteString("pkg.author: " +
		yaml.EscapeString(pkg.Desc().Author) + "\n")
	file.WriteString("pkg.homepage: " +
		yaml.EscapeString(pkg.Desc().Homepage) + "\n")

	file.WriteString("\n")

	file.WriteString(pkg.sequenceString("pkg.aflags"))
	file.WriteString(pkg.sequenceString("pkg.cflags"))
	file.WriteString(pkg.sequenceString("pkg.features"))
	file.WriteString(pkg.sequenceString("pkg.lflags"))

	return nil
}

// Load reads everything that isn't identity specific into the
// package
func (pkg *LocalPackage) Load() error {
	// Load configuration
	log.Debugf("Loading configuration for package %s", pkg.basePath)

	v, err := util.ReadConfig(pkg.basePath,
		strings.TrimSuffix(PACKAGE_FILE_NAME, ".yml"))
	if err != nil {
		return err
	}
	pkg.Viper = v

	// Set package name from the package
	pkg.name = v.GetString("pkg.name")

	typeString := v.GetString("pkg.type")
	pkg.packageType = PACKAGE_TYPE_LIB
	for t, n := range PackageTypeNames {
		if typeString == n {
			pkg.packageType = t
			break
		}
	}

	pkg.featureBlackList = v.GetStringMap("pkg.feature_blacklist")
	pkg.featureWhiteList = v.GetStringMap("pkg.feature_whitelist")

	// Read the package description from the file
	pkg.desc, err = pkg.readDesc(v)
	if err != nil {
		return err
	}

	pkg.AddCfgFilename(pkg.basePath + PACKAGE_FILE_NAME)

	return nil
}

func (pkg *LocalPackage) FeatureBlackList() map[string]interface{} {
	return pkg.featureBlackList
}

func (pkg *LocalPackage) FeatureWhiteList() map[string]interface{} {
	return pkg.featureWhiteList
}

func (pkg *LocalPackage) Clone(newRepo *repo.Repo,
	newName string) *LocalPackage {

	// XXX: Validate name.

	// Copy the package.
	newPkg := *pkg
	newPkg.repo = newRepo
	newPkg.name = newName
	newPkg.basePath = newRepo.Path() + "/" + newPkg.name

	// Insert the clone into the global package map.
	proj := interfaces.GetProject()
	pMap := proj.PackageList()
	(*pMap[newRepo.Name()])[newPkg.name] = &newPkg

	return &newPkg
}

func LoadLocalPackage(repo *repo.Repo, pkgDir string) (*LocalPackage, error) {
	pkg := &LocalPackage{}
	pkg.Init(repo, pkgDir)
	err := pkg.Load()
	return pkg, err
}

func LocalPackageSpecialName(dirName string) bool {
	_, ok := LocalPackageSpecialNames[dirName]
	return ok
}

func ReadLocalPackageRecursive(repo *repo.Repo,
	pkgList map[string]interfaces.PackageInterface, basePath string,
	pkgName string) error {

	dirList, err := ioutil.ReadDir(basePath + "/" + pkgName)
	if err != nil {
		return util.NewNewtError(err.Error())
	}

	for _, dirEnt := range dirList {
		if !dirEnt.IsDir() {
			continue
		}

		name := dirEnt.Name()
		if LocalPackageSpecialName(name) || strings.HasPrefix(name, ".") {
			continue
		}

		if err := ReadLocalPackageRecursive(repo, pkgList, basePath,
			pkgName+"/"+name); err != nil {
			return err
		}
	}

	if util.NodeNotExist(basePath + "/" + pkgName + "/" + PACKAGE_FILE_NAME) {
		return nil
	}

	pkg, err := LoadLocalPackage(repo, basePath+"/"+pkgName)
	if err != nil {
		return err
	}

	if oldPkg, ok := pkgList[pkg.Name()]; ok {
		oldlPkg := oldPkg.(*LocalPackage)
		return util.FmtNewtError("Multiple packages with same pkg.name=%s "+
			"in repo %s; path1=%s path2=%s", oldlPkg.Name(), repo.Name(),
			oldlPkg.BasePath(), pkg.BasePath())
	}

	pkgList[pkg.Name()] = pkg

	return nil
}

func ReadLocalPackages(repo *repo.Repo, basePath string,
	searchPaths []string) (*map[string]interfaces.PackageInterface, error) {

	pkgList := map[string]interfaces.PackageInterface{}

	for _, path := range searchPaths {
		pkgDir := basePath + "/" + path

		if util.NodeNotExist(pkgDir) {
			continue
		}

		dirList, err := ioutil.ReadDir(pkgDir)
		if err != nil {
			return nil, util.NewNewtError(err.Error())
		}

		for _, subDir := range dirList {
			name := subDir.Name()
			if filepath.HasPrefix(name, ".") || filepath.HasPrefix(name, "..") {
				continue
			}

			if !subDir.IsDir() {
				continue
			}

			if err := ReadLocalPackageRecursive(repo, pkgList, pkgDir,
				name); err != nil {
				return nil, util.NewNewtError(err.Error())
			}
		}
	}

	return &pkgList, nil
}
<|endoftext|>


<commit_before>package system

import (
	"database/sql"
	"fmt"
	"github.com/natefinch/lumberjack"
	"github.com/urfave/cli"
	"github.com/ziflex/bumblebee-cli/src/system/cmd"
	"github.com/ziflex/bumblebee-cli/src/system/initialization"
	"github.com/ziflex/bumblebee-cli/src/system/initialization/initializers"
	"github.com/ziflex/bumblebee-cli/src/system/logging"
	"github.com/ziflex/bumblebee-cli/src/system/storage"
	"github.com/ziflex/bumblebee-cli/src/system/storage/sqlite"
	"github.com/ziflex/bumblebee-cli/src/system/utils"
	"path"
	"strings"
)

type Application struct {
	engine       *cli.App
	db           *sql.DB
	initManager  *initialization.InitManager
	initializers map[string]initialization.Initializer
}

func NewApplication() (*Application, error) {
	var err error
	app := &Application{}

	app.engine = cli.NewApp()
	app.engine.Version = "2.2.0"
	app.engine.Name = "bumblebee-cli"
	app.engine.Usage = "CLI manager for bumblebee applications"

	logsDir := fmt.Sprintf("/var/log/%s/", strings.ToLower(app.engine.Name))

	if err = utils.EnsureDirectory(logsDir); err != nil {
		return nil, err
	}

	logger := logging.NewLogger(&lumberjack.Logger{
		Dir:        logsDir,
		MaxSize:    50 * lumberjack.Megabyte, // megabytes
		MaxBackups: 2,
		MaxAge:     28, //days
	})

	dbDir := fmt.Sprintf("/var/lib/%s/", strings.ToLower(app.engine.Name))

	if err = utils.EnsureDirectory(dbDir); err != nil {
		return nil, err
	}

	db, err := storage.OpenDb(path.Join(dbDir, "database.db"))

	if err != nil {
		logger.Fatalf("Failed to open db: %s", err.Error())
		return nil, err
	}

	app.db = db

	entries := sqlite.NewEntryRepository(storage.ENTRY_TABLE, db)
	settings := sqlite.NewSettingsRepository(storage.SETTINGS_TABLE, db)

	app.engine.Commands = []cli.Command{
		*cmd.NewListCommand(logger, entries, settings),
		*cmd.NewAddCommand(logger, entries, settings),
		*cmd.NewRemoveCommand(logger, entries, settings),
		*cmd.NewSyncCommand(logger, entries, settings),
		*cmd.NewSettingsCommand(logger, entries, settings),
	}

	app.initManager = initialization.NewInitManager(logger)
	app.initializers = map[string]initialization.Initializer{
		"database": initializers.NewDatabaseInitializer(logger, app.db),
	}

	return app, err
}

func (app *Application) Run(arguments []string) error {
	var err error

	defer app.db.Close()

	if err = app.initManager.Run(app.initializers); err != nil {
		return err
	}

	return app.engine.Run(arguments)
}
<commit_msg>Updated version<commit_after>package system

import (
	"database/sql"
	"fmt"
	"github.com/natefinch/lumberjack"
	"github.com/urfave/cli"
	"github.com/ziflex/bumblebee-cli/src/system/cmd"
	"github.com/ziflex/bumblebee-cli/src/system/initialization"
	"github.com/ziflex/bumblebee-cli/src/system/initialization/initializers"
	"github.com/ziflex/bumblebee-cli/src/system/logging"
	"github.com/ziflex/bumblebee-cli/src/system/storage"
	"github.com/ziflex/bumblebee-cli/src/system/storage/sqlite"
	"github.com/ziflex/bumblebee-cli/src/system/utils"
	"path"
	"strings"
)

type Application struct {
	engine       *cli.App
	db           *sql.DB
	initManager  *initialization.InitManager
	initializers map[string]initialization.Initializer
}

func NewApplication() (*Application, error) {
	var err error
	app := &Application{}

	app.engine = cli.NewApp()
	app.engine.Version = "2.2.1"
	app.engine.Name = "bumblebee-cli"
	app.engine.Usage = "CLI manager for bumblebee applications"

	logsDir := fmt.Sprintf("/var/log/%s/", strings.ToLower(app.engine.Name))

	if err = utils.EnsureDirectory(logsDir); err != nil {
		return nil, err
	}

	logger := logging.NewLogger(&lumberjack.Logger{
		Dir:        logsDir,
		MaxSize:    50 * lumberjack.Megabyte, // megabytes
		MaxBackups: 2,
		MaxAge:     28, //days
	})

	dbDir := fmt.Sprintf("/var/lib/%s/", strings.ToLower(app.engine.Name))

	if err = utils.EnsureDirectory(dbDir); err != nil {
		return nil, err
	}

	db, err := storage.OpenDb(path.Join(dbDir, "database.db"))

	if err != nil {
		logger.Fatalf("Failed to open db: %s", err.Error())
		return nil, err
	}

	app.db = db

	entries := sqlite.NewEntryRepository(storage.ENTRY_TABLE, db)
	settings := sqlite.NewSettingsRepository(storage.SETTINGS_TABLE, db)

	app.engine.Commands = []cli.Command{
		*cmd.NewListCommand(logger, entries, settings),
		*cmd.NewAddCommand(logger, entries, settings),
		*cmd.NewRemoveCommand(logger, entries, settings),
		*cmd.NewSyncCommand(logger, entries, settings),
		*cmd.NewSettingsCommand(logger, entries, settings),
	}

	app.initManager = initialization.NewInitManager(logger)
	app.initializers = map[string]initialization.Initializer{
		"database": initializers.NewDatabaseInitializer(logger, app.db),
	}

	return app, err
}

func (app *Application) Run(arguments []string) error {
	var err error

	defer app.db.Close()

	if err = app.initManager.Run(app.initializers); err != nil {
		return err
	}

	return app.engine.Run(arguments)
}
<|endoftext|>


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

package main

import (
	//"net/http/cookiejar"
	"net/http"
	"github.com/songtianyi/laosj/downloader"
	"github.com/songtianyi/laosj/spider"
	"github.com/songtianyi/rrframework/storage"
	"github.com/songtianyi/rrframework/logs"
	"github.com/songtianyi/rrframework/connector/redis"
	"time"
)
const (
	UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
)
var (
	Cookies []*http.Cookie
)

func main() {
	url := "http://www.douban.com/group/haixiuzu/discussion"
	d := &downloader.Downloader{
		ConcurrencyLimit: 10,
		UrlChannelFactor: 10,
		RedisConnStr: "10.19.147.75:6379",
		SourceQueue: "DATA:IMAGE:HAIXIUZU",
		Store: rrstorage.CreateLocalDiskStorage("/data/sexx/haixiuzu/"),
	}
	err, rc := rrredis.GetRedisClient("10.19.147.75:6379")
	if err != nil {
		panic(err)
	}
	go func() {
		d.Start()
	}()
	refer := ""

	for {
		req, err := http.NewRequest("GET", url, nil)
		if err != nil {
			logs.Error(err)
			break
		}
		req.Header.Add("User-Agent", UserAgent)
		req.Header.Add("Referer", refer)

		client := &http.Client{}
		resp, err := client.Do(req)
		if err != nil {
			logs.Error(err)
			break
		}
		if resp.StatusCode != 200 {
			logs.Debug(resp)
			break
		}
		if Cookies == nil {
			Cookies = resp.Cookies()
		}
		s, err := spider.CreateSpiderFromResponse(resp)
		if err != nil {
			logs.Debug(err)
			break
		}
		rs, _ := s.GetAttr("div.grid-16-8.clearfix>div.article>div>table.olt>tbody>tr>td.title>a", "href")
		refer = url
		for _, v := range rs {
			req01, _ := http.NewRequest("GET", v, nil)
			req01.Header.Add("User-Agent", UserAgent)
			req01.Header.Add("Referer", refer)
			resp01, err := client.Do(req01)
			if err != nil {
				logs.Error(err)
				continue
			}
			if resp01.StatusCode != 200 {
				logs.Debug(resp01)
				continue
			}
			s01, err := spider.CreateSpiderFromResponse(resp01)
			if err != nil {
				logs.Error(err)
				continue
			}
			rs01, _ := s01.GetAttr("div.grid-16-8.clearfix>div.article>div.topic-content.clearfix>div.topic-doc>div#link-report>div.topic-content>div.topic-figure.cc>img", "src")
			for _, vv := range rs01 {
				if _, err := rc.RPush("DATA:IMAGE:HAIXIUZU", vv); err != nil {
					logs.Error(err)
				}
			}
			time.Sleep(5 * time.Second)
		}
		rs1, _ := s.GetAttr("div.grid-16-8.clearfix>div.article>div.paginator>span.next>a", "href")
		if len(rs1) != 1 {
			break
		}
		url = rs1[0]
		logs.Notice("redirect to", url)
	}
}
<commit_msg>limit downloading<commit_after>// Copyright 2016 laosj Author @songtianyi. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	//"net/http/cookiejar"
	"net/http"
	"github.com/songtianyi/laosj/downloader"
	"github.com/songtianyi/laosj/spider"
	"github.com/songtianyi/rrframework/storage"
	"github.com/songtianyi/rrframework/logs"
	"github.com/songtianyi/rrframework/connector/redis"
	"time"
)
const (
	UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
)
var (
	Cookies []*http.Cookie
)

func main() {
	url := "http://www.douban.com/group/haixiuzu/discussion"
	d := &downloader.Downloader{
		ConcurrencyLimit: 3,
		UrlChannelFactor: 10,
		RedisConnStr: "127.0.0.1:6379",
		SourceQueue: "DATA:IMAGE:HAIXIUZU",
		Store: rrstorage.CreateLocalDiskStorage("./sexx/haixiuzu/"),
	}
	err, rc := rrredis.GetRedisClient("127.0.0.1:6379")
	if err != nil {
		panic(err)
	}
	go func() {
		d.Start()
	}()
	refer := ""

	for {
		req, err := http.NewRequest("GET", url, nil)
		if err != nil {
			logs.Error(err)
			break
		}
		req.Header.Add("User-Agent", UserAgent)
		req.Header.Add("Referer", refer)

		client := &http.Client{}
		resp, err := client.Do(req)
		if err != nil {
			logs.Error(err)
			break
		}
		if resp.StatusCode != 200 {
			logs.Debug(resp)
			break
		}
		if Cookies == nil {
			Cookies = resp.Cookies()
		}
		s, err := spider.CreateSpiderFromResponse(resp)
		if err != nil {
			logs.Debug(err)
			break
		}
		rs, _ := s.GetAttr("div.grid-16-8.clearfix>div.article>div>table.olt>tbody>tr>td.title>a", "href")
		refer = url
		for _, v := range rs {
			req01, _ := http.NewRequest("GET", v, nil)
			req01.Header.Add("User-Agent", UserAgent)
			req01.Header.Add("Referer", refer)
			resp01, err := client.Do(req01)
			if err != nil {
				logs.Error(err)
				continue
			}
			if resp01.StatusCode != 200 {
				logs.Debug(resp01)
				continue
			}
			s01, err := spider.CreateSpiderFromResponse(resp01)
			if err != nil {
				logs.Error(err)
				continue
			}
			rs01, _ := s01.GetAttr("div.grid-16-8.clearfix>div.article>div.topic-content.clearfix>div.topic-doc>div#link-report>div.topic-content>div.topic-figure.cc>img", "src")
			for _, vv := range rs01 {
				if _, err := rc.RPush("DATA:IMAGE:HAIXIUZU", vv); err != nil {
					logs.Error(err)
				}
			}
			time.Sleep(5 * time.Second)
		}
		rs1, _ := s.GetAttr("div.grid-16-8.clearfix>div.article>div.paginator>span.next>a", "href")
		if len(rs1) != 1 {
			break
		}
		url = rs1[0]
		logs.Notice("redirect to", url)
		time.Sleep(5 * time.Second)
	}
}
<|endoftext|>


<commit_before>package main

import(
	"bufio"
	// "errors"
	"fmt"
	"os"
	// "strings"
)

//
func things(st *Status) string {
	if st.CRole == "primary" {
		return "secondary"
	}
	return "primary"
}

//
func configureHBAConf() error {

	self := myself()
  other, err := Whois(otherRole(self))
  if err != nil {
  	log.Error("NO OTHER! %s", err)
  	os.Exit(1)
  }

	//
	entry := "host    all             all             all           trust"

	if other != nil {
		entry += fmt.Sprintf(`
host    replication     postgres        %s/32            trust`, other.Ip)
	}

	file := conf.DataDir+"pg_hba.conf"

	//
	// fi, err := stat(dataRoot"pg_hba.conf")

	//
	f, err := os.Create(file)
	if err != nil {
		log.Error("[pg_config.configureHBAConf] Failed to create '%s'!\n%s\n", file, err)
		return err
	}

	//
	if _, err := f.WriteString(entry); err != nil {
		log.Error("[pg_config.configureHBAConf] Failed to write to '%s'!\n%s\n", file, err)
		return err
	}

	return nil
}

//
func configurePGConf(master bool) error {

	//
	entry := `
listen_addresses = '0.0.0.0'
max_connections = 100
shared_buffers = 128MB
log_timezone = 'UTC'
datestyle = 'iso, mdy'
timezone = 'UTC'
lc_messages = 'en_US.UTF-8'
lc_monetary = 'en_US.UTF-8'
lc_numeric = 'en_US.UTF-8'
lc_time = 'en_US.UTF-8'
default_text_search_config = 'pg_catalog.english'

wal_level = hot_standby
archive_mode = on
archive_command = 'exit 0'
max_wal_senders = 10
wal_keep_segments = 5000
hot_standby = on`

	// master only
	if master {
		entry += `
synchronous_standby_names = slave`
	}

	file := conf.DataDir+"postgresql.conf"

	//
	f, err := os.Create(file)
	if err != nil {
		log.Error("[pg_config.configurePGConf] Failed to create '%s'!\n%s\n", file, err)
		return err
	}

	//
	if _, err := f.WriteString(entry); err != nil {
		log.Error("[pg_config.configurePGConf] Failed to write to '%s'!\n%s\n", file, err)
		return err
	}

	// #wal_level = minimal                    # minimal, archive, or hot_standby
	//                                         # (change requires restart)
	// #archive_mode = off             # allows archiving to be done
	//                                 # (change requires restart)
	// #archive_command = ''           # command to use to archive a logfile segment
	//                                 # placeholders: %p = path of file to archive
	//                                 #               %f = file name only
	//                                 # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
	// #max_wal_senders = 0            # max number of walsender processes
	//                                 # (change requires restart)
	// #wal_keep_segments = 0          # in logfile segments, 16MB each; 0 disables
	// #hot_standby = off                      # "on" allows queries during recovery
	//                                         # (change requires restart)

	//
	// opts := make(map[string]string)
	// opts["wal_level"] 								= "hot_standby"
	// opts["archive_mode"] 							= "on"
	// opts["archive_command"] 					= "exit 0"
	// opts["max_wal_senders"] 					= "10"
	// opts["wal_keep_segments"] 				= "5000"
	// opts["hot_standby"] 							= "on"
	// opts["synchronous_standby_names"] = "slave"

	return nil
}

//
func createRecovery() error {

	file := conf.DataDir+"recovery.conf"

	self := myself()
  other, err := Whois(otherRole(self))
  if err != nil {
  	log.Error("NO OTHER! %s", err)
  	os.Exit(1)
  }

	//
	f, err := os.Create(file)
	if err != nil {
		log.Error("[pg_config.createRecovery] Failed to create '%s'!\n%s\n", file, err)
		return err
	}

	//
	entry := fmt.Sprintf(`# -------------------------------------------------------
# PostgreSQL recovery config file generated by Pagoda Box
# -------------------------------------------------------

# When standby_mode is enabled, the PostgreSQL server will work as a standby. It
# tries to connect to the primary according to the connection settings
# primary_conninfo, and receives XLOG records continuously.
standby_mode = on
primary_conninfo = 'host=%s port=%s application_name=slave'

# restore_command specifies the shell command that is executed to copy log files
# back from archival storage. This parameter is *required* for an archive
# recovery, but optional for streaming replication. The given command satisfies
# the requirement without doing anything.
restore_command = 'exit 0'`, other.Ip, other.PGPort)

	//
	if _, err := f.WriteString(entry); err != nil {
		log.Error("[pg_config.createRecovery] Failed to write to '%s'!\n%s\n", file, err)
		return err
	}

	return nil
}

//
func destroyRecovery() {

	file := conf.DataDir+"recovery.conf"

	//
	err := os.Remove(file)
	if err != nil {
		log.Warn("[pg_config.destroyRecovery] No recovery.conf found at '%s'", file)
	}
}

//
func stat(f string) (os.FileInfo, error) {
	fi, err := os.Stat(f)
	if err != nil {
		log.Fatal("[pg_config.readFile]", err)
		return nil, err
	}

	return fi, nil
}

// parseFile will parse a config file, returning a 'opts' map of the resulting
// config options.
func parseFile(file string) (map[string]string, error) {

	// attempt to open file
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}

	defer f.Close()

	m := make(map[string]string)
	s := make([]string, 0)

	scanner := bufio.NewScanner(f)
	readLine := 1

	// Read line by line, sending lines to parseLine
	for scanner.Scan() {
		if err := parseLine(scanner.Text(), m, s); err != nil {
			log.Error("[pg_config] Error reading line: %v\n", readLine)
			return nil, err
		}

		readLine++
	}

	fmt.Println("SLICE???", s)

	return m, nil
}

// parseLine reads each line of the config file, extracting a key/value pair to
// insert into an 'conf' map.
func parseLine(line string, m map[string]string, s []string) error {

	// if the line isn't already in the map add it
	if _, ok := m[line]; !ok {
		m[line] = line
		s = append(s, line)
	}

	return nil
}
<commit_msg>last commit<commit_after>package main

import(
	"bufio"
	// "errors"
	"fmt"
	"os"
	// "strings"
)

//
func things(st *Status) string {
	if st.CRole == "primary" {
		return "secondary"
	}
	return "primary"
}

//
func configureHBAConf() error {

	self := myself()
  other, err := Whois(otherRole(self))
  if err != nil {
  	log.Warn("I cant find another. disabling replication")
  }

	//
	entry := "host    all             all             all           trust"

	if other != nil {
		entry += fmt.Sprintf(`
host    replication     postgres        %s/32            trust`, other.Ip)
	}

	file := conf.DataDir+"pg_hba.conf"

	//
	// fi, err := stat(dataRoot"pg_hba.conf")

	//
	f, err := os.Create(file)
	if err != nil {
		log.Error("[pg_config.configureHBAConf] Failed to create '%s'!\n%s\n", file, err)
		return err
	}

	//
	if _, err := f.WriteString(entry); err != nil {
		log.Error("[pg_config.configureHBAConf] Failed to write to '%s'!\n%s\n", file, err)
		return err
	}

	return nil
}

//
func configurePGConf(master bool) error {

	//
	entry := `
listen_addresses = '0.0.0.0'
max_connections = 100
shared_buffers = 128MB
log_timezone = 'UTC'
datestyle = 'iso, mdy'
timezone = 'UTC'
lc_messages = 'en_US.UTF-8'
lc_monetary = 'en_US.UTF-8'
lc_numeric = 'en_US.UTF-8'
lc_time = 'en_US.UTF-8'
default_text_search_config = 'pg_catalog.english'

wal_level = hot_standby
archive_mode = on
archive_command = 'exit 0'
max_wal_senders = 10
wal_keep_segments = 5000
hot_standby = on`

	// master only
	if master {
		entry += `
synchronous_standby_names = slave`
	}

	file := conf.DataDir+"postgresql.conf"

	//
	f, err := os.Create(file)
	if err != nil {
		log.Error("[pg_config.configurePGConf] Failed to create '%s'!\n%s\n", file, err)
		return err
	}

	//
	if _, err := f.WriteString(entry); err != nil {
		log.Error("[pg_config.configurePGConf] Failed to write to '%s'!\n%s\n", file, err)
		return err
	}

	// #wal_level = minimal                    # minimal, archive, or hot_standby
	//                                         # (change requires restart)
	// #archive_mode = off             # allows archiving to be done
	//                                 # (change requires restart)
	// #archive_command = ''           # command to use to archive a logfile segment
	//                                 # placeholders: %p = path of file to archive
	//                                 #               %f = file name only
	//                                 # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
	// #max_wal_senders = 0            # max number of walsender processes
	//                                 # (change requires restart)
	// #wal_keep_segments = 0          # in logfile segments, 16MB each; 0 disables
	// #hot_standby = off                      # "on" allows queries during recovery
	//                                         # (change requires restart)

	//
	// opts := make(map[string]string)
	// opts["wal_level"] 								= "hot_standby"
	// opts["archive_mode"] 							= "on"
	// opts["archive_command"] 					= "exit 0"
	// opts["max_wal_senders"] 					= "10"
	// opts["wal_keep_segments"] 				= "5000"
	// opts["hot_standby"] 							= "on"
	// opts["synchronous_standby_names"] = "slave"

	return nil
}

//
func createRecovery() error {

	file := conf.DataDir+"recovery.conf"

	self := myself()
  other, err := Whois(otherRole(self))
  if err != nil {
  	log.Error("NO OTHER! %s", err)
  	os.Exit(1)
  }

	//
	f, err := os.Create(file)
	if err != nil {
		log.Error("[pg_config.createRecovery] Failed to create '%s'!\n%s\n", file, err)
		return err
	}

	//
	entry := fmt.Sprintf(`# -------------------------------------------------------
# PostgreSQL recovery config file generated by Pagoda Box
# -------------------------------------------------------

# When standby_mode is enabled, the PostgreSQL server will work as a standby. It
# tries to connect to the primary according to the connection settings
# primary_conninfo, and receives XLOG records continuously.
standby_mode = on
primary_conninfo = 'host=%s port=%d application_name=slave'

# restore_command specifies the shell command that is executed to copy log files
# back from archival storage. This parameter is *required* for an archive
# recovery, but optional for streaming replication. The given command satisfies
# the requirement without doing anything.
restore_command = 'exit 0'`, other.Ip, other.PGPort)

	//
	if _, err := f.WriteString(entry); err != nil {
		log.Error("[pg_config.createRecovery] Failed to write to '%s'!\n%s\n", file, err)
		return err
	}

	return nil
}

//
func destroyRecovery() {

	file := conf.DataDir+"recovery.conf"

	//
	err := os.Remove(file)
	if err != nil {
		log.Warn("[pg_config.destroyRecovery] No recovery.conf found at '%s'", file)
	}
}

//
func stat(f string) (os.FileInfo, error) {
	fi, err := os.Stat(f)
	if err != nil {
		log.Fatal("[pg_config.readFile]", err)
		return nil, err
	}

	return fi, nil
}

// parseFile will parse a config file, returning a 'opts' map of the resulting
// config options.
func parseFile(file string) (map[string]string, error) {

	// attempt to open file
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}

	defer f.Close()

	m := make(map[string]string)
	s := make([]string, 0)

	scanner := bufio.NewScanner(f)
	readLine := 1

	// Read line by line, sending lines to parseLine
	for scanner.Scan() {
		if err := parseLine(scanner.Text(), m, s); err != nil {
			log.Error("[pg_config] Error reading line: %v\n", readLine)
			return nil, err
		}

		readLine++
	}

	fmt.Println("SLICE???", s)

	return m, nil
}

// parseLine reads each line of the config file, extracting a key/value pair to
// insert into an 'conf' map.
func parseLine(line string, m map[string]string, s []string) error {

	// if the line isn't already in the map add it
	if _, ok := m[line]; !ok {
		m[line] = line
		s = append(s, line)
	}

	return nil
}
<|endoftext|>


<commit_before>/* Copyright 2013 Robert Zaremba
 *
 * 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 surfer

import (
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)

type WithHTTPLogger struct {
	Writer io.Writer
	Next   http.Handler
}

func (this WithHTTPLogger) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	username := ""
	if req.URL.User != nil {
		if name := req.URL.User.Username(); name != "" {
			username = name
		}
	}
	start := time.Now()
	this.Next.ServeHTTP(w, req)
	elapsed := float64(time.Since(start)) / float64(time.Millisecond)

	fmt.Fprintf(this.Writer, "%s - %s \"%s %s %s\". Elapsed: %f ms\n",
		strings.Split(req.RemoteAddr, ":")[0],
		username,
		req.Method,
		req.RequestURI,
		req.Proto,
		// status,
		elapsed)
}

// Handler which check if request is from canonical host and uses https. Otherwise will
// redirect to https://<canonicalhost>/rest/of/the/url
type WithForceHTTPS struct {
	CanonicalHost string
	Next          http.Handler
}

func (this WithForceHTTPS) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	is_http := true
	if h, ok := req.Header["X-Forwarded-Proto"]; ok {
		if h[0] == "https" {
			is_http = false
		}
	}
	hostPort := strings.Split(req.Host, ":")
	if is_http || hostPort[0] != this.CanonicalHost {
		hostPort[0] = this.CanonicalHost
		url := "https://" + strings.Join(hostPort, ":") + req.URL.String()
		http.Redirect(w, req, url, http.StatusMovedPermanently)
		return
	}

	this.Next.ServeHTTP(w, req)
}

type Authenticator func(req *http.Request) bool

// Enusres authentication for handlers. Otherwise call fallback.
type WithAuth struct {
	A        Authenticator
	Next     http.Handler
	Fallback http.Handler
}

func (this WithAuth) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if this.A(req) {
		this.Next.ServeHTTP(w, req)
	} else {
		this.Fallback.ServeHTTP(w, req)
	}
}
<commit_msg>"Added panic handler<commit_after>/* Copyright 2013 Robert Zaremba
 *
 * 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 surfer

import (
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)

type WithHTTPLogger struct {
	Writer io.Writer
	Next   http.Handler
}

func (this WithHTTPLogger) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	username := ""
	if req.URL.User != nil {
		if name := req.URL.User.Username(); name != "" {
			username = name
		}
	}
	start := time.Now()
	this.Next.ServeHTTP(w, req)
	elapsed := float64(time.Since(start)) / float64(time.Millisecond)

	fmt.Fprintf(this.Writer, "%s - %s \"%s %s %s\". Elapsed: %f ms\n",
		strings.Split(req.RemoteAddr, ":")[0],
		username,
		req.Method,
		req.RequestURI,
		req.Proto,
		// status,
		elapsed)
}

// Handler which check if request is from canonical host and uses https. Otherwise will
// redirect to https://<canonicalhost>/rest/of/the/url
type WithForceHTTPS struct {
	CanonicalHost string
	Next          http.Handler
}

func (this WithForceHTTPS) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	is_http := true
	if h, ok := req.Header["X-Forwarded-Proto"]; ok {
		if h[0] == "https" {
			is_http = false
		}
	}
	hostPort := strings.Split(req.Host, ":")
	if is_http || hostPort[0] != this.CanonicalHost {
		hostPort[0] = this.CanonicalHost
		url := "https://" + strings.Join(hostPort, ":") + req.URL.String()
		http.Redirect(w, req, url, http.StatusMovedPermanently)
		return
	}

	this.Next.ServeHTTP(w, req)
}

type Authenticator func(req *http.Request) bool

// Enusres authentication for handlers. Otherwise call fallback.
type WithAuth struct {
	A        Authenticator
	Next     http.Handler
	Fallback http.Handler
}

func (this WithAuth) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if this.A(req) {
		this.Next.ServeHTTP(w, req)
	} else {
		this.Fallback.ServeHTTP(w, req)
	}
}

// Calls the wrapped handler and on panic calls the specified error handler.
// errH can make some logging or just return:
//   http.Error(w, fmt.Sprintf("%s", err), http.StatusInternalServerError)
func PanicHandler(h http.Handler, errH func(http.ResponseWriter, *http.Request, interface{})) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if err := recover(); err != nil {
				errH(w, r, err)
			}
		}()
		h.ServeHTTP(w, r)
	}
}
<|endoftext|>


<commit_before>package main

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

// Send a message to GCM
func send(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	tokens := r.PostForm["tokens"]
	jsonStr := r.PostFormValue("payload")

	go func() {
		incrementPending()
		sendMessageToGCM(tokens, jsonStr)
	}()

	// Return immediately
	output := "ok\n"
	w.Header().Set("Content-Type", "text/html")
	w.Header().Set("Content-Length", strconv.Itoa(len(output)))
	io.WriteString(w, output)
}

// Return a run report for this process
func getReport(w http.ResponseWriter, r *http.Request) {
	runReportMutex.Lock()
	a, _ := json.Marshal(runReport)
	runReportMutex.Unlock()
	b := string(a)
	io.WriteString(w, b)
}

// Return all currently collected canonical reports from GCM
func getCanonicalReport(w http.ResponseWriter, r *http.Request) {
	ids := map[string][]canonicalReplacement{"canonical_replacements": canonicalReplacements}
	a, _ := json.Marshal(ids)
	b := string(a)
	io.WriteString(w, b)

	// Clear out canonicals
	go func() {
		canonicalReplacementsMutex.Lock()
		defer canonicalReplacementsMutex.Unlock()
		canonicalReplacements = nil
	}()

	go func() {
		runReportMutex.Lock()
		defer runReportMutex.Unlock()
		runReport.Canonicals = 0
	}()
}
<commit_msg>Don't clear out canonicals reporting number after canonical report is retrieved<commit_after>package main

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

// Send a message to GCM
func send(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	tokens := r.PostForm["tokens"]
	jsonStr := r.PostFormValue("payload")

	go func() {
		incrementPending()
		sendMessageToGCM(tokens, jsonStr)
	}()

	// Return immediately
	output := "ok\n"
	w.Header().Set("Content-Type", "text/html")
	w.Header().Set("Content-Length", strconv.Itoa(len(output)))
	io.WriteString(w, output)
}

// Return a run report for this process
func getReport(w http.ResponseWriter, r *http.Request) {
	runReportMutex.Lock()
	a, _ := json.Marshal(runReport)
	runReportMutex.Unlock()
	b := string(a)
	io.WriteString(w, b)
}

// Return all currently collected canonical reports from GCM
func getCanonicalReport(w http.ResponseWriter, r *http.Request) {
	ids := map[string][]canonicalReplacement{"canonical_replacements": canonicalReplacements}
	a, _ := json.Marshal(ids)
	b := string(a)
	io.WriteString(w, b)

	// Clear out canonicals
	go func() {
		canonicalReplacementsMutex.Lock()
		defer canonicalReplacementsMutex.Unlock()
		canonicalReplacements = nil
	}()
}
<|endoftext|>


<commit_before>// Copyright 2013 - Will Groppe.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mockity

import (
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type Route struct {
	URL      string            `json:"url"`
	Method   string            `json:"method"`
	Headers  Header            `json:"headers"`
	Params   map[string]string `json:"params"`
	Response Response          `json:"response"`
}

// Response specifies the what to return when a Route is matched.
// The ContentType, SetCookie entries are shortcuts to frequently
// used Headers.
type Response struct {
	Headers     Header    `json:"headers"`
	ContentType string    `json:"content-type"`
	StatusCode  int       `json:"status"`
	SetCookie   Cookie    `json:"cookies"`
	Body        string    `json:"body"`
	Directive   Directive `json:"!directive"`
}

// Directive denotes special handling of a Response.
type Directive struct {
	Delay        int  `json:"delay"`
	Partial      bool `json:"partial"`
	Firehose     bool `json:"firehose"`
	Flaky        bool `json:"flaky"`
	RedirectLoop bool `json:"loop"`
}

type Header map[string][]string

type Cookie map[string]string

// MakeMockery returns a HTTP Handler that matches the supplied routes to
// http.Requests.  Unmatched requests are logged and returned as
// 404.
func MakeMockery(routes []Route) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		if strings.HasPrefix(r.URL.Path, "/_mockity_infinite_redirector") {
			redirectEndlessly(w, r)
			return
		}
		for _, route := range routes {
			if route.matches(r) {
				route.respond(w, r)
				return
			}
		}
		log.Printf("Unmatched: %s \"%s\"", r.Method, r.URL)
		http.NotFound(w, r)
	}
}

// matches determines if a HTTP request matches a defined route.  It
// checks the path, method, headers, and query/form parameters.
// It returns a boolean value indicating whether the route machtes the
// request.
func (route Route) matches(r *http.Request) bool {
	if route.URL != r.URL.Path {
		return false
	}
	if route.Method != "" && route.Method != r.Method {
		return false
	}
	for header, values := range route.Headers {
		if r.Header[header] == nil {
			return false
		} else {
			req_values := r.Header[header]
			for _, value := range values {
				if !contains(req_values, value) {
					return false
				}
			}
		}
	}
	for param, value := range route.Params {
		if r.FormValue(param) != value {
			return false
		}
	}
	return true
}

func (route Route) respond(w http.ResponseWriter, r *http.Request) {
	resp := route.Response
	switch {
	case resp.Directive.Delay > 0:
		d := time.Duration(resp.Directive.Delay) * time.Millisecond
		writeDelayedResponse(w, d, resp)
		return
	case resp.Directive.Delay < 0:
		d := time.Duration(100000) * time.Hour
		writeDelayedResponse(w, d, resp)
		return
	case resp.Directive.Partial:
		writePartialResponse(w, resp)
		return
	case resp.Directive.RedirectLoop:
		redirectEndlessly(w, r)
		return
	case resp.Directive.Firehose:
		writeInfiniteStream(w)
		return
	case resp.Directive.Flaky:
		maybeWriteResponse(w, resp)
		return
	}
	writeResponse(w, resp)
	return
}

func writeResponse(w http.ResponseWriter, resp Response) {
	setHeaders(w.Header(), resp)
	// Must happen last as changes to headers are ignored after
	// WriteHeader is called.
	if resp.StatusCode != 0 {
		w.WriteHeader(resp.StatusCode)
	}
	w.Write(getBody(resp))
}

func writeDelayedResponse(w http.ResponseWriter, d time.Duration, resp Response) {
	time.Sleep(d)
	writeResponse(w, resp)
}

func writePartialResponse(w http.ResponseWriter, resp Response) {
	partialResponse := resp
	body := getBody(resp)
	length := len(body)
	if length > 2 {
		total := rand.Intn(len(resp.Body) - 2)
		partialResponse.Body = string(body[:total+1])
	}
	writeResponse(w, partialResponse)
	hj, ok := w.(http.Hijacker)
	if !ok {
		http.Error(w, "Hijacking not supported, cannot do partial responses", http.StatusInternalServerError)
		return
	}
	conn, bufrw, err := hj.Hijack()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	bufrw.Flush()
	conn.Close()
}

// redirectEndlessly calls http.Redirect with an incrementing counter
// so the redirects are never circular.  Calling it directly with
// something other then a number as the last part of the URL will
// result in it resetting back to one.
func redirectEndlessly(w http.ResponseWriter, r *http.Request) {
	if !strings.HasPrefix(r.URL.Path, "/_mockity_infinite_redirector") {
		http.Redirect(w, r, "/_mockity_infinite_redirector/1", 301)
	} else {
		strCount := strings.Trim(r.URL.Path, "/_mockity_infinite_redirector/")
		redirectCount, err := strconv.ParseInt(strCount, 0, 64)
		if err != nil {
			http.Redirect(w, r, "/_mockity_infinite_redirector/1", 301)
		}
		url := fmt.Sprintf("/_mockity_infinite_redirector/%d", redirectCount+1)
		http.Redirect(w, r, url, 301)
	}
}

func writeInfiniteStream(w http.ResponseWriter) {
	fmt.Fprint(w, "On, ")
	for {
		fmt.Fprint(w, "and on, and on, ")
		time.Sleep(time.Duration(5) * time.Millisecond)
	}
}

// maybeWriteResponse flips a coin (ok generates a random number)
// to determine whether to return the correct response or throw
// a 500 Server Error.
func maybeWriteResponse(w http.ResponseWriter, resp Response) {
	randSrc := rand.New(rand.NewSource(time.Now().Unix()))
	if randSrc.Float64() > 0.4 {
		writeResponse(w, resp)
	} else {
		http.Error(w, "Server Error: I'm being flaky!", http.StatusInternalServerError)
	}
}

func setHeaders(headers http.Header, resp Response) {
	for name, values := range resp.Headers {
		for _, value := range values {
			headers.Add(name, value)
		}
	}
	// Short cuts may overwrite previously set headers.
	if resp.ContentType != "" {
		headers.Add("Content-Type", resp.ContentType)
	}
	if len(resp.SetCookie) > 0 {
		for name, value := range resp.SetCookie {
			c := &http.Cookie{Name: name, Value: value}
			headers.Add("Set-Cookie", c.String())
		}
	}
}

// getBody returns the Body of the response as a byte slice.  If the
// Body string starts with "!file:" then the response is read from
// filename provided.
func getBody(r Response) []byte {
	if strings.HasPrefix(r.Body, "!file:") {
		filename := strings.Trim(r.Body, "!file:")
		body, err := ioutil.ReadFile(filename)
		if err != nil {
			msg := fmt.Sprintf("Error reading response file: %s [%s]", filename, err.Error())
			log.Printf(msg)
			return []byte(msg)
		}
		return body
	}
	return []byte(r.Body)
}

// contains checks for the presence of a string in a slice of strings.
// It returns a boolean indicating inclusion.
func contains(set []string, s string) bool {
	for _, i := range set {
		if i == s {
			return true
		}
	}
	return false
}
<commit_msg>Stop logging favicon requests as 404s.  Fixes #3.<commit_after>// Copyright 2013 - Will Groppe.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mockity

import (
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type Route struct {
	URL      string            `json:"url"`
	Method   string            `json:"method"`
	Headers  Header            `json:"headers"`
	Params   map[string]string `json:"params"`
	Response Response          `json:"response"`
}

// Response specifies the what to return when a Route is matched.
// The ContentType, SetCookie entries are shortcuts to frequently
// used Headers.
type Response struct {
	Headers     Header    `json:"headers"`
	ContentType string    `json:"content-type"`
	StatusCode  int       `json:"status"`
	SetCookie   Cookie    `json:"cookies"`
	Body        string    `json:"body"`
	Directive   Directive `json:"!directive"`
}

// Directive denotes special handling of a Response.
type Directive struct {
	Delay        int  `json:"delay"`
	Partial      bool `json:"partial"`
	Firehose     bool `json:"firehose"`
	Flaky        bool `json:"flaky"`
	RedirectLoop bool `json:"loop"`
}

type Header map[string][]string

type Cookie map[string]string

// MakeMockery returns a HTTP Handler that matches the supplied routes to
// http.Requests.  Unmatched requests are logged and returned as
// 404.
func MakeMockery(routes []Route) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		if strings.HasPrefix(r.URL.Path, "/_mockity_infinite_redirector") {
			redirectEndlessly(w, r)
			return
		}
		for _, route := range routes {
			if route.matches(r) {
				route.respond(w, r)
				return
			}
		}
		if r.URL.Path != "/favicon.ico" {
			log.Printf("Unmatched: %s \"%s\"", r.Method, r.URL)
		}
		http.NotFound(w, r)
	}
}

// matches determines if a HTTP request matches a defined route.  It
// checks the path, method, headers, and query/form parameters.
// It returns a boolean value indicating whether the route machtes the
// request.
func (route Route) matches(r *http.Request) bool {
	if route.URL != r.URL.Path {
		return false
	}
	if route.Method != "" && route.Method != r.Method {
		return false
	}
	for header, values := range route.Headers {
		if r.Header[header] == nil {
			return false
		} else {
			req_values := r.Header[header]
			for _, value := range values {
				if !contains(req_values, value) {
					return false
				}
			}
		}
	}
	for param, value := range route.Params {
		if r.FormValue(param) != value {
			return false
		}
	}
	return true
}

func (route Route) respond(w http.ResponseWriter, r *http.Request) {
	resp := route.Response
	switch {
	case resp.Directive.Delay > 0:
		d := time.Duration(resp.Directive.Delay) * time.Millisecond
		writeDelayedResponse(w, d, resp)
		return
	case resp.Directive.Delay < 0:
		d := time.Duration(100000) * time.Hour
		writeDelayedResponse(w, d, resp)
		return
	case resp.Directive.Partial:
		writePartialResponse(w, resp)
		return
	case resp.Directive.RedirectLoop:
		redirectEndlessly(w, r)
		return
	case resp.Directive.Firehose:
		writeInfiniteStream(w)
		return
	case resp.Directive.Flaky:
		maybeWriteResponse(w, resp)
		return
	}
	writeResponse(w, resp)
	return
}

func writeResponse(w http.ResponseWriter, resp Response) {
	setHeaders(w.Header(), resp)
	// Must happen last as changes to headers are ignored after
	// WriteHeader is called.
	if resp.StatusCode != 0 {
		w.WriteHeader(resp.StatusCode)
	}
	w.Write(getBody(resp))
}

func writeDelayedResponse(w http.ResponseWriter, d time.Duration, resp Response) {
	time.Sleep(d)
	writeResponse(w, resp)
}

func writePartialResponse(w http.ResponseWriter, resp Response) {
	partialResponse := resp
	body := getBody(resp)
	length := len(body)
	if length > 2 {
		total := rand.Intn(len(resp.Body) - 2)
		partialResponse.Body = string(body[:total+1])
	}
	writeResponse(w, partialResponse)
	hj, ok := w.(http.Hijacker)
	if !ok {
		http.Error(w, "Hijacking not supported, cannot do partial responses", http.StatusInternalServerError)
		return
	}
	conn, bufrw, err := hj.Hijack()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	bufrw.Flush()
	conn.Close()
}

// redirectEndlessly calls http.Redirect with an incrementing counter
// so the redirects are never circular.  Calling it directly with
// something other then a number as the last part of the URL will
// result in it resetting back to one.
func redirectEndlessly(w http.ResponseWriter, r *http.Request) {
	if !strings.HasPrefix(r.URL.Path, "/_mockity_infinite_redirector") {
		http.Redirect(w, r, "/_mockity_infinite_redirector/1", 301)
	} else {
		strCount := strings.Trim(r.URL.Path, "/_mockity_infinite_redirector/")
		redirectCount, err := strconv.ParseInt(strCount, 0, 64)
		if err != nil {
			http.Redirect(w, r, "/_mockity_infinite_redirector/1", 301)
		}
		url := fmt.Sprintf("/_mockity_infinite_redirector/%d", redirectCount+1)
		http.Redirect(w, r, url, 301)
	}
}

func writeInfiniteStream(w http.ResponseWriter) {
	fmt.Fprint(w, "On, ")
	for {
		fmt.Fprint(w, "and on, and on, ")
		time.Sleep(time.Duration(5) * time.Millisecond)
	}
}

// maybeWriteResponse flips a coin (ok generates a random number)
// to determine whether to return the correct response or throw
// a 500 Server Error.
func maybeWriteResponse(w http.ResponseWriter, resp Response) {
	randSrc := rand.New(rand.NewSource(time.Now().Unix()))
	if randSrc.Float64() > 0.4 {
		writeResponse(w, resp)
	} else {
		http.Error(w, "Server Error: I'm being flaky!", http.StatusInternalServerError)
	}
}

func setHeaders(headers http.Header, resp Response) {
	for name, values := range resp.Headers {
		for _, value := range values {
			headers.Add(name, value)
		}
	}
	// Short cuts may overwrite previously set headers.
	if resp.ContentType != "" {
		headers.Add("Content-Type", resp.ContentType)
	}
	if len(resp.SetCookie) > 0 {
		for name, value := range resp.SetCookie {
			c := &http.Cookie{Name: name, Value: value}
			headers.Add("Set-Cookie", c.String())
		}
	}
}

// getBody returns the Body of the response as a byte slice.  If the
// Body string starts with "!file:" then the response is read from
// filename provided.
func getBody(r Response) []byte {
	if strings.HasPrefix(r.Body, "!file:") {
		filename := strings.Trim(r.Body, "!file:")
		body, err := ioutil.ReadFile(filename)
		if err != nil {
			msg := fmt.Sprintf("Error reading response file: %s [%s]", filename, err.Error())
			log.Printf(msg)
			return []byte(msg)
		}
		return body
	}
	return []byte(r.Body)
}

// contains checks for the presence of a string in a slice of strings.
// It returns a boolean indicating inclusion.
func contains(set []string, s string) bool {
	for _, i := range set {
		if i == s {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>// Copyright 2014 Google 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.

//go:generate go-extpoints
package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/GoogleCloudPlatform/heapster/manager"
	"github.com/GoogleCloudPlatform/heapster/sinks"
	"github.com/GoogleCloudPlatform/heapster/sources/api"
	"github.com/GoogleCloudPlatform/heapster/validate"
	"github.com/GoogleCloudPlatform/heapster/version"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/golang/glog"
)

var (
	argPollDuration    = flag.Duration("poll_duration", 10*time.Second, "The frequency at which heapster will poll for stats")
	argStatsResolution = flag.Duration("stats_resolution", 5*time.Second, "The resolution at which heapster will retain stats. Acceptible values are [second, 'poll_duration')")
	argPort            = flag.Int("port", 8082, "port to listen")
	argIp              = flag.String("listen_ip", "", "IP to listen on, defaults to all IPs")
	argMaxProcs        = flag.Int("max_procs", 0, "max number of CPUs that can be used simultaneously. Less than 1 for default (number of cores).")
	argCacheDuration   = flag.Duration("cache_duration", 10*time.Minute, "The total amount of historical data that will be cached by heapster.")
	argSources         Uris
	argSinks           Uris
)

func main() {
	defer glog.Flush()
	flag.Var(&argSources, "source", "source(s) to watch")
	flag.Var(&argSinks, "sink", "external sink(s) that receive data")
	flag.Parse()
	setMaxProcs()
	glog.Infof(strings.Join(os.Args, " "))
	glog.Infof("Heapster version %v", version.HeapsterVersion)
	if err := validateFlags(); err != nil {
		glog.Fatal(err)
	}
	sources, sink, err := doWork()
	if err != nil {
		glog.Error(err)
		os.Exit(1)
	}
	setupHandlers(sources, sink)
	addr := fmt.Sprintf("%s:%d", *argIp, *argPort)
	glog.Infof("Starting heapster on port %d", *argPort)
	glog.Fatal(http.ListenAndServe(addr, nil))
	os.Exit(0)
}

func validateFlags() error {
	if *argPollDuration <= time.Second {
		return fmt.Errorf("poll duration is invalid '%d'. Set it to a duration greater than a second", *argPollDuration)
	}
	if *argStatsResolution < time.Second {
		return fmt.Errorf("stats resolution needs to be greater than a second - %d", *argStatsResolution)
	}
	if *argStatsResolution >= *argPollDuration {
		return fmt.Errorf("stats resolution '%d' is not less than poll duration '%d'", *argStatsResolution, *argPollDuration)
	}

	return nil
}

func setupHandlers(sources []api.Source, sink sinks.ExternalSinkManager) {
	// Validation/Debug handler.
	http.HandleFunc(validate.ValidatePage, func(w http.ResponseWriter, r *http.Request) {
		err := validate.HandleRequest(w, sources, sink)
		if err != nil {
			fmt.Fprintf(w, "%s", err)
		}
	})

	// TODO(jnagal): Add a main status page.
	http.Handle("/", http.RedirectHandler(validate.ValidatePage, http.StatusTemporaryRedirect))
}

func doWork() ([]api.Source, sinks.ExternalSinkManager, error) {
	sources, err := newSources()
	if err != nil {
		return nil, nil, err
	}
	externalSinks, err := newSinks()
	if err != nil {
		return nil, nil, err
	}
	sinkManager, err := sinks.NewExternalSinkManager(externalSinks)
	if err != nil {
		return nil, nil, err
	}
	manager, err := manager.NewManager(sources, sinkManager, *argStatsResolution, *argCacheDuration)
	if err != nil {
		return nil, nil, err
	}
	go util.Until(manager.Housekeep, *argPollDuration, util.NeverStop)
	return sources, sinkManager, nil
}

func setMaxProcs() {
	// Allow as many threads as we have cores unless the user specified a value.
	var numProcs int
	if *argMaxProcs < 1 {
		numProcs = runtime.NumCPU()
	} else {
		numProcs = *argMaxProcs
	}
	runtime.GOMAXPROCS(numProcs)

	// Check if the setting was successful.
	actualNumProcs := runtime.GOMAXPROCS(0)
	if actualNumProcs != numProcs {
		glog.Warningf("Specified max procs of %d but using %d", numProcs, actualNumProcs)
	}
}
<commit_msg>Rewrote flag usage messages for clarity<commit_after>// Copyright 2014 Google 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.

//go:generate go-extpoints
package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/GoogleCloudPlatform/heapster/manager"
	"github.com/GoogleCloudPlatform/heapster/sinks"
	"github.com/GoogleCloudPlatform/heapster/sources/api"
	"github.com/GoogleCloudPlatform/heapster/validate"
	"github.com/GoogleCloudPlatform/heapster/version"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/golang/glog"
)

var (
	argPollDuration    = flag.Duration("poll_duration", 10*time.Second, "The frequency at which heapster will poll for stats")
	argStatsResolution = flag.Duration("stats_resolution", 5*time.Second, "The resolution at which heapster will retain stats. Acceptable values are in the range [1 second, 'poll_duration')")
	argPort            = flag.Int("port", 8082, "port to listen to")
	argIp              = flag.String("listen_ip", "", "IP to listen on, defaults to all IPs")
	argMaxProcs        = flag.Int("max_procs", 0, "max number of CPUs that can be used simultaneously. Less than 1 for default (number of cores).")
	argCacheDuration   = flag.Duration("cache_duration", 10*time.Minute, "The total duration of the historical data that will be cached by heapster.")
	argSources         Uris
	argSinks           Uris
)

func main() {
	defer glog.Flush()
	flag.Var(&argSources, "source", "source(s) to watch")
	flag.Var(&argSinks, "sink", "external sink(s) that receive data")
	flag.Parse()
	setMaxProcs()
	glog.Infof(strings.Join(os.Args, " "))
	glog.Infof("Heapster version %v", version.HeapsterVersion)
	if err := validateFlags(); err != nil {
		glog.Fatal(err)
	}
	sources, sink, err := doWork()
	if err != nil {
		glog.Error(err)
		os.Exit(1)
	}
	setupHandlers(sources, sink)
	addr := fmt.Sprintf("%s:%d", *argIp, *argPort)
	glog.Infof("Starting heapster on port %d", *argPort)
	glog.Fatal(http.ListenAndServe(addr, nil))
	os.Exit(0)
}

func validateFlags() error {
	if *argPollDuration <= time.Second {
		return fmt.Errorf("poll duration is invalid '%d'. Set it to a duration greater than a second", *argPollDuration)
	}
	if *argStatsResolution < time.Second {
		return fmt.Errorf("stats resolution needs to be greater than a second - %d", *argStatsResolution)
	}
	if *argStatsResolution >= *argPollDuration {
		return fmt.Errorf("stats resolution '%d' is not less than poll duration '%d'", *argStatsResolution, *argPollDuration)
	}

	return nil
}

func setupHandlers(sources []api.Source, sink sinks.ExternalSinkManager) {
	// Validation/Debug handler.
	http.HandleFunc(validate.ValidatePage, func(w http.ResponseWriter, r *http.Request) {
		err := validate.HandleRequest(w, sources, sink)
		if err != nil {
			fmt.Fprintf(w, "%s", err)
		}
	})

	// TODO(jnagal): Add a main status page.
	http.Handle("/", http.RedirectHandler(validate.ValidatePage, http.StatusTemporaryRedirect))
}

func doWork() ([]api.Source, sinks.ExternalSinkManager, error) {
	sources, err := newSources()
	if err != nil {
		return nil, nil, err
	}
	externalSinks, err := newSinks()
	if err != nil {
		return nil, nil, err
	}
	sinkManager, err := sinks.NewExternalSinkManager(externalSinks)
	if err != nil {
		return nil, nil, err
	}
	manager, err := manager.NewManager(sources, sinkManager, *argStatsResolution, *argCacheDuration)
	if err != nil {
		return nil, nil, err
	}
	go util.Until(manager.Housekeep, *argPollDuration, util.NeverStop)
	return sources, sinkManager, nil
}

func setMaxProcs() {
	// Allow as many threads as we have cores unless the user specified a value.
	var numProcs int
	if *argMaxProcs < 1 {
		numProcs = runtime.NumCPU()
	} else {
		numProcs = *argMaxProcs
	}
	runtime.GOMAXPROCS(numProcs)

	// Check if the setting was successful.
	actualNumProcs := runtime.GOMAXPROCS(0)
	if actualNumProcs != numProcs {
		glog.Warningf("Specified max procs of %d but using %d", numProcs, actualNumProcs)
	}
}
<|endoftext|>


<commit_before>package ping

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"time"
)

// HTTPing ...
type HTTPing struct {
	target *Target
	done   chan struct{}
	result *Result
	Method string
}

var _ Pinger = (*HTTPing)(nil)

// NewHTTPing return new HTTPing
func NewHTTPing(method string) *HTTPing {
	return &HTTPing{
		done:   make(chan struct{}),
		Method: method,
	}
}

// SetTarget ...
func (ping *HTTPing) SetTarget(target *Target) {
	ping.target = target
	if ping.result == nil {
		ping.result = &Result{Target: target}
	}
}

// Start ping
func (ping *HTTPing) Start() <-chan struct{} {
	go func() {
		t := time.NewTicker(ping.target.Interval)
		for {
			select {
			case <-t.C:
				if ping.result.Counter >= ping.target.Counter && ping.target.Counter != 0 {
					ping.Stop()
					return
				}
				duration, resp, err := ping.ping()
				ping.result.Counter++

				if err != nil {
					fmt.Printf("Ping %s - failed: %s\n", ping.target, err)
				} else {
					defer resp.Body.Close()
					length, _ := io.Copy(ioutil.Discard, resp.Body)
					fmt.Printf("Ping %s - %s is open - time=%s method=%s status=%d bytes=%d\n", ping.target, ping.target.Protocol, duration, ping.Method, resp.StatusCode, length)
					if ping.result.MinDuration == 0 {
						ping.result.MinDuration = duration
					}
					if ping.result.MaxDuration == 0 {
						ping.result.MaxDuration = duration
					}
					ping.result.SuccessCounter++
					if duration > ping.result.MaxDuration {
						ping.result.MaxDuration = duration
					} else if duration < ping.result.MinDuration {
						ping.result.MinDuration = duration
					}
					ping.result.TotalDuration += duration
				}
			case <-ping.done:
				return
			}
		}
	}()
	return ping.done
}

// Result return ping result
func (ping *HTTPing) Result() *Result {
	return ping.result
}

// Stop the tcping
func (ping *HTTPing) Stop() {
	ping.done <- struct{}{}
}

func (ping HTTPing) ping() (time.Duration, *http.Response, error) {
	var resp *http.Response
	var body io.Reader
	if ping.Method == "POST" {
		body = bytes.NewBufferString("{}")
	}
	req, err := http.NewRequest(ping.Method, ping.target.String(), body)
	req.Header.Set(http.CanonicalHeaderKey("User-Agent"), "tcping")
	if err != nil {
		return 0, nil, err
	}

	duration, errIfce := timeIt(func() interface{} {
		client := http.Client{Timeout: ping.target.Timeout}
		resp, err = client.Do(req)
		return err
	})
	if errIfce != nil {
		err := errIfce.(error)
		return 0, nil, err
	}
	return time.Duration(duration), resp, nil
}
<commit_msg>Fix ticker stop<commit_after>package ping

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"time"
)

// HTTPing ...
type HTTPing struct {
	target *Target
	done   chan struct{}
	result *Result
	Method string
}

var _ Pinger = (*HTTPing)(nil)

// NewHTTPing return new HTTPing
func NewHTTPing(method string) *HTTPing {
	return &HTTPing{
		done:   make(chan struct{}),
		Method: method,
	}
}

// SetTarget ...
func (ping *HTTPing) SetTarget(target *Target) {
	ping.target = target
	if ping.result == nil {
		ping.result = &Result{Target: target}
	}
}

// Start ping
func (ping *HTTPing) Start() <-chan struct{} {
	go func() {
		t := time.NewTicker(ping.target.Interval)
		defer t.Stop()
		for {
			select {
			case <-t.C:
				if ping.result.Counter >= ping.target.Counter && ping.target.Counter != 0 {
					ping.Stop()
					return
				}
				duration, resp, err := ping.ping()
				ping.result.Counter++

				if err != nil {
					fmt.Printf("Ping %s - failed: %s\n", ping.target, err)
				} else {
					defer resp.Body.Close()
					length, _ := io.Copy(ioutil.Discard, resp.Body)
					fmt.Printf("Ping %s - %s is open - time=%s method=%s status=%d bytes=%d\n", ping.target, ping.target.Protocol, duration, ping.Method, resp.StatusCode, length)
					if ping.result.MinDuration == 0 {
						ping.result.MinDuration = duration
					}
					if ping.result.MaxDuration == 0 {
						ping.result.MaxDuration = duration
					}
					ping.result.SuccessCounter++
					if duration > ping.result.MaxDuration {
						ping.result.MaxDuration = duration
					} else if duration < ping.result.MinDuration {
						ping.result.MinDuration = duration
					}
					ping.result.TotalDuration += duration
				}
			case <-ping.done:
				return
			}
		}
	}()
	return ping.done
}

// Result return ping result
func (ping *HTTPing) Result() *Result {
	return ping.result
}

// Stop the tcping
func (ping *HTTPing) Stop() {
	ping.done <- struct{}{}
}

func (ping HTTPing) ping() (time.Duration, *http.Response, error) {
	var resp *http.Response
	var body io.Reader
	if ping.Method == "POST" {
		body = bytes.NewBufferString("{}")
	}
	req, err := http.NewRequest(ping.Method, ping.target.String(), body)
	req.Header.Set(http.CanonicalHeaderKey("User-Agent"), "tcping")
	if err != nil {
		return 0, nil, err
	}

	duration, errIfce := timeIt(func() interface{} {
		client := http.Client{Timeout: ping.target.Timeout}
		resp, err = client.Do(req)
		return err
	})
	if errIfce != nil {
		err := errIfce.(error)
		return 0, nil, err
	}
	return time.Duration(duration), resp, nil
}
<|endoftext|>


<commit_before>package poke

import (
	"fmt"
	"github.com/raphamorim/go-rainbow"
	"gopkg.in/cheggaaa/pb.v1"
	"strconv"
)

const LONGEST_TYPE_NAME_LEN = 8

func strRepeat(amount int, str string) string {
	var toReturn string
	for i := 0; i < amount; i++ {
		toReturn += str
	}
	return toReturn
}

func typeLabel(t Type) string {
	padding := strRepeat(LONGEST_TYPE_NAME_LEN-len(t.Name), " ")
	return rainbow.Bold(rainbow.Hex("#FFFFFF", padding+t.Name+":"))
}

// Ensure all types have a 0 entry.
func emptyHisto() map[Type]int {
	histo := make(map[Type]int)
	for _, t := range TypeArr {
		histo[t] = 0
	}
	return histo
}

func printHisto(histo map[Type]int, sorted [18]Type) {
	for _, t := range sorted {
		bar := strRepeat(histo[t], "#")
		fmt.Printf("%s %s (%d)\n",
			typeLabel(t),
			rainbow.Hex(t.HexColor, bar),
			histo[t])
	}
}

func printRatios(ratios map[Type][2]int, sorted [18]Type) {
	for _, t := range sorted {
		fmt.Printf("%s %s / %s (%f)\n",
			typeLabel(t),
			rainbow.Hex(t.HexColor, strconv.Itoa(ratios[t][0])),
			rainbow.Hex(t.HexColor, strconv.Itoa(ratios[t][1])),
			float64(ratios[t][0])/float64(ratios[t][1]))
	}
}

func Histo(list []Pokemon, sortDir int) {
	histo := emptyHisto()
	for _, p := range list {
		for _, t := range p.Types {
			histo[t] += 1
		}
	}

	sortedTypes := GetSortedIntTypes(histo, sortDir)
	printHisto(histo, sortedTypes)
}

// Number of pokemons such type is good against.
func SuperEffectiveHisto(list []Pokemon, sortDir int) {
	histo := emptyHisto()

	for _, pokemon := range list {
		for _, t := range TypeArr {
			// Check if super-effective.  If so, add
			if TypeEffectiveness(t, pokemon.Types) >= 2.0 {
				histo[t] += 1
			}
		}
	}

	sortedTypes := GetSortedIntTypes(histo, sortDir)
	printHisto(histo, sortedTypes)
}

// For each type, take the ratio of
// how many pokemons are weak against it (compounded type is strong) vs
// how many pokemons are strong against it (have at least 1 super effective type)
// This does not worry about pokemon that can learn a move from another type
// and make it super effective.  e.g. a Gardevoir with Leaf Blade, makes
// Blastoise vulnerable to it, but such configuration are not consider here...
// Later, maybe we can make the 'vulnerable' definition to be pokemons
// that learn a strong (>60?) attack of a type that is super effective.
// TODO: Take type-combinations instead (+ single types too).
func GoodRatios(list []Pokemon, sortDir int) {
	ratios := make(map[Type][2]int)
	for _, t := range TypeArr {
		pokemonsItKills := 0
		pokemonsThatKillIt := 0
		for _, pokemon := range list {
			// We are good against this pokemon
			if TypeEffectiveness(t, pokemon.Types) >= 2.0 {
				pokemonsItKills += 1
			}

			// At least one of its type is good against us...
			for _, tt := range pokemon.Types {
				if TypeEffectiveness(tt, []Type{t}) >= 2.0 {
					pokemonsThatKillIt += 1
					break
				}
			}
		}

		ratios[t] = [2]int{pokemonsItKills, pokemonsThatKillIt}
	}

	sortedTypes := GetSortedRatioTypes(ratios, sortDir)
	printRatios(ratios, sortedTypes)
}

func BestPokemons(list []Pokemon, sortDir int) {
	fmt.Println("Analyzing optimal move sets...")
	bar := pb.StartNew(len(list))
	totalKts := make(map[int]int)
	moveSets := make(map[int][4]Move)
	pokemons := make(map[int]Pokemon)
	for _, p := range list {
		moveSet, totalKt := BestMoveSet(p, list)

		pokemons[p.Id] = p
		moveSets[p.Id] = moveSet
		totalKts[p.Id] = totalKt

		bar.Increment()
	}

	sortedPokemons := GetSortedPokemon(pokemons, totalKts, sortDir)
	for _, p := range sortedPokemons {
		PrintBattlePokemon(p, moveSets[p.Id])
	}
}
<commit_msg>Simple concurrency for BestPoke<commit_after>package poke

import (
	"fmt"
	"github.com/raphamorim/go-rainbow"
	"gopkg.in/cheggaaa/pb.v1"
	"strconv"
)

const LONGEST_TYPE_NAME_LEN = 8

func strRepeat(amount int, str string) string {
	var toReturn string
	for i := 0; i < amount; i++ {
		toReturn += str
	}
	return toReturn
}

func typeLabel(t Type) string {
	padding := strRepeat(LONGEST_TYPE_NAME_LEN-len(t.Name), " ")
	return rainbow.Bold(rainbow.Hex("#FFFFFF", padding+t.Name+":"))
}

// Ensure all types have a 0 entry.
func emptyHisto() map[Type]int {
	histo := make(map[Type]int)
	for _, t := range TypeArr {
		histo[t] = 0
	}
	return histo
}

func printHisto(histo map[Type]int, sorted [18]Type) {
	for _, t := range sorted {
		bar := strRepeat(histo[t], "#")
		fmt.Printf("%s %s (%d)\n",
			typeLabel(t),
			rainbow.Hex(t.HexColor, bar),
			histo[t])
	}
}

func printRatios(ratios map[Type][2]int, sorted [18]Type) {
	for _, t := range sorted {
		fmt.Printf("%s %s / %s (%f)\n",
			typeLabel(t),
			rainbow.Hex(t.HexColor, strconv.Itoa(ratios[t][0])),
			rainbow.Hex(t.HexColor, strconv.Itoa(ratios[t][1])),
			float64(ratios[t][0])/float64(ratios[t][1]))
	}
}

func Histo(list []Pokemon, sortDir int) {
	histo := emptyHisto()
	for _, p := range list {
		for _, t := range p.Types {
			histo[t] += 1
		}
	}

	sortedTypes := GetSortedIntTypes(histo, sortDir)
	printHisto(histo, sortedTypes)
}

// Number of pokemons such type is good against.
func SuperEffectiveHisto(list []Pokemon, sortDir int) {
	histo := emptyHisto()

	for _, pokemon := range list {
		for _, t := range TypeArr {
			// Check if super-effective.  If so, add
			if TypeEffectiveness(t, pokemon.Types) >= 2.0 {
				histo[t] += 1
			}
		}
	}

	sortedTypes := GetSortedIntTypes(histo, sortDir)
	printHisto(histo, sortedTypes)
}

// For each type, take the ratio of
// how many pokemons are weak against it (compounded type is strong) vs
// how many pokemons are strong against it (have at least 1 super effective type)
// This does not worry about pokemon that can learn a move from another type
// and make it super effective.  e.g. a Gardevoir with Leaf Blade, makes
// Blastoise vulnerable to it, but such configuration are not consider here...
// Later, maybe we can make the 'vulnerable' definition to be pokemons
// that learn a strong (>60?) attack of a type that is super effective.
// TODO: Take type-combinations instead (+ single types too).
func GoodRatios(list []Pokemon, sortDir int) {
	ratios := make(map[Type][2]int)
	for _, t := range TypeArr {
		pokemonsItKills := 0
		pokemonsThatKillIt := 0
		for _, pokemon := range list {
			// We are good against this pokemon
			if TypeEffectiveness(t, pokemon.Types) >= 2.0 {
				pokemonsItKills += 1
			}

			// At least one of its type is good against us...
			for _, tt := range pokemon.Types {
				if TypeEffectiveness(tt, []Type{t}) >= 2.0 {
					pokemonsThatKillIt += 1
					break
				}
			}
		}

		ratios[t] = [2]int{pokemonsItKills, pokemonsThatKillIt}
	}

	sortedTypes := GetSortedRatioTypes(ratios, sortDir)
	printRatios(ratios, sortedTypes)
}

type BestMoveSetResult struct {
	pokemon Pokemon
	moveSet [4]Move
	totalKt int
}

func BestPokemons(list []Pokemon, sortDir int) {
	fmt.Println("Analyzing optimal move sets...")
	bar := pb.StartNew(len(list))

	c := make(chan BestMoveSetResult, len(list))
	for _, p := range list {
		go func(p Pokemon) {
			moveSet, totalKt := BestMoveSet(p, list)
			bar.Increment()
			c <- BestMoveSetResult{p, moveSet, totalKt}
		}(p)
	}

	pokemons := make(map[int]Pokemon)
	moveSets := make(map[int][4]Move)
	totalKts := make(map[int]int)
	for _, _ = range list {
		r := <-c
		pokemons[r.pokemon.Id] = r.pokemon
		moveSets[r.pokemon.Id] = r.moveSet
		totalKts[r.pokemon.Id] = r.totalKt
	}

	sortedPokemons := GetSortedPokemon(pokemons, totalKts, sortDir)
	for _, p := range sortedPokemons {
		PrintBattlePokemon(p, moveSets[p.Id])
	}
}
<|endoftext|>


<commit_before>package main

import "fmt"

type car struct {
	name  string
	color string
}

func (c *car) SetName01(s string) {
	c.name = s
}

func (c car) SetName02(s string) {
	c.name = s
}

func main() {
	toyota := &car{
		name:  "toyota",
		color: "white",
	}

	fmt.Println(toyota.name)
	toyota.SetName01("foo")
	fmt.Println(toyota.name)
	toyota.SetName02("bar")
	fmt.Println(toyota.name)
	toyota.SetName02("test")
	fmt.Println(toyota.name)
}
<commit_msg>update<commit_after>package main

import "fmt"

type car struct {
	name  string
	color string
}

func (c *car) SetName01(s string) {
	fmt.Printf("SetName01: car address: %p\n", c)
	c.name = s
}

func (c car) SetName02(s string) {
	fmt.Printf("SetName02: car address: %p\n", &c)
	c.name = s
}

func main() {
	toyota := &car{
		name:  "toyota",
		color: "white",
	}

	fmt.Println(toyota.name)
	toyota.SetName01("foo")
	fmt.Println(toyota.name)
	toyota.SetName02("bar")
	fmt.Println(toyota.name)
	toyota.SetName02("test")
	fmt.Println(toyota.name)
}
<|endoftext|>


<commit_before><commit_msg>Outdated dependencies data<commit_after><|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"path/filepath"
	"time"
)

const lockfilename = ".lock.pid"

type LockFile struct {
	*os.File
}

func NewLockfile(filename string) *LockFile {
	lockfile, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, os.FileMode(0666))
	if lockfile == nil || err != nil {
		fmt.Printf("Could not create lock file %s. Probably an instance of %s is running?\n", lockfilename, filepath.Base(os.Args[0]))
		logger.Panicln("Fatal: Lockfile creation error")
	}
	logger.Println("Info: Lockfile successfully created")
	return &LockFile{lockfile}
}

func (lockfile *LockFile) Delete() {
	filename := lockfile.Name()
	if err := lockfile.Close(); err != nil { // Windows want's it's file closed before unlinking
		logger.Panicln("Fatal: Can not close lockfile")
	}
	if err := os.Remove(filename); err != nil {
		logger.Panicln("Fatal: Can not delete lockfile")
	}
	logger.Println("Info: Lockfile successfully deleted")
}

func (lockfile *LockFile) WriteInfo() {
	if err := lockfile.Truncate(0); err != nil {
		logger.Panicln("Fatal: Can not truncate lockfile")
	}
	if _, err := lockfile.Seek(0, 0); err != nil {
		logger.Panicln("Fatal: Can not seek in lockfile")
	}
	if _, err := lockfile.WriteString(fmt.Sprintf("%d:%s", os.Getpid(), time.Now())); err != nil {
		logger.Panicln("Fatal: Can not write to lockfile")
	}
	logger.Println("Info: Lockfile successfully written")
}
<commit_msg>delete file<commit_after><|endoftext|>


<commit_before>package entities

import (
	"github.com/oakmound/oak/event"
	"github.com/oakmound/oak/render"
)

// A Doodad is an entity composed of a position, a renderable, and a CallerID.
type Doodad struct {
	Point
	event.CID
	R render.Renderable
}

// NewDoodad returns a new doodad that is not drawn but is initialized.
// Passing a CID of 0 will initialize the entity as a Doodad. Passing
// any other CID will assume that the struct containing this doodad has
// already been initialized to the passed in CID.
// This applies to ALL NewX functions in entities which take in a CID.
func NewDoodad(x, y float64, r render.Renderable, CID event.CID) Doodad {
	if r != nil {
		r.SetPos(x, y)
	}
	d := Doodad{}
	d.Point = NewPoint(x, y)
	d.R = r
	d.CID = CID.Parse(&d)
	return d
}

// Init satisfies event.Entity
func (d *Doodad) Init() event.CID {
	d.CID = event.NextID(d)
	return d.CID
}

// GetID returns this Doodad's CID
// Consider: are these getters needed?
func (d *Doodad) GetID() event.CID {
	return d.CID
}

// GetRenderable returns this Doodad's Renderable
func (d *Doodad) GetRenderable() render.Renderable {
	return d.R
}

// SetRenderable sets this Doodad's renderable, drawing it.
// Todo:this automatic drawing doesn't really work with our
// two tiers of draw layers
func (d *Doodad) SetRenderable(r render.Renderable) {
	if d.R != nil {
		d.R.UnDraw()
	}
	d.R = r
	render.Draw(d.R, d.R.GetLayer())
}

// Destroy cleans up the events, renderable and
// entity mapping for this Doodad
func (d *Doodad) Destroy() {
	if d.R != nil {
		d.R.UnDraw()
	}
	d.CID.UnbindAll()
	event.DestroyEntity(int(d.CID))
}

// Overwrites

// SetPos both Sets logical position and renderable position
// The need for this sort of function is lessened with the introduction
// of vector attachement.
func (d *Doodad) SetPos(x, y float64) {
	d.SetLogicPos(x, y)
	d.R.SetPos(x, y)
}

func (d *Doodad) String() string {
	s := "Doodad: \nP{ "
	s += d.Point.String()
	s += " }\nR:{ "
	s += d.R.String()
	s += " }\nID:{ "
	s += d.CID.String()
	s += " }"
	return s
}
<commit_msg>Removing doodad renderable string expectation<commit_after>package entities

import (
	"github.com/oakmound/oak/event"
	"github.com/oakmound/oak/render"
)

// A Doodad is an entity composed of a position, a renderable, and a CallerID.
type Doodad struct {
	Point
	event.CID
	R render.Renderable
}

// NewDoodad returns a new doodad that is not drawn but is initialized.
// Passing a CID of 0 will initialize the entity as a Doodad. Passing
// any other CID will assume that the struct containing this doodad has
// already been initialized to the passed in CID.
// This applies to ALL NewX functions in entities which take in a CID.
func NewDoodad(x, y float64, r render.Renderable, CID event.CID) Doodad {
	if r != nil {
		r.SetPos(x, y)
	}
	d := Doodad{}
	d.Point = NewPoint(x, y)
	d.R = r
	d.CID = CID.Parse(&d)
	return d
}

// Init satisfies event.Entity
func (d *Doodad) Init() event.CID {
	d.CID = event.NextID(d)
	return d.CID
}

// GetID returns this Doodad's CID
// Consider: are these getters needed?
func (d *Doodad) GetID() event.CID {
	return d.CID
}

// GetRenderable returns this Doodad's Renderable
func (d *Doodad) GetRenderable() render.Renderable {
	return d.R
}

// SetRenderable sets this Doodad's renderable, drawing it.
// Todo:this automatic drawing doesn't really work with our
// two tiers of draw layers
func (d *Doodad) SetRenderable(r render.Renderable) {
	if d.R != nil {
		d.R.UnDraw()
	}
	d.R = r
	render.Draw(d.R, d.R.GetLayer())
}

// Destroy cleans up the events, renderable and
// entity mapping for this Doodad
func (d *Doodad) Destroy() {
	if d.R != nil {
		d.R.UnDraw()
	}
	d.CID.UnbindAll()
	event.DestroyEntity(int(d.CID))
}

// Overwrites

// SetPos both Sets logical position and renderable position
// The need for this sort of function is lessened with the introduction
// of vector attachement.
func (d *Doodad) SetPos(x, y float64) {
	d.SetLogicPos(x, y)
	d.R.SetPos(x, y)
}

func (d *Doodad) String() string {
	s := "Doodad: \nP{ "
	s += d.Point.String()
	s += " }\nID:{ "
	s += d.CID.String()
	s += " }"
	return s
}
<|endoftext|>


<commit_before><commit_msg>Add rsort test case<commit_after><|endoftext|>