<commit_before>package error

import (
	"errors"
	"fmt"

	"github.com/hashicorp/go-multierror"
)

const referenceTemplate = "https://github.com/opencontainers/runtime-spec/blob/v%s/%s"

// SpecErrorCode represents the compliance content.
type SpecErrorCode int

const (
	// NonError represents that an input is not an error
	NonError SpecErrorCode = iota
	// NonRFCError represents that an error is not a rfc2119 error
	NonRFCError

	// ConfigFileExistence represents the error code of 'config.json' existence test
	ConfigFileExistence
	// ArtifactsInSingleDir represents the error code of artifacts place test
	ArtifactsInSingleDir

	// SpecVersion represents the error code of specfication version test
	SpecVersion

	// RootOnNonHyperV represents the error code of root setting test on non hyper-v containers
	RootOnNonHyperV
	// RootOnHyperV represents the error code of root setting test on hyper-v containers
	RootOnHyperV
	// PathFormatOnWindows represents the error code of the path format test on Window
	PathFormatOnWindows
	// PathName represents the error code of the path name test
	PathName
	// PathExistence represents the error code of the path existence test
	PathExistence
	// ReadonlyFilesystem represents the error code of readonly test
	ReadonlyFilesystem
	// ReadonlyOnWindows represents the error code of readonly setting test on Windows
	ReadonlyOnWindows

	// DefaultFilesystems represents the error code of default filesystems test
	DefaultFilesystems

	// CreateWithID represents the error code of 'create' lifecyle test with 'id' provided
	CreateWithID
	// CreateWithUniqueID represents the error code of 'create' lifecyle test with unique 'id' provided
	CreateWithUniqueID
	// CreateNewContainer represents the error code 'create' lifecyle test that creates new container
	CreateNewContainer
)

type errorTemplate struct {
	Level     Level
	Reference func(version string) (reference string, err error)
}

var (
	containerFormatRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "bundle.md#container-format"), nil
	}
	specVersionRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "config.md#specification-version"), nil
	}
	rootRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "config.md#root"), nil
	}
	defaultFSRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "config-linux.md#default-filesystems"), nil
	}
	runtimeCreateRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "runtime.md#create"), nil
	}
)

var ociErrors = map[SpecErrorCode]errorTemplate{
	// Bundle.md
	// Container Format
	ConfigFileExistence:  errorTemplate{Level: Must, Reference: containerFormatRef},
	ArtifactsInSingleDir: errorTemplate{Level: Must, Reference: containerFormatRef},

	// Config.md
	// Specification Version
	SpecVersion: errorTemplate{Level: Must, Reference: specVersionRef},
	// Root
	RootOnNonHyperV: errorTemplate{Level: Required, Reference: rootRef},
	RootOnHyperV:    errorTemplate{Level: Must, Reference: rootRef},
	// TODO: add tests for 'PathFormatOnWindows'
	PathFormatOnWindows: errorTemplate{Level: Must, Reference: rootRef},
	PathName:            errorTemplate{Level: Should, Reference: rootRef},
	PathExistence:       errorTemplate{Level: Must, Reference: rootRef},
	ReadonlyFilesystem:  errorTemplate{Level: Must, Reference: rootRef},
	ReadonlyOnWindows:   errorTemplate{Level: Must, Reference: rootRef},

	// Config-Linux.md
	// Default Filesystems
	DefaultFilesystems: errorTemplate{Level: Should, Reference: defaultFSRef},

	// Runtime.md
	// Create
	CreateWithID:       errorTemplate{Level: Must, Reference: runtimeCreateRef},
	CreateWithUniqueID: errorTemplate{Level: Must, Reference: runtimeCreateRef},
	CreateNewContainer: errorTemplate{Level: Must, Reference: runtimeCreateRef},
}

// NewError creates an Error referencing a spec violation.  The error
// can be cast to a *runtime-tools.error.Error for extracting
// structured information about the level of the violation and a
// reference to the violated spec condition.
//
// A version string (for the version of the spec that was violated)
// must be set to get a working URL.
func NewError(code SpecErrorCode, msg string, version string) (err error) {
	template := ociErrors[code]
	reference, err := template.Reference(version)
	if err != nil {
		return err
	}
	return &Error{
		Level:     template.Level,
		Reference: reference,
		Err:       errors.New(msg),
		ErrCode:   int(code),
	}
}

// FindError finds an error from a source error (mulitple error) and
// returns the error code if founded.
// If the source error is nil or empty, return NonError.
// If the source error is not a multiple error, return NonRFCError.
func FindError(err error, code SpecErrorCode) SpecErrorCode {
	if err == nil {
		return NonError
	}

	if merr, ok := err.(*multierror.Error); ok {
		if merr.ErrorOrNil() == nil {
			return NonError
		}
		for _, e := range merr.Errors {
			if rfcErr, ok := e.(*Error); ok {
				if rfcErr.ErrCode == int(code) {
					return code
				}
			}
		}
	}
	return NonRFCError
}
<commit_msg>error: small fix<commit_after>package error

import (
	"errors"
	"fmt"

	"github.com/hashicorp/go-multierror"
)

const referenceTemplate = "https://github.com/opencontainers/runtime-spec/blob/v%s/%s"

// SpecErrorCode represents the compliance content.
type SpecErrorCode int

const (
	// NonError represents that an input is not an error
	NonError SpecErrorCode = iota
	// NonRFCError represents that an error is not a rfc2119 error
	NonRFCError

	// ConfigFileExistence represents the error code of 'config.json' existence test
	ConfigFileExistence
	// ArtifactsInSingleDir represents the error code of artifacts place test
	ArtifactsInSingleDir

	// SpecVersion represents the error code of specfication version test
	SpecVersion

	// RootOnNonHyperV represents the error code of root setting test on non hyper-v containers
	RootOnNonHyperV
	// RootOnHyperV represents the error code of root setting test on hyper-v containers
	RootOnHyperV
	// PathFormatOnWindows represents the error code of the path format test on Window
	PathFormatOnWindows
	// PathName represents the error code of the path name test
	PathName
	// PathExistence represents the error code of the path existence test
	PathExistence
	// ReadonlyFilesystem represents the error code of readonly test
	ReadonlyFilesystem
	// ReadonlyOnWindows represents the error code of readonly setting test on Windows
	ReadonlyOnWindows

	// DefaultFilesystems represents the error code of default filesystems test
	DefaultFilesystems

	// CreateWithID represents the error code of 'create' lifecyle test with 'id' provided
	CreateWithID
	// CreateWithUniqueID represents the error code of 'create' lifecyle test with unique 'id' provided
	CreateWithUniqueID
	// CreateNewContainer represents the error code 'create' lifecyle test that creates new container
	CreateNewContainer
)

type errorTemplate struct {
	Level     Level
	Reference func(version string) (reference string, err error)
}

var (
	containerFormatRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "bundle.md#container-format"), nil
	}
	specVersionRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "config.md#specification-version"), nil
	}
	rootRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "config.md#root"), nil
	}
	defaultFSRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "config-linux.md#default-filesystems"), nil
	}
	runtimeCreateRef = func(version string) (reference string, err error) {
		return fmt.Sprintf(referenceTemplate, version, "runtime.md#create"), nil
	}
)

var ociErrors = map[SpecErrorCode]errorTemplate{
	// Bundle.md
	// Container Format
	ConfigFileExistence:  {Level: Must, Reference: containerFormatRef},
	ArtifactsInSingleDir: {Level: Must, Reference: containerFormatRef},

	// Config.md
	// Specification Version
	SpecVersion: {Level: Must, Reference: specVersionRef},
	// Root
	RootOnNonHyperV: {Level: Required, Reference: rootRef},
	RootOnHyperV:    {Level: Must, Reference: rootRef},
	// TODO: add tests for 'PathFormatOnWindows'
	PathFormatOnWindows: {Level: Must, Reference: rootRef},
	PathName:            {Level: Should, Reference: rootRef},
	PathExistence:       {Level: Must, Reference: rootRef},
	ReadonlyFilesystem:  {Level: Must, Reference: rootRef},
	ReadonlyOnWindows:   {Level: Must, Reference: rootRef},

	// Config-Linux.md
	// Default Filesystems
	DefaultFilesystems: {Level: Should, Reference: defaultFSRef},

	// Runtime.md
	// Create
	CreateWithID:       {Level: Must, Reference: runtimeCreateRef},
	CreateWithUniqueID: {Level: Must, Reference: runtimeCreateRef},
	CreateNewContainer: {Level: Must, Reference: runtimeCreateRef},
}

// NewError creates an Error referencing a spec violation.  The error
// can be cast to a *runtime-tools.error.Error for extracting
// structured information about the level of the violation and a
// reference to the violated spec condition.
//
// A version string (for the version of the spec that was violated)
// must be set to get a working URL.
func NewError(code SpecErrorCode, msg string, version string) (err error) {
	template := ociErrors[code]
	reference, err := template.Reference(version)
	if err != nil {
		return err
	}
	return &Error{
		Level:     template.Level,
		Reference: reference,
		Err:       errors.New(msg),
		ErrCode:   int(code),
	}
}

// FindError finds an error from a source error (multiple error) and
// returns the error code if founded.
// If the source error is nil or empty, return NonError.
// If the source error is not a multiple error, return NonRFCError.
func FindError(err error, code SpecErrorCode) SpecErrorCode {
	if err == nil {
		return NonError
	}

	if merr, ok := err.(*multierror.Error); ok {
		if merr.ErrorOrNil() == nil {
			return NonError
		}
		for _, e := range merr.Errors {
			if rfcErr, ok := e.(*Error); ok {
				if rfcErr.ErrCode == int(code) {
					return code
				}
			}
		}
	}
	return NonRFCError
}
<|endoftext|>


<commit_before>// +build !ignore_autogenerated

