<commit_before>package pddl

import (
	"fmt"
	"io"
)

const indent = "\t"

// PrintDomain prints the domain in valid PDDL to the given writer.
func PrintDomain(w io.Writer, d *Domain) {
	fmt.Fprintf(w, "(define (domain %s)\n", d.Name)
	printRequirements(w, d.Requirements)

	if len(d.Types) > 0 {
		fmt.Fprintf(w, "%s(:types", indent)
		printTypedNames(w, "\n"+indent+indent, d.Types)
		fmt.Fprintln(w, ")")
	}

	if len(d.Constants) > 0 {
		fmt.Fprintf(w, "%s(:constants", indent)
		printTypedNames(w, "\n"+indent+indent, d.Constants)
		fmt.Fprintln(w, ")")
	}

	if len(d.Predicates) > 0 {
		fmt.Fprintf(w, "%s(:predicates\n", indent)
		for i, p := range d.Predicates {
			fmt.Fprintf(w, "%s(%s", indent+indent, p.Name.Str)
			printTypedNames(w, " ", p.Parameters)
			fmt.Fprint(w, ")")
			if i < len(d.Predicates)-1 {
				fmt.Fprint(w, "\n")
			}
		}
		fmt.Fprintln(w, ")")
	}

	for _, act := range d.Actions {
		fmt.Fprintf(w, "%s(:action %s\n", indent, act.Name)
		fmt.Fprintf(w, "%s:parameters (", indent+indent+indent)
		printTypedNames(w, "", act.Parameters)
		fmt.Fprint(w, ")")
		if act.Precondition != nil {
			fmt.Fprint(w, "\n")
			fmt.Fprintf(w, "%s:precondition\n", indent+indent+indent)
			act.Precondition.print(w, indent+indent+indent+indent)
		}
		if act.Effect != nil {
			fmt.Fprint(w, "\n")
			fmt.Fprintf(w, "%s:effect\n", indent+indent+indent)
			act.Effect.print(w, indent+indent+indent+indent)
		}
		fmt.Fprintln(w, ")")
	}

	fmt.Fprintln(w, ")")
}

// PrintProblem prints the problem in valid PDDL to the given writer.
func PrintProblem(w io.Writer, p *Problem) {
	fmt.Fprintf(w, "(define (problem %s)\n%s(:domain %s)\n", p.Name, indent, p.Domain)
	printRequirements(w, p.Requirements)

	if len(p.Objects) > 0 {
		fmt.Fprintf(w, "%s(:objects", indent)
		printTypedNames(w, "\n"+indent+indent, p.Objects)
		fmt.Fprintln(w, ")")
	}

	fmt.Fprintf(w, "%s(:init", indent)
	for _, f := range p.Init {
		fmt.Fprint(w, "\n")
		f.print(w, indent+indent)
	}
	fmt.Fprint(w, ")\n")

	fmt.Fprintf(w, "%s(:goal\n", indent)
	p.Goal.print(w, indent+indent)

	fmt.Fprintln(w, ")\n)")
}

func printRequirements(w io.Writer, reqs []Name) {
	if len(reqs) > 0 {
		fmt.Fprintf(w, "%s(:requirements\n", indent)
		for i, r := range reqs {
			s := r.Str
			if i == len(reqs)-1 {
				s += ")"
			}
			fmt.Fprintln(w, indent+indent, s)
		}
	}
}

// declGroup is a group of declarators along
// with their type.
type declGroup struct {
	typ string
	ents []string
}

// declGroups implements sort.Interface, sorting
// the list of typed declarations by their type name.
type declGroups []declGroup

func (t declGroups) Len() int {
	return len(t)
}

func (t declGroups) Less(i, j int) bool {
	return t[i].typ < t[j].typ
}

func (t declGroups) Swap(i, j int) {
	t[i], t[j] = t[j], t[i]
}

// printTypedNames prints a slice of TypedNames
// in their given order. The prefix is printed before
// each group.
func printTypedNames(w io.Writer, prefix string, ns []TypedName) {
	if len(ns) == 0 {
		return
	}
	tprev := typeString(ns[0].Types)
	sep := prefix
	for _, n := range ns {
		tcur := typeString(n.Types)
		if tcur != tprev {
			if tprev == "" {
				// There should be no way to get into
				// this situation!
				panic(n.Loc.String() + ": untyped declarations in the middle of a typed list")
			}
			fmt.Fprintf(w, " - %s", tprev)
			tprev = tcur
			sep = prefix
			if sep == "" {
				sep = " "
			}
		}
		fmt.Fprintf(w, "%s%s", sep, n.Str)
		sep = " "
	}
	if tprev != "" {
		fmt.Fprintf(w, " - %s", tprev)
	}
}

// typeString returns the string representation of a type.
func typeString(t []Name) (str string) {
	switch len(t) {
	case 0:
		break
	case 1:
		str = t[0].Str
	default:
		str = "(either"
		for _, n := range t {
			str += " " + n.Str
		}
		str += ")"
	}
	return
}

func (l *PropositionNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(", prefix)
	fmt.Fprint(w, l.Predicate.Str)
	for _, t := range l.Parameters {
		fmt.Fprintf(w, " %s", t.Name.Str)
	}
	fmt.Fprint(w, ")")
}

func (n *AndNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(and", prefix)
	for _, f := range n.Formula {
		fmt.Fprint(w, "\n")
		f.print(w, prefix+indent)
	}
	fmt.Fprint(w, ")")
}

func (n *OrNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(or", prefix)
	for _, f := range n.Formula {
		fmt.Fprint(w, "\n")
		f.print(w, prefix+indent)
	}
	fmt.Fprint(w, ")")
}

func (n *NotNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(not\n", prefix)
	n.Formula.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *ImplyNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(imply\n", prefix)
	n.Left.print(w, prefix+indent)
	fmt.Fprint(w, "\n")
	n.Right.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *ForallNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(forall (", prefix)
	printTypedNames(w, "", n.Variables)
	fmt.Fprint(w, ")\n")
	n.Formula.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *ExistsNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(exists (", prefix)
	printTypedNames(w, "", n.Variables)
	fmt.Fprint(w, ")\n")
	n.Formula.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *WhenNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(when\n", prefix)
	n.Condition.print(w, prefix+indent)
	fmt.Fprint(w, "\n")
	n.Formula.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *AssignNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(%s %s %s)", prefix, n.Op, n.Lval, n.Rval)
}
<commit_msg>Change a comment.<commit_after>package pddl

import (
	"fmt"
	"io"
)

const indent = "\t"

// PrintDomain prints the domain in valid PDDL to the given writer.
func PrintDomain(w io.Writer, d *Domain) {
	fmt.Fprintf(w, "(define (domain %s)\n", d.Name)
	printRequirements(w, d.Requirements)

	if len(d.Types) > 0 {
		fmt.Fprintf(w, "%s(:types", indent)
		printTypedNames(w, "\n"+indent+indent, d.Types)
		fmt.Fprintln(w, ")")
	}

	if len(d.Constants) > 0 {
		fmt.Fprintf(w, "%s(:constants", indent)
		printTypedNames(w, "\n"+indent+indent, d.Constants)
		fmt.Fprintln(w, ")")
	}

	if len(d.Predicates) > 0 {
		fmt.Fprintf(w, "%s(:predicates\n", indent)
		for i, p := range d.Predicates {
			fmt.Fprintf(w, "%s(%s", indent+indent, p.Name.Str)
			printTypedNames(w, " ", p.Parameters)
			fmt.Fprint(w, ")")
			if i < len(d.Predicates)-1 {
				fmt.Fprint(w, "\n")
			}
		}
		fmt.Fprintln(w, ")")
	}

	for _, act := range d.Actions {
		fmt.Fprintf(w, "%s(:action %s\n", indent, act.Name)
		fmt.Fprintf(w, "%s:parameters (", indent+indent+indent)
		printTypedNames(w, "", act.Parameters)
		fmt.Fprint(w, ")")
		if act.Precondition != nil {
			fmt.Fprint(w, "\n")
			fmt.Fprintf(w, "%s:precondition\n", indent+indent+indent)
			act.Precondition.print(w, indent+indent+indent+indent)
		}
		if act.Effect != nil {
			fmt.Fprint(w, "\n")
			fmt.Fprintf(w, "%s:effect\n", indent+indent+indent)
			act.Effect.print(w, indent+indent+indent+indent)
		}
		fmt.Fprintln(w, ")")
	}

	fmt.Fprintln(w, ")")
}

// PrintProblem prints the problem in valid PDDL to the given writer.
func PrintProblem(w io.Writer, p *Problem) {
	fmt.Fprintf(w, "(define (problem %s)\n%s(:domain %s)\n", p.Name, indent, p.Domain)
	printRequirements(w, p.Requirements)

	if len(p.Objects) > 0 {
		fmt.Fprintf(w, "%s(:objects", indent)
		printTypedNames(w, "\n"+indent+indent, p.Objects)
		fmt.Fprintln(w, ")")
	}

	fmt.Fprintf(w, "%s(:init", indent)
	for _, f := range p.Init {
		fmt.Fprint(w, "\n")
		f.print(w, indent+indent)
	}
	fmt.Fprint(w, ")\n")

	fmt.Fprintf(w, "%s(:goal\n", indent)
	p.Goal.print(w, indent+indent)

	fmt.Fprintln(w, ")\n)")
}

func printRequirements(w io.Writer, reqs []Name) {
	if len(reqs) > 0 {
		fmt.Fprintf(w, "%s(:requirements\n", indent)
		for i, r := range reqs {
			s := r.Str
			if i == len(reqs)-1 {
				s += ")"
			}
			fmt.Fprintln(w, indent+indent, s)
		}
	}
}

// declGroup is a group of declarators along
// with their type.
type declGroup struct {
	typ string
	ents []string
}

// declGroups implements sort.Interface, sorting
// the list of typed declarations by their type name.
type declGroups []declGroup

func (t declGroups) Len() int {
	return len(t)
}

func (t declGroups) Less(i, j int) bool {
	return t[i].typ < t[j].typ
}

func (t declGroups) Swap(i, j int) {
	t[i], t[j] = t[j], t[i]
}

// printTypedNames prints a slice of TypedNames
// in their given order. The prefix is printed before
// each group.
func printTypedNames(w io.Writer, prefix string, ns []TypedName) {
	if len(ns) == 0 {
		return
	}
	tprev := typeString(ns[0].Types)
	sep := prefix
	for _, n := range ns {
		tcur := typeString(n.Types)
		if tcur != tprev {
			if tprev == "" {
				// Should be impossible.
				panic(n.Loc.String() + ": untyped declarations in the middle of a typed list")
			}
			fmt.Fprintf(w, " - %s", tprev)
			tprev = tcur
			sep = prefix
			if sep == "" {
				sep = " "
			}
		}
		fmt.Fprintf(w, "%s%s", sep, n.Str)
		sep = " "
	}
	if tprev != "" {
		fmt.Fprintf(w, " - %s", tprev)
	}
}

// typeString returns the string representation of a type.
func typeString(t []Name) (str string) {
	switch len(t) {
	case 0:
		break
	case 1:
		str = t[0].Str
	default:
		str = "(either"
		for _, n := range t {
			str += " " + n.Str
		}
		str += ")"
	}
	return
}

func (l *PropositionNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(", prefix)
	fmt.Fprint(w, l.Predicate.Str)
	for _, t := range l.Parameters {
		fmt.Fprintf(w, " %s", t.Name.Str)
	}
	fmt.Fprint(w, ")")
}

func (n *AndNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(and", prefix)
	for _, f := range n.Formula {
		fmt.Fprint(w, "\n")
		f.print(w, prefix+indent)
	}
	fmt.Fprint(w, ")")
}

func (n *OrNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(or", prefix)
	for _, f := range n.Formula {
		fmt.Fprint(w, "\n")
		f.print(w, prefix+indent)
	}
	fmt.Fprint(w, ")")
}

func (n *NotNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(not\n", prefix)
	n.Formula.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *ImplyNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(imply\n", prefix)
	n.Left.print(w, prefix+indent)
	fmt.Fprint(w, "\n")
	n.Right.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *ForallNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(forall (", prefix)
	printTypedNames(w, "", n.Variables)
	fmt.Fprint(w, ")\n")
	n.Formula.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *ExistsNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(exists (", prefix)
	printTypedNames(w, "", n.Variables)
	fmt.Fprint(w, ")\n")
	n.Formula.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *WhenNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(when\n", prefix)
	n.Condition.print(w, prefix+indent)
	fmt.Fprint(w, "\n")
	n.Formula.print(w, prefix+indent)
	fmt.Fprint(w, ")")
}

func (n *AssignNode) print(w io.Writer, prefix string) {
	fmt.Fprintf(w, "%s(%s %s %s)", prefix, n.Op, n.Lval, n.Rval)
}
<|endoftext|>


<commit_before>package permission

import (
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"sort"

	"github.com/go-yaml/yaml"
)

type Permission struct {
	CPANMeta string
	MetaCPAN string
	Client   *http.Client
}

func New() *Permission {
	return &Permission{
		CPANMeta: "http://cpanmetadb.plackperl.org/v1.0/package",
		MetaCPAN: "https://fastapi.metacpan.org/v1/permission",
		Client:   http.DefaultClient,
	}
}

func (p *Permission) Get(module string) (string, []PermissionResult, error) {
	distfile, modules, err := p.getMeta(module)
	if err != nil {
		return "", nil, err
	}
	res, err := p.get(modules)
	if err != nil {
		return "", nil, err
	}
	return distfile, res, nil
}

type cpanmetaResult struct {
	Distfile string            `yaml:"distfile"`
	Provides map[string]string `yaml:"provides"`
	Version  string            `yaml:"version"`
}

func (p *Permission) getMeta(module string) (string, []string, error) {
	url := p.CPANMeta + "/" + module
	res, err := p.Client.Get(url)
	if err != nil {
		return "", nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		err := errors.New(res.Status + ", " + url)
		return "", nil, err
	}
	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return "", nil, err
	}
	var result cpanmetaResult
	if err := yaml.Unmarshal(b, &result); err != nil {
		return "", nil, err
	}
	modules := make([]string, 0, len(result.Provides))
	for module, _ := range result.Provides {
		modules = append(modules, module)
	}
	sort.Strings(modules)

	return result.Distfile, modules, nil
}

type metacpanQuery struct {
	Query map[string]map[string][]metacpanQueryTerm `json:"query"`
	Size  int                                       `json:"size"`
}

type metacpanQueryTerm struct {
	Term map[string]string `json:"term"`
}

type metacpanResult struct {
	Shards struct {
		Successful int `json:"successful"`
		Total      int `json:"total"`
		Failed     int `json:"failed"`
	} `json:"_shards"`
	Hits struct {
		Total int `json:"total"`
		Hits  []struct {
			Source struct {
				ModuleName    string   `json:"module_name"`
				Owner         string   `json:"owner"`
				CoMaintainers []string `json:"co_maintainers"`
			} `json:"_source"`
			ID    string  `json:"_id"`
			Type  string  `json:"_type"`
			Index string  `json:"_index"`
			Score float64 `json:"_score"`
		} `json:"hits"`
		MaxScore float64 `json:"max_score"`
	} `json:"hits"`
	TimedOut bool `json:"timed_out"`
	Took     int  `json:"took"`
}

func makeMetaCPANQuery(modules []string) metacpanQuery {
	query := metacpanQuery{
		Query: make(map[string]map[string][]metacpanQueryTerm),
		Size:  len(modules),
	}
	query.Query["bool"] = make(map[string][]metacpanQueryTerm)
	terms := make([]metacpanQueryTerm, 0, len(modules))
	for _, module := range modules {
		terms = append(terms, metacpanQueryTerm{Term: map[string]string{"module_name": module}})
	}
	query.Query["bool"]["should"] = terms
	return query
}

func (p *Permission) get(modules []string) ([]PermissionResult, error) {
	url := p.MetaCPAN + "/_search"
	query := makeMetaCPANQuery(modules)
	b, err := json.Marshal(query)
	if err != nil {
		return nil, err
	}
	res, err := p.Client.Post(url, "application/json", bytes.NewReader(b))
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		err := errors.New(res.Status + ", " + url)
		return nil, err
	}
	var result metacpanResult
	if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
		return nil, err
	}

	hits := result.Hits.Hits
	seen := make(map[string]struct{})
	results := make(permissionResults, 0, len(hits))
	for _, hit := range hits {
		seen[hit.Source.ModuleName] = struct{}{}
		co := hit.Source.CoMaintainers
		sort.Strings(co)
		p := PermissionResult{
			Owner:         hit.Source.Owner,
			ModuleName:    hit.Source.ModuleName,
			CoMaintainers: co,
		}
		results = append(results, p)
	}
	for _, module := range modules {
		if _, ok := seen[module]; !ok {
			results = append(results, PermissionResult{ModuleName: module})
		}
	}
	sort.Sort(results)
	return results, nil
}
<commit_msg>empty array<commit_after>package permission

import (
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"sort"

	"github.com/go-yaml/yaml"
)

type Permission struct {
	CPANMeta string
	MetaCPAN string
	Client   *http.Client
}

func New() *Permission {
	return &Permission{
		CPANMeta: "http://cpanmetadb.plackperl.org/v1.0/package",
		MetaCPAN: "https://fastapi.metacpan.org/v1/permission",
		Client:   http.DefaultClient,
	}
}

func (p *Permission) Get(module string) (string, []PermissionResult, error) {
	distfile, modules, err := p.getMeta(module)
	if err != nil {
		return "", nil, err
	}
	res, err := p.get(modules)
	if err != nil {
		return "", nil, err
	}
	return distfile, res, nil
}

type cpanmetaResult struct {
	Distfile string            `yaml:"distfile"`
	Provides map[string]string `yaml:"provides"`
	Version  string            `yaml:"version"`
}

func (p *Permission) getMeta(module string) (string, []string, error) {
	url := p.CPANMeta + "/" + module
	res, err := p.Client.Get(url)
	if err != nil {
		return "", nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		err := errors.New(res.Status + ", " + url)
		return "", nil, err
	}
	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return "", nil, err
	}
	var result cpanmetaResult
	if err := yaml.Unmarshal(b, &result); err != nil {
		return "", nil, err
	}
	modules := make([]string, 0, len(result.Provides))
	for module, _ := range result.Provides {
		modules = append(modules, module)
	}
	sort.Strings(modules)

	return result.Distfile, modules, nil
}

type metacpanQuery struct {
	Query map[string]map[string][]metacpanQueryTerm `json:"query"`
	Size  int                                       `json:"size"`
}

type metacpanQueryTerm struct {
	Term map[string]string `json:"term"`
}

type metacpanResult struct {
	Shards struct {
		Successful int `json:"successful"`
		Total      int `json:"total"`
		Failed     int `json:"failed"`
	} `json:"_shards"`
	Hits struct {
		Total int `json:"total"`
		Hits  []struct {
			Source struct {
				ModuleName    string   `json:"module_name"`
				Owner         string   `json:"owner"`
				CoMaintainers []string `json:"co_maintainers"`
			} `json:"_source"`
			ID    string  `json:"_id"`
			Type  string  `json:"_type"`
			Index string  `json:"_index"`
			Score float64 `json:"_score"`
		} `json:"hits"`
		MaxScore float64 `json:"max_score"`
	} `json:"hits"`
	TimedOut bool `json:"timed_out"`
	Took     int  `json:"took"`
}

func makeMetaCPANQuery(modules []string) metacpanQuery {
	query := metacpanQuery{
		Query: make(map[string]map[string][]metacpanQueryTerm),
		Size:  len(modules),
	}
	query.Query["bool"] = make(map[string][]metacpanQueryTerm)
	terms := make([]metacpanQueryTerm, 0, len(modules))
	for _, module := range modules {
		terms = append(terms, metacpanQueryTerm{Term: map[string]string{"module_name": module}})
	}
	query.Query["bool"]["should"] = terms
	return query
}

func (p *Permission) get(modules []string) ([]PermissionResult, error) {
	url := p.MetaCPAN + "/_search"
	query := makeMetaCPANQuery(modules)
	b, err := json.Marshal(query)
	if err != nil {
		return nil, err
	}
	res, err := p.Client.Post(url, "application/json", bytes.NewReader(b))
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		err := errors.New(res.Status + ", " + url)
		return nil, err
	}
	var result metacpanResult
	if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
		return nil, err
	}

	hits := result.Hits.Hits
	seen := make(map[string]struct{})
	results := make(permissionResults, 0, len(hits))
	for _, hit := range hits {
		seen[hit.Source.ModuleName] = struct{}{}
		co := hit.Source.CoMaintainers
		if co == nil {
			co = []string{}
		}
		sort.Strings(co)
		p := PermissionResult{
			Owner:         hit.Source.Owner,
			ModuleName:    hit.Source.ModuleName,
			CoMaintainers: co,
		}
		results = append(results, p)
	}
	for _, module := range modules {
		if _, ok := seen[module]; !ok {
			results = append(results, PermissionResult{ModuleName: module})
		}
	}
	sort.Sort(results)
	return results, nil
}
<|endoftext|>


<commit_before>package pingu

import (
	"fmt"
	"github.com/nlopes/slack"
	"github.com/robfig/cron"
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
	"log"
	"regexp"
	"time"
)

type Command struct {
	Description string
	Func        func(pi *Pingu, ev *slack.MessageEvent)
	Trigger     *regexp.Regexp
}

type Commands []*Command

type Pingu struct {
	builtAt     time.Time
	connectedAt time.Time
	config      *viper.Viper
	latency     time.Duration
	logger      *logrus.Logger
	name        string
	plugins     Plugins
	rtm         *slack.RTM
	startedAt   time.Time
	version     string
}

type Task struct {
	Func     func(pi *Pingu)
	Interval time.Duration
}

type Tasks []*Task

func New(config *viper.Viper, logger *logrus.Logger) *Pingu {
	factories, err := LoadPlugins(config.GetString("pingu.plugin_path"))

	if err != nil {
		logger.Fatal(err)
	}

	plugins := make(Plugins, len(factories))

	for i, factory := range factories {
		plugins[i] = factory(config)

		logger.WithFields(logrus.Fields{
			"author":  plugins[i].Author(),
			"name":    plugins[i].Name(),
			"version": plugins[i].Version(),
		}).Info("Plugin loaded")
	}

	api := slack.New(config.GetString("slack.token"))
	rtm := api.NewRTM()

	return &Pingu{
		config:    config,
		logger:    logger,
		name:      "Pingu",
		plugins:   plugins,
		rtm:       rtm,
		startedAt: time.Now(),
	}
}

func (p *Pingu) BuiltAt() time.Time {
	return p.builtAt
}

func (p *Pingu) ConnectedAt() time.Time {
	return p.connectedAt
}

func (p *Pingu) Latency() time.Duration {
	return p.latency
}

func (p *Pingu) Logger() *logrus.Logger {
	return p.logger
}

func (p *Pingu) Name() string {
	return p.name
}

func (p *Pingu) Plugins() Plugins {
	return p.plugins
}

func (p *Pingu) Reply(ev *slack.MessageEvent, msg string) {
	p.Say(fmt.Sprintf("<@%s>: %s", ev.User, msg), ev.Channel)
}

func (p *Pingu) Run() {
	c := cron.New()
	w := p.logger.Writer()

	defer w.Close()

	c.ErrorLog = log.New(w, "", 0)

	for _, plugin := range p.plugins {
		plugin := plugin
		for _, task := range plugin.Tasks() {
			task := task
			if err := c.AddFunc(fmt.Sprintf("@every %s", task.Interval.String()), func() {
				task.Func(p)
				p.logger.WithFields(logrus.Fields{
					"plugin": plugin.Name(),
				}).Info("Task executed")
			}); err != nil {
				p.logger.Fatal(err)
			}
		}
	}

	go p.rtm.ManageConnection()

	for msg := range p.rtm.IncomingEvents {
		switch ev := msg.Data.(type) {
		case *slack.ConnectedEvent:
			p.connectedAt = time.Now()
			p.logger.Info("Connection established")

			for _, plugin := range p.plugins {
				plugin := plugin
				for _, task := range plugin.Tasks() {
					task := task
					task.Func(p)
					p.logger.WithFields(logrus.Fields{
						"plugin": plugin.Name(),
					}).Info("Task executed")
				}
			}

			c.Start()
		case *slack.DisconnectedEvent:
			p.logger.Info("Connection lost")
			c.Stop()
		case *slack.LatencyReport:
			p.latency = ev.Value
		case *slack.InvalidAuthEvent:
			p.logger.Fatal("Authentication failed")
		case *slack.MessageEvent:
			for _, plugin := range p.plugins {
				plugin := plugin
				for _, command := range plugin.Commands() {
					command := command
					if command.Trigger.MatchString(ev.Text) {
						p.logger.WithFields(logrus.Fields{
							"plugin":  plugin.Name(),
							"trigger": command.Trigger.String(),
						}).Info("Command triggered")
						command.Func(p, ev)
					}
				}
			}
		}
	}
}

func (p *Pingu) Say(msg string, ch string) {
	p.rtm.SendMessage(p.rtm.NewOutgoingMessage(msg, ch))
}

func (p *Pingu) SendAttachments(attachments []slack.Attachment, msg string, ch string) {
	_, _, err := p.rtm.PostMessage(ch, "", slack.PostMessageParameters{
		AsUser:      true,
		LinkNames:   1,
		UnfurlLinks: false,
		UnfurlMedia: true,
		Attachments: attachments,
	})

	if err != nil {
		p.logger.Error(err)
	}
}

func (p *Pingu) StartedAt() time.Time {
	return p.startedAt
}

func (p *Pingu) Version() string {
	return p.version
}
<commit_msg>Make it possible to set build date and version with ldflags<commit_after>package pingu

import (
	"fmt"
	"github.com/nlopes/slack"
	"github.com/robfig/cron"
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
	"log"
	"regexp"
	"time"
)

type Command struct {
	Description string
	Func        func(pi *Pingu, ev *slack.MessageEvent)
	Trigger     *regexp.Regexp
}

type Commands []*Command

type Pingu struct {
	builtAt     time.Time
	connectedAt time.Time
	config      *viper.Viper
	latency     time.Duration
	logger      *logrus.Logger
	name        string
	plugins     Plugins
	rtm         *slack.RTM
	startedAt   time.Time
	version     string
}

type Task struct {
	Func     func(pi *Pingu)
	Interval time.Duration
}

type Tasks []*Task

var builtAt string
var version string

func init() {
	if builtAt == "" {
		builtAt = time.Now().Format(time.RFC3339)
	}

	if version == "" {
		version = "dev"
	}
}

func New(config *viper.Viper, logger *logrus.Logger) *Pingu {
	factories, err := LoadPlugins(config.GetString("pingu.plugin_path"))

	if err != nil {
		logger.Fatal(err)
	}

	plugins := make(Plugins, len(factories))

	for i, factory := range factories {
		plugins[i] = factory(config)

		logger.WithFields(logrus.Fields{
			"author":  plugins[i].Author(),
			"name":    plugins[i].Name(),
			"version": plugins[i].Version(),
		}).Info("Plugin loaded")
	}

	api := slack.New(config.GetString("slack.token"))
	rtm := api.NewRTM()
	builtAtTime, err := time.Parse(time.RFC3339, builtAt)

	if err != nil {
		logger.Fatal(err)
	}

	return &Pingu{
		builtAt:   builtAtTime,
		config:    config,
		logger:    logger,
		name:      "Pingu",
		plugins:   plugins,
		rtm:       rtm,
		startedAt: time.Now(),
		version:   version,
	}
}

func (p *Pingu) BuiltAt() time.Time {
	return p.builtAt
}

func (p *Pingu) ConnectedAt() time.Time {
	return p.connectedAt
}

func (p *Pingu) Latency() time.Duration {
	return p.latency
}

func (p *Pingu) Logger() *logrus.Logger {
	return p.logger
}

func (p *Pingu) Name() string {
	return p.name
}

func (p *Pingu) Plugins() Plugins {
	return p.plugins
}

func (p *Pingu) Reply(ev *slack.MessageEvent, msg string) {
	p.Say(fmt.Sprintf("<@%s>: %s", ev.User, msg), ev.Channel)
}

func (p *Pingu) Run() {
	p.logger.WithFields(logrus.Fields{
		"builtAt": p.builtAt,
		"version": p.version,
	}).Info("Pingu started")

	c := cron.New()
	w := p.logger.Writer()

	defer w.Close()

	c.ErrorLog = log.New(w, "", 0)

	for _, plugin := range p.plugins {
		plugin := plugin
		for _, task := range plugin.Tasks() {
			task := task
			if err := c.AddFunc(fmt.Sprintf("@every %s", task.Interval.String()), func() {
				task.Func(p)
				p.logger.WithFields(logrus.Fields{
					"plugin": plugin.Name(),
				}).Info("Task executed")
			}); err != nil {
				p.logger.Fatal(err)
			}
		}
	}

	go p.rtm.ManageConnection()

	for msg := range p.rtm.IncomingEvents {
		switch ev := msg.Data.(type) {
		case *slack.ConnectedEvent:
			p.connectedAt = time.Now()
			p.logger.Info("Connection established")

			for _, plugin := range p.plugins {
				plugin := plugin
				for _, task := range plugin.Tasks() {
					task := task
					task.Func(p)
					p.logger.WithFields(logrus.Fields{
						"plugin": plugin.Name(),
					}).Info("Task executed")
				}
			}

			c.Start()
		case *slack.DisconnectedEvent:
			p.logger.Info("Connection lost")
			c.Stop()
		case *slack.LatencyReport:
			p.latency = ev.Value
		case *slack.InvalidAuthEvent:
			p.logger.Fatal("Authentication failed")
		case *slack.MessageEvent:
			for _, plugin := range p.plugins {
				plugin := plugin
				for _, command := range plugin.Commands() {
					command := command
					if command.Trigger.MatchString(ev.Text) {
						p.logger.WithFields(logrus.Fields{
							"plugin":  plugin.Name(),
							"trigger": command.Trigger.String(),
						}).Info("Command triggered")
						command.Func(p, ev)
					}
				}
			}
		}
	}
}

func (p *Pingu) Say(msg string, ch string) {
	p.rtm.SendMessage(p.rtm.NewOutgoingMessage(msg, ch))
}

func (p *Pingu) SendAttachments(attachments []slack.Attachment, msg string, ch string) {
	_, _, err := p.rtm.PostMessage(ch, "", slack.PostMessageParameters{
		AsUser:      true,
		LinkNames:   1,
		UnfurlLinks: false,
		UnfurlMedia: true,
		Attachments: attachments,
	})

	if err != nil {
		p.logger.Error(err)
	}
}

func (p *Pingu) StartedAt() time.Time {
	return p.startedAt
}

func (p *Pingu) Version() string {
	return p.version
}
<|endoftext|>


<commit_before>// +build linux

package mount

import (
	"fmt"
	"os"
	"path/filepath"
	"syscall"

	"github.com/dotcloud/docker/pkg/label"
	"github.com/dotcloud/docker/pkg/libcontainer"
	"github.com/dotcloud/docker/pkg/libcontainer/mount/nodes"
	"github.com/dotcloud/docker/pkg/system"
)

// default mount point flags
const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV

type mount struct {
	source string
	path   string
	device string
	flags  int
	data   string
}

// InitializeMountNamespace setups up the devices, mount points, and filesystems for use inside a
// new mount namepsace
func InitializeMountNamespace(rootfs, console string, container *libcontainer.Container) error {
	var (
		err  error
		flag = syscall.MS_PRIVATE
	)
	if container.NoPivotRoot {
		flag = syscall.MS_SLAVE
	}
	if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil {
		return fmt.Errorf("mounting / as slave %s", err)
	}
	if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("mouting %s as bind %s", rootfs, err)
	}
	if err := mountSystem(rootfs, container); err != nil {
		return fmt.Errorf("mount system %s", err)
	}
	if err := setupBindmounts(rootfs, container.Mounts); err != nil {
		return fmt.Errorf("bind mounts %s", err)
	}
	if err := nodes.CopyN(rootfs, nodes.DefaultNodes); err != nil {
		return fmt.Errorf("copy dev nodes %s", err)
	}
	if err := SetupPtmx(rootfs, console, container.Context["mount_label"]); err != nil {
		return err
	}
	if err := system.Chdir(rootfs); err != nil {
		return fmt.Errorf("chdir into %s %s", rootfs, err)
	}

	if container.NoPivotRoot {
		err = MsMoveRoot(rootfs)
	} else {
		err = PivotRoot(rootfs)
	}
	if err != nil {
		return err
	}

	if container.ReadonlyFs {
		if err := SetReadonly(); err != nil {
			return fmt.Errorf("set readonly %s", err)
		}
	}

	system.Umask(0022)

	return nil
}

// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
// inside the mount namespace
func mountSystem(rootfs string, container *libcontainer.Container) error {
	for _, m := range newSystemMounts(rootfs, container.Context["mount_label"], container.Mounts) {
		if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
			return fmt.Errorf("mkdirall %s %s", m.path, err)
		}
		if err := system.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil {
			return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err)
		}
	}
	return nil
}

func createIfNotExists(path string, isDir bool) error {
	if _, err := os.Stat(path); err != nil {
		if os.IsNotExist(err) {
			if isDir {
				if err := os.MkdirAll(path, 0755); err != nil {
					return err
				}
			} else {
				if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
					return err
				}
				f, err := os.OpenFile(path, os.O_CREATE, 0755)
				if err != nil {
					return err
				}
				f.Close()
			}
		}
	}
	return nil
}

func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error {
	for _, m := range bindMounts.OfType("bind") {
		var (
			flags = syscall.MS_BIND | syscall.MS_REC
			dest  = filepath.Join(rootfs, m.Destination)
		)
		if !m.Writable {
			flags = flags | syscall.MS_RDONLY
		}

		stat, err := os.Stat(m.Source)
		if err != nil {
			return err
		}
		if err := createIfNotExists(dest, stat.IsDir()); err != nil {
			return fmt.Errorf("Creating new bind-mount target, %s\n", err)
		}

		if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
			return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err)
		}
		if !m.Writable {
			if err := system.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil {
				return fmt.Errorf("remounting %s into %s %s", m.Source, dest, err)
			}
		}
		if m.Private {
			if err := system.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
				return fmt.Errorf("mounting %s private %s", dest, err)
			}
		}
	}
	return nil
}

// TODO: this is crappy right now and should be cleaned up with a better way of handling system and
// standard bind mounts allowing them to be more dynamic
func newSystemMounts(rootfs, mountLabel string, mounts libcontainer.Mounts) []mount {
	systemMounts := []mount{
		{source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags},
		{source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: defaultMountFlags},
		{source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: label.FormatMountLabel("mode=1777,size=65536k", mountLabel)},
		{source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: label.FormatMountLabel("newinstance,ptmxmode=0666,mode=620,gid=5", mountLabel)},
	}

	if len(mounts.OfType("devtmpfs")) == 1 {
		systemMounts = append([]mount{{source: "tmpfs", path: filepath.Join(rootfs, "dev"), device: "tmpfs", flags: syscall.MS_NOSUID | syscall.MS_STRICTATIME, data: label.FormatMountLabel("mode=755", mountLabel)}}, systemMounts...)
	}
	return systemMounts
}
<commit_msg>Remove newline char in error message Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)<commit_after>// +build linux

package mount

import (
	"fmt"
	"os"
	"path/filepath"
	"syscall"

	"github.com/dotcloud/docker/pkg/label"
	"github.com/dotcloud/docker/pkg/libcontainer"
	"github.com/dotcloud/docker/pkg/libcontainer/mount/nodes"
	"github.com/dotcloud/docker/pkg/system"
)

// default mount point flags
const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV

type mount struct {
	source string
	path   string
	device string
	flags  int
	data   string
}

// InitializeMountNamespace setups up the devices, mount points, and filesystems for use inside a
// new mount namepsace
func InitializeMountNamespace(rootfs, console string, container *libcontainer.Container) error {
	var (
		err  error
		flag = syscall.MS_PRIVATE
	)
	if container.NoPivotRoot {
		flag = syscall.MS_SLAVE
	}
	if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil {
		return fmt.Errorf("mounting / as slave %s", err)
	}
	if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("mouting %s as bind %s", rootfs, err)
	}
	if err := mountSystem(rootfs, container); err != nil {
		return fmt.Errorf("mount system %s", err)
	}
	if err := setupBindmounts(rootfs, container.Mounts); err != nil {
		return fmt.Errorf("bind mounts %s", err)
	}
	if err := nodes.CopyN(rootfs, nodes.DefaultNodes); err != nil {
		return fmt.Errorf("copy dev nodes %s", err)
	}
	if err := SetupPtmx(rootfs, console, container.Context["mount_label"]); err != nil {
		return err
	}
	if err := system.Chdir(rootfs); err != nil {
		return fmt.Errorf("chdir into %s %s", rootfs, err)
	}

	if container.NoPivotRoot {
		err = MsMoveRoot(rootfs)
	} else {
		err = PivotRoot(rootfs)
	}
	if err != nil {
		return err
	}

	if container.ReadonlyFs {
		if err := SetReadonly(); err != nil {
			return fmt.Errorf("set readonly %s", err)
		}
	}

	system.Umask(0022)

	return nil
}

// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
// inside the mount namespace
func mountSystem(rootfs string, container *libcontainer.Container) error {
	for _, m := range newSystemMounts(rootfs, container.Context["mount_label"], container.Mounts) {
		if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
			return fmt.Errorf("mkdirall %s %s", m.path, err)
		}
		if err := system.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil {
			return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err)
		}
	}
	return nil
}

func createIfNotExists(path string, isDir bool) error {
	if _, err := os.Stat(path); err != nil {
		if os.IsNotExist(err) {
			if isDir {
				if err := os.MkdirAll(path, 0755); err != nil {
					return err
				}
			} else {
				if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
					return err
				}
				f, err := os.OpenFile(path, os.O_CREATE, 0755)
				if err != nil {
					return err
				}
				f.Close()
			}
		}
	}
	return nil
}

func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error {
	for _, m := range bindMounts.OfType("bind") {
		var (
			flags = syscall.MS_BIND | syscall.MS_REC
			dest  = filepath.Join(rootfs, m.Destination)
		)
		if !m.Writable {
			flags = flags | syscall.MS_RDONLY
		}

		stat, err := os.Stat(m.Source)
		if err != nil {
			return err
		}
		if err := createIfNotExists(dest, stat.IsDir()); err != nil {
			return fmt.Errorf("Creating new bind-mount target, %s", err)
		}

		if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
			return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err)
		}
		if !m.Writable {
			if err := system.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil {
				return fmt.Errorf("remounting %s into %s %s", m.Source, dest, err)
			}
		}
		if m.Private {
			if err := system.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
				return fmt.Errorf("mounting %s private %s", dest, err)
			}
		}
	}
	return nil
}