/*
Copyright 2017 The Kubernetes Authors.

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

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

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

// This file was autogenerated by deepcopy-gen. Do not edit it manually!

package federation

import (
	reflect "reflect"

	conversion "k8s.io/apimachinery/pkg/conversion"
	runtime "k8s.io/apimachinery/pkg/runtime"
	api "k8s.io/kubernetes/pkg/api"
)

func init() {
	SchemeBuilder.Register(RegisterDeepCopies)
}

// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
// to allow building arbitrary schemes.
func RegisterDeepCopies(scheme *runtime.Scheme) error {
	return scheme.AddGeneratedDeepCopyFuncs(
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_Cluster, InType: reflect.TypeOf(&Cluster{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterCondition, InType: reflect.TypeOf(&ClusterCondition{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterList, InType: reflect.TypeOf(&ClusterList{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterReplicaSetPreferences, InType: reflect.TypeOf(&ClusterReplicaSetPreferences{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterSpec, InType: reflect.TypeOf(&ClusterSpec{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterStatus, InType: reflect.TypeOf(&ClusterStatus{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_FederatedReplicaSetPreferences, InType: reflect.TypeOf(&FederatedReplicaSetPreferences{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ServerAddressByClientCIDR, InType: reflect.TypeOf(&ServerAddressByClientCIDR{})},
	)
}

func DeepCopy_federation_Cluster(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*Cluster)
		out := out.(*Cluster)
		*out = *in
		if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
			return err
		}
		if err := DeepCopy_federation_ClusterSpec(&in.Spec, &out.Spec, c); err != nil {
			return err
		}
		if err := DeepCopy_federation_ClusterStatus(&in.Status, &out.Status, c); err != nil {
			return err
		}
		return nil
	}
}

func DeepCopy_federation_ClusterCondition(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterCondition)
		out := out.(*ClusterCondition)
		*out = *in
		out.LastProbeTime = in.LastProbeTime.DeepCopy()
		out.LastTransitionTime = in.LastTransitionTime.DeepCopy()
		return nil
	}
}

func DeepCopy_federation_ClusterList(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterList)
		out := out.(*ClusterList)
		*out = *in
		if in.Items != nil {
			in, out := &in.Items, &out.Items
			*out = make([]Cluster, len(*in))
			for i := range *in {
				if err := DeepCopy_federation_Cluster(&(*in)[i], &(*out)[i], c); err != nil {
					return err
				}
			}
		}
		return nil
	}
}

func DeepCopy_federation_ClusterReplicaSetPreferences(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterReplicaSetPreferences)
		out := out.(*ClusterReplicaSetPreferences)
		*out = *in
		if in.MaxReplicas != nil {
			in, out := &in.MaxReplicas, &out.MaxReplicas
			*out = new(int64)
			**out = **in
		}
		return nil
	}
}

func DeepCopy_federation_ClusterSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterSpec)
		out := out.(*ClusterSpec)
		*out = *in
		if in.ServerAddressByClientCIDRs != nil {
			in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
			*out = make([]ServerAddressByClientCIDR, len(*in))
			for i := range *in {
				(*out)[i] = (*in)[i]
			}
		}
		if in.SecretRef != nil {
			in, out := &in.SecretRef, &out.SecretRef
			*out = new(api.LocalObjectReference)
			**out = **in
		}
		return nil
	}
}

func DeepCopy_federation_ClusterStatus(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterStatus)
		out := out.(*ClusterStatus)
		*out = *in
		if in.Conditions != nil {
			in, out := &in.Conditions, &out.Conditions
			*out = make([]ClusterCondition, len(*in))
			for i := range *in {
				if err := DeepCopy_federation_ClusterCondition(&(*in)[i], &(*out)[i], c); err != nil {
					return err
				}
			}
		}
		if in.Zones != nil {
			in, out := &in.Zones, &out.Zones
			*out = make([]string, len(*in))
			copy(*out, *in)
		}
		return nil
	}
}

func DeepCopy_federation_FederatedReplicaSetPreferences(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*FederatedReplicaSetPreferences)
		out := out.(*FederatedReplicaSetPreferences)
		*out = *in
		if in.Clusters != nil {
			in, out := &in.Clusters, &out.Clusters
			*out = make(map[string]ClusterReplicaSetPreferences)
			for key, val := range *in {
				newVal := new(ClusterReplicaSetPreferences)
				if err := DeepCopy_federation_ClusterReplicaSetPreferences(&val, newVal, c); err != nil {
					return err
				}
				(*out)[key] = *newVal
			}
		}
		return nil
	}
}

func DeepCopy_federation_ServerAddressByClientCIDR(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ServerAddressByClientCIDR)
		out := out.(*ServerAddressByClientCIDR)
		*out = *in
		return nil
	}
}
<commit_msg>generated: staging<commit_after>// +build !ignore_autogenerated

/*
Copyright 2017 The Kubernetes Authors.

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

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

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

// This file was autogenerated by deepcopy-gen. Do not edit it manually!

package federation

import (
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	conversion "k8s.io/apimachinery/pkg/conversion"
	runtime "k8s.io/apimachinery/pkg/runtime"
	api "k8s.io/kubernetes/pkg/api"
	reflect "reflect"
)

func init() {
	SchemeBuilder.Register(RegisterDeepCopies)
}

// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
// to allow building arbitrary schemes.
func RegisterDeepCopies(scheme *runtime.Scheme) error {
	return scheme.AddGeneratedDeepCopyFuncs(
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_Cluster, InType: reflect.TypeOf(&Cluster{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterCondition, InType: reflect.TypeOf(&ClusterCondition{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterList, InType: reflect.TypeOf(&ClusterList{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterReplicaSetPreferences, InType: reflect.TypeOf(&ClusterReplicaSetPreferences{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterSpec, InType: reflect.TypeOf(&ClusterSpec{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ClusterStatus, InType: reflect.TypeOf(&ClusterStatus{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_FederatedReplicaSetPreferences, InType: reflect.TypeOf(&FederatedReplicaSetPreferences{})},
		conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_federation_ServerAddressByClientCIDR, InType: reflect.TypeOf(&ServerAddressByClientCIDR{})},
	)
}

func DeepCopy_federation_Cluster(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*Cluster)
		out := out.(*Cluster)
		*out = *in
		if newVal, err := c.DeepCopy(&in.ObjectMeta); err != nil {
			return err
		} else {
			out.ObjectMeta = *newVal.(*v1.ObjectMeta)
		}
		if err := DeepCopy_federation_ClusterSpec(&in.Spec, &out.Spec, c); err != nil {
			return err
		}
		if err := DeepCopy_federation_ClusterStatus(&in.Status, &out.Status, c); err != nil {
			return err
		}
		return nil
	}
}

func DeepCopy_federation_ClusterCondition(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterCondition)
		out := out.(*ClusterCondition)
		*out = *in
		out.LastProbeTime = in.LastProbeTime.DeepCopy()
		out.LastTransitionTime = in.LastTransitionTime.DeepCopy()
		return nil
	}
}

func DeepCopy_federation_ClusterList(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterList)
		out := out.(*ClusterList)
		*out = *in
		if in.Items != nil {
			in, out := &in.Items, &out.Items
			*out = make([]Cluster, len(*in))
			for i := range *in {
				if err := DeepCopy_federation_Cluster(&(*in)[i], &(*out)[i], c); err != nil {
					return err
				}
			}
		}
		return nil
	}
}

func DeepCopy_federation_ClusterReplicaSetPreferences(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterReplicaSetPreferences)
		out := out.(*ClusterReplicaSetPreferences)
		*out = *in
		if in.MaxReplicas != nil {
			in, out := &in.MaxReplicas, &out.MaxReplicas
			*out = new(int64)
			**out = **in
		}
		return nil
	}
}

func DeepCopy_federation_ClusterSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterSpec)
		out := out.(*ClusterSpec)
		*out = *in
		if in.ServerAddressByClientCIDRs != nil {
			in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
			*out = make([]ServerAddressByClientCIDR, len(*in))
			for i := range *in {
				(*out)[i] = (*in)[i]
			}
		}
		if in.SecretRef != nil {
			in, out := &in.SecretRef, &out.SecretRef
			*out = new(api.LocalObjectReference)
			**out = **in
		}
		return nil
	}
}

func DeepCopy_federation_ClusterStatus(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ClusterStatus)
		out := out.(*ClusterStatus)
		*out = *in
		if in.Conditions != nil {
			in, out := &in.Conditions, &out.Conditions
			*out = make([]ClusterCondition, len(*in))
			for i := range *in {
				if err := DeepCopy_federation_ClusterCondition(&(*in)[i], &(*out)[i], c); err != nil {
					return err
				}
			}
		}
		if in.Zones != nil {
			in, out := &in.Zones, &out.Zones
			*out = make([]string, len(*in))
			copy(*out, *in)
		}
		return nil
	}
}

func DeepCopy_federation_FederatedReplicaSetPreferences(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*FederatedReplicaSetPreferences)
		out := out.(*FederatedReplicaSetPreferences)
		*out = *in
		if in.Clusters != nil {
			in, out := &in.Clusters, &out.Clusters
			*out = make(map[string]ClusterReplicaSetPreferences)
			for key, val := range *in {
				newVal := new(ClusterReplicaSetPreferences)
				if err := DeepCopy_federation_ClusterReplicaSetPreferences(&val, newVal, c); err != nil {
					return err
				}
				(*out)[key] = *newVal
			}
		}
		return nil
	}
}

func DeepCopy_federation_ServerAddressByClientCIDR(in interface{}, out interface{}, c *conversion.Cloner) error {
	{
		in := in.(*ServerAddressByClientCIDR)
		out := out.(*ServerAddressByClientCIDR)
		*out = *in
		return nil
	}
}
<|endoftext|>


<commit_before>package oauth2Utils

import (
	"github.com/RangelReale/osin"
	"github.com/astaxie/beego/context"
	"net/http"
	"strings"

	. "github.com/francoishill/goangi2/utils/cookieUtils"
)

const (
	cOSIN_ACCESS_OUTPUT_ACCESS_TOKEN_MAP_KEY = "access_token"
)

type StringPredicate func(string) bool

var OsinServerObject *osin.Server

type IExpectedUser interface {
	GetRands() string
	GetPassword() string
	GetId() int64
	IAmAUser()
}

type iAuthUserProvider interface {
	DoVerifyUser(userName, password string) (bool, IExpectedUser) //This can handle both login/register
}

func checkError(err error) {
	if err != nil {
		panic(err)
	}
}

func InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(request *http.Request) {
	authorizationHeader := request.Header.Get("Authorization")
	accessTokenFromAuthHeader := ""
	if strings.HasPrefix(authorizationHeader, "Bearer ") {
		//This means if the "code" was set in the get/set form it will be overwritten if we use the Authorization header
		accessTokenFromAuthHeader = authorizationHeader[7:]
		request.ParseForm()
		request.Form.Set("code", accessTokenFromAuthHeader)
	}
}

func OverwriteOsinResponseErrorWithOwn(osinResponse *osin.Response) {
	errKey, ok := osinResponse.Output["error"].(string)
	if ok {
		if errKey == osin.E_INVALID_REQUEST {
			osinResponse.SetError(errKey, errorMapKeys[errKey])
		}
	}
}

func OverwriteOsinResponseErrorWithOwn_SpecifyErrorKey(osinResponse *osin.Response, errorKey string) {
	osinResponse.SetError(errorKey, errorMapKeys[errorKey])
}

func GetAuthorizedContextFromAccessToken(osinResponse *osin.Response, ctx *context.Context) *AuthorizedContext {
	InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(ctx.Request)

	var usr IExpectedUser
	var castedToUserType bool

	ir := OsinServerObject.HandleInfoRequest(osinResponse, ctx.Request)
	if ir == nil {
		panic(createOsinAuthorizeError(E_INVALID_AUTH_DATA, errorMapKeys[E_INVALID_AUTH_DATA]))
	}

	if ir.AccessData.UserData == nil {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(1)"))
	}
	if strings.Trim(ir.AccessData.AccessToken, " ") == "" {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(2)"))
	}
	usr, castedToUserType = ir.AccessData.UserData.(IExpectedUser)
	if !castedToUserType {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(3)"))
	}

	return CreateAuthorizedContext(usr, ir.AccessData.Scope, ir.AccessData.AccessToken)
}

func CheckRequiredScopeSatisfied(responseWriter http.ResponseWriter, authorizedScope string, functionToCheckRequiredScope StringPredicate) {
	if !functionToCheckRequiredScope(authorizedScope) {
		panic(createOsinAuthorizeError(E_INSUFFICIENT_SCOPE, errorMapKeys[E_INSUFFICIENT_SCOPE]))
	}
}

func ServeAccessTokenWithRouter(ctx *context.Context) {
	w := ctx.ResponseWriter
	r := ctx.Request

	InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(r)

	resp := OsinServerObject.NewResponse()
	if ir := OsinServerObject.HandleInfoRequest(resp, r); ir != nil {
		OsinServerObject.FinishInfoRequest(resp, r, ir)
	}

	if resp.IsError {
		OverwriteOsinResponseErrorWithOwn(resp)
	}
	osin.OutputJSON(resp, w, r)
}

func setExpirationForAccessRequest(accessRequest *osin.AccessRequest) {
	accessRequest.Expiration = 60 * 60 * 24 * 365 * 10 //Ten years
	//accessRequest.Expiration = 60 * 60 * 24 * 365 * 1 //One year
	// accessRequest.Expiration = 60 * 60 * 24 //One day
	//beego.Warning("Currently hardcoded the access token expiration to one year, is this correct?")
}

func ExtractAccessTokenFromSuccessfulResponseData(responseData osin.ResponseData) (string, bool) {
	if token, ok := responseData[cOSIN_ACCESS_OUTPUT_ACCESS_TOKEN_MAP_KEY]; ok {
		if stringToken, ok := token.(string); ok {
			return stringToken, true
		}
	}

	return "", false
}

type outputHandlerFunc func(ctx *context.Context) bool

func AuthorizeAndServeNewAccessTokenWithRouter(ctx *context.Context, authUserProvider iAuthUserProvider, setCookies bool, successfulOutputHandler outputHandlerFunc) {
	resp := OsinServerObject.NewResponse()
	r := ctx.Request
	w := ctx.ResponseWriter

	ar := OsinServerObject.HandleAccessRequest(resp, r)
	if ar != nil {
		switch ar.Type {
		/*case osin.AUTHORIZATION_CODE:
		ar.Authorized = true*/
		case osin.REFRESH_TOKEN:
			ar.Authorized = true
			setExpirationForAccessRequest(ar)
		case osin.PASSWORD:
			ar.Authorized, ar.UserData = authUserProvider.DoVerifyUser(ar.Username, ar.Password)
			if !ar.Authorized {
				OverwriteOsinResponseErrorWithOwn_SpecifyErrorKey(resp, E_EMAIL_DOES_NOT_EXIST_OR_PASSWORD_INCORRECT)
			}
			setExpirationForAccessRequest(ar)

			/*case osin.CLIENT_CREDENTIALS:
			ar.Authorized = true*/
		}
		OsinServerObject.FinishAccessRequest(resp, r, ar)
	}

	if resp.IsError {
		if resp.InternalError != nil {
			OverwriteOsinResponseErrorWithOwn(resp)
		}

		resp.ErrorStatusCode = 401
		resp.StatusCode = 401
	}

	if setCookies && !resp.IsError {
		if accessToken, ok := ExtractAccessTokenFromSuccessfulResponseData(resp.Output); ok {
			if ar != nil && ar.UserData != nil {
				if usr, ok := ar.UserData.(IExpectedUser); ok {
					SetUserCookies(ctx, usr.GetId())
				}
			}

			SetEncryptedAccessTokenInCookie(ctx, accessToken)
		}
	}

	if successfulOutputHandler != nil {
		if handledOutput := successfulOutputHandler(ctx); handledOutput {
			return
		}
	}

	err := osin.OutputJSON(resp, w, r)
	checkError(err)
}

func InitOsinServerObject() {
	sconfig := osin.NewServerConfig()

	sconfig.AllowGetAccessRequest = false
	sconfig.AllowedAuthorizeTypes = osin.AllowedAuthorizeType{osin.CODE, osin.TOKEN}
	sconfig.AllowedAccessTypes = osin.AllowedAccessType{
		// osin.AUTHORIZATION_CODE,
		osin.REFRESH_TOKEN,
		osin.PASSWORD,
		// osin.CLIENT_CREDENTIALS,
	}
	OsinServerObject = osin.NewServer(sconfig, NewOAuth2Storage())
}
<commit_msg>Added `user_id` and `success=true` to access token response.<commit_after>package oauth2Utils

import (
	"github.com/RangelReale/osin"
	"github.com/astaxie/beego/context"
	"net/http"
	"strings"

	. "github.com/francoishill/goangi2/utils/cookieUtils"
)

const (
	cOSIN_ACCESS_OUTPUT_ACCESS_TOKEN_MAP_KEY = "access_token"
)

type StringPredicate func(string) bool