// TODO: this is crappy right now and should be cleaned up with a better way of handling system and
// standard bind mounts allowing them to be more dynamic
func newSystemMounts(rootfs, mountLabel string, mounts libcontainer.Mounts) []mount {
	systemMounts := []mount{
		{source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags},
		{source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: defaultMountFlags},
		{source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: label.FormatMountLabel("mode=1777,size=65536k", mountLabel)},
		{source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: label.FormatMountLabel("newinstance,ptmxmode=0666,mode=620,gid=5", mountLabel)},
	}

	if len(mounts.OfType("devtmpfs")) == 1 {
		systemMounts = append([]mount{{source: "tmpfs", path: filepath.Join(rootfs, "dev"), device: "tmpfs", flags: syscall.MS_NOSUID | syscall.MS_STRICTATIME, data: label.FormatMountLabel("mode=755", mountLabel)}}, systemMounts...)
	}
	return systemMounts
}
<|endoftext|>


<commit_before>/* Gorilla Sessions backend for MySQL.

Copyright (c) 2013 Contributors. See the list of contributors in the CONTRIBUTORS file for details.

This software is licensed under a MIT style license available in the LICENSE file.
*/
package mysqlstore

import (
	"database/sql"
	"encoding/gob"
	"errors"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/securecookie"
	"github.com/gorilla/sessions"
	"log"
	"net/http"
	"strings"
	"time"
)