var OsinServerObject *osin.Server

type IExpectedUser interface {
	GetRands() string
	GetPassword() string
	GetId() int64
	IAmAUser()
}

type iAuthUserProvider interface {
	DoVerifyUser(userName, password string) (bool, IExpectedUser) //This can handle both login/register
}

func checkError(err error) {
	if err != nil {
		panic(err)
	}
}

func InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(request *http.Request) {
	authorizationHeader := request.Header.Get("Authorization")
	accessTokenFromAuthHeader := ""
	if strings.HasPrefix(authorizationHeader, "Bearer ") {
		//This means if the "code" was set in the get/set form it will be overwritten if we use the Authorization header
		accessTokenFromAuthHeader = authorizationHeader[7:]
		request.ParseForm()
		request.Form.Set("code", accessTokenFromAuthHeader)
	}
}

func OverwriteOsinResponseErrorWithOwn(osinResponse *osin.Response) {
	errKey, ok := osinResponse.Output["error"].(string)
	if ok {
		if errKey == osin.E_INVALID_REQUEST {
			osinResponse.SetError(errKey, errorMapKeys[errKey])
		}
	}
}

func OverwriteOsinResponseErrorWithOwn_SpecifyErrorKey(osinResponse *osin.Response, errorKey string) {
	osinResponse.SetError(errorKey, errorMapKeys[errorKey])
}

func GetAuthorizedContextFromAccessToken(osinResponse *osin.Response, ctx *context.Context) *AuthorizedContext {
	InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(ctx.Request)

	var usr IExpectedUser
	var castedToUserType bool

	ir := OsinServerObject.HandleInfoRequest(osinResponse, ctx.Request)
	if ir == nil {
		panic(createOsinAuthorizeError(E_INVALID_AUTH_DATA, errorMapKeys[E_INVALID_AUTH_DATA]))
	}

	if ir.AccessData.UserData == nil {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(1)"))
	}
	if strings.Trim(ir.AccessData.AccessToken, " ") == "" {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(2)"))
	}
	usr, castedToUserType = ir.AccessData.UserData.(IExpectedUser)
	if !castedToUserType {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(3)"))
	}

	return CreateAuthorizedContext(usr, ir.AccessData.Scope, ir.AccessData.AccessToken)
}

func CheckRequiredScopeSatisfied(responseWriter http.ResponseWriter, authorizedScope string, functionToCheckRequiredScope StringPredicate) {
	if !functionToCheckRequiredScope(authorizedScope) {
		panic(createOsinAuthorizeError(E_INSUFFICIENT_SCOPE, errorMapKeys[E_INSUFFICIENT_SCOPE]))
	}
}

func ServeAccessTokenWithRouter(ctx *context.Context) {
	w := ctx.ResponseWriter
	r := ctx.Request

	InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(r)

	resp := OsinServerObject.NewResponse()
	if ir := OsinServerObject.HandleInfoRequest(resp, r); ir != nil {
		OsinServerObject.FinishInfoRequest(resp, r, ir)
	}

	if resp.IsError {
		OverwriteOsinResponseErrorWithOwn(resp)
	}
	osin.OutputJSON(resp, w, r)
}

func setExpirationForAccessRequest(accessRequest *osin.AccessRequest) {
	accessRequest.Expiration = 60 * 60 * 24 * 365 * 10 //Ten years
	//accessRequest.Expiration = 60 * 60 * 24 * 365 * 1 //One year
	// accessRequest.Expiration = 60 * 60 * 24 //One day
	//beego.Warning("Currently hardcoded the access token expiration to one year, is this correct?")
}

func ExtractAccessTokenFromSuccessfulResponseData(responseData osin.ResponseData) (string, bool) {
	if token, ok := responseData[cOSIN_ACCESS_OUTPUT_ACCESS_TOKEN_MAP_KEY]; ok {
		if stringToken, ok := token.(string); ok {
			return stringToken, true
		}
	}

	return "", false
}

type outputHandlerFunc func(ctx *context.Context) bool

func AuthorizeAndServeNewAccessTokenWithRouter(ctx *context.Context, authUserProvider iAuthUserProvider, setCookies bool, successfulOutputHandler outputHandlerFunc) {
	resp := OsinServerObject.NewResponse()
	r := ctx.Request
	w := ctx.ResponseWriter

	var userId int64

	ar := OsinServerObject.HandleAccessRequest(resp, r)
	if ar != nil {
		switch ar.Type {
		/*case osin.AUTHORIZATION_CODE:
		ar.Authorized = true*/
		case osin.REFRESH_TOKEN:
			ar.Authorized = true
			setExpirationForAccessRequest(ar)
		case osin.PASSWORD:
			var tmpUser IExpectedUser
			ar.Authorized, tmpUser = authUserProvider.DoVerifyUser(ar.Username, ar.Password)
			if !ar.Authorized {
				OverwriteOsinResponseErrorWithOwn_SpecifyErrorKey(resp, E_EMAIL_DOES_NOT_EXIST_OR_PASSWORD_INCORRECT)
			} else {
				ar.UserData = tmpUser
				userId = tmpUser.GetId()
			}
			setExpirationForAccessRequest(ar)

			/*case osin.CLIENT_CREDENTIALS:
			ar.Authorized = true*/
		}
		OsinServerObject.FinishAccessRequest(resp, r, ar)
	}

	if resp.IsError {
		if resp.InternalError != nil {
			OverwriteOsinResponseErrorWithOwn(resp)
		}

		resp.ErrorStatusCode = 401
		resp.StatusCode = 401
	} else {
		resp.Output["user_id"] = userId
		resp.Output["success"] = true
	}

	if setCookies && !resp.IsError {
		if accessToken, ok := ExtractAccessTokenFromSuccessfulResponseData(resp.Output); ok {
			if ar != nil && ar.UserData != nil {
				if usr, ok := ar.UserData.(IExpectedUser); ok {
					SetUserCookies(ctx, usr.GetId())
				}
			}

			SetEncryptedAccessTokenInCookie(ctx, accessToken)
		}
	}

	if successfulOutputHandler != nil {
		if handledOutput := successfulOutputHandler(ctx); handledOutput {
			return
		}
	}

	err := osin.OutputJSON(resp, w, r)
	checkError(err)
}

func InitOsinServerObject() {
	sconfig := osin.NewServerConfig()

	sconfig.AllowGetAccessRequest = false
	sconfig.AllowedAuthorizeTypes = osin.AllowedAuthorizeType{osin.CODE, osin.TOKEN}
	sconfig.AllowedAccessTypes = osin.AllowedAccessType{
		// osin.AUTHORIZATION_CODE,
		osin.REFRESH_TOKEN,
		osin.PASSWORD,
		// osin.CLIENT_CREDENTIALS,
	}
	OsinServerObject = osin.NewServer(sconfig, NewOAuth2Storage())
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"sync"

	"github.com/dfordsoft/golib/fsutil"
	"github.com/fsnotify/fsnotify"
	"github.com/gin-gonic/gin"
)

var (
	fontFiles   []string
	mutexBooks  sync.Mutex
	mutexMaking sync.Mutex
	books       []*HistoryItem
)

// HistoryItem - 书籍记录，有4种状态，分别是有效，失败，进行，等待
type HistoryItem struct {
	TOCURL       string `template:"tocurl"`
	BookName     string `template:"name"`
	Status       string `template:"status"`
	DownloadLink string `template:"downloadLink"`
	DeleteLink   string `template:"deleteLink"`
}

func homePage(c *gin.Context) {
	c.HTML(http.StatusOK, "home.tmpl", gin.H{
		"title":     "GetNovel",
		"fontFiles": fontFiles,
		"items":     books,
	})
}

type GetNovelAuguments struct {
	TOCURL          string  `form:"tocurl"`
	Format          string  `form:"format"`
	PageType        string  `form:"pageType"`
	LeftMargin      int     `form:"leftMargin"`
	TopMargin       int     `form:"topMargin"`
	TitleFontSize   int     `form:"titleFontSize"`
	ContentFontSize int     `form:"contentFontSize"`
	LineSpacing     float32 `form:"lineSpacing"`
	PagesPerFile    int     `form:"pagesPerFile"`
	ChaptersPerFile int     `form:"chaptersPerFile"`
	FontFile        string  `form:"fontFile"`
	FromTitle       string  `form:"fromTitle"`
	ToTitle         string  `form:"toTitle"`
	FromChapter     int     `form:"fromChapter"`
	ToChapter       int     `form:"toChapter"`
}

func makeEbook(c *gin.Context) {
	var gnargs GetNovelAuguments
	if err := c.ShouldBindJSON(&gnargs); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": fmt.Sprintf("%v", err),
		})
		return
	}
	getnovel, _ := exec.LookPath(`getnovel`)

	if b, e := fsutil.FileExists(getnovel); e != nil || !b {
		if dir, err := filepath.Abs(filepath.Dir(os.Args[0])); err == nil {
			getnovel = filepath.Join(dir, `getnovel`)
		}
	}

	if b, e := fsutil.FileExists(getnovel); e != nil || !b {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "getnovel not found",
		})
		return
	}

	args := []string{
		"-f",
		gnargs.Format,
		"-p",
		gnargs.PageType,
		fmt.Sprintf("--fontFile=%s", gnargs.FontFile),
	}

	if gnargs.Format == "pdf" {
		args = append(args,
			[]string{
				fmt.Sprintf("--leftMargin=%d", gnargs.LeftMargin),
				fmt.Sprintf("--topMargin=%d", gnargs.TopMargin),
				fmt.Sprintf("--titleFontSize=%d", gnargs.TitleFontSize),
				fmt.Sprintf("--contentFontSize=%d", gnargs.ContentFontSize),
				fmt.Sprintf("--lineSpacing=%f", gnargs.LineSpacing),
				fmt.Sprintf("--pagesPerFile=%d", gnargs.PagesPerFile),
				fmt.Sprintf("--chaptersPerFile=%d", gnargs.ChaptersPerFile),
			}...)
	}
	if gnargs.FromTitle != "" {
		args = append(args, fmt.Sprintf("--fromTitle=%s", gnargs.FromTitle))
	}
	if gnargs.ToTitle != "" {
		args = append(args, fmt.Sprintf("--toTitle=%s", gnargs.ToTitle))
	}
	if gnargs.FromChapter != 0 {
		args = append(args, fmt.Sprintf("--fromChapter=%d", gnargs.FromChapter))
	}
	if gnargs.ToChapter != 0 {
		args = append(args, fmt.Sprintf("--toChapter=%d", gnargs.ToChapter))
	}
	args = append(args, gnargs.TOCURL)

	cmd := exec.Command(getnovel, args...)
	kindlegen, _ := exec.LookPath(`kindlegen`)
	if b, e := fsutil.FileExists(kindlegen); e != nil || !b {
		if dir, err := filepath.Abs(filepath.Dir(os.Args[0])); err == nil {
			kindlegen = filepath.Join(dir, `kindlegen`)
		}
	}
	cmd.Env = append(os.Environ(),
		"KINDLEGEN_PATH="+kindlegen, // ignored
	)
	go func() {
		item := &HistoryItem{
			TOCURL:   gnargs.TOCURL,
			BookName: gnargs.TOCURL,
			Status:   "等待制作",
		}
		mutexBooks.Lock()
		books = append(books, item)
		mutexBooks.Unlock()

		mutexMaking.Lock()
		// monitor current directory
		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			log.Println(err)
		}

		dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
		if err != nil {
			log.Println(err)
		}

		go func() {
			err := watcher.Add(dir)
			if err != nil {
				log.Println(err)
				return
			}
			defer watcher.Close()
			for {
				select {
				case event := <-watcher.Events:
					if event.Op&fsnotify.Write == fsnotify.Write {
						if strings.ToLower(filepath.Ext(event.Name)) == ".pdf" {
							item.BookName = filepath.Base(event.Name)
							item.DownloadLink = "/download/pdf/" + filepath.Base(event.Name)
							item.DeleteLink = "/delete/pdf/" + filepath.Base(event.Name)
							return
						}
						if strings.ToLower(filepath.Ext(event.Name)) == ".mobi" ||
							strings.ToLower(filepath.Ext(event.Name)) == ".epub" {
							item.BookName = filepath.Base(event.Name)
							item.DownloadLink = "/download/" + filepath.Base(path.Dir(event.Name)) + "/" + filepath.Base(event.Name)
							item.DeleteLink = "/delete/" + filepath.Base(path.Dir(event.Name)) + "/" + filepath.Base(event.Name)
							return
						}
						if b, e := fsutil.IsDir(event.Name); e == nil && b {
							err = watcher.Add(event.Name)
							if err != nil {
								log.Println(err)
							}
							watcher.Remove(dir)
						}
					}
				case err := <-watcher.Errors:
					if err != nil {
						log.Println("error:", err)
					}
				}
			}
		}()

		item.Status = "制作中"
		err = cmd.Run()
		mutexMaking.Unlock()

		if err != nil {
			item.Status = "制作失败"
		} else {
			item.Status = "有效"
		}
	}()

	c.JSON(http.StatusOK, gin.H{})
}

func downloadBook(c *gin.Context) {
	path := c.Param("path")
	if path == "pdf" {
		path = ""
	}
	name := c.Param("name")
	c.File(filepath.Join(path, name))
}