type MySQLStore struct {
	db         *sql.DB
	stmtInsert *sql.Stmt
	stmtDelete *sql.Stmt
	stmtUpdate *sql.Stmt
	stmtSelect *sql.Stmt

	Codecs  []securecookie.Codec
	Options *sessions.Options
	table   string
}

type sessionRow struct {
	id         string
	data       string
	createdOn  time.Time
	modifiedOn time.Time
	expiresOn  time.Time
}

func init() {
	gob.Register(time.Time{})
}

func NewMySQLStore(endpoint string, tableName string, path string, maxAge int, keyPairs ...[]byte) (*MySQLStore, error) {
	db, err := sql.Open("mysql", endpoint)
	if err != nil {
		return nil, err
	}

	return NewMySQLStoreFromConnection(db, tableName, path, maxAge, keyPairs...)
}

func NewMySQLStoreFromConnection(db *sql.DB, tableName string, path string, maxAge int, keyPairs ...[]byte) (*MySQLStore, error) {
	// Make sure table name is enclosed.
	tableName = "`" + strings.Trim(tableName, "`") + "`"

	cTableQ := "CREATE TABLE IF NOT EXISTS " +
		tableName + " (id INT NOT NULL AUTO_INCREMENT, " +
		"session_data LONGBLOB, " +
		"created_on TIMESTAMP DEFAULT 0, " +
		"modified_on TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP, " +
		"expires_on TIMESTAMP DEFAULT 0, PRIMARY KEY(`id`)) ENGINE=InnoDB;"
	if _, err := db.Exec(cTableQ); err != nil {
		return nil, err
	}

	insQ := "INSERT INTO " + tableName +
		"(id, session_data, created_on, modified_on, expires_on) VALUES (NULL, ?, ?, ?, ?)"
	stmtInsert, stmtErr := db.Prepare(insQ)
	if stmtErr != nil {
		return nil, stmtErr
	}

	delQ := "DELETE FROM " + tableName + " WHERE id = ?"
	stmtDelete, stmtErr := db.Prepare(delQ)
	if stmtErr != nil {
		return nil, stmtErr
	}

	updQ := "UPDATE " + tableName + " SET session_data = ?, created_on = ?, expires_on = ? " +
		"WHERE id = ?"
	stmtUpdate, stmtErr := db.Prepare(updQ)
	if stmtErr != nil {
		return nil, stmtErr
	}

	selQ := "SELECT id, session_data, created_on, modified_on, expires_on from " +
		tableName + " WHERE id = ?"
	stmtSelect, stmtErr := db.Prepare(selQ)
	if stmtErr != nil {
		return nil, stmtErr
	}

	return &MySQLStore{
		db:         db,
		stmtInsert: stmtInsert,
		stmtDelete: stmtDelete,
		stmtUpdate: stmtUpdate,
		stmtSelect: stmtSelect,
		Codecs:     securecookie.CodecsFromPairs(keyPairs...),
		Options: &sessions.Options{
			Path:   path,
			MaxAge: maxAge,
		},
		table: tableName,
	}, nil
}

func (m *MySQLStore) Close() {
	m.stmtSelect.Close()
	m.stmtUpdate.Close()
	m.stmtDelete.Close()
	m.stmtInsert.Close()
	m.db.Close()
}

func (m *MySQLStore) Get(r *http.Request, name string) (*sessions.Session, error) {
	return sessions.GetRegistry(r).Get(m, name)
}

func (m *MySQLStore) New(r *http.Request, name string) (*sessions.Session, error) {
	session := sessions.NewSession(m, name)
	session.Options = &sessions.Options{
		Path:   m.Options.Path,
		MaxAge: m.Options.MaxAge,
	}
	session.IsNew = true
	var err error
	if cook, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, cook.Value, &session.ID, m.Codecs...)
		if err == nil {
			err = m.load(session)
			if err == nil {
				session.IsNew = false
			} else {
				err = nil
			}
		}
	}
	return session, err
}

func (m *MySQLStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
	var err error
	if session.ID == "" {
		if err = m.insert(session); err != nil {
			return err
		}
	} else if err = m.save(session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, m.Codecs...)
	if err != nil {
		return err
	}
	http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options))
	return nil
}

func (m *MySQLStore) insert(session *sessions.Session) error {
	var createdOn time.Time
	var modifiedOn time.Time
	var expiresOn time.Time
	crOn := session.Values["created_on"]
	if crOn == nil {
		createdOn = time.Now()
	} else {
		createdOn = crOn.(time.Time)
	}
	modifiedOn = createdOn
	exOn := session.Values["expires_on"]
	if exOn == nil {
		expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge))
	} else {
		expiresOn = exOn.(time.Time)
	}
	delete(session.Values, "created_on")
	delete(session.Values, "expires_on")
	delete(session.Values, "modified_on")

	encoded, encErr := securecookie.EncodeMulti(session.Name(), session.Values, m.Codecs...)
	if encErr != nil {
		return encErr
	}
	res, insErr := m.stmtInsert.Exec(encoded, createdOn, modifiedOn, expiresOn)
	if insErr != nil {
		return insErr
	}
	lastInserted, lInsErr := res.LastInsertId()
	if lInsErr != nil {
		return lInsErr
	}
	session.ID = fmt.Sprintf("%d", lastInserted)
	return nil
}

func (m *MySQLStore) Delete(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {

	// Set cookie to expire.
	options := *session.Options
	options.MaxAge = -1
	http.SetCookie(w, sessions.NewCookie(session.Name(), "", &options))
	// Clear session values.
	for k := range session.Values {
		delete(session.Values, k)
	}

	_, delErr := m.stmtDelete.Exec(session.ID)
	if delErr != nil {
		return delErr
	}
	return nil
}

func (m *MySQLStore) save(session *sessions.Session) error {
	if session.IsNew == true {
		return m.insert(session)
	}
	var createdOn time.Time
	var expiresOn time.Time
	crOn := session.Values["created_on"]
	if crOn == nil {
		createdOn = time.Now()
	} else {
		createdOn = crOn.(time.Time)
	}

	exOn := session.Values["expires_on"]
	if exOn == nil {
		expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge))
		log.Print("nil")
	} else {
		expiresOn = exOn.(time.Time)
		if expiresOn.Sub(time.Now().Add(time.Second*time.Duration(session.Options.MaxAge))) < 0 {
			expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge))
		}
	}

	delete(session.Values, "created_on")
	delete(session.Values, "expires_on")
	delete(session.Values, "modified_on")
	encoded, encErr := securecookie.EncodeMulti(session.Name(), session.Values, m.Codecs...)
	if encErr != nil {
		return encErr
	}
	_, updErr := m.stmtUpdate.Exec(encoded, createdOn, expiresOn, session.ID)
	if updErr != nil {
		return updErr
	}
	return nil
}

func (m *MySQLStore) load(session *sessions.Session) error {
	row := m.stmtSelect.QueryRow(session.ID)
	sess := sessionRow{}
	scanErr := row.Scan(&sess.id, &sess.data, &sess.createdOn, &sess.modifiedOn, &sess.expiresOn)
	if scanErr != nil {
		return scanErr
	}
	if sess.expiresOn.Sub(time.Now()) < 0 {
		log.Printf("Session expired on %s, but it is %s now.", sess.expiresOn, time.Now())
		return errors.New("Session expired")
	}
	err := securecookie.DecodeMulti(session.Name(), sess.data, &session.Values, m.Codecs...)
	if err != nil {
		return err
	}
	session.Values["created_on"] = sess.createdOn
	session.Values["modified_on"] = sess.modifiedOn
	session.Values["expires_on"] = sess.expiresOn
	return nil

}
<commit_msg>continue if create command denied<commit_after>/* Gorilla Sessions backend for MySQL.

Copyright (c) 2013 Contributors. See the list of contributors in the CONTRIBUTORS file for details.

This software is licensed under a MIT style license available in the LICENSE file.
*/
package mysqlstore

import (
	"database/sql"
	"encoding/gob"
	"errors"
	"fmt"
	"github.com/go-sql-driver/mysql"
	"github.com/gorilla/securecookie"
	"github.com/gorilla/sessions"
	"log"
	"net/http"
	"strings"
	"time"
)

type MySQLStore struct {
	db         *sql.DB
	stmtInsert *sql.Stmt
	stmtDelete *sql.Stmt
	stmtUpdate *sql.Stmt
	stmtSelect *sql.Stmt

	Codecs  []securecookie.Codec
	Options *sessions.Options
	table   string
}

type sessionRow struct {
	id         string
	data       string
	createdOn  time.Time
	modifiedOn time.Time
	expiresOn  time.Time
}

func init() {
	gob.Register(time.Time{})
}

func NewMySQLStore(endpoint string, tableName string, path string, maxAge int, keyPairs ...[]byte) (*MySQLStore, error) {
	db, err := sql.Open("mysql", endpoint)
	if err != nil {
		return nil, err
	}

	return NewMySQLStoreFromConnection(db, tableName, path, maxAge, keyPairs...)
}

func NewMySQLStoreFromConnection(db *sql.DB, tableName string, path string, maxAge int, keyPairs ...[]byte) (*MySQLStore, error) {
	// Make sure table name is enclosed.
	tableName = "`" + strings.Trim(tableName, "`") + "`"

	cTableQ := "CREATE TABLE IF NOT EXISTS " +
		tableName + " (id INT NOT NULL AUTO_INCREMENT, " +
		"session_data LONGBLOB, " +
		"created_on TIMESTAMP DEFAULT 0, " +
		"modified_on TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP, " +
		"expires_on TIMESTAMP DEFAULT 0, PRIMARY KEY(`id`)) ENGINE=InnoDB;"
	if _, err := db.Exec(cTableQ); err != nil {
		switch err.(type) {
		case *mysql.MySQLError:
			// Error 1142 means permission denied for create command
			if err.(*mysql.MySQLError).Number == 1142 {
				break
			} else {
				return nil, err
			}
		default:
			return nil, err
		}
	}

	insQ := "INSERT INTO " + tableName +
		"(id, session_data, created_on, modified_on, expires_on) VALUES (NULL, ?, ?, ?, ?)"
	stmtInsert, stmtErr := db.Prepare(insQ)
	if stmtErr != nil {
		return nil, stmtErr
	}

	delQ := "DELETE FROM " + tableName + " WHERE id = ?"
	stmtDelete, stmtErr := db.Prepare(delQ)
	if stmtErr != nil {
		return nil, stmtErr
	}

	updQ := "UPDATE " + tableName + " SET session_data = ?, created_on = ?, expires_on = ? " +
		"WHERE id = ?"
	stmtUpdate, stmtErr := db.Prepare(updQ)
	if stmtErr != nil {
		return nil, stmtErr
	}

	selQ := "SELECT id, session_data, created_on, modified_on, expires_on from " +
		tableName + " WHERE id = ?"
	stmtSelect, stmtErr := db.Prepare(selQ)
	if stmtErr != nil {
		return nil, stmtErr
	}

	return &MySQLStore{
		db:         db,
		stmtInsert: stmtInsert,
		stmtDelete: stmtDelete,
		stmtUpdate: stmtUpdate,
		stmtSelect: stmtSelect,
		Codecs:     securecookie.CodecsFromPairs(keyPairs...),
		Options: &sessions.Options{
			Path:   path,
			MaxAge: maxAge,
		},
		table: tableName,
	}, nil
}

func (m *MySQLStore) Close() {
	m.stmtSelect.Close()
	m.stmtUpdate.Close()
	m.stmtDelete.Close()
	m.stmtInsert.Close()
	m.db.Close()
}

func (m *MySQLStore) Get(r *http.Request, name string) (*sessions.Session, error) {
	return sessions.GetRegistry(r).Get(m, name)
}

func (m *MySQLStore) New(r *http.Request, name string) (*sessions.Session, error) {
	session := sessions.NewSession(m, name)
	session.Options = &sessions.Options{
		Path:   m.Options.Path,
		MaxAge: m.Options.MaxAge,
	}
	session.IsNew = true
	var err error
	if cook, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, cook.Value, &session.ID, m.Codecs...)
		if err == nil {
			err = m.load(session)
			if err == nil {
				session.IsNew = false
			} else {
				err = nil
			}
		}
	}
	return session, err
}

func (m *MySQLStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
	var err error
	if session.ID == "" {
		if err = m.insert(session); err != nil {
			return err
		}
	} else if err = m.save(session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, m.Codecs...)
	if err != nil {
		return err
	}
	http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options))
	return nil
}

func (m *MySQLStore) insert(session *sessions.Session) error {
	var createdOn time.Time
	var modifiedOn time.Time
	var expiresOn time.Time
	crOn := session.Values["created_on"]
	if crOn == nil {
		createdOn = time.Now()
	} else {
		createdOn = crOn.(time.Time)
	}
	modifiedOn = createdOn
	exOn := session.Values["expires_on"]
	if exOn == nil {
		expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge))
	} else {
		expiresOn = exOn.(time.Time)
	}
	delete(session.Values, "created_on")
	delete(session.Values, "expires_on")
	delete(session.Values, "modified_on")

	encoded, encErr := securecookie.EncodeMulti(session.Name(), session.Values, m.Codecs...)
	if encErr != nil {
		return encErr
	}
	res, insErr := m.stmtInsert.Exec(encoded, createdOn, modifiedOn, expiresOn)
	if insErr != nil {
		return insErr
	}
	lastInserted, lInsErr := res.LastInsertId()
	if lInsErr != nil {
		return lInsErr
	}
	session.ID = fmt.Sprintf("%d", lastInserted)
	return nil
}

func (m *MySQLStore) Delete(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {

	// Set cookie to expire.
	options := *session.Options
	options.MaxAge = -1
	http.SetCookie(w, sessions.NewCookie(session.Name(), "", &options))
	// Clear session values.
	for k := range session.Values {
		delete(session.Values, k)
	}

	_, delErr := m.stmtDelete.Exec(session.ID)
	if delErr != nil {
		return delErr
	}
	return nil
}

func (m *MySQLStore) save(session *sessions.Session) error {
	if session.IsNew == true {
		return m.insert(session)
	}
	var createdOn time.Time
	var expiresOn time.Time
	crOn := session.Values["created_on"]
	if crOn == nil {
		createdOn = time.Now()
	} else {
		createdOn = crOn.(time.Time)
	}

	exOn := session.Values["expires_on"]
	if exOn == nil {
		expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge))
		log.Print("nil")
	} else {
		expiresOn = exOn.(time.Time)
		if expiresOn.Sub(time.Now().Add(time.Second*time.Duration(session.Options.MaxAge))) < 0 {
			expiresOn = time.Now().Add(time.Second * time.Duration(session.Options.MaxAge))
		}
	}

	delete(session.Values, "created_on")
	delete(session.Values, "expires_on")
	delete(session.Values, "modified_on")
	encoded, encErr := securecookie.EncodeMulti(session.Name(), session.Values, m.Codecs...)
	if encErr != nil {
		return encErr
	}
	_, updErr := m.stmtUpdate.Exec(encoded, createdOn, expiresOn, session.ID)
	if updErr != nil {
		return updErr
	}
	return nil
}