func deleteBook(c *gin.Context) {
	path := c.Param("path")
	if path == "pdf" {
		path = ""
	}
	name := c.Param("name")
	os.Remove(filepath.Join(path, name))
	mutexBooks.Lock()
	for i, book := range books {
		if book.BookName == strings.Replace(filepath.Join(path, name), "\\", "/", -1) {
			books = append(books[:i], books[i+1:]...)
			break
		}
	}
	mutexBooks.Unlock()
	c.Redirect(http.StatusFound, "/")
}

func main() {
	addr := ":8089"
	if bind, ok := os.LookupEnv("BIND"); ok {
		addr = bind
	}
	r := gin.Default()
	r.LoadHTMLGlob("templates/*")
	r.GET("/", homePage)
	r.GET("/download/:path/:name", downloadBook)
	r.GET("/delete/:path/:name", deleteBook)
	r.POST("/makeebook", makeEbook)

	// glob font files
	matches, err := filepath.Glob("fonts/*.ttf")
	if err != nil {
		panic(err)
	}
	for _, v := range matches {
		fontFiles = append(fontFiles, filepath.Base(v))
	}

	matches, err = filepath.Glob("*.pdf")
	if err == nil {
		for _, v := range matches {
			books = append(books, &HistoryItem{
				BookName:     v,
				Status:       "有效",
				DownloadLink: "/download/pdf/" + v,
				DeleteLink:   "/delete/pdf/" + v,
			})
		}
	}

	matches, err = filepath.Glob("**/*.mobi")
	if err == nil {
		for _, v := range matches {
			books = append(books, &HistoryItem{
				BookName:     filepath.Base(v),
				Status:       "有效",
				DownloadLink: "/download/" + strings.Replace(v, "\\", "/", -1),
				DeleteLink:   "/delete/" + strings.Replace(v, "\\", "/", -1),
			})
		}
	}
	matches, err = filepath.Glob("**/*.epub")
	if err == nil {
		for _, v := range matches {
			books = append(books, &HistoryItem{
				BookName:     filepath.Base(v),
				Status:       "有效",
				DownloadLink: "/download/" + strings.Replace(v, "\\", "/", -1),
				DeleteLink:   "/delete/" + strings.Replace(v, "\\", "/", -1),
			})
		}
	}
	r.Run(addr)
}
<commit_msg>(*)fs notify fix<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"sync"

	"github.com/dfordsoft/golib/fsutil"
	"github.com/fsnotify/fsnotify"
	"github.com/gin-gonic/gin"
)

var (
	fontFiles   []string
	mutexBooks  sync.Mutex
	mutexMaking sync.Mutex
	books       []*HistoryItem
)

// HistoryItem - 书籍记录，有4种状态，分别是有效，失败，进行，等待
type HistoryItem struct {
	TOCURL       string `template:"tocurl"`
	BookName     string `template:"name"`
	Status       string `template:"status"`
	DownloadLink string `template:"downloadLink"`
	DeleteLink   string `template:"deleteLink"`
}

func homePage(c *gin.Context) {
	c.HTML(http.StatusOK, "home.tmpl", gin.H{
		"title":     "GetNovel",
		"fontFiles": fontFiles,
		"items":     books,
	})
}

type GetNovelAuguments struct {
	TOCURL          string  `form:"tocurl"`
	Format          string  `form:"format"`
	PageType        string  `form:"pageType"`
	LeftMargin      int     `form:"leftMargin"`
	TopMargin       int     `form:"topMargin"`
	TitleFontSize   int     `form:"titleFontSize"`
	ContentFontSize int     `form:"contentFontSize"`
	LineSpacing     float32 `form:"lineSpacing"`
	PagesPerFile    int     `form:"pagesPerFile"`
	ChaptersPerFile int     `form:"chaptersPerFile"`
	FontFile        string  `form:"fontFile"`
	FromTitle       string  `form:"fromTitle"`
	ToTitle         string  `form:"toTitle"`
	FromChapter     int     `form:"fromChapter"`
	ToChapter       int     `form:"toChapter"`
}

func makeEbook(c *gin.Context) {
	var gnargs GetNovelAuguments
	if err := c.ShouldBindJSON(&gnargs); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": fmt.Sprintf("%v", err),
		})
		return
	}
	getnovel, _ := exec.LookPath(`getnovel`)

	if b, e := fsutil.FileExists(getnovel); e != nil || !b {
		if dir, err := filepath.Abs(filepath.Dir(os.Args[0])); err == nil {
			getnovel = filepath.Join(dir, `getnovel`)
		}
	}

	if b, e := fsutil.FileExists(getnovel); e != nil || !b {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "getnovel not found",
		})
		return
	}

	args := []string{
		"-f",
		gnargs.Format,
		"-p",
		gnargs.PageType,
		fmt.Sprintf("--fontFile=%s", gnargs.FontFile),
	}

	if gnargs.Format == "pdf" {
		args = append(args,
			[]string{
				fmt.Sprintf("--leftMargin=%d", gnargs.LeftMargin),
				fmt.Sprintf("--topMargin=%d", gnargs.TopMargin),
				fmt.Sprintf("--titleFontSize=%d", gnargs.TitleFontSize),
				fmt.Sprintf("--contentFontSize=%d", gnargs.ContentFontSize),
				fmt.Sprintf("--lineSpacing=%f", gnargs.LineSpacing),
				fmt.Sprintf("--pagesPerFile=%d", gnargs.PagesPerFile),
				fmt.Sprintf("--chaptersPerFile=%d", gnargs.ChaptersPerFile),
			}...)
	}
	if gnargs.FromTitle != "" {
		args = append(args, fmt.Sprintf("--fromTitle=%s", gnargs.FromTitle))
	}
	if gnargs.ToTitle != "" {
		args = append(args, fmt.Sprintf("--toTitle=%s", gnargs.ToTitle))
	}
	if gnargs.FromChapter != 0 {
		args = append(args, fmt.Sprintf("--fromChapter=%d", gnargs.FromChapter))
	}
	if gnargs.ToChapter != 0 {
		args = append(args, fmt.Sprintf("--toChapter=%d", gnargs.ToChapter))
	}
	args = append(args, gnargs.TOCURL)

	cmd := exec.Command(getnovel, args...)

	kindlegenName := `kindlegen`
	if runtime.GOOS == "windows" {
		kindlegenName = `kindlegen.exe`
	}
	kindlegenPath, _ := exec.LookPath(kindlegenName)
	if b, e := fsutil.FileExists(kindlegenPath); e != nil || !b {
		if dir, err := filepath.Abs(filepath.Dir(os.Args[0])); err == nil {
			kindlegenPath = filepath.Join(dir, kindlegenName)
		}
	}
	if !filepath.IsAbs(kindlegenPath) {
		kindlegenPath, _ = filepath.Abs(kindlegenPath)
	}
	cmd.Env = append(os.Environ(),
		"KINDLEGEN_PATH="+kindlegenPath, // ignored
	)
	go func() {
		item := &HistoryItem{
			TOCURL:   gnargs.TOCURL,
			BookName: gnargs.TOCURL,
			Status:   "等待制作",
		}
		mutexBooks.Lock()
		books = append(books, item)
		mutexBooks.Unlock()

		mutexMaking.Lock()
		// monitor current directory
		watcher, err := fsnotify.NewWatcher()
		if err != nil {
			log.Println(err)
		}

		dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
		if err != nil {
			log.Println(err)
		}

		go func() {
			err := watcher.Add(dir)
			if err != nil {
				log.Println(err)
				return
			}
			defer watcher.Close()
			for {
				select {
				case event := <-watcher.Events:
					if event.Op&fsnotify.Write == fsnotify.Write {
						if strings.ToLower(filepath.Ext(event.Name)) == ".pdf" {
							baseName := filepath.Base(event.Name)
							item.BookName = baseName
							item.DownloadLink = "/download/pdf/" + baseName
							item.DeleteLink = "/delete/pdf/" + baseName
							return
						}
						if strings.ToLower(filepath.Ext(event.Name)) == ".mobi" ||
							strings.ToLower(filepath.Ext(event.Name)) == ".epub" {
							baseName := filepath.Base(event.Name)
							item.BookName = baseName
							item.DownloadLink = "/download/" + baseName[:len(baseName)-5] + "/" + baseName
							item.DeleteLink = "/delete/" + baseName[:len(baseName)-5] + "/" + baseName
							return
						}
						if b, e := fsutil.IsDir(event.Name); e == nil && b {
							err = watcher.Add(event.Name)
							if err != nil {
								log.Println(err)
							}
							watcher.Remove(dir)
						}
					}
				case err := <-watcher.Errors:
					if err != nil {
						log.Println("error:", err)
					}
				}
			}
		}()

		item.Status = "制作中"
		err = cmd.Run()
		mutexMaking.Unlock()

		if err != nil {
			item.Status = "制作失败"
		} else {
			item.Status = "有效"
		}
	}()

	c.JSON(http.StatusOK, gin.H{})
}

func downloadBook(c *gin.Context) {
	path := c.Param("path")
	if path == "pdf" {
		path = ""
	}
	name := c.Param("name")
	c.File(filepath.Join(path, name))
}

func deleteBook(c *gin.Context) {
	path := c.Param("path")
	if path == "pdf" {
		path = ""
	}
	name := c.Param("name")
	os.Remove(filepath.Join(path, name))
	mutexBooks.Lock()
	for i, book := range books {
		if book.BookName == strings.Replace(filepath.Join(path, name), "\\", "/", -1) {
			books = append(books[:i], books[i+1:]...)
			break
		}
	}
	mutexBooks.Unlock()
	c.Redirect(http.StatusFound, "/")
}

func main() {
	addr := ":8089"
	if bind, ok := os.LookupEnv("BIND"); ok {
		addr = bind
	}
	r := gin.Default()
	r.LoadHTMLGlob("templates/*")
	r.GET("/", homePage)
	r.GET("/download/:path/:name", downloadBook)
	r.GET("/delete/:path/:name", deleteBook)
	r.POST("/makeebook", makeEbook)

	// glob font files
	matches, err := filepath.Glob("fonts/*.ttf")
	if err != nil {
		panic(err)
	}
	for _, v := range matches {
		fontFiles = append(fontFiles, filepath.Base(v))
	}

	matches, err = filepath.Glob("*.pdf")
	if err == nil {
		for _, v := range matches {
			books = append(books, &HistoryItem{
				BookName:     v,
				Status:       "有效",
				DownloadLink: "/download/pdf/" + v,
				DeleteLink:   "/delete/pdf/" + v,
			})
		}
	}

	matches, err = filepath.Glob("**/*.mobi")
	if err == nil {
		for _, v := range matches {
			books = append(books, &HistoryItem{
				BookName:     filepath.Base(v),
				Status:       "有效",
				DownloadLink: "/download/" + strings.Replace(v, "\\", "/", -1),
				DeleteLink:   "/delete/" + strings.Replace(v, "\\", "/", -1),
			})
		}
	}
	matches, err = filepath.Glob("**/*.epub")
	if err == nil {
		for _, v := range matches {
			books = append(books, &HistoryItem{
				BookName:     filepath.Base(v),
				Status:       "有效",
				DownloadLink: "/download/" + strings.Replace(v, "\\", "/", -1),
				DeleteLink:   "/delete/" + strings.Replace(v, "\\", "/", -1),
			})
		}
	}
	r.Run(addr)
}
<|endoftext|>


<commit_before>package godirwalk

import (
	"fmt"
	"sort"
	"testing"
)

func ensureStringSlicesMatch(tb testing.TB, actual, expected []string) {
	tb.Helper()

	results := make(map[string]int)

	for _, s := range actual {
		results[s] -= 1
	}
	for _, s := range expected {
		results[s] += 1
	}

	keys := make([]string, 0, len(results))
	for k := range results {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, s := range keys {
		v, ok := results[s]
		if !ok {
			panic(fmt.Errorf("cannot find key: %s", s))
		}
		switch v {
		case -1:
			tb.Errorf("GOT: %q (extra)", s)
		case 0:
			// both slices have this key
		case 1:
			tb.Errorf("WANT: %q (missing)", s)
		default:
			tb.Errorf("key has invalid value: %s: %d", s, v)
		}
	}
}
<commit_msg>test helper panics when unreachable code hit<commit_after>package godirwalk

import (
	"fmt"
	"sort"
	"testing"
)

func ensureStringSlicesMatch(tb testing.TB, actual, expected []string) {
	tb.Helper()

	results := make(map[string]int)

	for _, s := range actual {
		results[s] -= 1
	}
	for _, s := range expected {
		results[s] += 1
	}

	keys := make([]string, 0, len(results))
	for k := range results {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, s := range keys {
		v, ok := results[s]
		if !ok {
			panic(fmt.Errorf("cannot find key: %s", s)) // panic because this function is broken
		}
		switch v {
		case -1:
			tb.Errorf("GOT: %q (extra)", s)
		case 0:
			// both slices have this key
		case 1:
			tb.Errorf("WANT: %q (missing)", s)
		default:
			panic(fmt.Errorf("key has invalid value: %s: %d", s, v)) // panic because this function is broken
		}
	}
}
<|endoftext|>


<commit_before>package registry

import (
	"github.com/astaxie/beego"
	"github.com/sirupsen/logrus"
	"github.com/snagles/docker-registry-manager/app/models"
)

// RepositoriesController controls interactions between the UI and any repository related information
type RepositoriesController struct {
	beego.Controller
}

// GetRepositories returns the template for the table on the repositories page
func (c *RepositoriesController) GetRepositories() {

	registryName := c.Ctx.Input.Param(":registryName")

	if r, ok := manager.AllRegistries.Registries[registryName]; ok {
		c.Data["registryName"] = registryName
		c.Data["repositories"] = r.Repositories
	}
	// Index template
	c.TplName = "repositories.tpl"
}

// GetAllRepositoryCount returns the number of currently available repositories
func (c *RepositoriesController) GetAllRepositoryCount() {
	c.Data["registries"] = manager.AllRegistries.Registries

	var count int
	for _, reg := range manager.AllRegistries.Registries {
		repositories, err := reg.Registry.Repositories()
		if err != nil {
			logrus.Errorf("Could not connect to registry (%s) to get the repository count: %s ", reg.Registry.URL, err.Error())
		}
		count += len(repositories)
	}
	repositoryCount := struct {
		Count int
	}{
		count,
	}

	c.Data["json"] = &repositoryCount
	c.ServeJSON()
}

// GetAllRepositories returns the template for the all registries page
func (c *RepositoriesController) GetAllRepositories() {

	repos := make(map[string][]*manager.Repository)

	for registryName, registry := range manager.AllRegistries.Registries {
		for _, repository := range registry.Repositories {
			repos[registryName] = append(repos[registryName], repository)
		}
	}

	c.Data["repositories"] = repos

	// Index template
	c.TplName = "allrepositories.tpl"
}
<commit_msg>Use cached registry data for count information. #135<commit_after>package registry

import (
	"github.com/astaxie/beego"
	"github.com/snagles/docker-registry-manager/app/models"
)

// RepositoriesController controls interactions between the UI and any repository related information
type RepositoriesController struct {
	beego.Controller
}

// GetRepositories returns the template for the table on the repositories page
func (c *RepositoriesController) GetRepositories() {

	registryName := c.Ctx.Input.Param(":registryName")

	if r, ok := manager.AllRegistries.Registries[registryName]; ok {
		c.Data["registryName"] = registryName
		c.Data["repositories"] = r.Repositories
	}
	// Index template
	c.TplName = "repositories.tpl"
}

// GetAllRepositoryCount returns the number of currently available repositories
func (c *RepositoriesController) GetAllRepositoryCount() {
	c.Data["registries"] = manager.AllRegistries.Registries

	var repositoryCount struct {
		Count int
	}
	for _, reg := range manager.AllRegistries.Registries {
		repositoryCount.Count += len(reg.Repositories)
	}

	c.Data["json"] = &repositoryCount
	c.ServeJSON()
}

// GetAllRepositories returns the template for the all registries page
func (c *RepositoriesController) GetAllRepositories() {

	repos := make(map[string][]*manager.Repository)

	for registryName, registry := range manager.AllRegistries.Registries {
		for _, repository := range registry.Repositories {
			repos[registryName] = append(repos[registryName], repository)
		}
	}

	c.Data["repositories"] = repos

	// Index template
	c.TplName = "allrepositories.tpl"
}
<|endoftext|>


<commit_before>package main

/*
 * An example of how to use lxd's golang /dev/lxd client. This is intended to
 * be run from inside a container.
 */

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"

	"github.com/gorilla/websocket"
	"gopkg.in/yaml.v2"
)

type devLxdDialer struct {
	Path string
}

func (d devLxdDialer) devLxdDial(network, path string) (net.Conn, error) {
	addr, err := net.ResolveUnixAddr("unix", d.Path)
	if err != nil {
		return nil, err
	}

	conn, err := net.DialUnix("unix", nil, addr)
	if err != nil {
		return nil, err
	}

	return conn, err
}

var devLxdTransport = &http.Transport{
	Dial: devLxdDialer{"/dev/lxd/sock"}.devLxdDial,
}

func devlxdMonitor(c http.Client) {
	dialer := websocket.Dialer{
		NetDial: devLxdTransport.Dial,
	}

	conn, _, err := dialer.Dial("ws://unix.socket/1.0/events", nil)
	if err != nil {
		return
	}

	for {
		_, data, err := conn.ReadMessage()
		if err != nil {
			return
		}

		message := make(map[string]interface{})
		err = json.Unmarshal(data, &message)
		if err != nil {
			return
		}
		message["timestamp"] = nil

		msg, err := yaml.Marshal(&message)
		if err != nil {
			return
		}

		fmt.Printf("%s\n", msg)
	}
}

func main() {
	c := http.Client{Transport: devLxdTransport}
	raw, err := c.Get("http://meshuggah-rocks/")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if raw.StatusCode != http.StatusOK {
		fmt.Println("http error", raw.StatusCode)
		result, err := ioutil.ReadAll(raw.Body)
		if err == nil {
			fmt.Println(string(result))
		}
		os.Exit(1)
	}

	result := []string{}
	if err := json.NewDecoder(raw.Body).Decode(&result); err != nil {
		fmt.Println("err decoding response", err)
		os.Exit(1)
	}

	if result[0] != "/1.0" {
		fmt.Println("unknown response", result)
		os.Exit(1)
	}

	if len(os.Args) > 1 {
		if os.Args[1] == "monitor" {
			devlxdMonitor(c)
			os.Exit(0)
		}

		raw, err := c.Get(fmt.Sprintf("http://meshuggah-rocks/1.0/config/%s", os.Args[1]))
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		value, err := ioutil.ReadAll(raw.Body)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		fmt.Println(string(value))
	} else {
		fmt.Println("/dev/lxd ok")
	}
}
<commit_msg>tests: Avoid err == nil pattern<commit_after>package main

/*
 * An example of how to use lxd's golang /dev/lxd client. This is intended to
 * be run from inside a container.
 */

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"

	"github.com/gorilla/websocket"
	"gopkg.in/yaml.v2"
)

type devLxdDialer struct {
	Path string
}

func (d devLxdDialer) devLxdDial(network, path string) (net.Conn, error) {
	addr, err := net.ResolveUnixAddr("unix", d.Path)
	if err != nil {
		return nil, err
	}

	conn, err := net.DialUnix("unix", nil, addr)
	if err != nil {
		return nil, err
	}

	return conn, err
}

var devLxdTransport = &http.Transport{
	Dial: devLxdDialer{"/dev/lxd/sock"}.devLxdDial,
}

func devlxdMonitor(c http.Client) {
	dialer := websocket.Dialer{
		NetDial: devLxdTransport.Dial,
	}

	conn, _, err := dialer.Dial("ws://unix.socket/1.0/events", nil)
	if err != nil {
		return
	}

	for {
		_, data, err := conn.ReadMessage()
		if err != nil {
			return
		}

		message := make(map[string]interface{})
		err = json.Unmarshal(data, &message)
		if err != nil {
			return
		}
		message["timestamp"] = nil

		msg, err := yaml.Marshal(&message)
		if err != nil {
			return
		}

		fmt.Printf("%s\n", msg)
	}
}

func main() {
	c := http.Client{Transport: devLxdTransport}
	raw, err := c.Get("http://meshuggah-rocks/")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if raw.StatusCode != http.StatusOK {
		fmt.Println("http error", raw.StatusCode)
		result, err := ioutil.ReadAll(raw.Body)
		if err != nil {
			os.Exit(1)
		}

		fmt.Println(string(result))
	}

	result := []string{}
	if err := json.NewDecoder(raw.Body).Decode(&result); err != nil {
		fmt.Println("err decoding response", err)
		os.Exit(1)
	}

	if result[0] != "/1.0" {
		fmt.Println("unknown response", result)
		os.Exit(1)
	}

	if len(os.Args) > 1 {
		if os.Args[1] == "monitor" {
			devlxdMonitor(c)
			os.Exit(0)
		}

		raw, err := c.Get(fmt.Sprintf("http://meshuggah-rocks/1.0/config/%s", os.Args[1]))
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		value, err := ioutil.ReadAll(raw.Body)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		fmt.Println(string(value))
	} else {
		fmt.Println("/dev/lxd ok")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/miekg/dns"
	"os"
	"strings"
	"time"
)

const (
	TIMEOUT time.Duration = 5 // seconds
)

var (
	localm *dns.Msg
	localc *dns.Client
	conf   *dns.ClientConfig
)

func localQuery(qname string, qtype uint16) (r *dns.Msg, err error) {
	localm.SetQuestion(qname, qtype)
	for i := range conf.Servers {
		server := conf.Servers[i]
		r, err := localc.Exchange(localm, server+":"+conf.Port)
		if r == nil || r.Rcode == dns.RcodeNameError || r.Rcode == dns.RcodeSuccess {
			return r, err
		}
	}
	return nil, errors.New("No name server to answer the question")
}

func main() {
	var err error
	if len(os.Args) != 2 {
		fmt.Printf("%s ZONE\n", os.Args[0])
		os.Exit(1)
	}
	conf, err = dns.ClientConfigFromFile("/etc/resolv.conf")
	if conf == nil {
		fmt.Printf("Cannot initialize the local resolver: %s\n", err)
		os.Exit(1)
	}
	localm = new(dns.Msg)
	localm.MsgHdr.RecursionDesired = true
	localm.Question = make([]dns.Question, 1)
	localc = new(dns.Client)
	localc.ReadTimeout = TIMEOUT * 1e9
	r, err := localQuery(dns.Fqdn(os.Args[1]), dns.TypeNS)
	if r == nil {
		fmt.Printf("Cannot retrieve the list of name servers for %s: %s\n", dns.Fqdn(os.Args[1]), err)
		os.Exit(1)
	}
	if r.Rcode == dns.RcodeNameError {
		fmt.Printf("No such domain %s\n", dns.Fqdn(os.Args[1]))
		os.Exit(1)
	}
	m := new(dns.Msg)
	m.MsgHdr.RecursionDesired = false
	m.Question = make([]dns.Question, 1)
	c := new(dns.Client)
	c.ReadTimeout = TIMEOUT * 1e9
	success := true
	numNS := 0
	for _, ans := range r.Answer {
		switch ans.(type) {
		case *dns.RR_NS:
			nameserver := ans.(*dns.RR_NS).Ns
			numNS += 1
			ips := make([]string, 0)
			fmt.Printf("%s : ", nameserver)
			ra, err := localQuery(nameserver, dns.TypeA)
			if ra == nil {
				fmt.Printf("Error getting the IPv4 address of %s: %s\n", nameserver, err)
				os.Exit(1)
			}
			if ra.Rcode != dns.RcodeSuccess {
				fmt.Printf("Error getting the IPv4 address of %s: %s\n", nameserver, dns.Rcode_str[ra.Rcode])
				os.Exit(1)
			}
			for _, ansa := range ra.Answer {
				switch ansa.(type) {
				case *dns.RR_A:
					ips = append(ips, ansa.(*dns.RR_A).A.String())
				}
			}
			raaaa, err := localQuery(nameserver, dns.TypeAAAA)
			if raaaa == nil {
				fmt.Printf("Error getting the IPv6 address of %s: %s\n", nameserver, err)
				os.Exit(1)
			}
			if raaaa.Rcode != dns.RcodeSuccess {
				fmt.Printf("Error getting the IPv6 address of %s: %s\n", nameserver, dns.Rcode_str[raaaa.Rcode])
				os.Exit(1)
			}
			for _, ansaaaa := range raaaa.Answer {
				switch ansaaaa.(type) {
				case *dns.RR_AAAA:
					ips = append(ips, ansaaaa.(*dns.RR_AAAA).AAAA.String())
				}
			}
			if len(ips) == 0 {
				success = false
				fmt.Printf("No IP address for this server")
			}
			for _, ip := range ips {
				m.Question[0] = dns.Question{dns.Fqdn(os.Args[1]), dns.TypeSOA, dns.ClassINET}
				nsAddressPort := ""
				if strings.ContainsAny(":", ip) {
					/* IPv6 address */
					nsAddressPort = "[" + ip + "]:53"
				} else {
					nsAddressPort = ip + ":53"
				}
				soa, err := c.Exchange(m, nsAddressPort)
				// TODO: retry if timeout? Otherwise, one lost UDP packet and it is the end
				if soa == nil {
					success = false
					fmt.Printf("%s (%s) ", ip, err)
				} else {
					if soa.Rcode != dns.RcodeSuccess {
						success = false
						fmt.Printf("%s (%s) ", ips, dns.Rcode_str[soa.Rcode])
					} else {
						if len(soa.Answer) == 0 { // May happen if the server is a recursor, not authoritative, since we query with RD=0
							success = false
							fmt.Printf("%s (0 answer) ", ip)
						} else {
							rsoa := soa.Answer[0]
							switch rsoa.(type) {
							case *dns.RR_SOA:
								if soa.MsgHdr.Authoritative {
									// TODO: test if all name servers have the same serial ?
									fmt.Printf("%s (%d) ", ips, rsoa.(*dns.RR_SOA).Serial)
								} else {
									success = false
									fmt.Printf("%s (not authoritative) ", ips)
								}
							}
						}
					}
				}
			}
			fmt.Printf("\n")
		}
	}
	if numNS == 0 {
		fmt.Printf("No NS records for \"%s\". It is probably a CNAME to a domain but not a zone\n", dns.Fqdn(os.Args[1]))
		os.Exit(1)
	}
	if success {
		os.Exit(0)
	}
	os.Exit(1)
}
<commit_msg>Go comments<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/miekg/dns"
	"os"
	"strings"
	"time"
)

const (
	TIMEOUT time.Duration = 5 // seconds
)

var (
	localm *dns.Msg
	localc *dns.Client
	conf   *dns.ClientConfig
)