func (m *MySQLStore) load(session *sessions.Session) error {
	row := m.stmtSelect.QueryRow(session.ID)
	sess := sessionRow{}
	scanErr := row.Scan(&sess.id, &sess.data, &sess.createdOn, &sess.modifiedOn, &sess.expiresOn)
	if scanErr != nil {
		return scanErr
	}
	if sess.expiresOn.Sub(time.Now()) < 0 {
		log.Printf("Session expired on %s, but it is %s now.", sess.expiresOn, time.Now())
		return errors.New("Session expired")
	}
	err := securecookie.DecodeMulti(session.Name(), sess.data, &session.Values, m.Codecs...)
	if err != nil {
		return err
	}
	session.Values["created_on"] = sess.createdOn
	session.Values["modified_on"] = sess.modifiedOn
	session.Values["expires_on"] = sess.expiresOn
	return nil

}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "net/http"
    "os"
    "os/exec"
    "encoding/json"
    "log"
    "time"
    "strings"
    //"math/rand"
    "regexp"
)

type Config struct {
    Host string
    Port int
    Reg_filter string
    Mystem_path string
    Mystem_workers int
    Channel_buffer int
    Max_word_length int
    Max_words int
}

type Answer struct {
    data string
    err error
}

type Data struct {
    word string
    channel chan Answer
}

var for_process chan Data
var reg_filter *regexp.Regexp
var config Config

func makePanic(msg string) {
    log.Fatal(msg)
    panic(msg)
}

func loadConfig() (cfg Config, err error) {
    var f_name string = "conf.json"
    if (len(os.Args) > 1) {
        f_name = os.Args[1]
    }
    file, err := os.Open(f_name)
    defer file.Close()
    if err == nil {
        f_stat, _ := file.Stat()
        raw_json := make([]byte, f_stat.Size())
        _, err = file.Read(raw_json)
        if err == nil {
            err = json.Unmarshal(raw_json, &cfg)
        }
    }
    return cfg, err
}

func workerMystem(for_process chan Data, mystem_path string) int {
    //name := rand.Int()
    //log.Print("Mystem started ", name)
    mystem := exec.Command(mystem_path, "-n", "--format", "json")
    mystem_writer, err_w := mystem.StdinPipe()
    mystem_reader, err_r := mystem.StdoutPipe()
    err := mystem.Start()
    if (err_w != nil) || (err_r != nil) {
        makePanic(fmt.Sprintf("Can't start: \n%v\n%v", err_w, err_r))
    }
    if err != nil {
        makePanic(fmt.Sprintf("Can't start: %v", err))
    } else {
        var data Data
        var buf []byte
        var n int
        var answer Answer
        for {
            data = <- for_process
            n, err = mystem_writer.Write([]byte(fmt.Sprintf("%v\n", data.word)))
            if err != nil {
                log.Panic(fmt.Sprintf("Can't send word to mystem: %v", err))
            }
            buf = make([]byte, 1000)
            n, err = mystem_reader.Read(buf)
            if err != nil {
                log.Panic(fmt.Sprintf("Can't read answer from mystem: %v", err))
            }
            answer.data = strings.TrimSpace(string(buf[:n]))
            answer.err = err
            //time.Sleep(time.Second * time.Duration(rand.Intn(5)))
            data.channel <- answer
            time.Sleep(time.Millisecond * 100)
        }
    }
    return 0
}

func checkInput(req *http.Request) (words []string, code int) {
    var words_count int = len(req.Form["words[]"])
    if words_count == 0 {
        code = http.StatusNotAcceptable
    } else if words_count > int(config.Max_words) {
        code = http.StatusRequestEntityTooLarge
    } else {
        var w string = ""
        for _, word := range req.Form["words[]"] {
            w = strings.TrimSpace(word)
            if len(w) > int(config.Max_word_length) {
                w = word[:int(config.Max_word_length)]
            }
            if w != "" {
                words = append(words, w)
            }
        }
    }
    return words, code
}

func processWords(resp http.ResponseWriter, req *http.Request) {
    var data Data
    var answer Answer
    var request_answer string = ""
    req.ParseForm()
    words, status_code := checkInput(req)
    var words_count int = len(words)
    resp.Header().Set("Content-Type", "application/json;charset=utf-8")
    if words_count > 0 {
        request_answer = "["
        var local_channel chan Answer = make(chan Answer, words_count)
        data.channel = local_channel
        var start int = 0
        for _, word := range words {
            if reg_filter.MatchString(word) {
                data.word = word
                for_process <- data
            } else {
                start++
                request_answer += fmt.Sprintf(`{"analysis":[], "text":"%v"},`, word)
            }
        }
        for i := start; i < words_count; i++ {
            answer = <- local_channel
            if (i + 1) < words_count {
                answer.data += ","
            }
            request_answer += answer.data
        }
        request_answer += "]"
    } else {
        request_answer = fmt.Sprintf(`{"status": %v, "reason": "%v"}`, status_code, http.StatusText(status_code))
        resp.WriteHeader(status_code)
    }
    resp.Write([]byte(request_answer))
}

func main() {
    var err error = nil
    config, err = loadConfig()
    if err != nil {
        makePanic(fmt.Sprintf("Can't load config: %v", err))
    } else {
        reg_filter, err = regexp.Compile(config.Reg_filter)
        if err != nil {
            makePanic(fmt.Sprintf("Can`t compile regular expression: %v", err))
        }
        _, err = os.Open(config.Mystem_path)
        if  err != nil {
            makePanic(fmt.Sprintf("Can't find mystem: %v", err))
        }
        var i int
        if config.Channel_buffer > 0 {
            for_process = make(chan Data, int(config.Channel_buffer))
        } else {
            for_process = make(chan Data)
        }
        log.Print("Config load successful")
        for i = 0; i < int(config.Mystem_workers); i++ {
            go workerMystem(for_process, config.Mystem_path)
        }
        http.HandleFunc("/", processWords)
        log.Print(fmt.Sprintf("Server start on: %v:%v", config.Host, config.Port))
        err = http.ListenAndServe(fmt.Sprintf("%v:%v", config.Host, config.Port), nil)
        if err != nil {
            makePanic(fmt.Sprintf("Can't start http server: %v", err))
        }
    }
}<commit_msg>just save some parts of code<commit_after>package main

import (
    "fmt"
    "net/http"
    "os"
    "os/exec"
    "encoding/json"
    "log"
    "time"
    "strings"
    //"math/rand"
    "regexp"
)

type Config struct {
    Host string
    Port int
    Reg_filter string
    Mystem_path string
    Mystem_options []string
    Mystem_workers int
    Channel_buffer int
    Max_word_length int
    Max_words int
}

type Answer struct {
    data string
    err error
}

type Data struct {
    word string
    channel chan Answer
}

type Option struct {
    deny bool
    important bool
    value string
    values []string
}

var for_process chan Data
var reg_filter *regexp.Regexp
var config Config

func makePanic(msg string) {
    log.Fatal(msg)
    panic(msg)
}

func processMystemOptions(in_opts []string) (out_opts []string, err error) {
    var options map map[string][string]
    options_list := map[string]Option{
        "-n": Option{false, true, nil, nil},
        "-c": Option{false, false, nil, nil},
        "-w": Option{false, false, nil, nil},
        "-l": Option{false, false, nil, nil},
        "-i": Option{false, false, nil, nil},
        "-g": Option{false, false, nil, nil},
        "-s": Option{false, false, nil, nil},
        "-e": Option{true, false, "utf-8", []string{"cp866", "cp1251", "koi8-r", "utf-8"}},
        "-d": Option{false, false, nil, nil},
        "--eng-gr": Option{false, false, nil, nil},
        "--filter-gram": Option{false, false, nil, nil},
        "--fixlist": Option{false, false, nil, nil},
        "--format": Option{false, true, "json", []string{"json", "text", "xml"}},
        "--generate-all": Option{false, false, nil, nil},
        "--weight": Option{false, false, nil, nil},
    }
    var opts_arr [2]string = [2]string{nil, nil}
    var val Option
    var exists bool = false
    var approve bool = false
    for opt := range in_opts {
        opt = string.TrimSpace(opt)
        if strings.Index(opt, " ") == -1 {
            opts_arr[0] = opt
        } else {
            opts_arr = strings.Split(opt, ' ')
        }
        val, exists = options_list[opt]
        if exists && (!val["deny"]) {
            if opt_arr[1] == nil {
                approve = true
            } else {

            }
            if approve {
                out_opts = append(out_ops, opt_arr...)
            }
        } else {
            log.Printf("Mystem option '%v' ignored (wrong or unnecessary)")
        }
        approve = false
        opt_arr = [2]string{nil, nil}
    }
    return out_opts, err
}

func loadConfig() (cfg Config, err error) {
    var f_name string = "conf.json"
    if (len(os.Args) > 1) {
        f_name = os.Args[1]
    }
    file, err := os.Open(f_name)
    defer file.Close()
    if err == nil {
        f_stat, _ := file.Stat()
        raw_json := make([]byte, f_stat.Size())
        _, err = file.Read(raw_json)
        if err == nil {
            err = json.Unmarshal(raw_json, &cfg)
            fmt.Println(cfg.Mystem_options, err)
            if err == nil {
                cfg.Mystem_options, err = processMystemOptions(cfg.Mystem_options)
            }
        }
    }
    return cfg, err
}

func workerMystem(for_process chan Data, mystem_path string) int {
    //name := rand.Int()
    //log.Print("Mystem started ", name)
    mystem := exec.Command(mystem_path, config.Mystem_options...)
    mystem_writer, err_w := mystem.StdinPipe()
    mystem_reader, err_r := mystem.StdoutPipe()
    err := mystem.Start()
    if (err_w != nil) || (err_r != nil) {
        makePanic(fmt.Sprintf("Can't start: \n%v\n%v", err_w, err_r))
    }
    if err != nil {
        makePanic(fmt.Sprintf("Can't start: %v", err))
    } else {
        var data Data
        var buf []byte
        var n int
        var answer Answer
        for {
            data = <- for_process
            n, err = mystem_writer.Write([]byte(fmt.Sprintf("%v\n", data.word)))
            if err != nil {
                log.Panicf("Can't send word to mystem: %v", err)
            }
            buf = make([]byte, 1000)
            n, err = mystem_reader.Read(buf)
            if err != nil {
                log.Panicf("Can't read answer from mystem: %v", err)
            }
            answer.data = strings.TrimSpace(string(buf[:n]))
            answer.err = err
            //time.Sleep(time.Second * time.Duration(rand.Intn(5)))
            data.channel <- answer
            time.Sleep(time.Millisecond * 100)
        }
    }
    return 0
}

func checkInput(req *http.Request) (words []string, code int) {
    var words_count int = len(req.Form["words[]"])
    if words_count == 0 {
        code = http.StatusNotAcceptable
    } else if words_count > int(config.Max_words) {
        code = http.StatusRequestEntityTooLarge
    } else {
        var w string = ""
        for _, word := range req.Form["words[]"] {
            w = strings.TrimSpace(word)
            if len(w) > int(config.Max_word_length) {
                w = word[:int(config.Max_word_length)]
            }
            if w != "" {
                words = append(words, w)
            }
        }
    }
    return words, code
}