func localQuery(qname string, qtype uint16) (r *dns.Msg, err error) {
	localm.SetQuestion(qname, qtype)
	for i := range conf.Servers {
		server := conf.Servers[i]
		r, err := localc.Exchange(localm, server+":"+conf.Port)
		if r == nil || r.Rcode == dns.RcodeNameError || r.Rcode == dns.RcodeSuccess {
			return r, err
		}
	}
	return nil, errors.New("No name server to answer the question")
}

func main() {
	var err error
	if len(os.Args) != 2 {
		fmt.Printf("%s ZONE\n", os.Args[0])
		os.Exit(1)
	}
	conf, err = dns.ClientConfigFromFile("/etc/resolv.conf")
	if conf == nil {
		fmt.Printf("Cannot initialize the local resolver: %s\n", err)
		os.Exit(1)
	}
	localm = new(dns.Msg)
	localm.MsgHdr.RecursionDesired = true
	localm.Question = make([]dns.Question, 1)
	localc = new(dns.Client)
	localc.ReadTimeout = TIMEOUT * 1e9
	r, err := localQuery(dns.Fqdn(os.Args[1]), dns.TypeNS)
	if r == nil {
		fmt.Printf("Cannot retrieve the list of name servers for %s: %s\n", dns.Fqdn(os.Args[1]), err)
		os.Exit(1)
	}
	if r.Rcode == dns.RcodeNameError {
		fmt.Printf("No such domain %s\n", dns.Fqdn(os.Args[1]))
		os.Exit(1)
	}
	m := new(dns.Msg)
	m.MsgHdr.RecursionDesired = false
	m.Question = make([]dns.Question, 1)
	c := new(dns.Client)
	c.ReadTimeout = TIMEOUT * 1e9
	success := true
	numNS := 0
	for _, ans := range r.Answer {
		switch ans.(type) {
		case *dns.RR_NS:
			nameserver := ans.(*dns.RR_NS).Ns
			numNS += 1
			ips := make([]string, 0)
			fmt.Printf("%s : ", nameserver)
			ra, err := localQuery(nameserver, dns.TypeA)
			if ra == nil {
				fmt.Printf("Error getting the IPv4 address of %s: %s\n", nameserver, err)
				os.Exit(1)
			}
			if ra.Rcode != dns.RcodeSuccess {
				fmt.Printf("Error getting the IPv4 address of %s: %s\n", nameserver, dns.Rcode_str[ra.Rcode])
				os.Exit(1)
			}
			for _, ansa := range ra.Answer {
				switch ansa.(type) {
				case *dns.RR_A:
					ips = append(ips, ansa.(*dns.RR_A).A.String())
				}
			}
			raaaa, err := localQuery(nameserver, dns.TypeAAAA)
			if raaaa == nil {
				fmt.Printf("Error getting the IPv6 address of %s: %s\n", nameserver, err)
				os.Exit(1)
			}
			if raaaa.Rcode != dns.RcodeSuccess {
				fmt.Printf("Error getting the IPv6 address of %s: %s\n", nameserver, dns.Rcode_str[raaaa.Rcode])
				os.Exit(1)
			}
			for _, ansaaaa := range raaaa.Answer {
				switch ansaaaa.(type) {
				case *dns.RR_AAAA:
					ips = append(ips, ansaaaa.(*dns.RR_AAAA).AAAA.String())
				}
			}
			if len(ips) == 0 {
				success = false
				fmt.Printf("No IP address for this server")
			}
			for _, ip := range ips {
				m.Question[0] = dns.Question{dns.Fqdn(os.Args[1]), dns.TypeSOA, dns.ClassINET}
				nsAddressPort := ""
				if strings.ContainsAny(":", ip) {
					// IPv6 address
					nsAddressPort = "[" + ip + "]:53"
				} else {
					nsAddressPort = ip + ":53"
				}
				soa, err := c.Exchange(m, nsAddressPort)
				// TODO: retry if timeout? Otherwise, one lost UDP packet and it is the end
				if soa == nil {
					success = false
					fmt.Printf("%s (%s) ", ip, err)
				} else {
					if soa.Rcode != dns.RcodeSuccess {
						success = false
						fmt.Printf("%s (%s) ", ips, dns.Rcode_str[soa.Rcode])
					} else {
						if len(soa.Answer) == 0 { // May happen if the server is a recursor, not authoritative, since we query with RD=0
							success = false
							fmt.Printf("%s (0 answer) ", ip)
						} else {
							rsoa := soa.Answer[0]
							switch rsoa.(type) {
							case *dns.RR_SOA:
								if soa.MsgHdr.Authoritative {
									// TODO: test if all name servers have the same serial ?
									fmt.Printf("%s (%d) ", ips, rsoa.(*dns.RR_SOA).Serial)
								} else {
									success = false
									fmt.Printf("%s (not authoritative) ", ips)
								}
							}
						}
					}
				}
			}
			fmt.Printf("\n")
		}
	}
	if numNS == 0 {
		fmt.Printf("No NS records for \"%s\". It is probably a CNAME to a domain but not a zone\n", dns.Fqdn(os.Args[1]))
		os.Exit(1)
	}
	if success {
		os.Exit(0)
	}
	os.Exit(1)
}
<|endoftext|>


<commit_before>package main

import (
	"compress/gzip"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"time"
)

func logDuration(m string, startTime time.Time) {
	log.Printf("Completed %v in %v", m, time.Since(startTime))
}

func backupTo(w io.Writer) (err error) {
	fch := make(chan *namedFile)
	ech := make(chan error)
	qch := make(chan bool)

	defer close(qch)

	defer logDuration("backup", time.Now())

	go pathGenerator("", fch, ech, qch)

	gz := gzip.NewWriter(w)
	defer func() {
		e := gz.Close()
		if err != nil {
			err = e
		}
	}()

	enc := json.NewEncoder(gz)

	for {
		select {
		case f, ok := <-fch:
			if !ok {
				return nil
			}
			log.Printf("backing up %v", f.name)
			err := enc.Encode(map[string]interface{}{
				"path": f.name,
				"meta": f.meta,
			})
			if err != nil {
				return err
			}
		case e, ok := <-ech:
			if ok {
				return e
			}
			ech = nil
		}
	}

	panic("unreachable")
}

func recordBackupObject(h string) error {
	f, err := os.Create(filepath.Join(*root, ".backup"))
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = fmt.Fprintf(f, "%v\n", h)
	return err
}

func recordRemoteBackupObjects(h string) {
	rn, err := findRemoteNodes()
	if err != nil {
		log.Printf("Error getting remote nodes for recording backup: %v",
			err)
		return
	}
	for _, n := range rn {
		u := fmt.Sprintf("http://%s%s",
			n.Address(), markBackupPrefix)
		c := n.Client()
		res, err := c.Post(u, "application/octet-stream", nil)
		if err != nil {
			log.Printf("Error posting to %v: %v", u, err)
			continue
		}
		res.Body.Close()
		if res.StatusCode != 204 {
			log.Printf("HTTP Error posting to %v: %v", u, res.Status)
		}
	}
}

func backupToCBFS(fn string) error {
	f, err := NewHashRecord(*root, "")
	if err != nil {
		return err
	}
	defer f.Close()

	pr, pw := io.Pipe()

	go func() { pw.CloseWithError(backupTo(pw)) }()

	h, length, err := f.Process(pr)
	if err != nil {
		return err
	}

	err = recordBlobOwnership(h, length, true)
	if err != nil {
		return err
	}

	fm := fileMeta{
		OID:      h,
		Length:   length,
		Modified: time.Now().UTC(),
	}

	err = storeMeta(fn, fm, 1)
	if err != nil {
		return err
	}

	err = recordBackupObject(h)
	if err != nil {
		log.Printf("Failed to record backup OID: %v", err)
	}

	go recordRemoteBackupObjects(h)

	log.Printf("Replicating backup %v.", h)
	go increaseReplicaCount(h, length, globalConfig.MinReplicas-1)

	return nil
}

func doMarkBackup(w http.ResponseWriter, req *http.Request, h string) {
	err := recordBackupObject(h)
	if err != nil {
		w.WriteHeader(500)
		fmt.Fprintf(w, "Error marking backup: %v", err)
	}
	w.WriteHeader(204)
}

func doBackupDocs(w http.ResponseWriter, req *http.Request) {
	fn := req.FormValue("fn")
	if fn == "" {
		w.WriteHeader(400)
		return
	}

	if bg, _ := strconv.ParseBool(req.FormValue("bg")); bg {
		go func() {
			err := backupToCBFS(fn)
			if err != nil {
				log.Printf("Error performing bg backup: %v", err)
			}
		}()
		w.WriteHeader(202)
		return
	}

	err := backupToCBFS(fn)
	if err != nil {
		w.WriteHeader(500)
		fmt.Fprintf(w, "Error performing backup: %v", err)
		return
	}

	w.WriteHeader(201)
}
<commit_msg>I need to pass along the hash when marking.<commit_after>package main

import (
	"compress/gzip"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"time"
)

func logDuration(m string, startTime time.Time) {
	log.Printf("Completed %v in %v", m, time.Since(startTime))
}

func backupTo(w io.Writer) (err error) {
	fch := make(chan *namedFile)
	ech := make(chan error)
	qch := make(chan bool)

	defer close(qch)

	defer logDuration("backup", time.Now())

	go pathGenerator("", fch, ech, qch)

	gz := gzip.NewWriter(w)
	defer func() {
		e := gz.Close()
		if err != nil {
			err = e
		}
	}()

	enc := json.NewEncoder(gz)

	for {
		select {
		case f, ok := <-fch:
			if !ok {
				return nil
			}
			log.Printf("backing up %v", f.name)
			err := enc.Encode(map[string]interface{}{
				"path": f.name,
				"meta": f.meta,
			})
			if err != nil {
				return err
			}
		case e, ok := <-ech:
			if ok {
				return e
			}
			ech = nil
		}
	}

	panic("unreachable")
}

func recordBackupObject(h string) error {
	f, err := os.Create(filepath.Join(*root, ".backup"))
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = fmt.Fprintf(f, "%v\n", h)
	return err
}

func recordRemoteBackupObjects(h string) {
	rn, err := findRemoteNodes()
	if err != nil {
		log.Printf("Error getting remote nodes for recording backup: %v",
			err)
		return
	}
	for _, n := range rn {
		u := fmt.Sprintf("http://%s%s%s",
			n.Address(), markBackupPrefix, h)
		c := n.Client()
		res, err := c.Post(u, "application/octet-stream", nil)
		if err != nil {
			log.Printf("Error posting to %v: %v", u, err)
			continue
		}
		res.Body.Close()
		if res.StatusCode != 204 {
			log.Printf("HTTP Error posting to %v: %v", u, res.Status)
		}
	}
}

func backupToCBFS(fn string) error {
	f, err := NewHashRecord(*root, "")
	if err != nil {
		return err
	}
	defer f.Close()

	pr, pw := io.Pipe()

	go func() { pw.CloseWithError(backupTo(pw)) }()

	h, length, err := f.Process(pr)
	if err != nil {
		return err
	}

	err = recordBlobOwnership(h, length, true)
	if err != nil {
		return err
	}

	fm := fileMeta{
		OID:      h,
		Length:   length,
		Modified: time.Now().UTC(),
	}

	err = storeMeta(fn, fm, 1)
	if err != nil {
		return err
	}

	err = recordBackupObject(h)
	if err != nil {
		log.Printf("Failed to record backup OID: %v", err)
	}

	go recordRemoteBackupObjects(h)

	log.Printf("Replicating backup %v.", h)
	go increaseReplicaCount(h, length, globalConfig.MinReplicas-1)

	return nil
}

func doMarkBackup(w http.ResponseWriter, req *http.Request, h string) {
	err := recordBackupObject(h)
	if err != nil {
		w.WriteHeader(500)
		fmt.Fprintf(w, "Error marking backup: %v", err)
	}
	w.WriteHeader(204)
}

func doBackupDocs(w http.ResponseWriter, req *http.Request) {
	fn := req.FormValue("fn")
	if fn == "" {
		w.WriteHeader(400)
		return
	}

	if bg, _ := strconv.ParseBool(req.FormValue("bg")); bg {
		go func() {
			err := backupToCBFS(fn)
			if err != nil {
				log.Printf("Error performing bg backup: %v", err)
			}
		}()
		w.WriteHeader(202)
		return
	}

	err := backupToCBFS(fn)
	if err != nil {
		w.WriteHeader(500)
		fmt.Fprintf(w, "Error performing backup: %v", err)
		return
	}

	w.WriteHeader(201)
}
<|endoftext|>


<commit_before>// Copyright 2018 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package reader

import (
	"time"

	"github.com/Shopify/sarama"
	"github.com/pingcap/errors"
	"github.com/pingcap/log"
	pb "github.com/pingcap/tidb-tools/tidb-binlog/slave_binlog_proto/go-binlog"
	"go.uber.org/zap"
)

const (
	KafkaReadTimeout = 10 * time.Minute
	KafkaWaitTimeout = 11 * time.Minute
)

func init() {
	// log.SetLevel(log.LOG_LEVEL_NONE)
	sarama.MaxResponseSize = 1 << 30
}

// Config for Reader
type Config struct {
	KafkaAddr []string
	// the CommitTs of binlog return by reader will bigger than the config CommitTs
	CommitTS int64
	Offset   int64 // start at kafka offset
	// if Topic is empty, use the default name in drainer <ClusterID>_obinlog
	Topic     string
	ClusterID string
}