func processWords(resp http.ResponseWriter, req *http.Request) {
    var data Data
    var answer Answer
    var request_answer string = ""
    req.ParseForm()
    words, status_code := checkInput(req)
    var words_count int = len(words)
    resp.Header().Set("Content-Type", "application/json;charset=utf-8")
    if words_count > 0 {
        request_answer = "["
        var local_channel chan Answer = make(chan Answer, words_count)
        data.channel = local_channel
        var start int = 0
        for _, word := range words {
            if reg_filter.MatchString(word) {
                data.word = word
                for_process <- data
            } else {
                start++
                request_answer += fmt.Sprintf(`{"analysis":[], "text":"%v"},`, word)
            }
        }
        for i := start; i < words_count; i++ {
            answer = <- local_channel
            if (i + 1) < words_count {
                answer.data += ","
            }
            request_answer += answer.data
        }
        request_answer += "]"
        close(local_channel)
    } else {
        request_answer = fmt.Sprintf(`{"status": %v, "reason": "%v"}`, status_code, http.StatusText(status_code))
        resp.WriteHeader(status_code)
    }
    resp.Write([]byte(request_answer))
}

func main() {
    var err error = nil
    config, err = loadConfig()
    if err != nil {
        makePanic(fmt.Sprintf("Can't load config: %v", err))
    } else {
        reg_filter, err = regexp.Compile(config.Reg_filter)
        if err != nil {
            makePanic(fmt.Sprintf("Can`t compile regular expression: %v", err))
        }
        _, err = os.Open(config.Mystem_path)
        if  err != nil {
            makePanic(fmt.Sprintf("Can't find mystem: %v", err))
        }
        var i int
        if config.Channel_buffer > 0 {
            for_process = make(chan Data, int(config.Channel_buffer))
        } else {
            for_process = make(chan Data)
        }
        log.Print("Config load successful")
        for i = 0; i < int(config.Mystem_workers); i++ {
            go workerMystem(for_process, config.Mystem_path)
        }
        http.HandleFunc("/", processWords)
        log.Printf("Server start on: %v:%v", config.Host, config.Port)
        err = http.ListenAndServe(fmt.Sprintf("%v:%v", config.Host, config.Port), nil)
        if err != nil {
            makePanic(fmt.Sprintf("Can't start http server: %v", err))
        }
    }
}<|endoftext|>


<commit_before>package negotiator

import (
	"net/http"
	"strings"
)

const MimeJSON = "application/json"
const MimeXML = "application/xml"

// Encoder is an interface for a struct that can encode data into []byte
type Encoder interface {
	PrettyPrint bool
	Encode(data interface{}) ([]byte, error)
	ContentType() string
}

// A Negotiator can Negotiate to determine what content type to convert
// a struct into for client consumption
type Negotiator interface {
	Negotiate(req *http.Request, data interface{}) ([]byte, error)
}

// ContentNegotiator is a Neotiator that supports pretty printing
// and a fallback/default encoder as well as dynamically adding
// encoders
type ContentNegotiator struct {
	PrettyPrint    bool
	DefaultEncoder Encoder
	ResponseWriter http.ResponseWriter
	encoderMap     map[string]Encoder
}

func NewJsonXmlContentNegotiator(prettyPrint bool, defaultEncoder Encoder, responseWriter http.ResponseWriter) ContentNegotiator {
	result := ContentNegotiator{prettyPrint, defaultEncoder, responseWriter}
	result.AddEncoder(MimeJSON, JsonEncoder{prettyPrint})
	result.AddEncoder(MimeXML, XmlEncoder{prettyPrint})
	return result
}

// Negotiate inspects the request for the accept header and
// encodes the response appropriately.
func (cn ContentNegotiator) Negotiate(req *http.Request, data interface{}) ([]byte, error) {
	if len(cn.encoderMap) <= 0 {
		panic("No Encoders present. Please add them using ContentNegotiator.AddEncoder()")
	}
	var e = cn.getEncoder(req)
	cn.ResponseWriter.Header().Set("Content-Type", e.ContentType())
	return e.Encode(data)
}

// AddEncoder registers a mimetype and its encoder to be used if a client
// requests that mimetype
func (cn ContentNegotiator) AddEncoder(mimeType string, enc Encoder) {
	cn.encoderMap[mimeType] = enc
}

// getEncoder parses the Accept header an returns the appropriate encoder to use
func (cn ContentNegotiator) getEncoder(req *http.Request) Encoder {
	var result = cn.DefaultEncoder
	accept := req.Header.Get("Accept")

	for k, v := range cn.encoderMap {
		if strings.Contains(accept, k) {
			result = v
			break
		}
	}
	return result
}

// Check for an error and panic
func Must(data []byte, err error) []byte {
	if err != nil {
		panic(err)
	}
	return data
}
<commit_msg>removing typo<commit_after>package negotiator

import (
	"net/http"
	"strings"
)

const MimeJSON = "application/json"
const MimeXML = "application/xml"

// Encoder is an interface for a struct that can encode data into []byte
type Encoder interface {
	Encode(data interface{}) ([]byte, error)
	ContentType() string
}

// A Negotiator can Negotiate to determine what content type to convert
// a struct into for client consumption
type Negotiator interface {
	Negotiate(req *http.Request, data interface{}) ([]byte, error)
}

// ContentNegotiator is a Neotiator that supports pretty printing
// and a fallback/default encoder as well as dynamically adding
// encoders
type ContentNegotiator struct {
	PrettyPrint    bool
	DefaultEncoder Encoder
	ResponseWriter http.ResponseWriter
	encoderMap     map[string]Encoder
}

func NewJsonXmlContentNegotiator(prettyPrint bool, defaultEncoder Encoder, responseWriter http.ResponseWriter) ContentNegotiator {
	result := ContentNegotiator{prettyPrint, defaultEncoder, responseWriter}
	result.AddEncoder(MimeJSON, JsonEncoder{prettyPrint})
	result.AddEncoder(MimeXML, XmlEncoder{prettyPrint})
	return result
}

// Negotiate inspects the request for the accept header and
// encodes the response appropriately.
func (cn ContentNegotiator) Negotiate(req *http.Request, data interface{}) ([]byte, error) {
	if len(cn.encoderMap) <= 0 {
		panic("No Encoders present. Please add them using ContentNegotiator.AddEncoder()")
	}
	var e = cn.getEncoder(req)
	cn.ResponseWriter.Header().Set("Content-Type", e.ContentType())
	return e.Encode(data)
}

// AddEncoder registers a mimetype and its encoder to be used if a client
// requests that mimetype
func (cn ContentNegotiator) AddEncoder(mimeType string, enc Encoder) {
	cn.encoderMap[mimeType] = enc
}

// getEncoder parses the Accept header an returns the appropriate encoder to use
func (cn ContentNegotiator) getEncoder(req *http.Request) Encoder {
	var result = cn.DefaultEncoder
	accept := req.Header.Get("Accept")

	for k, v := range cn.encoderMap {
		if strings.Contains(accept, k) {
			result = v
			break
		}
	}
	return result
}

// Check for an error and panic
func Must(data []byte, err error) []byte {
	if err != nil {
		panic(err)
	}
	return data
}
<|endoftext|>


<commit_before>package optimization

import (
	"fmt"
	"math"
	"math/rand"
)

type function func([]float64) float64

func reflection(x []float64, c []float64, alpha float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+alpha*(c[i]-x[i]))
	}
	return
}

func expansion(x []float64, c []float64, gamma float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+gamma*(x[i]-c[i]))
	}
	return
}

func contraction(x []float64, c []float64, beta float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+beta*(x[i]-c[i]))
	}
	return
}

func shrink(x []float64, y []float64, delta float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, x[i]+delta*(y[i]-x[i]))
	}
	return
}

func around(c []float64, n int) (out [][]float64) {
	var p []float64
	radius := 0.1
	for i := 0; i < n; i++ {
		degrees := float64(rand.Intn(360))
		for i := 0; i < len(c); i++ {
			p = append(p, c[i]+radius*math.Cos(degrees*math.Pi/180.00))
		}
		out = append(out, p)
	}
	return
}

func mean(x []float64) float64 {
	out := 0.00
	n := len(x)
	for i := 0; i < n; i++ {
		out = out + x[i]
	}
	out = out / float64(n)
	return out
}

func apply(X [][]float64, n int, f function) (out []float64) {
	switch {
	// apply by row
	case n == 1:
		for i := 0; i < len(X); i++ {
			out = append(out, f(X[i]))
		}
		// apply by column
	case n == 2:
		var t [][]float64
		for i := 0; i < len(X[0]); i++ {
			var column []float64
			for j := 0; j < len(X); j++ {
				column = append(column, X[j][i])
			}
			t = append(t, column)
		}
		fmt.Println(t)
		for i := 0; i < len(t); i++ {
			out = append(out, f(t[i]))
		}
	case n > 2 || n < 1:
		panic("n must be 1 or 2!.")
	}
	return out
}

func neldermead(variable []float64, fn function, iter int) {
	n := len(variable)
	p := append(around(variable, n+1), variable)
	fmt.Println(p)
	for i := 0; i < iter; i++ {
		//var f []float64

	}

}
<commit_msg>Add interface function.<commit_after>package optimization

import (
	"fmt"
	"math"
	"math/rand"
)

type parameter struct {
	theta, y []float64
	X        [][]float64
}

type fn func([]float64) float64

type function func(parameter) float64

func reflection(x []float64, c []float64, alpha float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+alpha*(c[i]-x[i]))
	}
	return
}

func expansion(x []float64, c []float64, gamma float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+gamma*(x[i]-c[i]))
	}
	return
}

func contraction(x []float64, c []float64, beta float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+beta*(x[i]-c[i]))
	}
	return
}

func shrink(x []float64, y []float64, delta float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, x[i]+delta*(y[i]-x[i]))
	}
	return
}

func around(c []float64, n int) (out [][]float64) {
	var p []float64
	radius := 0.1
	for i := 0; i < n; i++ {
		degrees := float64(rand.Intn(360))
		for i := 0; i < len(c); i++ {
			p = append(p, c[i]+radius*math.Cos(degrees*math.Pi/180.00))
		}
		out = append(out, p)
	}
	return
}

func mean(x []float64) float64 {
	out := 0.00
	n := len(x)
	for i := 0; i < n; i++ {
		out = out + x[i]
	}
	out = out / float64(n)
	return out
}

func apply(X [][]float64, n int, f fn) (out []float64) {
	switch {
	// apply by row
	case n == 1:
		for i := 0; i < len(X); i++ {
			out = append(out, f(X[i]))
		}
		// apply by column
	case n == 2:
		var t [][]float64
		for i := 0; i < len(X[0]); i++ {
			var column []float64
			for j := 0; j < len(X); j++ {
				column = append(column, X[j][i])
			}
			t = append(t, column)
		}
		fmt.Println(t)
		for i := 0; i < len(t); i++ {
			out = append(out, f(t[i]))
		}
	case n > 2 || n < 1:
		panic("n must be 1 or 2!.")
	}
	return out
}

func neldermead(variables parameter, fn function, iter int) {
	n := len(variables.theta)
	p := append(around(variables.theta, n+1), variable)
	fmt.Println(p)
	for i := 0; i < iter; i++ {
		//var f []float64
		fmt.Println(fn(variables))

	}

}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "math"
)

func main(){
    var x, y int = 5, 9
    var f float64 = math.Sqrt(float64(x*x + y*y))

    //No need for 'var' declaration when using :=
    //The type will be infered
    z := int(f)

    fmt.Println(x, y, z)
}
<commit_msg>Using more constructs for assignment<commit_after>package primitives