func (c *Config) valid() error {
	if len(c.Topic) == 0 && len(c.ClusterID) == 0 {
		return errors.New("Topic or ClusterID must be set")
	}

	return nil
}

// Message read from reader
type Message struct {
	Binlog *pb.Binlog
	Offset int64 // kafka offset
}

// Reader to read binlog from kafka
type Reader struct {
	cfg    *Config
	client sarama.Client

	msgs      chan *Message
	stop      chan struct{}
	clusterID string
}

func (r *Reader) getTopic() (string, int32) {
	if r.cfg.Topic != "" {
		return r.cfg.Topic, 0
	}

	return r.cfg.ClusterID + "_obinlog", 0
}

// NewReader creates an instance of Reader
func NewReader(cfg *Config) (r *Reader, err error) {
	err = cfg.valid()
	if err != nil {
		errors.Trace(err)
	}

	r = &Reader{
		cfg:       cfg,
		stop:      make(chan struct{}),
		msgs:      make(chan *Message, 1024),
		clusterID: cfg.ClusterID,
	}

	r.client, err = sarama.NewClient(r.cfg.KafkaAddr, nil)
	if err != nil {
		err = errors.Trace(err)
		r = nil
		return
	}

	if r.cfg.CommitTS > 0 {
		r.cfg.Offset, err = r.getOffsetByTS(r.cfg.CommitTS)
		if err != nil {
			err = errors.Trace(err)
			r = nil
			return
		}
		log.Debug("set offset to", zap.Int64("offset", r.cfg.Offset))
	}

	go r.run()

	return
}

// Close shuts down the reader
func (r *Reader) Close() {
	close(r.stop)

	r.client.Close()
}

// Messages returns a chan that contains unread buffered message
func (r *Reader) Messages() (msgs <-chan *Message) {
	return r.msgs
}

func (r *Reader) getOffsetByTS(ts int64) (offset int64, err error) {
	conf := sarama.NewConfig()
	// set to 5 minutes to prevent i/o timeout when reading huge message
	conf.Net.ReadTimeout = KafkaReadTimeout
	conf.Consumer.Return.Errors = true
	seeker, err := NewKafkaSeeker(r.cfg.KafkaAddr, conf)
	if err != nil {
		err = errors.Trace(err)
		return
	}

	topic, partition := r.getTopic()
	log.Debug("get offset",
		zap.String("topic", topic),
		zap.Int32("partition", partition),
		zap.Int64("ts", ts))
	offsets, err := seeker.Seek(topic, ts, []int32{partition})
	if err != nil {
		err = errors.Trace(err)
		return
	}

	offset = offsets[0]

	return
}

func (r *Reader) run() {
	offset := r.cfg.Offset
	log.Debug("start at", zap.Int64("offset", offset))

	consumer, err := sarama.NewConsumerFromClient(r.client)
	if err != nil {
		log.Fatal("create kafka consumer failed", zap.Error(err))
	}
	defer consumer.Close()
	topic, partition := r.getTopic()
	partitionConsumer, err := consumer.ConsumePartition(topic, partition, offset)
	if err != nil {
		log.Fatal("create kafka partition consumer failed", zap.Error(err))
	}
	defer partitionConsumer.Close()

	// add select to avoid message blocking while reading
	for {
		select {
		case <-r.stop:
			// clean environment
			partitionConsumer.Close()
			close(r.msgs)
			log.Info("reader stop to run")
			return
		case kmsg := <-partitionConsumer.Messages():
			log.Debug("get kafka message", zap.Int64("offset", kmsg.Offset))
			binlog := new(pb.Binlog)
			err := binlog.Unmarshal(kmsg.Value)
			if err != nil {
				log.Warn("unmarshal binlog failed", zap.Error(err))
				continue
			}
			if r.cfg.CommitTS > 0 && binlog.CommitTs <= r.cfg.CommitTS {
				log.Warn("skip binlog CommitTs", zap.Int64("commitTS", binlog.CommitTs))
				continue
			}

			msg := &Message{
				Binlog: binlog,
				Offset: kmsg.Offset,
			}
			select {
			case r.msgs <- msg:
			case <-r.stop:
				// In the next iteration, the <-r.stop would match again and prepare to quit
				continue
			}
		}

	}
}
<commit_msg>use common kafka config in reader (#289)<commit_after>// Copyright 2018 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package reader

import (
	"time"

	"github.com/Shopify/sarama"
	"github.com/pingcap/errors"
	"github.com/pingcap/log"
	pb "github.com/pingcap/tidb-tools/tidb-binlog/slave_binlog_proto/go-binlog"
	"go.uber.org/zap"
)

const (
	KafkaReadTimeout = 10 * time.Minute
	KafkaWaitTimeout = 11 * time.Minute
)

func init() {
	// log.SetLevel(log.LOG_LEVEL_NONE)
	sarama.MaxResponseSize = 1 << 30
}

// Config for Reader
type Config struct {
	KafkaAddr []string
	// the CommitTs of binlog return by reader will bigger than the config CommitTs
	CommitTS int64
	Offset   int64 // start at kafka offset
	// if Topic is empty, use the default name in drainer <ClusterID>_obinlog
	Topic     string
	ClusterID string
}

func (c *Config) valid() error {
	if len(c.Topic) == 0 && len(c.ClusterID) == 0 {
		return errors.New("Topic or ClusterID must be set")
	}

	return nil
}

// Message read from reader
type Message struct {
	Binlog *pb.Binlog
	Offset int64 // kafka offset
}

// Reader to read binlog from kafka
type Reader struct {
	cfg    *Config
	client sarama.Client

	msgs      chan *Message
	stop      chan struct{}
	clusterID string
}

func (r *Reader) getTopic() (string, int32) {
	if r.cfg.Topic != "" {
		return r.cfg.Topic, 0
	}

	return r.cfg.ClusterID + "_obinlog", 0
}

// NewReader creates an instance of Reader
func NewReader(cfg *Config) (r *Reader, err error) {
	err = cfg.valid()
	if err != nil {
		errors.Trace(err)
	}

	r = &Reader{
		cfg:       cfg,
		stop:      make(chan struct{}),
		msgs:      make(chan *Message, 1024),
		clusterID: cfg.ClusterID,
	}

	conf := sarama.NewConfig()
	// set to 10 minutes to prevent i/o timeout when reading huge message
	conf.Net.ReadTimeout = KafkaReadTimeout

	r.client, err = sarama.NewClient(r.cfg.KafkaAddr, conf)
	if err != nil {
		err = errors.Trace(err)
		r = nil
		return
	}

	if r.cfg.CommitTS > 0 {
		r.cfg.Offset, err = r.getOffsetByTS(r.cfg.CommitTS, conf)
		if err != nil {
			err = errors.Trace(err)
			r = nil
			return
		}
		log.Debug("set offset to", zap.Int64("offset", r.cfg.Offset))
	}

	go r.run()

	return
}

// Close shuts down the reader
func (r *Reader) Close() {
	close(r.stop)

	r.client.Close()
}

// Messages returns a chan that contains unread buffered message
func (r *Reader) Messages() (msgs <-chan *Message) {
	return r.msgs
}

func (r *Reader) getOffsetByTS(ts int64, conf *sarama.Config) (offset int64, err error) {
	// set true to retrive error
	conf.Consumer.Return.Errors = true
	seeker, err := NewKafkaSeeker(r.cfg.KafkaAddr, conf)
	if err != nil {
		err = errors.Trace(err)
		return
	}

	topic, partition := r.getTopic()
	log.Debug("get offset",
		zap.String("topic", topic),
		zap.Int32("partition", partition),
		zap.Int64("ts", ts))
	offsets, err := seeker.Seek(topic, ts, []int32{partition})
	if err != nil {
		err = errors.Trace(err)
		return
	}

	offset = offsets[0]

	return
}

func (r *Reader) run() {
	offset := r.cfg.Offset
	log.Debug("start at", zap.Int64("offset", offset))

	consumer, err := sarama.NewConsumerFromClient(r.client)
	if err != nil {
		log.Fatal("create kafka consumer failed", zap.Error(err))
	}
	defer consumer.Close()
	topic, partition := r.getTopic()
	partitionConsumer, err := consumer.ConsumePartition(topic, partition, offset)
	if err != nil {
		log.Fatal("create kafka partition consumer failed", zap.Error(err))
	}
	defer partitionConsumer.Close()

	// add select to avoid message blocking while reading
	for {
		select {
		case <-r.stop:
			// clean environment
			partitionConsumer.Close()
			close(r.msgs)
			log.Info("reader stop to run")
			return
		case kmsg := <-partitionConsumer.Messages():
			log.Debug("get kafka message", zap.Int64("offset", kmsg.Offset))
			binlog := new(pb.Binlog)
			err := binlog.Unmarshal(kmsg.Value)
			if err != nil {
				log.Warn("unmarshal binlog failed", zap.Error(err))
				continue
			}
			if r.cfg.CommitTS > 0 && binlog.CommitTs <= r.cfg.CommitTS {
				log.Warn("skip binlog CommitTs", zap.Int64("commitTS", binlog.CommitTs))
				continue
			}

			msg := &Message{
				Binlog: binlog,
				Offset: kmsg.Offset,
			}
			select {
			case r.msgs <- msg:
			case <-r.stop:
				// In the next iteration, the <-r.stop would match again and prepare to quit
				continue
			}
		}

	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"time"
)

const bolt = "\u26A1"

type batMon struct {
	batPerc []byte
}

func (b *batMon) Run(done chan int) {
	for {
		perc, err := ioutil.ReadFile("/sys/class/power_supply/BAT0/capacity")
		if err != nil {
			panic("Cannot read battery status.")
		}
		b.batPerc = perc[:len(perc)-1]
		done <- 1
		time.Sleep(time.Minute)
	}
}

func (b *batMon) String() string {
	return fmt.Sprintf("%s%%", b.batPerc)
}
<commit_msg>batmon: display errors in status line<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"time"
)

const (
	batfile = "/sys/class/power_supply/BAT0/capacity"
	bolt    = "\u26A1"
)

type batMon struct {
	batPerc []byte
	emsg    string
}

func (b *batMon) Run(done chan int) {
	for {
		perc, err := ioutil.ReadFile(batfile)
		if err != nil {
			log.Println("Cannot read battery status.")
			b.emsg = "N/A"
			return
		}
		b.batPerc = perc[:len(perc)-1]
		done <- 1
		time.Sleep(time.Minute)
	}
}

func (b *batMon) String() string {
	if b.emsg != "" {
		return b.emsg
	}
	return fmt.Sprintf("%s%%", b.batPerc)
}
<|endoftext|>


<commit_before>package spec

import (
	"tritium/src/tritium/packager"
	tp "athena/src/athena/proto"
	. "tritium/src/tritium"
	. "path/filepath"
	"tritium/src/tritium/shark"
	. "fmt"
	l4g "log4go"
	"os"
	"runtime/debug"
)

func All(directory string, options ...string) {

	var mixerPath string
	if len(options) == 1 {
		mixerPath = options[0]
	}

	logger := make(l4g.Logger)
	logger.AddFilter("test", l4g.ERROR, l4g.NewConsoleLogWriter())
	l4g.Global = logger
	eng := shark.NewEngine(logger)

	var pkg *tp.Package

	if len(mixerPath) > 0 {
		// Used when testing in ambrosia
		mixer := tp.OpenMixer(mixerPath)
		pkg = mixer.Package
	} else {
		bigPackage := packager.BuildDefaultPackage()
		pkg = bigPackage.Package
	}

	globalResult := NewResult()
	globalResult.all(directory, pkg, eng, logger)

	logger.AddFilter("stdout", l4g.ERROR, l4g.NewConsoleLogWriter())

	// TODO : Walk over the results here and print errors.

	var foundError = false

	for _, error := range globalResult.Errors {
		foundError = true
		println("\n=========================================", error.Location, "\n")
		if error.Panic {
			Printf(error.Message)
		} else {
			Printf("\n==========\n%v :: %v \n\n Got \n----------\n%v\n\n Expected \n----------\n%v\n", error.Name, error.Message, error.Got, error.Expected)
		}
	}
	println("\n\n")
	println("+++TEST COMPLETE+++\n\n")

	if foundError {
		os.Exit(1)
	}
}

func (result *Result) all(directory string, pkg *tp.Package, eng Engine, logger l4g.Logger) {
	_, err := Glob(Join(directory, "main.ts"))

	if err == nil {
		newResult := RunSpec(directory, pkg, eng, logger)
		result.Merge(newResult)
	}
	subdirs, _ := Glob(Join(directory, "*"))
	for _, subdir := range subdirs {
		result.all(subdir, pkg, eng, logger)
	}
}

func RunSpec(dir string, pkg *tp.Package, eng Engine, logger l4g.Logger) (result *Result) {
	result = NewResult()
	logWriter := NewTestLogWriter()
	logger["test"] = &l4g.Filter{l4g.WARNING, "test", logWriter}

	defer func() {
		//log.Println("done")  // Println executes normally even in there is a panic
		if x := recover(); x != nil {
			err, ok := x.(os.Error)
			if ok {
				logger.Error(dir + " === " + err.String() + "\n\n" + string(debug.Stack()))
			} else {
				logger.Error(dir + " === " + x.(string) + "\n\n" + string(debug.Stack()))
			}

		}
		for _, rec := range logWriter.Logs {
			//println("HAZ LOGS")
			error := l4g.FormatLogRecord("[%D %T] [%L] (%S) %M", rec)
			result.Error(dir, error)
		}
		print(result.CharStatus())
	}()
	spec, err := LoadSpec(dir, pkg)
	if err != nil {
		result.Error(dir, err.String())
	} else {
		result.Merge(spec.Compare(eng.Run(spec.Script, spec.Input, spec.Vars)))
	}
	return
}
<commit_msg>Update to match new log4go API<commit_after>package spec

import (
	"tritium/src/tritium/packager"
	tp "athena/src/athena/proto"
	. "tritium/src/tritium"
	. "path/filepath"
	"tritium/src/tritium/shark"
	. "fmt"
	l4g "log4go"
	"os"
	"runtime/debug"
)

func All(directory string, options ...string) {

	var mixerPath string
	if len(options) == 1 {
		mixerPath = options[0]
	}

	logger := make(l4g.Logger)
	logger.AddFilter("test", l4g.ERROR, l4g.NewConsoleLogWriter())
	l4g.Global = logger
	eng := shark.NewEngine(logger)

	var pkg *tp.Package

	if len(mixerPath) > 0 {
		// Used when testing in ambrosia
		mixer := tp.OpenMixer(mixerPath)
		pkg = mixer.Package
	} else {
		bigPackage := packager.BuildDefaultPackage()
		pkg = bigPackage.Package
	}

	globalResult := NewResult()
	globalResult.all(directory, pkg, eng, logger)

	logger.AddFilter("stdout", l4g.ERROR, l4g.NewConsoleLogWriter())

	// TODO : Walk over the results here and print errors.

	var foundError = false

	for _, error := range globalResult.Errors {
		foundError = true
		println("\n=========================================", error.Location, "\n")
		if error.Panic {
			Printf(error.Message)
		} else {
			Printf("\n==========\n%v :: %v \n\n Got \n----------\n%v\n\n Expected \n----------\n%v\n", error.Name, error.Message, error.Got, error.Expected)
		}
	}
	println("\n\n")
	println("+++TEST COMPLETE+++\n\n")

	if foundError {
		os.Exit(1)
	}
}

func (result *Result) all(directory string, pkg *tp.Package, eng Engine, logger l4g.Logger) {
	_, err := Glob(Join(directory, "main.ts"))

	if err == nil {
		newResult := RunSpec(directory, pkg, eng, logger)
		result.Merge(newResult)
	}
	subdirs, _ := Glob(Join(directory, "*"))
	for _, subdir := range subdirs {
		result.all(subdir, pkg, eng, logger)
	}
}

func RunSpec(dir string, pkg *tp.Package, eng Engine, logger l4g.Logger) (result *Result) {
	result = NewResult()
	logWriter := NewTestLogWriter()
	logger["test"] = &l4g.Filter{l4g.WARNING, "test", "", logWriter}

	defer func() {
		//log.Println("done")  // Println executes normally even in there is a panic
		if x := recover(); x != nil {
			err, ok := x.(os.Error)
			if ok {
				logger.Error(dir + " === " + err.String() + "\n\n" + string(debug.Stack()))
			} else {
				logger.Error(dir + " === " + x.(string) + "\n\n" + string(debug.Stack()))
			}

		}
		for _, rec := range logWriter.Logs {
			//println("HAZ LOGS")
			error := l4g.FormatLogRecord("[%D %T] [%L] (%S) %M", rec)
			result.Error(dir, error)
		}
		print(result.CharStatus())
	}()
	spec, err := LoadSpec(dir, pkg)
	if err != nil {
		result.Error(dir, err.String())
	} else {
		result.Merge(spec.Compare(eng.Run(spec.Script, spec.Input, spec.Vars)))
	}
	return
}
<|endoftext|>


<commit_before>// Package ode provides the Euler-Forward and Runge-Kutta
// Method for solving ordinary differential equations.
package ode

import "fmt"

func EulerForward(from, h, to, t float64, y []float64, fn func(float64, []float64) []float64) [][]float64 {
	var steps int = int((to - from) / h)
	var parameters = len(y)

	fmt.Println(steps)
	fmt.Println(parameters)

	// initialize 'outer slice'
	ySlice := make([][]float64, steps)
	// initialize first 'inner slice'
	ySlice[0] = make([]float64, parameters+1)

	// fill with start values
	for i := 0; i < parameters; i++ {
		ySlice[0][i+1] = y[i]
	}

	yn := make([]float64, parameters)

	for step := 1; step < steps; step++ {
		t += h
		// initialize 'inner slice'
		ySlice[step] = make([]float64, parameters+1)
		ySlice[step][0] = t

		for value := 0; value < parameters; value++ {
			yn[value] = ySlice[step-1][value+1]
		}

		for value := 0; value < parameters; value++ {
			y[value] += h * fn(t, yn)[value]
			ySlice[step][value+1] = y[value]
		}
	}
	return ySlice
}

// func RungeKutta4 is an implementation of the 4th order Runge-Kutta method
func RungeKutta4(from, h, to, t float64, y []float64, fn func(float64, []float64) []float64) [][]float64 {
	var steps int = int((to - from) / h)
	var parameters = len(y)

	fmt.Println(steps)
	fmt.Println(parameters)

	// initialize 'outer slice'
	ySlice := make([][]float64, steps)
	// initialize first 'inner slice'
	ySlice[0] = make([]float64, parameters+1)

	// fill with start values
	for i := 0; i < parameters; i++ {
		ySlice[0][i+1] = y[i]
	}

	var k1 []float64 = make([]float64, parameters)
	var k2 []float64 = make([]float64, parameters)
	var k3 []float64 = make([]float64, parameters)
	var k4 []float64 = make([]float64, parameters)

	var yn []float64 = make([]float64, parameters)

	// the parameters to pass into the corresponding function calls
	var k2p []float64 = make([]float64, parameters)
	var k3p []float64 = make([]float64, parameters)
	var k4p []float64 = make([]float64, parameters)

	for step := 1; step < steps; step++ {
		// initialize 'inner slice'
		ySlice[step] = make([]float64, parameters+1)

		// get last yn from the slice to make the rest of the function shorter
		for value := 0; value < parameters; value++ {
			yn[value] = ySlice[step-1][value+1]
		}

		// generate k1
		for value := 0; value < parameters; value++ {
			k1[value] = fn(t, yn)[value]
		}

		t += h / 2

		// generate the parameter for k2
		for value := 0; value < parameters; value++ {
			k2p[value] = yn[value] + 0.5*k1[value]
		}

		// generate k2
		for value := 0; value < parameters; value++ {
			k2[value] = fn(t, k2p)[value]
		}

		// generate the parameter for k3
		for value := 0; value < parameters; value++ {
			k3p[value] = yn[value] + 0.5*k2[value]
		}

		// generate k3
		for value := 0; value < parameters; value++ {
			k3[value] = fn(t, k3p)[value]
		}

		// generate the parameter for k4
		for value := 0; value < parameters; value++ {
			k4p[value] = yn[value] + fn(t, k3p)[value]
		}

		t += h / 2

		// generate k4
		for value := 0; value < parameters; value++ {
			k4[value] = fn(t, k4p)[value]
		}

		ySlice[step][0] = t

		// generate yn (saved in the slice)
		for value := 0; value < parameters; value++ {
			ySlice[step][value+1] = ySlice[step-1][value+1] + h*(k1[value]+2*k2[value]+2*k3[value]+k4[value])/6.0
		}
	}
	return ySlice
}
<commit_msg>and even more fixing the step size in runge-kutta<commit_after>// Package ode provides the Euler-Forward and Runge-Kutta
// Method for solving ordinary differential equations.
package ode

import "fmt"

func EulerForward(from, h, to, t float64, y []float64, fn func(float64, []float64) []float64) [][]float64 {
	var steps int = int((to - from) / h)
	var parameters = len(y)

	fmt.Println(steps)
	fmt.Println(parameters)

	// initialize 'outer slice'
	ySlice := make([][]float64, steps)
	// initialize first 'inner slice'
	ySlice[0] = make([]float64, parameters+1)

	// fill with start values
	for i := 0; i < parameters; i++ {
		ySlice[0][i+1] = y[i]
	}

	yn := make([]float64, parameters)

	for step := 1; step < steps; step++ {
		t += h
		// initialize 'inner slice'
		ySlice[step] = make([]float64, parameters+1)
		ySlice[step][0] = t

		for value := 0; value < parameters; value++ {
			yn[value] = ySlice[step-1][value+1]
		}

		for value := 0; value < parameters; value++ {
			y[value] += h * fn(t, yn)[value]
			ySlice[step][value+1] = y[value]
		}
	}
	return ySlice
}

// func RungeKutta4 is an implementation of the 4th order Runge-Kutta method
func RungeKutta4(from, h, to, t float64, y []float64, fn func(float64, []float64) []float64) [][]float64 {
	var steps int = int((to - from) / h)
	var parameters = len(y)

	fmt.Println(steps)
	fmt.Println(parameters)

	// initialize 'outer slice'
	ySlice := make([][]float64, steps+1)
	// initialize first 'inner slice'
	ySlice[0] = make([]float64, parameters+1)

	// fill with start values
	for i := 0; i < parameters; i++ {
		ySlice[0][i+1] = y[i]
	}

	var k1 []float64 = make([]float64, parameters)
	var k2 []float64 = make([]float64, parameters)
	var k3 []float64 = make([]float64, parameters)
	var k4 []float64 = make([]float64, parameters)

	var yn []float64 = make([]float64, parameters)

	// the parameters to pass into the corresponding function calls
	var k2p []float64 = make([]float64, parameters)
	var k3p []float64 = make([]float64, parameters)
	var k4p []float64 = make([]float64, parameters)

	for step := 1; step <= steps; step++ {
		// initialize 'inner slice'
		ySlice[step] = make([]float64, parameters+1)

		// get last yn from the slice to make the rest of the function shorter
		for value := 0; value < parameters; value++ {
			yn[value] = ySlice[step-1][value+1]
		}

		// generate k1
		for value := 0; value < parameters; value++ {
			k1[value] = fn(t, yn)[value]
		}

		t += h / 2

		// generate the parameter for k2
		for value := 0; value < parameters; value++ {
			k2p[value] = yn[value] + 0.5*h*k1[value]
		}

		// generate k2
		for value := 0; value < parameters; value++ {
			k2[value] = fn(t, k2p)[value]
		}

		// generate the parameter for k3
		for value := 0; value < parameters; value++ {
			k3p[value] = yn[value] + 0.5*h*k2[value]
		}

		// generate k3
		for value := 0; value < parameters; value++ {
			k3[value] = fn(t, k3p)[value]
		}

		// generate the parameter for k4
		for value := 0; value < parameters; value++ {
			k4p[value] = yn[value] + h*fn(t, k3p)[value]
		}

		t += h / 2

		// generate k4
		for value := 0; value < parameters; value++ {
			k4[value] = fn(t, k4p)[value]
		}

		ySlice[step][0] = t

		// generate yn (saved in the slice)
		for value := 0; value < parameters; value++ {
			ySlice[step][value+1] = ySlice[step-1][value+1] + h*(k1[value]+2*k2[value]+2*k3[value]+k4[value])/6.0
		}
	}
	return ySlice
}
<|endoftext|>


<commit_before>package urlfetch

import "testing"
import "fmt"

// Local helper functions
func test_getdata4urls(urls []string) {
    // create HTTP client
    client := HttpClient()

    ch := make(chan []byte)
    n := 0
    for _, url := range urls {
        n++
        go Getdata(client, url, ch)
    }
    for i:=0; i<n; i++ {
        fmt.Println(string(<-ch))
    }
}
func test_getdata(url string) {
    // create HTTP client
    client := HttpClient()

    ch := make(chan []byte)
    go Getdata(client, url, ch)
    fmt.Println(string(<-ch))
}

// Test function
func TestGetdata(t *testing.T) {
    url1 := "http://www.google.com"
    url2 := "http://www.golang.org"
    urls := []string{url1, url2}
    t.Log("test getdata call")
    test_getdata(url1)
    t.Log("test getdata call with multiple urls")
    test_getdata4urls(urls)
}
<commit_msg>Use regexp to match end of html; let local test function to return bool status<commit_after>package urlfetch

import "testing"
import "regexp"

// Local helper functions
func parse(output string) bool {
    test, err := regexp.MatchString("</html>", output)
    if  err != nil {
        return false
    }
    return test
}
func test_getdata4urls(urls []string) bool {
    ch := make(chan []byte)
    for _, url := range urls {
        go Getdata(url, ch)
    }
    for i := 0; i<len(urls); i++ {
        res := string(<-ch)
        if  ! parse(res) {
            return false
        }
    }
    return true
}
func test_getdata(url string) bool {
    ch := make(chan []byte)
    go Getdata(url, ch)
    res := string(<-ch)
    return parse(res)
}

// Test function
func TestGetdata(t *testing.T) {
    url1 := "http://www.google.com"
    url2 := "http://www.golang.org"
    urls := []string{url1, url2}
    var test bool
    test = test_getdata(url1)
    if  ! test {
        t.Log("test getdata call", url1)
        t.Fail()
    }
    test = test_getdata4urls(urls)
    if  ! test {
        t.Log("test getdata call with multiple urls", urls)
        t.Fail()
    }
}
<|endoftext|>