import (
    "fmt"
    "math"
)

func Declares(){
    var x, y int = 5, 9
    var f float64 = math.Sqrt(float64(x*x + y*y))

    //No need for 'var' declaration when using :=
    //The type will be infered
    z := int(f)

    for i := 1; i < 10; i++{
        z += i
        fmt.Println(x, y, z)
    }
}
<|endoftext|>


<commit_before>package ngorm

import (
	"fmt"
	"testing"

	_ "github.com/cznic/ql/driver"
)

type Foo struct {
	Id    int
	Stuff string
}

func TestDB(t *testing.T) {
	db, err := Open("ql-mem", "test.db")
	if err != nil {
		t.Fatal(err)
	}

	// create table tests
	sql, err := db.CreateTableSQL(&Foo{})
	if err != nil {
		t.Fatal(err)
	}
	fmt.Println(sql.Q)
	_, err = db.CreateTable(&Foo{})
	if err != nil {
		t.Error(err)
	}

}
<commit_msg>Add tests<commit_after>package ngorm

import (
	"fmt"
	"strings"
	"testing"

	_ "github.com/cznic/ql/driver"
)

type Foo struct {
	Id    int
	Stuff string
}

func TestDB(t *testing.T) {
	db, err := Open("ql-mem", "test.db")
	if err != nil {
		t.Fatal(err)
	}

	// create table tests
	sql, err := db.CreateTableSQL(&Foo{})
	if err != nil {
		t.Fatal(err)
	}
	expect := `
BEGIN TRANSACTION;
	CREATE TABLE foos (id int,stuff string ) ;
COMMIT;`
	expect = strings.TrimSpace(expect)
	if sql.Q != expect {
		t.Errorf("expected %s got %s", expect, sql.Q)
	}
	fmt.Println(sql.Q)
	_, err = db.CreateTable(&Foo{})
	if err != nil {
		t.Error(err)
	}

}
<|endoftext|>


<commit_before>package ngorm

import (
	"strings"
	"testing"

	_ "github.com/cznic/ql/driver"
	"github.com/gernest/ngorm/fixture"
)

type Foo struct {
	Id    int
	Stuff string
}

func TestDB(t *testing.T) {
	db, err := Open("ql-mem", "test.db")
	if err != nil {
		t.Fatal(err)
	}

	// create table tests
	sql, err := db.CreateTableSQL(&Foo{})
	if err != nil {
		t.Fatal(err)
	}
	expect := `
BEGIN TRANSACTION;
	CREATE TABLE foos (id int,stuff string ) ;
COMMIT;`
	expect = strings.TrimSpace(expect)
	if sql.Q != expect {
		t.Errorf("expected %s got %s", expect, sql.Q)
	}
	_, err = db.CreateTable(&Foo{})
	if err != nil {
		t.Error(err)
	}

	// multiple tables
	sql, err = db.CreateTableSQL(
		&fixture.User{},
	)
	if err != nil {
		t.Fatal(err)
	}
	expect = `
BEGIN TRANSACTION;
	CREATE TABLE users (id int64,age int64,user_num int64,name string,email string,birthday time,created_at time,updated_at time,billing_address_id int64,shipping_address_id int64,latitude float64,company_id int,role string,password_hash blob,sequence uint ) ;
	CREATE TABLE user_languages (user_id uint,language_id uint ) ;
COMMIT;`
	expect = strings.TrimSpace(expect)
	if sql.Q != expect {
		t.Errorf("expected %s got %s", expect, sql.Q)
	}
}
<commit_msg>Add tests<commit_after>package ngorm

import (
	"strings"
	"testing"

	_ "github.com/cznic/ql/driver"
	"github.com/gernest/ngorm/fixture"
)

type Foo struct {
	Id    int
	Stuff string
}

func TestDB(t *testing.T) {
	db, err := Open("ql-mem", "test.db")
	if err != nil {
		t.Fatal(err)
	}

	// create table tests
	sql, err := db.CreateTableSQL(&Foo{})
	if err != nil {
		t.Fatal(err)
	}
	expect := `
BEGIN TRANSACTION;
	CREATE TABLE foos (id int,stuff string ) ;
COMMIT;`
	expect = strings.TrimSpace(expect)
	if sql.Q != expect {
		t.Errorf("expected %s got %s", expect, sql.Q)
	}
	_, err = db.CreateTable(&Foo{})
	if err != nil {
		t.Error(err)
	}

	// multiple tables
	sql, err = db.CreateTableSQL(
		&fixture.User{},
	)
	if err != nil {
		t.Fatal(err)
	}
	expect = `
BEGIN TRANSACTION;
	CREATE TABLE users (id int64,age int64,user_num int64,name string,email string,birthday time,created_at time,updated_at time,billing_address_id int64,shipping_address_id int64,latitude float64,company_id int,role string,password_hash blob,sequence uint ) ;
	CREATE TABLE user_languages (user_id uint,language_id uint ) ;
COMMIT;`
	expect = strings.TrimSpace(expect)
	if sql.Q != expect {
		t.Errorf("expected %s got %s", expect, sql.Q)
	}
	_, err = db.CreateTable(&fixture.User{})
	if err != nil {
		t.Error(err)
	}
}
<|endoftext|>


<commit_before>package pty

import (
	"code.google.com/p/go-charset/charset"
	_ "code.google.com/p/go-charset/data"
	"errors"
	"fmt"
	"io"
	"os"
	"syscall"
	"unsafe"
)

type PTY struct {
	Master        *os.File
	MasterEncoded io.WriteCloser
	No            int
	Slave         *os.File
}

// see ioccom.h
const sys_IOCPARM_MASK = 0x1fff

func New() *PTY {
	p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
	if err != nil {
		fmt.Println("open pty", err)
	}

	sname, err := ptsname(p)
	if err != nil {
		fmt.Println("ptsname", err)
	}

	err = grantpt(p)
	if err != nil {
		fmt.Println("grantpt", err)
	}

	err = unlockpt(p)
	if err != nil {
		fmt.Println("unlockpt", err)
	}

	t, err := os.OpenFile(sname, os.O_RDWR, 0)
	if err != nil {
		fmt.Println("open tty", err)
	}

	masterEncoded, err := charset.NewWriter("ISO-8859-1", p)
	if err != nil {
		fmt.Println("charset err", err)
	}

	pty := &PTY{
		Master:        p,
		Slave:         t,
		No:            0,
		MasterEncoded: masterEncoded,
	}

	return pty
}

func (pty *PTY) GetSize() (int, int, error) {
	var ws winsize
	err := windowrect(&ws, pty.Master.Fd())
	return int(ws.ws_row), int(ws.ws_col), err
}

func (pty *PTY) SetSize(x, y uint16) {
	winsize := winsize{ws_col: x, ws_row: y}
	err := windowrect(&winsize, pty.Master.Fd())
	if err != nil {
		fmt.Println("error setting windows size", err)
	}
}

func (pty *PTY) Signal(sig syscall.Signal) {
	// TODO: implement this
}

type winsize struct {
	ws_row    uint16
	ws_col    uint16
	ws_xpixel uint16
	ws_ypixel uint16
}

func windowrect(ws *winsize, fd uintptr) error {
	_, _, errno := syscall.Syscall(
		syscall.SYS_IOCTL,
		fd,
		syscall.TIOCGWINSZ,
		uintptr(unsafe.Pointer(ws)),
	)
	if errno != 0 {
		return syscall.Errno(errno)
	}
	return nil
}

func ptsname(f *os.File) (string, error) {
	var n [(syscall.TIOCPTYGNAME >> 16) & sys_IOCPARM_MASK]byte

	ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n)))
	for i, c := range n {
		if c == 0 {
			return string(n[:i]), nil
		}
	}
	return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
}

func grantpt(f *os.File) error {
	var u int
	return ioctl(f.Fd(), syscall.TIOCPTYGRANT, uintptr(unsafe.Pointer(&u)))
}

func unlockpt(f *os.File) error {
	var u int
	return ioctl(f.Fd(), syscall.TIOCPTYUNLK, uintptr(unsafe.Pointer(&u)))
}

func ioctl(fd, cmd, ptr uintptr) error {
	_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
	if e != 0 {
		return syscall.ENOTTY
	}
	return nil
}
<commit_msg>Little details<commit_after>package pty

import (
	"code.google.com/p/go-charset/charset"
	_ "code.google.com/p/go-charset/data"
	"errors"
	"fmt"
	"io"
	"os"
	"syscall"
	"unsafe"
)

type PTY struct {
	Master        *os.File
	MasterEncoded io.WriteCloser
	No            int
	Slave         *os.File
}

// see ioccom.h
const sys_IOCPARM_MASK = 0x1fff

func New() *PTY {
	p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
	if err != nil {
		fmt.Println("open pty", err)
	}

	sname, err := ptsname(p)
	if err != nil {
		fmt.Println("ptsname", err)
	}

	err = grantpt(p)
	if err != nil {
		fmt.Println("grantpt", err)
	}

	err = unlockpt(p)
	if err != nil {
		fmt.Println("unlockpt", err)
	}

	t, err := os.OpenFile(sname, os.O_RDWR, 0)
	if err != nil {
		fmt.Println("open tty", err)
	}

	masterEncoded, err := charset.NewWriter("ISO-8859-1", p)
	if err != nil {
		fmt.Println("charset err", err)
	}

	pty := &PTY{
		Master:        p,
		Slave:         t,
		No:            0,
		MasterEncoded: masterEncoded,
	}

	return pty
}

func (pty *PTY) GetSize() (int, int, error) {
	var ws winsize
	err := windowrect(&ws, pty.Master.Fd())
	return int(ws.ws_row), int(ws.ws_col), err
}

func (pty *PTY) SetSize(x, y uint16) {
	winsize := winsize{ws_col: x, ws_row: y}
	err := windowrect(&winsize, pty.Master.Fd())
	if err != nil {
		fmt.Println("error setting windows size", err)
	}
}

func (pty *PTY) Signal(sig syscall.Signal) {
	// TODO: implement this
}

type winsize struct {
	ws_row    uint16
	ws_col    uint16
	ws_xpixel uint16
	ws_ypixel uint16
}

func windowrect(ws *winsize, fd uintptr) error {
	_, _, errno := syscall.Syscall(
		syscall.SYS_IOCTL,
		fd,
		syscall.TIOCSWINSZ,
		uintptr(unsafe.Pointer(ws)),
	)
	if errno != 0 {
		return syscall.Errno(errno)
	}
	return nil
}

func ptsname(f *os.File) (string, error) {
	var n [(syscall.TIOCPTYGNAME >> 16) & sys_IOCPARM_MASK]byte

	ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n)))
	for i, c := range n {
		if c == 0 {
			return string(n[:i]), nil
		}
	}
	return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
}

func grantpt(f *os.File) error {
	var u int
	return ioctl(f.Fd(), syscall.TIOCPTYGRANT, uintptr(unsafe.Pointer(&u)))
}

func unlockpt(f *os.File) error {
	var u int
	return ioctl(f.Fd(), syscall.TIOCPTYUNLK, uintptr(unsafe.Pointer(&u)))
}

func ioctl(fd, cmd, ptr uintptr) error {
	_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
	if e != 0 {
		return syscall.ENOTTY
	}
	return nil
}
<|endoftext|>