<commit_before>package main

import (
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

// contact type holds the fields related to a particular contact.
// omitempty tag will make sure the database doesn't contain content like:
//
//   {
//    _id: someId
//    company: ABC
//    Person: Xyz
//    Phone:
//    Skype:
//    Country:
//   }
//Instead, it will store the above data as:
//
//   {
//    _id: someId
//    company: ABC
//    Person: Xyz
//   }
type contact struct {
	Id      bson.ObjectId `bson:"_id"               json:"id"`
	Company string        `bson:"company,omitempty" json:"company,omitempty"`
	Person  string        `bson:"person,omitempty"  json:"person,omitempty"`
	Email   string        `bson:"email,omitempty"   json:"email,omitempty"`
	Phone   string        `bson:"phone,omitempty"   json:"phone,omitempty"`
	SkypeId string        `bson:"skypeid,omitempty" json:"skypeid,omitempty"`
	Country string        `bson:"country,omitempty" json:"country,omitempty"`
}

// NewContact takes the fields of a contact, initializes a struct of contact type and returns
// the pointer to that struct.
// Also, It inserts the contact data into a mongoDB collection, which is passed as the first parameter.
func NewContact(c *mgo.Collection, company, person, email, phone, skypeid, country string) (*contact, error) {
	doc := contact{
		Id:      bson.NewObjectId(),
		Company: company,
		Person:  person,
		Email:   email,
		Phone:   phone,
		SkypeId: skypeid,
		Country: country,
	}
	err := c.Insert(doc)
	if err != nil {
		return &contact{}, err
	}
	return &doc, nil
}
<commit_msg>Add GetContact() function<commit_after>package main

import (
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

// contact type holds the fields related to a particular contact.
// omitempty tag will make sure the database doesn't contain content like:
//
//   {
//    _id: someId
//    company: ABC
//    Person: Xyz
//    Phone:
//    Skype:
//    Country:
//   }
//Instead, it will store the above data as:
//
//   {
//    _id: someId
//    company: ABC
//    Person: Xyz
//   }
type contact struct {
	Id      bson.ObjectId `bson:"_id"               json:"id"`
	Company string        `bson:"company,omitempty" json:"company,omitempty"`
	Person  string        `bson:"person,omitempty"  json:"person,omitempty"`
	Email   string        `bson:"email,omitempty"   json:"email,omitempty"`
	Phone   string        `bson:"phone,omitempty"   json:"phone,omitempty"`
	SkypeId string        `bson:"skypeid,omitempty" json:"skypeid,omitempty"`
	Country string        `bson:"country,omitempty" json:"country,omitempty"`
}

// NewContact takes the fields of a contact, initializes a struct of contact type and returns
// the pointer to that struct.
// Also, It inserts the contact data into a mongoDB collection, which is passed as the first parameter.
func NewContact(c *mgo.Collection, company, person, email, phone, skypeid, country string) (*contact, error) {
	doc := contact{
		Id:      bson.NewObjectId(),
		Company: company,
		Person:  person,
		Email:   email,
		Phone:   phone,
		SkypeId: skypeid,
		Country: country,
	}
	err := c.Insert(doc)
	if err != nil {
		return &contact{}, err
	}
	return &doc, nil
}

// TODO(Hari): Move session logic into a config file and a separate function
func GetContact(i bson.ObjectId) (*contact, error) {
	sess, err := mgo.Dial("localhost")
	if err != nil {
		return &contact{}, err
	}
	defer sess.Close()
	sess.SetMode(mgo.Monotonic, true)
	sess.SetSafe(&mgo.Safe{})
	collection := sess.DB("test").C("newcontact")
	var c contact
	err = collection.FindId(i).One(&c)
	if err != nil {
		return &contact{}, err
	}
	return &c, nil
}
<|endoftext|>


<commit_before>package pongo2

import (
	"errors"
	"fmt"
	"regexp"
)

var reIdentifiers = regexp.MustCompile("^[a-zA-Z0-9_]+$")

type Context map[string]interface{}

func (c *Context) checkForValidIdentifiers() error {
	for k, v := range *c {
		if !reIdentifiers.MatchString(k) {
			return errors.New(fmt.Sprintf("Context-key '%s' (value: '%+v') is not a valid identifier.", k, v))
		}
	}
	return nil
}

// If you're writing a custom tag, your tag's Execute()-function will
// have access to the ExecutionContext. This struct stores anything
// about the current rendering process's Context including
// the Context provided by the user (field Public).
// You can safely use the Private context to provide data to the user's
// template (like a 'forloop'-information). The Shared-context is used
// to share data between tags. All ExecutionContexts share this context.
//
// Please be careful when accessing the Public data.
// PLEASE DO NOT MODIFY THE PUBLIC CONTEXT (read-only).
//
// To create your own execution context within tags, use the
// NewExecutionContext(parent) function.
type ExecutionContext struct {
	template *Template
	Public   Context
	Private  Context
	Shared   Context
}

func NewExecutionContext(parent *ExecutionContext) *ExecutionContext {
	newctx := &ExecutionContext{
		template: parent.template,
		Public:   parent.Public,
		Private:  make(Context),
	}
	newctx.Shared = parent.Shared

	// Copy all existing private items
	for key, value := range parent.Private {
		newctx.Private[key] = value
	}

	return newctx
}

func (ctx *ExecutionContext) Error(msg string, token *Token) error {
	pos := ""
	if token != nil {
		// No tokens available
		// TODO: Add location (from where?)
		pos = fmt.Sprintf(" | Line %d Col %d (%s)",
			token.Line, token.Col, token.String())
	}
	return errors.New(
		fmt.Sprintf("[Execution Error in %s%s] %s",
			ctx.template.name, pos, msg,
		))
}
<commit_msg>Added Context.Update() function to update one Context with another.<commit_after>package pongo2

import (
	"errors"
	"fmt"
	"regexp"
)

var reIdentifiers = regexp.MustCompile("^[a-zA-Z0-9_]+$")

type Context map[string]interface{}

func (c Context) checkForValidIdentifiers() error {
	for k, v := range c {
		if !reIdentifiers.MatchString(k) {
			return errors.New(fmt.Sprintf("Context-key '%s' (value: '%+v') is not a valid identifier.", k, v))
		}
	}
	return nil
}

func (c Context) Update(other Context) Context {
	for k, v := range other {
		c[k] = v
	}
	return c
}

// If you're writing a custom tag, your tag's Execute()-function will
// have access to the ExecutionContext. This struct stores anything
// about the current rendering process's Context including
// the Context provided by the user (field Public).
// You can safely use the Private context to provide data to the user's
// template (like a 'forloop'-information). The Shared-context is used
// to share data between tags. All ExecutionContexts share this context.
//
// Please be careful when accessing the Public data.
// PLEASE DO NOT MODIFY THE PUBLIC CONTEXT (read-only).
//
// To create your own execution context within tags, use the
// NewExecutionContext(parent) function.
type ExecutionContext struct {
	template *Template
	Public   Context
	Private  Context
	Shared   Context
}

func NewExecutionContext(parent *ExecutionContext) *ExecutionContext {
	newctx := &ExecutionContext{
		template: parent.template,
		Public:   parent.Public,
		Private:  make(Context),
	}
	newctx.Shared = parent.Shared

	// Copy all existing private items
	for key, value := range parent.Private {
		newctx.Private[key] = value
	}

	return newctx
}

func (ctx *ExecutionContext) Error(msg string, token *Token) error {
	pos := ""
	if token != nil {
		// No tokens available
		// TODO: Add location (from where?)
		pos = fmt.Sprintf(" | Line %d Col %d (%s)",
			token.Line, token.Col, token.String())
	}
	return errors.New(
		fmt.Sprintf("[Execution Error in %s%s] %s",
			ctx.template.name, pos, msg,
		))
}
<|endoftext|>


<commit_before>package cli

import (
	"context"
	"errors"
	"flag"
	"fmt"
	"strings"
)

// Context is a type that is passed through to
// each Handler action in a cli application. Context
// can be used to retrieve context-specific args and
// parsed command-line options.
type Context struct {
	context.Context
	App           *App
	Command       *Command
	shellComplete bool
	flagSet       *flag.FlagSet
	parentContext *Context
}

// NewContext creates a new context. For use in when invoking an App or Command action.
func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
	c := &Context{App: app, flagSet: set, parentContext: parentCtx}
	if parentCtx != nil {
		c.Context = parentCtx.Context
		c.shellComplete = parentCtx.shellComplete
		if parentCtx.flagSet == nil {
			parentCtx.flagSet = &flag.FlagSet{}
		}
	}

	c.Command = &Command{}

	if c.Context == nil {
		c.Context = context.Background()
	}

	return c
}

// NumFlags returns the number of flags set
func (c *Context) NumFlags() int {
	return c.flagSet.NFlag()
}

// Set sets a context flag to a value.
func (c *Context) Set(name, value string) error {
	return c.flagSet.Set(name, value)
}

// IsSet determines if the flag was actually set
func (c *Context) IsSet(name string) bool {
	if fs := lookupFlagSet(name, c); fs != nil {
		if fs := lookupFlagSet(name, c); fs != nil {
			isSet := false
			fs.Visit(func(f *flag.Flag) {
				if f.Name == name {
					isSet = true
				}
			})
			if isSet {
				return true
			}
		}

		f := lookupFlag(name, c)
		if f == nil {
			return false
		}

		return f.IsSet()
	}

	return false
}

// LocalFlagNames returns a slice of flag names used in this context.
func (c *Context) LocalFlagNames() []string {
	var names []string
	c.flagSet.Visit(makeFlagNameVisitor(&names))
	return names
}

// FlagNames returns a slice of flag names used by the this context and all of
// its parent contexts.
func (c *Context) FlagNames() []string {
	var names []string
	for _, ctx := range c.Lineage() {
		ctx.flagSet.Visit(makeFlagNameVisitor(&names))
	}
	return names
}

// Lineage returns *this* context and all of its ancestor contexts in order from
// child to parent
func (c *Context) Lineage() []*Context {
	var lineage []*Context

	for cur := c; cur != nil; cur = cur.parentContext {
		lineage = append(lineage, cur)
	}

	return lineage
}

// Value returns the value of the flag corresponding to `name`
func (c *Context) Value(name string) interface{} {
	return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
}

// Args returns the command line arguments associated with the context.
func (c *Context) Args() Args {
	ret := args(c.flagSet.Args())
	return &ret
}

// NArg returns the number of the command line arguments.
func (c *Context) NArg() int {
	return c.Args().Len()
}

func lookupFlag(name string, ctx *Context) Flag {
	for _, c := range ctx.Lineage() {
		if c.Command == nil {
			continue
		}

		for _, f := range c.Command.Flags {
			for _, n := range f.Names() {
				if n == name {
					return f
				}
			}
		}
	}

	if ctx.App != nil {
		for _, f := range ctx.App.Flags {
			for _, n := range f.Names() {
				if n == name {
					return f
				}
			}
		}
	}

	return nil
}

func lookupFlagSet(name string, ctx *Context) *flag.FlagSet {
	for _, c := range ctx.Lineage() {
		if f := c.flagSet.Lookup(name); f != nil {
			return c.flagSet
		}
	}

	return nil
}

func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
	switch ff.Value.(type) {
	case Serializer:
		_ = set.Set(name, ff.Value.(Serializer).Serialize())
	default:
		_ = set.Set(name, ff.Value.String())
	}
}

func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
	visited := make(map[string]bool)
	set.Visit(func(f *flag.Flag) {
		visited[f.Name] = true
	})
	for _, f := range flags {
		parts := f.Names()
		if len(parts) == 1 {
			continue
		}
		var ff *flag.Flag
		for _, name := range parts {
			name = strings.Trim(name, " ")
			if visited[name] {
				if ff != nil {
					return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
				}
				ff = set.Lookup(name)
			}
		}
		if ff == nil {
			continue
		}
		for _, name := range parts {
			name = strings.Trim(name, " ")
			if !visited[name] {
				copyFlag(name, ff, set)
			}
		}
	}
	return nil
}

func makeFlagNameVisitor(names *[]string) func(*flag.Flag) {
	return func(f *flag.Flag) {
		nameParts := strings.Split(f.Name, ",")
		name := strings.TrimSpace(nameParts[0])

		for _, part := range nameParts {
			part = strings.TrimSpace(part)
			if len(part) > len(name) {
				name = part
			}
		}

		if name != "" {
			*names = append(*names, name)
		}
	}
}

type requiredFlagsErr interface {
	error
	getMissingFlags() []string
}

type errRequiredFlags struct {
	missingFlags []string
}

func (e *errRequiredFlags) Error() string {
	numberOfMissingFlags := len(e.missingFlags)
	if numberOfMissingFlags == 1 {
		return fmt.Sprintf("Required flag %q not set", e.missingFlags[0])
	}
	joinedMissingFlags := strings.Join(e.missingFlags, ", ")
	return fmt.Sprintf("Required flags %q not set", joinedMissingFlags)
}

func (e *errRequiredFlags) getMissingFlags() []string {
	return e.missingFlags
}

func checkRequiredFlags(flags []Flag, context *Context) requiredFlagsErr {
	var missingFlags []string
	for _, f := range flags {
		if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
			var flagPresent bool
			var flagName string

			for _, key := range f.Names() {
				if len(key) > 1 {
					flagName = key
				}

				if context.IsSet(strings.TrimSpace(key)) {
					flagPresent = true
				}
			}

			if !flagPresent && flagName != "" {
				missingFlags = append(missingFlags, flagName)
			}
		}
	}

	if len(missingFlags) != 0 {
		return &errRequiredFlags{missingFlags: missingFlags}
	}

	return nil
}
<commit_msg>add file with incorrec formatting to verify test<commit_after>package cli

import (
	"context"
	"errors"
	"flag"
	"fmt"
	"strings"
)

// Context is a type that is passed through to
// each Handler action in a cli application. Context
// can be used to retrieve context-specific args and
// parsed command-line options.
type Context struct {
	context.Context
	App           *App
	Command       *Command
	shellComplete bool
	flagSet       *flag.FlagSet
	parentContext *Context
}

// NewContext creates a new context. For use in when invoking an App or Command action.
func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
	c := &Context{App: app, flagSet: set, parentContext: parentCtx}
	if parentCtx != nil {
		c.Context = parentCtx.Context
		c.shellComplete = parentCtx.shellComplete
		if parentCtx.flagSet == nil {
			parentCtx.flagSet = &flag.FlagSet{}
		}
	}

	c.Command = &Command{}

	if c.Context == nil {
		c.Context = context.Background()
	}

	return c
}

// NumFlags returns the number of flags set
func (c *Context) NumFlags() int {
			return c.flagSet.NFlag()
}

// Set sets a context flag to a value.
func (c *Context) Set(name, value string) error {
	return c.flagSet.Set(name, value)
}

// IsSet determines if the flag was actually set
func (c *Context) IsSet(name string) bool {
	if fs := lookupFlagSet(name, c); fs != nil {
		if fs := lookupFlagSet(name, c); fs != nil {
			isSet := false
			fs.Visit(func(f *flag.Flag) {
				if f.Name == name {
					isSet = true
				}
			})
			if isSet {
				return true
			}
		}

		f := lookupFlag(name, c)
		if f == nil {
			return false
		}

		return f.IsSet()
	}

	return false
}

// LocalFlagNames returns a slice of flag names used in this context.
func (c *Context) LocalFlagNames() []string {
	var names []string
	c.flagSet.Visit(makeFlagNameVisitor(&names))
	return names
}

// FlagNames returns a slice of flag names used by the this context and all of
// its parent contexts.
func (c *Context) FlagNames() []string {
	var names []string
	for _, ctx := range c.Lineage() {
		ctx.flagSet.Visit(makeFlagNameVisitor(&names))
	}
	return names
}

// Lineage returns *this* context and all of its ancestor contexts in order from
// child to parent
func (c *Context) Lineage() []*Context {
	var lineage []*Context

	for cur := c; cur != nil; cur = cur.parentContext {
		lineage = append(lineage, cur)
	}

	return lineage
}

// Value returns the value of the flag corresponding to `name`
func (c *Context) Value(name string) interface{} {
	return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
}

// Args returns the command line arguments associated with the context.
func (c *Context) Args() Args {
	ret := args(c.flagSet.Args())
	return &ret
}

// NArg returns the number of the command line arguments.
func (c *Context) NArg() int {
	return c.Args().Len()
}

func lookupFlag(name string, ctx *Context) Flag {
	for _, c := range ctx.Lineage() {
		if c.Command == nil {
			continue
		}

		for _, f := range c.Command.Flags {
			for _, n := range f.Names() {
				if n == name {
					return f
				}
			}
		}
	}

	if ctx.App != nil {
		for _, f := range ctx.App.Flags {
			for _, n := range f.Names() {
				if n == name {
					return f
				}
			}
		}
	}

	return nil
}

func lookupFlagSet(name string, ctx *Context) *flag.FlagSet {
	for _, c := range ctx.Lineage() {
		if f := c.flagSet.Lookup(name); f != nil {
			return c.flagSet
		}
	}

	return nil
}

func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
	switch ff.Value.(type) {
	case Serializer:
		_ = set.Set(name, ff.Value.(Serializer).Serialize())
	default:
		_ = set.Set(name, ff.Value.String())
	}
}

func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
	visited := make(map[string]bool)
	set.Visit(func(f *flag.Flag) {
		visited[f.Name] = true
	})
	for _, f := range flags {
		parts := f.Names()
		if len(parts) == 1 {
			continue
		}
		var ff *flag.Flag
		for _, name := range parts {
			name = strings.Trim(name, " ")
			if visited[name] {
				if ff != nil {
					return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
				}
				ff = set.Lookup(name)
			}
		}
		if ff == nil {
			continue
		}
		for _, name := range parts {
			name = strings.Trim(name, " ")
			if !visited[name] {
				copyFlag(name, ff, set)
			}
		}
	}
	return nil
}

func makeFlagNameVisitor(names *[]string) func(*flag.Flag) {
	return func(f *flag.Flag) {
		nameParts := strings.Split(f.Name, ",")
		name := strings.TrimSpace(nameParts[0])

		for _, part := range nameParts {
			part = strings.TrimSpace(part)
			if len(part) > len(name) {
				name = part
			}
		}

		if name != "" {
			*names = append(*names, name)
		}
	}
}

type requiredFlagsErr interface {
	error
	getMissingFlags() []string
}

type errRequiredFlags struct {
	missingFlags []string
}

func (e *errRequiredFlags) Error() string {
	numberOfMissingFlags := len(e.missingFlags)
	if numberOfMissingFlags == 1 {
		return fmt.Sprintf("Required flag %q not set", e.missingFlags[0])
	}
	joinedMissingFlags := strings.Join(e.missingFlags, ", ")
	return fmt.Sprintf("Required flags %q not set", joinedMissingFlags)
}

func (e *errRequiredFlags) getMissingFlags() []string {
	return e.missingFlags
}

func checkRequiredFlags(flags []Flag, context *Context) requiredFlagsErr {
	var missingFlags []string
	for _, f := range flags {
		if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
			var flagPresent bool
			var flagName string

			for _, key := range f.Names() {
				if len(key) > 1 {
					flagName = key
				}

				if context.IsSet(strings.TrimSpace(key)) {
					flagPresent = true
				}
			}

			if !flagPresent && flagName != "" {
				missingFlags = append(missingFlags, flagName)
			}
		}
	}

	if len(missingFlags) != 0 {
		return &errRequiredFlags{missingFlags: missingFlags}
	}

	return nil
}
<|endoftext|>


<commit_before>package napnap

import (
	"encoding/json"
	"errors"
	"net"
	"net/http"
	"net/url"
	"strings"
)

// Param is a single URL parameter, consisting of a key and a value.
type Param struct {
	Key   string
	Value string
}

type store map[string]interface{}

type Context struct {
	NapNap  *NapNap
	Request *http.Request
	Writer  http.ResponseWriter
	query   url.Values
	params  []Param
	store   store
}

// NewContext returns a new context instance
func NewContext(napnap *NapNap, req *http.Request, writer http.ResponseWriter) *Context {
	return &Context{
		NapNap:  napnap,
		Request: req,
		Writer:  writer,
	}
}

// Render returns html format
func (c *Context) Render(code int, viewName string, data interface{}) (err error) {
	c.Writer.WriteHeader(code)
	c.NapNap.template.ExecuteTemplate(c.Writer, viewName, data)
	return
}

// String returns string format
func (c *Context) String(code int, s string) (err error) {
	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
	c.Writer.WriteHeader(code)
	c.Writer.Write([]byte(s))
	return
}

// JSON returns json format
func (c *Context) JSON(code int, i interface{}) (err error) {
	b, err := json.Marshal(i)
	if err != nil {
		return err
	}
	c.Writer.Header().Set("Content-Type", "application/json")
	c.Writer.WriteHeader(code)
	c.Writer.Write(b)
	return
}

// BindJSON binds the request body into provided type `obj`. The default binder does
// it based on Content-Type header.
func (c *Context) BindJSON(obj interface{}) (err error) {
	req := c.Request
	contentType := req.Header.Get("Content-Type")

	if contentType == "application/json" {
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(obj)
		if err != nil {
			return err
		}
	} else {
		return errors.New("content type doesn't match application/json")
	}

	return
}

// Query returns query parameter by key.
func (c *Context) Query(key string) string {
	if c.query == nil {
		c.query = c.Request.URL.Query()
	}
	return c.query.Get(key)
}

// Form returns form parameter by key.
func (c *Context) Form(key string) string {
	req := c.Request
	if s := req.PostFormValue(key); len(s) > 0 {
		return s
	}
	if req.MultipartForm != nil {
		if values := req.MultipartForm.Value[key]; len(values) > 0 {
			return values[0]
		}
	}
	return ""
}

// Get retrieves data from the context.
func (c *Context) Get(key string) interface{} {
	return c.store[key]
}

// Set saves data in the context.
func (c *Context) Set(key string, val interface{}) {
	if c.store == nil {
		c.store = make(store)
	}
	c.store[key] = val
}

// Param returns form values by parameter
func (c *Context) Param(name string) string {
	for _, param := range c.params {
		if param.Key == name {
			return param.Value
		}
	}
	return ""
}

// RemoteIpAddress returns the remote ip address, it parses
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
func (c *Context) RemoteIpAddress() string {
	if c.NapNap.ForwardRemoteIpAddress {
		remoteIpAddr := strings.TrimSpace(c.Request.Header.Get("X-Real-Ip"))
		if len(remoteIpAddr) > 0 {
			return remoteIpAddr
		}
		remoteIpAddr = c.Request.Header.Get("X-Forwarded-For")
		if index := strings.IndexByte(remoteIpAddr, ','); index >= 0 {
			remoteIpAddr = remoteIpAddr[0:index]
		}
		remoteIpAddr = strings.TrimSpace(remoteIpAddr)
		if len(remoteIpAddr) > 0 {
			return remoteIpAddr
		}
	}
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr)); err == nil {
		return ip
	}
	return ""
}

// ContentType returns the Content-Type header of the request.
func (c *Context) ContentType() string {
	return filterFlags(c.Request.Header.Get("Content-Type"))
}

// SetCookie allows us to create an cookie
func (c *Context) SetCookie(
	name string,
	value string,
	maxAge int,
	path string,
	domain string,
	secure bool,
	httpOnly bool,
) {
	if path == "" {
		path = "/"
	}
	http.SetCookie(c.Writer, &http.Cookie{
		Name:     name,
		Value:    url.QueryEscape(value),
		MaxAge:   maxAge,
		Path:     path,
		Domain:   domain,
		Secure:   secure,
		HttpOnly: httpOnly,
	})
}

// Cookie returns cookie value
func (c *Context) Cookie(name string) (string, error) {
	cookie, err := c.Request.Cookie(name)
	if err != nil {
		return "", err
	}
	val, _ := url.QueryUnescape(cookie.Value)
	return val, nil
}

// Status is a intelligent shortcut for c.Writer.WriteHeader(code)
func (c *Context) Status(code int) {
	c.Writer.WriteHeader(code)
}

// RespHeader is a intelligent shortcut for c.Writer.Header().Set(key, value)
// It writes a header in the response.
// If value == "", this method removes the header `c.Writer.Header().Del(key)`
func (c *Context) RespHeader(key, value string) {
	if len(value) == 0 {
		c.Writer.Header().Del(key)
	} else {
		c.Writer.Header().Set(key, value)
	}
}

// RequestHeader is a intelligent shortcut for c.Request.Header.Get(key)
func (c *Context) RequestHeader(key string) string {
	return c.Request.Header.Get(key)
}

func (c *Context) reset(req *http.Request, w http.ResponseWriter) {
	c.Request = req
	c.Writer = w
	c.store = nil
	c.query = nil
	c.params = nil
}
<commit_msg>fixed BindJSON bug<commit_after>package napnap

import (
	"encoding/json"
	"net"
	"net/http"
	"net/url"
	"strings"
)

// Param is a single URL parameter, consisting of a key and a value.
type Param struct {
	Key   string
	Value string
}

type store map[string]interface{}

type Context struct {
	NapNap  *NapNap
	Request *http.Request
	Writer  http.ResponseWriter
	query   url.Values
	params  []Param
	store   store
}

// NewContext returns a new context instance
func NewContext(napnap *NapNap, req *http.Request, writer http.ResponseWriter) *Context {
	return &Context{
		NapNap:  napnap,
		Request: req,
		Writer:  writer,
	}
}

// Render returns html format
func (c *Context) Render(code int, viewName string, data interface{}) (err error) {
	c.Writer.WriteHeader(code)
	c.NapNap.template.ExecuteTemplate(c.Writer, viewName, data)
	return
}

// String returns string format
func (c *Context) String(code int, s string) (err error) {
	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
	c.Writer.WriteHeader(code)
	c.Writer.Write([]byte(s))
	return
}

// JSON returns json format
func (c *Context) JSON(code int, i interface{}) (err error) {
	b, err := json.Marshal(i)
	if err != nil {
		return err
	}
	c.Writer.Header().Set("Content-Type", "application/json")
	c.Writer.WriteHeader(code)
	c.Writer.Write(b)
	return
}

// BindJSON binds the request body into provided type `obj`. The default binder does
// it based on Content-Type header.
func (c *Context) BindJSON(obj interface{}) error {
	req := c.Request
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(obj)
	if err != nil {
		return err
	}
	return nil
}

// Query returns query parameter by key.
func (c *Context) Query(key string) string {
	if c.query == nil {
		c.query = c.Request.URL.Query()
	}
	return c.query.Get(key)
}

// Form returns form parameter by key.
func (c *Context) Form(key string) string {
	req := c.Request
	if s := req.PostFormValue(key); len(s) > 0 {
		return s
	}
	if req.MultipartForm != nil {
		if values := req.MultipartForm.Value[key]; len(values) > 0 {
			return values[0]
		}
	}
	return ""
}

// Get retrieves data from the context.
func (c *Context) Get(key string) interface{} {
	return c.store[key]
}

// Set saves data in the context.
func (c *Context) Set(key string, val interface{}) {
	if c.store == nil {
		c.store = make(store)
	}
	c.store[key] = val
}

// Param returns form values by parameter
func (c *Context) Param(name string) string {
	for _, param := range c.params {
		if param.Key == name {
			return param.Value
		}
	}
	return ""
}

// RemoteIpAddress returns the remote ip address, it parses
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
func (c *Context) RemoteIpAddress() string {
	if c.NapNap.ForwardRemoteIpAddress {
		remoteIpAddr := strings.TrimSpace(c.Request.Header.Get("X-Real-Ip"))
		if len(remoteIpAddr) > 0 {
			return remoteIpAddr
		}
		remoteIpAddr = c.Request.Header.Get("X-Forwarded-For")
		if index := strings.IndexByte(remoteIpAddr, ','); index >= 0 {
			remoteIpAddr = remoteIpAddr[0:index]
		}
		remoteIpAddr = strings.TrimSpace(remoteIpAddr)
		if len(remoteIpAddr) > 0 {
			return remoteIpAddr
		}
	}
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr)); err == nil {
		return ip
	}
	return ""
}

// ContentType returns the Content-Type header of the request.
func (c *Context) ContentType() string {
	return filterFlags(c.Request.Header.Get("Content-Type"))
}

// SetCookie allows us to create an cookie
func (c *Context) SetCookie(
	name string,
	value string,
	maxAge int,
	path string,
	domain string,
	secure bool,
	httpOnly bool,
) {
	if path == "" {
		path = "/"
	}
	http.SetCookie(c.Writer, &http.Cookie{
		Name:     name,
		Value:    url.QueryEscape(value),
		MaxAge:   maxAge,
		Path:     path,
		Domain:   domain,
		Secure:   secure,
		HttpOnly: httpOnly,
	})
}

// Cookie returns cookie value
func (c *Context) Cookie(name string) (string, error) {
	cookie, err := c.Request.Cookie(name)
	if err != nil {
		return "", err
	}
	val, _ := url.QueryUnescape(cookie.Value)
	return val, nil
}

// Status is a intelligent shortcut for c.Writer.WriteHeader(code)
func (c *Context) Status(code int) {
	c.Writer.WriteHeader(code)
}

// RespHeader is a intelligent shortcut for c.Writer.Header().Set(key, value)
// It writes a header in the response.
// If value == "", this method removes the header `c.Writer.Header().Del(key)`
func (c *Context) RespHeader(key, value string) {
	if len(value) == 0 {
		c.Writer.Header().Del(key)
	} else {
		c.Writer.Header().Set(key, value)
	}
}

// RequestHeader is a intelligent shortcut for c.Request.Header.Get(key)
func (c *Context) RequestHeader(key string) string {
	return c.Request.Header.Get(key)
}

func (c *Context) reset(req *http.Request, w http.ResponseWriter) {
	c.Request = req
	c.Writer = w
	c.store = nil
	c.query = nil
	c.params = nil
}
<|endoftext|>


<commit_before>package telebot

import (
	"strings"

	"github.com/pkg/errors"
)

// HandlerFunc represents a handler function, which is
// used to handle actual endpoints.
type HandlerFunc func(Context) error

// Context represents a context of the current event. It stores data
// depending on its type, whether it's a message, callback or whatever.
type Context interface {
	// Message returns stored message if such presented.
	Message() *Message

	// Callback returns stored callback if such presented.
	Callback() *Callback

	// Query returns stored query if such presented.
	Query() *Query

	// ChosenInlineResult returns stored inline result if such presented.
	ChosenInlineResult() *ChosenInlineResult

	// ShippingQuery returns stored shipping query if such presented.
	ShippingQuery() *ShippingQuery

	// PreCheckoutQuery returns stored pre checkout query if such presented.
	PreCheckoutQuery() *PreCheckoutQuery

	// Poll returns stored poll if such presented.
	Poll() *Poll

	// PollAnswer returns stored poll answer if such presented.
	PollAnswer() *PollAnswer

	// Migration returns both migration from and to chat IDs.
	Migration() (int64, int64)

	// Sender returns the current recipient, depending on the context type.
	// Returns nil if user is not presented.
	Sender() *User

	// Chat returns the current chat, depending on the context type.
	// Returns nil if chat is not presented.
	Chat() *Chat

	// Recipient combines both Sender and Chat functions. If there is no user
	// the chat will be returned. The native context cannot be without sender,
	// but it is useful in the case when the context created intentionally
	// by the NewContext constructor and have only Chat field inside.
	Recipient() Recipient

	// Text returns the message text, depending on the context type.
	// In the case when no related data presented, returns an empty string.
	Text() string

	// Data returns the current data, depending on the context type.
	// If the context contains payment, returns its payload.
	// In the case when no related data presented, returns an empty string.
	Data() string

	// Args returns a raw slice of command or callback arguments as strings.
	// The message arguments split by space, while the callback's ones by a "|" symbol.
	Args() []string

	// Send sends a message to the current recipient.
	// See Send from bot.go.
	Send(what interface{}, opts ...interface{}) error

	// SendAlbum sends an album to the current recipient.
	// See SendAlbum from bot.go.
	SendAlbum(a Album, opts ...interface{}) error

	// Reply replies to the current message.
	// See Reply from bot.go.
	Reply(what interface{}, opts ...interface{}) error

	// Forward forwards the given message to the current recipient.
	// See Forward from bot.go.
	Forward(msg Editable, opts ...interface{}) error

	// ForwardTo forwards the current message to the given recipient.
	// See Forward from bot.go
	ForwardTo(to Recipient, opts ...interface{}) error

	// Edit edits the current message.
	// See Edit from bot.go.
	Edit(what interface{}, opts ...interface{}) error

	// EditCaption edits the caption of the current message.
	// See EditCaption from bot.go.
	EditCaption(caption string, opts ...interface{}) error

	// Delete removes the current message.
	// See Delete from bot.go.
	Delete() error

	// Notify updates the chat action for the current recipient.
	// See Notify from bot.go.
	Notify(action ChatAction) error

	// Ship replies to the current shipping query.
	// See Ship from bot.go.
	Ship(what ...interface{}) error

	// Accept finalizes the current deal.
	// See Accept from bot.go.
	Accept(errorMessage ...string) error

	// Answer sends a response to the current inline query.
	// See Answer from bot.go.
	Answer(resp *QueryResponse) error

	// Respond sends a response for the current callback query.
	// See Respond from bot.go.
	Respond(resp ...*CallbackResponse) error
}

// nativeContext is a native implementation of the Context interface.
// "context" is taken by context package, maybe there is a better name.
type nativeContext struct {
	b *Bot

	message            *Message
	callback           *Callback
	query              *Query
	chosenInlineResult *ChosenInlineResult
	shippingQuery      *ShippingQuery
	preCheckoutQuery   *PreCheckoutQuery
	poll               *Poll
	pollAnswer         *PollAnswer
}

func (c *nativeContext) Message() *Message {
	switch {
	case c.message != nil:
		return c.message
	case c.callback != nil:
		return c.callback.Message
	default:
		return nil
	}
}

func (c *nativeContext) Callback() *Callback {
	return c.callback
}

func (c *nativeContext) Query() *Query {
	return c.query
}

func (c *nativeContext) ChosenInlineResult() *ChosenInlineResult {
	return c.chosenInlineResult
}

func (c *nativeContext) ShippingQuery() *ShippingQuery {
	return c.shippingQuery
}

func (c *nativeContext) PreCheckoutQuery() *PreCheckoutQuery {
	return c.preCheckoutQuery
}

func (c *nativeContext) Poll() *Poll {
	return c.poll
}

func (c *nativeContext) PollAnswer() *PollAnswer {
	return c.pollAnswer
}

func (c *nativeContext) Migration() (int64, int64) {
	return c.message.MigrateFrom, c.message.MigrateTo
}

func (c *nativeContext) Sender() *User {
	switch {
	case c.message != nil:
		return c.message.Sender
	case c.callback != nil:
		return c.callback.Sender
	case c.query != nil:
		return c.query.Sender
	case c.chosenInlineResult != nil:
		return c.chosenInlineResult.Sender
	case c.shippingQuery != nil:
		return c.shippingQuery.Sender
	case c.preCheckoutQuery != nil:
		return c.preCheckoutQuery.Sender
	case c.pollAnswer != nil:
		return c.pollAnswer.Sender
	default:
		return nil
	}
}

func (c *nativeContext) Chat() *Chat {
	switch {
	case c.message != nil:
		return c.message.Chat
	case c.callback != nil:
		return c.callback.Message.Chat
	default:
		return nil
	}
}

func (c *nativeContext) Recipient() Recipient {
	chat := c.Chat()
	if chat != nil {
		return chat
	}
	return c.Sender()
}

func (c *nativeContext) Text() string {
	switch {
	case c.message != nil:
		return c.message.Text
	case c.callback != nil:
		return c.callback.Message.Text
	default:
		return ""
	}
}

func (c *nativeContext) Data() string {
	switch {
	case c.callback != nil:
		return c.callback.Data
	case c.query != nil:
		return c.query.Text
	case c.chosenInlineResult != nil:
		return c.chosenInlineResult.Query
	case c.shippingQuery != nil:
		return c.shippingQuery.Payload
	case c.preCheckoutQuery != nil:
		return c.preCheckoutQuery.Payload
	default:
		return ""
	}
}

func (c *nativeContext) Args() []string {
	if c.message != nil {
		return strings.Split(c.message.Payload, " ")
	}
	if c.callback != nil {
		return strings.Split(c.callback.Data, "|")
	}
	return nil
}

func (c *nativeContext) Send(what interface{}, opts ...interface{}) error {
	_, err := c.b.Send(c.Recipient(), what, opts...)
	return err
}

func (c *nativeContext) SendAlbum(a Album, opts ...interface{}) error {
	_, err := c.b.SendAlbum(c.Recipient(), a, opts...)
	return err
}

func (c *nativeContext) Reply(what interface{}, opts ...interface{}) error {
	msg := c.Message()
	if msg == nil {
		return ErrBadContext
	}
	_, err := c.b.Reply(msg, what, opts...)
	return err
}

func (c *nativeContext) Forward(msg Editable, opts ...interface{}) error {
	_, err := c.b.Forward(c.Recipient(), msg, opts...)
	return err
}

func (c *nativeContext) ForwardTo(to Recipient, opts ...interface{}) error {
	msg := c.Message()
	if msg == nil {
		return ErrBadContext
	}
	_, err := c.b.Forward(to, msg, opts...)
	return err
}

func (c *nativeContext) Edit(what interface{}, opts ...interface{}) error {
	clb := c.callback
	if clb == nil || clb.Message == nil {
		return ErrBadContext
	}
	_, err := c.b.Edit(clb.Message, what, opts...)
	return err
}

func (c *nativeContext) EditCaption(caption string, opts ...interface{}) error {
	clb := c.callback
	if clb == nil || clb.Message == nil {
		return ErrBadContext
	}
	_, err := c.b.EditCaption(clb.Message, caption, opts...)
	return err
}

func (c *nativeContext) Delete() error {
	msg := c.Message()
	if msg == nil {
		return ErrBadContext
	}
	return c.b.Delete(msg)
}

func (c *nativeContext) Notify(action ChatAction) error {
	return c.b.Notify(c.Recipient(), action)
}

func (c *nativeContext) Ship(what ...interface{}) error {
	if c.shippingQuery == nil {
		return errors.New("telebot: context shipping query is nil")
	}
	return c.b.Ship(c.shippingQuery, what...)
}

func (c *nativeContext) Accept(errorMessage ...string) error {
	if c.preCheckoutQuery == nil {
		return errors.New("telebot: context pre checkout query is nil")
	}
	return c.b.Accept(c.preCheckoutQuery, errorMessage...)
}

func (c *nativeContext) Answer(resp *QueryResponse) error {
	if c.query == nil {
		return errors.New("telebot: context inline query is nil")
	}
	return c.b.Answer(c.query, resp)
}

func (c *nativeContext) Respond(resp ...*CallbackResponse) error {
	if c.callback == nil {
		return errors.New("telebot: context callback is nil")
	}
	return c.b.Respond(c.callback, resp...)
}
<commit_msg>context: return command payload on Data<commit_after>package telebot

import (
	"strings"

	"github.com/pkg/errors"
)

// HandlerFunc represents a handler function, which is
// used to handle actual endpoints.
type HandlerFunc func(Context) error

// Context represents a context of the current event. It stores data
// depending on its type, whether it's a message, callback or whatever.
type Context interface {
	// Message returns stored message if such presented.
	Message() *Message

	// Callback returns stored callback if such presented.
	Callback() *Callback

	// Query returns stored query if such presented.
	Query() *Query

	// ChosenInlineResult returns stored inline result if such presented.
	ChosenInlineResult() *ChosenInlineResult

	// ShippingQuery returns stored shipping query if such presented.
	ShippingQuery() *ShippingQuery

	// PreCheckoutQuery returns stored pre checkout query if such presented.
	PreCheckoutQuery() *PreCheckoutQuery

	// Poll returns stored poll if such presented.
	Poll() *Poll

	// PollAnswer returns stored poll answer if such presented.
	PollAnswer() *PollAnswer

	// Migration returns both migration from and to chat IDs.
	Migration() (int64, int64)

	// Sender returns the current recipient, depending on the context type.
	// Returns nil if user is not presented.
	Sender() *User

	// Chat returns the current chat, depending on the context type.
	// Returns nil if chat is not presented.
	Chat() *Chat

	// Recipient combines both Sender and Chat functions. If there is no user
	// the chat will be returned. The native context cannot be without sender,
	// but it is useful in the case when the context created intentionally
	// by the NewContext constructor and have only Chat field inside.
	Recipient() Recipient

	// Text returns the message text, depending on the context type.
	// In the case when no related data presented, returns an empty string.
	Text() string

	// Data returns the current data, depending on the context type.
	// If the context contains command, returns its arguments string.
	// If the context contains payment, returns its payload.
	// In the case when no related data presented, returns an empty string.
	Data() string

	// Args returns a raw slice of command or callback arguments as strings.
	// The message arguments split by space, while the callback's ones by a "|" symbol.
	Args() []string

	// Send sends a message to the current recipient.
	// See Send from bot.go.
	Send(what interface{}, opts ...interface{}) error

	// SendAlbum sends an album to the current recipient.
	// See SendAlbum from bot.go.
	SendAlbum(a Album, opts ...interface{}) error

	// Reply replies to the current message.
	// See Reply from bot.go.
	Reply(what interface{}, opts ...interface{}) error

	// Forward forwards the given message to the current recipient.
	// See Forward from bot.go.
	Forward(msg Editable, opts ...interface{}) error

	// ForwardTo forwards the current message to the given recipient.
	// See Forward from bot.go
	ForwardTo(to Recipient, opts ...interface{}) error

	// Edit edits the current message.
	// See Edit from bot.go.
	Edit(what interface{}, opts ...interface{}) error

	// EditCaption edits the caption of the current message.
	// See EditCaption from bot.go.
	EditCaption(caption string, opts ...interface{}) error

	// Delete removes the current message.
	// See Delete from bot.go.
	Delete() error

	// Notify updates the chat action for the current recipient.
	// See Notify from bot.go.
	Notify(action ChatAction) error

	// Ship replies to the current shipping query.
	// See Ship from bot.go.
	Ship(what ...interface{}) error

	// Accept finalizes the current deal.
	// See Accept from bot.go.
	Accept(errorMessage ...string) error

	// Answer sends a response to the current inline query.
	// See Answer from bot.go.
	Answer(resp *QueryResponse) error

	// Respond sends a response for the current callback query.
	// See Respond from bot.go.
	Respond(resp ...*CallbackResponse) error
}

// nativeContext is a native implementation of the Context interface.
// "context" is taken by context package, maybe there is a better name.
type nativeContext struct {
	b *Bot

	message            *Message
	callback           *Callback
	query              *Query
	chosenInlineResult *ChosenInlineResult
	shippingQuery      *ShippingQuery
	preCheckoutQuery   *PreCheckoutQuery
	poll               *Poll
	pollAnswer         *PollAnswer
}

func (c *nativeContext) Message() *Message {
	switch {
	case c.message != nil:
		return c.message
	case c.callback != nil:
		return c.callback.Message
	default:
		return nil
	}
}

func (c *nativeContext) Callback() *Callback {
	return c.callback
}

func (c *nativeContext) Query() *Query {
	return c.query
}

func (c *nativeContext) ChosenInlineResult() *ChosenInlineResult {
	return c.chosenInlineResult
}

func (c *nativeContext) ShippingQuery() *ShippingQuery {
	return c.shippingQuery
}

func (c *nativeContext) PreCheckoutQuery() *PreCheckoutQuery {
	return c.preCheckoutQuery
}

func (c *nativeContext) Poll() *Poll {
	return c.poll
}

func (c *nativeContext) PollAnswer() *PollAnswer {
	return c.pollAnswer
}

func (c *nativeContext) Migration() (int64, int64) {
	return c.message.MigrateFrom, c.message.MigrateTo
}

func (c *nativeContext) Sender() *User {
	switch {
	case c.message != nil:
		return c.message.Sender
	case c.callback != nil:
		return c.callback.Sender
	case c.query != nil:
		return c.query.Sender
	case c.chosenInlineResult != nil:
		return c.chosenInlineResult.Sender
	case c.shippingQuery != nil:
		return c.shippingQuery.Sender
	case c.preCheckoutQuery != nil:
		return c.preCheckoutQuery.Sender
	case c.pollAnswer != nil:
		return c.pollAnswer.Sender
	default:
		return nil
	}
}

func (c *nativeContext) Chat() *Chat {
	switch {
	case c.message != nil:
		return c.message.Chat
	case c.callback != nil:
		return c.callback.Message.Chat
	default:
		return nil
	}
}

func (c *nativeContext) Recipient() Recipient {
	chat := c.Chat()
	if chat != nil {
		return chat
	}
	return c.Sender()
}

func (c *nativeContext) Text() string {
	switch {
	case c.message != nil:
		return c.message.Text
	case c.callback != nil:
		return c.callback.Message.Text
	default:
		return ""
	}
}

func (c *nativeContext) Data() string {
	switch {
	case c.message != nil:
		return c.message.Payload
	case c.callback != nil:
		return c.callback.Data
	case c.query != nil:
		return c.query.Text
	case c.chosenInlineResult != nil:
		return c.chosenInlineResult.Query
	case c.shippingQuery != nil:
		return c.shippingQuery.Payload
	case c.preCheckoutQuery != nil:
		return c.preCheckoutQuery.Payload
	default:
		return ""
	}
}

func (c *nativeContext) Args() []string {
	if c.message != nil {
		return strings.Split(c.message.Payload, " ")
	}
	if c.callback != nil {
		return strings.Split(c.callback.Data, "|")
	}
	return nil
}

func (c *nativeContext) Send(what interface{}, opts ...interface{}) error {
	_, err := c.b.Send(c.Recipient(), what, opts...)
	return err
}

func (c *nativeContext) SendAlbum(a Album, opts ...interface{}) error {
	_, err := c.b.SendAlbum(c.Recipient(), a, opts...)
	return err
}

func (c *nativeContext) Reply(what interface{}, opts ...interface{}) error {
	msg := c.Message()
	if msg == nil {
		return ErrBadContext
	}
	_, err := c.b.Reply(msg, what, opts...)
	return err
}

func (c *nativeContext) Forward(msg Editable, opts ...interface{}) error {
	_, err := c.b.Forward(c.Recipient(), msg, opts...)
	return err
}

func (c *nativeContext) ForwardTo(to Recipient, opts ...interface{}) error {
	msg := c.Message()
	if msg == nil {
		return ErrBadContext
	}
	_, err := c.b.Forward(to, msg, opts...)
	return err
}

func (c *nativeContext) Edit(what interface{}, opts ...interface{}) error {
	clb := c.callback
	if clb == nil || clb.Message == nil {
		return ErrBadContext
	}
	_, err := c.b.Edit(clb.Message, what, opts...)
	return err
}

func (c *nativeContext) EditCaption(caption string, opts ...interface{}) error {
	clb := c.callback
	if clb == nil || clb.Message == nil {
		return ErrBadContext
	}
	_, err := c.b.EditCaption(clb.Message, caption, opts...)
	return err
}

func (c *nativeContext) Delete() error {
	msg := c.Message()
	if msg == nil {
		return ErrBadContext
	}
	return c.b.Delete(msg)
}

func (c *nativeContext) Notify(action ChatAction) error {
	return c.b.Notify(c.Recipient(), action)
}

func (c *nativeContext) Ship(what ...interface{}) error {
	if c.shippingQuery == nil {
		return errors.New("telebot: context shipping query is nil")
	}
	return c.b.Ship(c.shippingQuery, what...)
}

func (c *nativeContext) Accept(errorMessage ...string) error {
	if c.preCheckoutQuery == nil {
		return errors.New("telebot: context pre checkout query is nil")
	}
	return c.b.Accept(c.preCheckoutQuery, errorMessage...)
}

func (c *nativeContext) Answer(resp *QueryResponse) error {
	if c.query == nil {
		return errors.New("telebot: context inline query is nil")
	}
	return c.b.Answer(c.query, resp)
}

func (c *nativeContext) Respond(resp ...*CallbackResponse) error {
	if c.callback == nil {
		return errors.New("telebot: context callback is nil")
	}
	return c.b.Respond(c.callback, resp...)
}
<|endoftext|>


<commit_before>package rest

import (
	"encoding/json"
	"net/http"
	"net/url"
)

func NewContext() *Context {
	c := new(Context)
	c.params = url.Values{}
	return c
}

type Context struct {
	req                   *http.Request
	params                url.Values
	user                  User
	runParseMultipartForm bool
	AutoSetUser           func()
}

func (self *Context) User() User {
	if self.user.Id == "" {
		self.AutoSetUser()
	}

	return self.user
}

func (self *Context) SetUser(user User) {
	self.user = user
}

func (self *Context) SetReq(req *http.Request) {
	self.req = req
}

func (self *Context) Req() *http.Request {
	return self.req
}

func (self *Context) JsonDecode(out interface{}) error {
	defer self.req.Body.Close()
	return json.NewDecoder(self.req.Body).Decode(out)
}

func (self *Context) initParams() {
	if self.runParseMultipartForm {
		return
	}

	// 32m
	self.req.ParseMultipartForm(32 << 20)
	self.params = self.req.Form
	self.runParseMultipartForm = true
}

func (self *Context) Params() url.Values {
	self.initParams()
	return self.params
}
<commit_msg>allow the replace the default "Decode" method by client side<commit_after>package rest

import (
	"encoding/json"
	"net/http"
	"net/url"
)

func NewContext() *Context {
	c := new(Context)
	c.params = url.Values{}

	// Default "Decode" method
	c.Decode = func(out interface{}) error {
		defer c.req.Body.Close()
		return json.NewDecoder(c.req.Body).Decode(out)
	}

	return c
}

type Context struct {
	req                   *http.Request
	params                url.Values
	user                  User
	runParseMultipartForm bool
	AutoSetUser           func()
	Decode                func(out interface{}) error
}

func (self *Context) User() User {
	if self.user.Id == "" {
		self.AutoSetUser()
	}

	return self.user
}

func (self *Context) SetUser(user User) {
	self.user = user
}

func (self *Context) SetReq(req *http.Request) {
	self.req = req
}

func (self *Context) Req() *http.Request {
	return self.req
}

func (self *Context) initParams() {
	if self.runParseMultipartForm {
		return
	}

	// 32m
	self.req.ParseMultipartForm(32 << 20)
	self.params = self.req.Form
	self.runParseMultipartForm = true
}

func (self *Context) Params() url.Values {
	self.initParams()
	return self.params
}
<|endoftext|>


<commit_before>package napnap

import (
	"encoding/json"
	"errors"
	"net"
	"net/http"
	"net/url"
	"strings"
)

type (
	// Param is a single URL parameter, consisting of a key and a value.
	Param struct {
		Key   string
		Value string
	}

	Context struct {
		NapNap  *NapNap
		Request *http.Request
		Writer  http.ResponseWriter
		query   url.Values
		params  []Param
		store   store
	}
	store map[string]interface{}
)

// NewContext returns a new context instance
func NewContext(napnap *NapNap, req *http.Request, writer http.ResponseWriter) *Context {
	return &Context{
		NapNap:  napnap,
		Request: req,
		Writer:  writer,
	}
}

// Render returns html format
func (c *Context) Render(code int, viewName string, data interface{}) (err error) {
	c.Writer.WriteHeader(code)
	c.NapNap.template.ExecuteTemplate(c.Writer, viewName, data)
	return
}

// String returns string format
func (c *Context) String(code int, s string) (err error) {
	c.Writer.WriteHeader(code)
	c.Writer.Write([]byte(s))
	return
}

// JSON returns json format
func (c *Context) JSON(code int, i interface{}) (err error) {
	b, err := json.Marshal(i)
	if err != nil {
		return err
	}
	c.Writer.Header().Set("Content-Type", "application/json")
	c.Writer.WriteHeader(code)
	c.Writer.Write(b)
	return
}

// BindJSON binds the request body into provided type `obj`. The default binder does
// it based on Content-Type header.
func (c *Context) BindJSON(obj interface{}) (err error) {
	req := c.Request
	contentType := req.Header.Get("Content-Type")

	if contentType == "application/json" {
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(obj)
		if err != nil {
			return err
		}
	} else {
		return errors.New("content type doesn't match application/json")
	}

	return
}

// Query returns query parameter by key.
func (c *Context) Query(key string) string {
	if c.query == nil {
		c.query = c.Request.URL.Query()
	}
	return c.query.Get(key)
}

// Form returns form parameter by key.
func (c *Context) Form(key string) string {
	req := c.Request
	if s := req.PostFormValue(key); len(s) > 0 {
		return s
	}
	if req.MultipartForm != nil {
		if values := req.MultipartForm.Value[key]; len(values) > 0 {
			return values[0]
		}
	}
	return ""
}

// Get retrieves data from the context.
func (c *Context) Get(key string) interface{} {
	return c.store[key]
}

// Set saves data in the context.
func (c *Context) Set(key string, val interface{}) {
	if c.store == nil {
		c.store = make(store)
	}
	c.store[key] = val
}

// Param returns form values by parameter
func (c *Context) Param(name string) string {
	for _, param := range c.params {
		if param.Key == name {
			return param.Value
		}
	}
	return ""
}

// RemoteIpAddress returns the remote ip address, it parses
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
func (c *Context) RemoteIpAddress() string {
	if c.NapNap.ForwardRemoteIpAddress {
		remoteIpAddr := strings.TrimSpace(c.Request.Header.Get("X-Real-Ip"))
		if len(remoteIpAddr) > 0 {
			return remoteIpAddr
		}
		remoteIpAddr = c.Request.Header.Get("X-Forwarded-For")
		if index := strings.IndexByte(remoteIpAddr, ','); index >= 0 {
			remoteIpAddr = remoteIpAddr[0:index]
		}
		remoteIpAddr = strings.TrimSpace(remoteIpAddr)
		if len(remoteIpAddr) > 0 {
			return remoteIpAddr
		}
	}
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr)); err == nil {
		return ip
	}
	return ""
}

// ContentType returns the Content-Type header of the request.
func (c *Context) ContentType() string {
	return filterFlags(c.Request.Header.Get("Content-Type"))
}

// SetCookie allows us to create an cookie
func (c *Context) SetCookie(
	name string,
	value string,
	maxAge int,
	path string,
	domain string,
	secure bool,
	httpOnly bool,
) {
	if path == "" {
		path = "/"
	}
	http.SetCookie(c.Writer, &http.Cookie{
		Name:     name,
		Value:    url.QueryEscape(value),
		MaxAge:   maxAge,
		Path:     path,
		Domain:   domain,
		Secure:   secure,
		HttpOnly: httpOnly,
	})
}

// Cookie returns cookie value
func (c *Context) Cookie(name string) (string, error) {
	cookie, err := c.Request.Cookie(name)
	if err != nil {
		return "", err
	}
	val, _ := url.QueryUnescape(cookie.Value)
	return val, nil
}

func (c *Context) reset(req *http.Request, w http.ResponseWriter) {
	c.Request = req
	c.Writer = w
	c.store = nil
	c.query = nil
	c.params = nil
}
<commit_msg>added content type to "text/plain; charset=utf-8" for string function<commit_after>package napnap

import (
	"encoding/json"
	"errors"
	"net"
	"net/http"
	"net/url"
	"strings"
)

type (
	// Param is a single URL parameter, consisting of a key and a value.
	Param struct {
		Key   string
		Value string
	}

	Context struct {
		NapNap  *NapNap
		Request *http.Request
		Writer  http.ResponseWriter
		query   url.Values
		params  []Param
		store   store
	}
	store map[string]interface{}
)

// NewContext returns a new context instance
func NewContext(napnap *NapNap, req *http.Request, writer http.ResponseWriter) *Context {
	return &Context{
		NapNap:  napnap,
		Request: req,
		Writer:  writer,
	}
}

// Render returns html format
func (c *Context) Render(code int, viewName string, data interface{}) (err error) {
	c.Writer.WriteHeader(code)
	c.NapNap.template.ExecuteTemplate(c.Writer, viewName, data)
	return
}

// String returns string format
func (c *Context) String(code int, s string) (err error) {
	c.Writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
	c.Writer.WriteHeader(code)
	c.Writer.Write([]byte(s))
	return
}

// JSON returns json format
func (c *Context) JSON(code int, i interface{}) (err error) {
	b, err := json.Marshal(i)
	if err != nil {
		return err
	}
	c.Writer.Header().Set("Content-Type", "application/json")
	c.Writer.WriteHeader(code)
	c.Writer.Write(b)
	return
}

// BindJSON binds the request body into provided type `obj`. The default binder does
// it based on Content-Type header.
func (c *Context) BindJSON(obj interface{}) (err error) {
	req := c.Request
	contentType := req.Header.Get("Content-Type")

	if contentType == "application/json" {
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(obj)
		if err != nil {
			return err
		}
	} else {
		return errors.New("content type doesn't match application/json")
	}

	return
}

// Query returns query parameter by key.
func (c *Context) Query(key string) string {
	if c.query == nil {
		c.query = c.Request.URL.Query()
	}
	return c.query.Get(key)
}

// Form returns form parameter by key.
func (c *Context) Form(key string) string {
	req := c.Request
	if s := req.PostFormValue(key); len(s) > 0 {
		return s
	}
	if req.MultipartForm != nil {
		if values := req.MultipartForm.Value[key]; len(values) > 0 {
			return values[0]
		}
	}
	return ""
}

// Get retrieves data from the context.
func (c *Context) Get(key string) interface{} {
	return c.store[key]
}

// Set saves data in the context.
func (c *Context) Set(key string, val interface{}) {
	if c.store == nil {
		c.store = make(store)
	}
	c.store[key] = val
}

// Param returns form values by parameter
func (c *Context) Param(name string) string {
	for _, param := range c.params {
		if param.Key == name {
			return param.Value
		}
	}
	return ""
}

// RemoteIpAddress returns the remote ip address, it parses
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
func (c *Context) RemoteIpAddress() string {
	if c.NapNap.ForwardRemoteIpAddress {
		remoteIpAddr := strings.TrimSpace(c.Request.Header.Get("X-Real-Ip"))
		if len(remoteIpAddr) > 0 {
			return remoteIpAddr
		}
		remoteIpAddr = c.Request.Header.Get("X-Forwarded-For")
		if index := strings.IndexByte(remoteIpAddr, ','); index >= 0 {
			remoteIpAddr = remoteIpAddr[0:index]
		}
		remoteIpAddr = strings.TrimSpace(remoteIpAddr)
		if len(remoteIpAddr) > 0 {
			return remoteIpAddr
		}
	}
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr)); err == nil {
		return ip
	}
	return ""
}

// ContentType returns the Content-Type header of the request.
func (c *Context) ContentType() string {
	return filterFlags(c.Request.Header.Get("Content-Type"))
}

// SetCookie allows us to create an cookie
func (c *Context) SetCookie(
	name string,
	value string,
	maxAge int,
	path string,
	domain string,
	secure bool,
	httpOnly bool,
) {
	if path == "" {
		path = "/"
	}
	http.SetCookie(c.Writer, &http.Cookie{
		Name:     name,
		Value:    url.QueryEscape(value),
		MaxAge:   maxAge,
		Path:     path,
		Domain:   domain,
		Secure:   secure,
		HttpOnly: httpOnly,
	})
}

// Cookie returns cookie value
func (c *Context) Cookie(name string) (string, error) {
	cookie, err := c.Request.Cookie(name)
	if err != nil {
		return "", err
	}
	val, _ := url.QueryUnescape(cookie.Value)
	return val, nil
}

func (c *Context) reset(req *http.Request, w http.ResponseWriter) {
	c.Request = req
	c.Writer = w
	c.store = nil
	c.query = nil
	c.params = nil
}
<|endoftext|>


<commit_before>package goldb

import (
	"bytes"
	"github.com/syndtr/goleveldb/leveldb"
	"github.com/syndtr/goleveldb/leveldb/iterator"
	"github.com/syndtr/goleveldb/leveldb/opt"
	"github.com/syndtr/goleveldb/leveldb/util"
)

// Context is context of reading data via get or fetch-methods.
// Context is implemented by Transaction and Storage
type Context struct {
	qCtx         queryContext
	ReadOptions  *opt.ReadOptions
	WriteOptions *opt.WriteOptions
}

type queryContext interface {
	Get(key []byte, ro *opt.ReadOptions) (value []byte, err error)
	NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator
}

// Get returns raw data by key
func (c *Context) Get(key []byte) ([]byte, error) {
	data, err := c.qCtx.Get(key, c.ReadOptions)
	if err != nil && err != leveldb.ErrNotFound {
		return nil, nil
	}
	return data, err
}

// GetNum returns uint64-data by key
func (c *Context) GetInt(key []byte) (num int64, err error) {
	_, err = c.GetVar(key, &num)
	return
}

// GetID returns uint64-data by key
func (c *Context) GetID(key []byte) (id uint64, err error) {
	data, err := c.Get(key)
	if err == nil {
		id, err = DecodeID(data)
	}
	return
}

// GetVar get data by key and unmarshal to to variable;
// Returns true when data by key existed
func (c *Context) GetVar(key []byte, v interface{}) (bool, error) {
	data, err := c.Get(key)
	if err == leveldb.ErrNotFound {
		return false, nil
	}
	if err == nil {
		err = DecodeData(data, v)
	}
	if err != nil {
		return false, err
	}
	return true, nil
}

// Fetch fetches raw-data by query
func (c *Context) Fetch(q *Query, fnRow func(value []byte) error) error {
	return c.execute(q, fnRow)
}

// FetchID fetches uint64-ID by query
func (c *Context) FetchID(q *Query, fnRow func(id uint64) error) error {
	return c.execute(q, func(v []byte) error {
		if id, err := DecodeID(v); err != nil {
			return err
		} else {
			return fnRow(id)
		}
	})
}

// FetchObject fetches object by query
func (c *Context) FetchObject(q *Query, obj interface{}, fnRow func() error) error {
	return c.execute(q, func(data []byte) error {
		if err := DecodeData(data, obj); err != nil {
			return err
		} else {
			return fnRow()
		}
	})
}

// QueryIDs returns slice of row-id by query
func (c *Context) QueryIDs(q *Query) (ids []uint64, err error) {
	err = c.FetchID(q, func(id uint64) error {
		ids = append(ids, id)
		return nil
	})
	return
}

// QueryID returns first row-id by query
func (c *Context) QueryID(q *Query) (id uint64, err error) {
	q.Limit(1)
	ids, err := c.QueryIDs(q)
	if len(ids) > 0 {
		return ids[0], err
	}
	return 0, err
}

//------ private ------
var tail1024 = bytes.Repeat([]byte{255}, 1024)

func (c *Context) execute(q *Query, fnRow func([]byte) error) (err error) {
	q.NumRows = 0
	pfx := q.filter
	pfxLen := len(pfx)
	start := append(pfx, q.offset...)
	nStart := len(start)
	limit := q.limit
	skipFirst := len(q.offset) > 0

	var iter iterator.Iterator
	var iterNext func() bool
	var rowID uint64
	fnRecordFilter := q.recFilter

	if !q.desc { // ask
		iter = c.qCtx.NewIterator(&util.Range{Start: start}, nil)
		iterNext = func() bool { return iter.Next() }

	} else { // desc
		iter = c.qCtx.NewIterator(nil, nil)
		iter.Seek(append(start, tail1024...))
		iterNext = func() bool { return iter.Prev() }
	}

	defer func() {
		iter.Release()
		if err == nil {
			err = iter.Error()
		}
	}()

	for limit > 0 && iterNext() {
		key := iter.Key()
		if !bytes.HasPrefix(key, pfx) {
			break
		}
		if skipFirst { // skip first record if record.key == startOffset
			//if q.strongOffset { // todo: use only strong compare (returns actual offset after each query)
			//	skipFirst = false
			//	if bytes.Equal(key, start) {
			//		continue
			//	}
			//} else {
			if len(key) >= nStart && bytes.Equal(key[:nStart], start) {
				continue
			}
			skipFirst = false
			//}
		}
		val := iter.Value()
		if fnRecordFilter != nil {
			if rowID, err = DecodeID(val); err != nil {
				break
			} else if !fnRecordFilter(rowID) {
				continue
			}
		}
		q.offset = key[pfxLen:]
		limit--
		if fnRow != nil {
			if err = fnRow(val); err != nil {
				break
			}
		}
		q.NumRows++
	}
	return
}
<commit_msg>query num-rows<commit_after>package goldb

import (
	"bytes"

	"github.com/syndtr/goleveldb/leveldb"
	"github.com/syndtr/goleveldb/leveldb/iterator"
	"github.com/syndtr/goleveldb/leveldb/opt"
	"github.com/syndtr/goleveldb/leveldb/util"
)

// Context is context of reading data via get or fetch-methods.
// Context is implemented by Transaction and Storage
type Context struct {
	qCtx         queryContext
	ReadOptions  *opt.ReadOptions
	WriteOptions *opt.WriteOptions
}

type queryContext interface {
	Get(key []byte, ro *opt.ReadOptions) (value []byte, err error)
	NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator
}

// Get returns raw data by key
func (c *Context) Get(key []byte) ([]byte, error) {
	data, err := c.qCtx.Get(key, c.ReadOptions)
	if err != nil && err != leveldb.ErrNotFound {
		return nil, nil
	}
	return data, err
}

// GetNum returns uint64-data by key
func (c *Context) GetInt(key []byte) (num int64, err error) {
	_, err = c.GetVar(key, &num)
	return
}

// GetID returns uint64-data by key
func (c *Context) GetID(key []byte) (id uint64, err error) {
	data, err := c.Get(key)
	if err == nil {
		id, err = DecodeID(data)
	}
	return
}

// GetVar get data by key and unmarshal to to variable;
// Returns true when data by key existed
func (c *Context) GetVar(key []byte, v interface{}) (bool, error) {
	data, err := c.Get(key)
	if err == leveldb.ErrNotFound {
		return false, nil
	}
	if err == nil {
		err = DecodeData(data, v)
	}
	if err != nil {
		return false, err
	}
	return true, nil
}

// GetNumRows fetches data by query and calculates count rows
func (c *Context) GetNumRows(q *Query) (numRows uint64, err error) {
	err = c.execute(q, nil)
	numRows = q.NumRows
	return
}

// Fetch fetches raw-data by query
func (c *Context) Fetch(q *Query, fnRow func(value []byte) error) error {
	return c.execute(q, fnRow)
}

// FetchID fetches uint64-ID by query
func (c *Context) FetchID(q *Query, fnRow func(id uint64) error) error {
	return c.execute(q, func(v []byte) error {
		if id, err := DecodeID(v); err != nil {
			return err
		} else {
			return fnRow(id)
		}
	})
}

// FetchObject fetches object by query
func (c *Context) FetchObject(q *Query, obj interface{}, fnRow func() error) error {
	return c.execute(q, func(data []byte) error {
		if err := DecodeData(data, obj); err != nil {
			return err
		} else {
			return fnRow()
		}
	})
}

// QueryIDs returns slice of row-id by query
func (c *Context) QueryIDs(q *Query) (ids []uint64, err error) {
	err = c.FetchID(q, func(id uint64) error {
		ids = append(ids, id)
		return nil
	})
	return
}

// QueryID returns first row-id by query
func (c *Context) QueryID(q *Query) (id uint64, err error) {
	q.Limit(1)
	ids, err := c.QueryIDs(q)
	if len(ids) > 0 {
		return ids[0], err
	}
	return 0, err
}

//------ private ------
var tail1024 = bytes.Repeat([]byte{255}, 1024)

func (c *Context) execute(q *Query, fnRow func([]byte) error) (err error) {
	q.NumRows = 0
	pfx := q.filter
	pfxLen := len(pfx)
	start := append(pfx, q.offset...)
	nStart := len(start)
	limit := q.limit
	skipFirst := len(q.offset) > 0

	var iter iterator.Iterator
	var iterNext func() bool
	var rowID uint64
	fnRecordFilter := q.recFilter

	if !q.desc { // ask
		iter = c.qCtx.NewIterator(&util.Range{Start: start}, nil)
		iterNext = func() bool { return iter.Next() }

	} else { // desc
		iter = c.qCtx.NewIterator(nil, nil)
		iter.Seek(append(start, tail1024...))
		iterNext = func() bool { return iter.Prev() }
	}

	defer func() {
		iter.Release()
		if err == nil {
			err = iter.Error()
		}
	}()

	for limit > 0 && iterNext() {
		key := iter.Key()
		if !bytes.HasPrefix(key, pfx) {
			break
		}
		if skipFirst { // skip first record if record.key == startOffset
			//if q.strongOffset { // todo: use only strong compare (returns actual offset after each query)
			//	skipFirst = false
			//	if bytes.Equal(key, start) {
			//		continue
			//	}
			//} else {
			if len(key) >= nStart && bytes.Equal(key[:nStart], start) {
				continue
			}
			skipFirst = false
			//}
		}
		val := iter.Value()
		if fnRecordFilter != nil {
			if rowID, err = DecodeID(val); err != nil {
				break
			} else if !fnRecordFilter(rowID) {
				continue
			}
		}
		q.offset = key[pfxLen:]
		limit--
		if fnRow != nil {
			if err = fnRow(val); err != nil {
				break
			}
		}
		q.NumRows++
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"sort"
)

// Participant someone having a role in the tournament
type Participant interface {
	ID() string
}

// ScoreData is a structured Key/Value pair list for scores
type ScoreData struct {
	Key    string
	Value  int
	Player *Player
}

// Player is a Participant that is actively participating in battles.
type Player struct {
	Name           string `json:"name"`
	PreferredColor string `json:"preferred_color"`
	Shots          int    `json:"shots"`
	Sweeps         int    `json:"sweeps"`
	Kills          int    `json:"kills"`
	Self           int    `json:"self"`
	Explosions     int    `json:"explosions"`
	Matches        int    `json:"matches"`
	Match          *Match
}

// NewPlayer returns a new instance of a player
func NewPlayer() Player {
	p := Player{}
	return p
}

func (p *Player) String() string {
	return fmt.Sprintf(
		"%s: %dsh %dsw %dk %ds %de",
		p.Name,
		p.Shots,
		p.Sweeps,
		p.Kills,
		p.Self,
		p.Explosions,
	)
}

// Score calculates the score to determine runnerup positions.
func (p *Player) Score() (out int) {
	// This algorithm is probably flawed, but at least it should be able to
	// determine who is the most entertaining.
	// When executed, a sweep is basically 11 points since scoring a sweep
	// also comes with a shot and three kills.

	out += p.Sweeps * 5
	out += p.Shots * 3
	out += p.Kills * 2
	out += p.Self
	out += p.Explosions

	return
}

// ScoreData returns this players set of ScoreData
func (p *Player) ScoreData() []ScoreData {
	sd := []ScoreData{
		ScoreData{Key: "kills", Value: p.Kills, Player: p},
		ScoreData{Key: "shots", Value: p.Shots, Player: p},
		ScoreData{Key: "sweeps", Value: p.Sweeps, Player: p},
		ScoreData{Key: "self", Value: p.Self, Player: p},
		ScoreData{Key: "explosions", Value: p.Explosions, Player: p},
	}
	return sd
}

// URL returns the URL to this player
//
// Used for action URLs
func (p *Player) URL() string {
	out := fmt.Sprintf(
		"%s/%d/",
		p.Match.URL(),
		p.Index(),
	)
	return out
}

// Color returns the color that the player prefers.
func (p *Player) Color() string {
	if p.IsPrefill() {
		return "prefill"
	}
	return p.PreferredColor
}

// Index returns the index in the current match
func (p *Player) Index() int {
	if p.Match != nil {
		for i, o := range p.Match.Players {
			if p.Name == o.Name {
				return i
			}
		}
	}
	return -1
}

// IsPrefill returns whether the player is a prefill placeholder or not
func (p *Player) IsPrefill() bool {
	return p.Name == ""
}

// AddShot increases the shot count
func (p *Player) AddShot() {
	p.Shots++
}

// RemoveShot decreases the shot count
// Fails silently if shots are zero.
func (p *Player) RemoveShot() {
	if p.Shots == 0 {
		return
	}
	p.Shots--
}

// AddSweep increases the sweep count, gives three kills and a shot.
func (p *Player) AddSweep() {
	p.Sweeps++
	p.AddShot()
	p.AddKill()
	p.AddKill()
	p.AddKill()
}

// RemoveSweep decreases the sweep count, three kills and a shot
// Fails silently if sweeps are zero.
func (p *Player) RemoveSweep() {
	if p.Sweeps == 0 {
		return
	}
	p.Sweeps--
	p.RemoveShot()
	p.RemoveKill()
	p.RemoveKill()
	p.RemoveKill()
}

// AddKill increases the kill count
func (p *Player) AddKill(kills ...int) {
	// This is basically only to help out with testing.
	// Adding an optional argument with the amount of kills lets us just use
	// one call to AddKill() rather than 10.
	if len(kills) > 0 {
		p.Kills += kills[0]
	} else {
		p.Kills++
	}
}

// RemoveKill decreases the kill count
// Fails silently if kills are zero.
func (p *Player) RemoveKill() {
	if p.Kills == 0 {
		return
	}
	p.Kills--
}

// AddSelf increases the self count, decreases the kill, and gives a shot
func (p *Player) AddSelf() {
	p.Self++
	p.RemoveKill()
	p.AddShot()
}

// RemoveSelf decreases the self count and a shot
// Fails silently if selfs are zero.
func (p *Player) RemoveSelf() {
	if p.Self == 0 {
		return
	}
	p.Self--
	p.AddKill()
	p.RemoveShot()
}

// AddExplosion increases the explosion count, the kill count and gives a shot
func (p *Player) AddExplosion() {
	p.Explosions++
	p.AddShot()
	p.AddKill()
}

// RemoveExplosion decreases the explosion count, a shot and a kill
// Fails silently if Explosions are zero.
func (p *Player) RemoveExplosion() {
	if p.Explosions == 0 {
		return
	}
	p.Explosions--
	p.RemoveShot()
	p.RemoveKill()
}

// Reset resets the stats on a Player to 0
//
// It is to be run in Match.Start()
func (p *Player) Reset() {
	p.Shots = 0
	p.Sweeps = 0
	p.Kills = 0
	p.Self = 0
	p.Explosions = 0
	p.Matches = 0
}

// Update updates a player with the scores of another
//
// This is primarily used by the tournament score calculator
func (p *Player) Update(other *Player) error {
	p.Shots += other.Shots
	p.Sweeps += other.Sweeps
	p.Kills += other.Kills
	p.Self += other.Self
	p.Explosions += other.Explosions

	// Every call to this method is per match. Count every call
	// as if a match.
	p.Matches++

	return nil
}

// HTML renders the HTML of a player
func (p *Player) HTML() (out string) {
	return
}

// ByScore is a sort.Interface that sorts players by their score
type ByScore []Player

func (s ByScore) Len() int {
	return len(s)

}
func (s ByScore) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByScore) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Score() > s[j].Score()
}

// SortByScore returns a list in order of the score the players have
func SortByScore(ps []Player) []Player {
	sort.Sort(ByScore(ps))
	return ps
}

// ByKills is a sort.Interface that sorts players by their kills
type ByKills []Player

func (s ByKills) Len() int {
	return len(s)

}
func (s ByKills) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByKills) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Kills > s[j].Kills
}

// SortByKills returns a list in order of the kills the players have
func SortByKills(ps []Player) []Player {
	sort.Sort(ByKills(ps))
	return ps
}

// ByRunnerup is a sort.Interface that sorts players by their runnerup status
//
// This is almost exactly the same as score, but the number of matches a player
// has played factors in, and players that have played less matches are sorted
// favorably.
type ByRunnerup []Player

func (s ByRunnerup) Len() int {
	return len(s)

}
func (s ByRunnerup) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByRunnerup) Less(i, j int) bool {
	if s[i].Matches == s[j].Matches {
		// Same as by kills
		return s[i].Kills > s[j].Kills
	}
	// Lower is better - the ones that have not played should be at the top
	return s[i].Matches < s[j].Matches
}

// SortByRunnerup returns a list in order of the kills the players have
func SortByRunnerup(ps []Player) []Player {
	sort.Sort(ByRunnerup(ps))
	return ps
}

// Judge is a Participant that has access to the judge functions
type Judge struct {
}
<commit_msg>Add indication of Match pointer to Player.String()<commit_after>package main

import (
	"fmt"
	"sort"
)

// Participant someone having a role in the tournament
type Participant interface {
	ID() string
}

// ScoreData is a structured Key/Value pair list for scores
type ScoreData struct {
	Key    string
	Value  int
	Player *Player
}

// Player is a Participant that is actively participating in battles.
type Player struct {
	Name           string `json:"name"`
	PreferredColor string `json:"preferred_color"`
	Shots          int    `json:"shots"`
	Sweeps         int    `json:"sweeps"`
	Kills          int    `json:"kills"`
	Self           int    `json:"self"`
	Explosions     int    `json:"explosions"`
	Matches        int    `json:"matches"`
	Match          *Match
}

// NewPlayer returns a new instance of a player
func NewPlayer() Player {
	p := Player{}
	return p
}

func (p *Player) String() string {
	IsPointed := "."
	if p.Match != nil {
		IsPointed = "!"
	}
	return fmt.Sprintf(
		"<%s: %dsh %dsw %dk %ds %de %s>",
		p.Name,
		p.Shots,
		p.Sweeps,
		p.Kills,
		p.Self,
		p.Explosions,
		IsPointed,
	)
}

// Score calculates the score to determine runnerup positions.
func (p *Player) Score() (out int) {
	// This algorithm is probably flawed, but at least it should be able to
	// determine who is the most entertaining.
	// When executed, a sweep is basically 11 points since scoring a sweep
	// also comes with a shot and three kills.

	out += p.Sweeps * 5
	out += p.Shots * 3
	out += p.Kills * 2
	out += p.Self
	out += p.Explosions

	return
}

// ScoreData returns this players set of ScoreData
func (p *Player) ScoreData() []ScoreData {
	sd := []ScoreData{
		ScoreData{Key: "kills", Value: p.Kills, Player: p},
		ScoreData{Key: "shots", Value: p.Shots, Player: p},
		ScoreData{Key: "sweeps", Value: p.Sweeps, Player: p},
		ScoreData{Key: "self", Value: p.Self, Player: p},
		ScoreData{Key: "explosions", Value: p.Explosions, Player: p},
	}
	return sd
}

// URL returns the URL to this player
//
// Used for action URLs
func (p *Player) URL() string {
	out := fmt.Sprintf(
		"%s/%d/",
		p.Match.URL(),
		p.Index(),
	)
	return out
}

// Color returns the color that the player prefers.
func (p *Player) Color() string {
	if p.IsPrefill() {
		return "prefill"
	}
	return p.PreferredColor
}

// Index returns the index in the current match
func (p *Player) Index() int {
	if p.Match != nil {
		for i, o := range p.Match.Players {
			if p.Name == o.Name {
				return i
			}
		}
	}
	return -1
}

// IsPrefill returns whether the player is a prefill placeholder or not
func (p *Player) IsPrefill() bool {
	return p.Name == ""
}

// AddShot increases the shot count
func (p *Player) AddShot() {
	p.Shots++
}

// RemoveShot decreases the shot count
// Fails silently if shots are zero.
func (p *Player) RemoveShot() {
	if p.Shots == 0 {
		return
	}
	p.Shots--
}

// AddSweep increases the sweep count, gives three kills and a shot.
func (p *Player) AddSweep() {
	p.Sweeps++
	p.AddShot()
	p.AddKill()
	p.AddKill()
	p.AddKill()
}

// RemoveSweep decreases the sweep count, three kills and a shot
// Fails silently if sweeps are zero.
func (p *Player) RemoveSweep() {
	if p.Sweeps == 0 {
		return
	}
	p.Sweeps--
	p.RemoveShot()
	p.RemoveKill()
	p.RemoveKill()
	p.RemoveKill()
}

// AddKill increases the kill count
func (p *Player) AddKill(kills ...int) {
	// This is basically only to help out with testing.
	// Adding an optional argument with the amount of kills lets us just use
	// one call to AddKill() rather than 10.
	if len(kills) > 0 {
		p.Kills += kills[0]
	} else {
		p.Kills++
	}
}

// RemoveKill decreases the kill count
// Fails silently if kills are zero.
func (p *Player) RemoveKill() {
	if p.Kills == 0 {
		return
	}
	p.Kills--
}

// AddSelf increases the self count, decreases the kill, and gives a shot
func (p *Player) AddSelf() {
	p.Self++
	p.RemoveKill()
	p.AddShot()
}

// RemoveSelf decreases the self count and a shot
// Fails silently if selfs are zero.
func (p *Player) RemoveSelf() {
	if p.Self == 0 {
		return
	}
	p.Self--
	p.AddKill()
	p.RemoveShot()
}

// AddExplosion increases the explosion count, the kill count and gives a shot
func (p *Player) AddExplosion() {
	p.Explosions++
	p.AddShot()
	p.AddKill()
}

// RemoveExplosion decreases the explosion count, a shot and a kill
// Fails silently if Explosions are zero.
func (p *Player) RemoveExplosion() {
	if p.Explosions == 0 {
		return
	}
	p.Explosions--
	p.RemoveShot()
	p.RemoveKill()
}

// Reset resets the stats on a Player to 0
//
// It is to be run in Match.Start()
func (p *Player) Reset() {
	p.Shots = 0
	p.Sweeps = 0
	p.Kills = 0
	p.Self = 0
	p.Explosions = 0
	p.Matches = 0
}

// Update updates a player with the scores of another
//
// This is primarily used by the tournament score calculator
func (p *Player) Update(other *Player) error {
	p.Shots += other.Shots
	p.Sweeps += other.Sweeps
	p.Kills += other.Kills
	p.Self += other.Self
	p.Explosions += other.Explosions

	// Every call to this method is per match. Count every call
	// as if a match.
	p.Matches++

	return nil
}

// HTML renders the HTML of a player
func (p *Player) HTML() (out string) {
	return
}

// ByScore is a sort.Interface that sorts players by their score
type ByScore []Player

func (s ByScore) Len() int {
	return len(s)

}
func (s ByScore) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByScore) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Score() > s[j].Score()
}

// SortByScore returns a list in order of the score the players have
func SortByScore(ps []Player) []Player {
	sort.Sort(ByScore(ps))
	return ps
}

// ByKills is a sort.Interface that sorts players by their kills
type ByKills []Player

func (s ByKills) Len() int {
	return len(s)

}
func (s ByKills) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByKills) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Kills > s[j].Kills
}

// SortByKills returns a list in order of the kills the players have
func SortByKills(ps []Player) []Player {
	sort.Sort(ByKills(ps))
	return ps
}

// ByRunnerup is a sort.Interface that sorts players by their runnerup status
//
// This is almost exactly the same as score, but the number of matches a player
// has played factors in, and players that have played less matches are sorted
// favorably.
type ByRunnerup []Player

func (s ByRunnerup) Len() int {
	return len(s)

}
func (s ByRunnerup) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByRunnerup) Less(i, j int) bool {
	if s[i].Matches == s[j].Matches {
		// Same as by kills
		return s[i].Kills > s[j].Kills
	}
	// Lower is better - the ones that have not played should be at the top
	return s[i].Matches < s[j].Matches
}

// SortByRunnerup returns a list in order of the kills the players have
func SortByRunnerup(ps []Player) []Player {
	sort.Sort(ByRunnerup(ps))
	return ps
}

// Judge is a Participant that has access to the judge functions
type Judge struct {
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"sort"
)

// Participant someone having a role in the tournament
type Participant interface {
	ID() string
}

// ScoreData is a structured Key/Value pair list for scores
type ScoreData struct {
	Key    string
	Value  int
	Player *Player
}

// Player is a Participant that is actively participating in battles.
type Player struct {
	Name           string `json:"name"`
	PreferredColor string `json:"preferred_color"`
	Shots          int    `json:"shots"`
	Sweeps         int    `json:"sweeps"`
	Kills          int    `json:"kills"`
	Self           int    `json:"self"`
	Explosions     int    `json:"explosions"`
	Matches        int    `json:"matches"`
	Match          *Match `json:"-"`
}

// NewPlayer returns a new instance of a player
func NewPlayer() Player {
	p := Player{}
	return p
}

func (p *Player) String() string {
	IsPointed := "."
	if p.Match != nil {
		IsPointed = "!"
	}
	return fmt.Sprintf(
		"<%s: %dsh %dsw %dk %ds %de %s>",
		p.Name,
		p.Shots,
		p.Sweeps,
		p.Kills,
		p.Self,
		p.Explosions,
		IsPointed,
	)
}

// Score calculates the score to determine runnerup positions.
func (p *Player) Score() (out int) {
	// This algorithm is probably flawed, but at least it should be able to
	// determine who is the most entertaining.
	// When executed, a sweep is basically 11 points since scoring a sweep
	// also comes with a shot and three kills.

	out += p.Sweeps * 5
	out += p.Shots * 3
	out += p.Kills * 2
	out += p.Self
	out += p.Explosions

	return
}

// ScoreData returns this players set of ScoreData
func (p *Player) ScoreData() []ScoreData {
	sd := []ScoreData{
		ScoreData{Key: "kills", Value: p.Kills, Player: p},
		ScoreData{Key: "shots", Value: p.Shots, Player: p},
		ScoreData{Key: "sweeps", Value: p.Sweeps, Player: p},
		ScoreData{Key: "self", Value: p.Self, Player: p},
		ScoreData{Key: "explosions", Value: p.Explosions, Player: p},
	}
	return sd
}

// URL returns the URL to this player
//
// Used for action URLs
func (p *Player) URL() string {
	out := fmt.Sprintf(
		"%s/%d",
		p.Match.URL(),
		p.Index(),
	)
	return out
}

// Classes returns the CSS color classes for the player
func (p *Player) Classes() string {
	if p.IsPrefill() {
		return "prefill"
	}

	if p.Match.IsEnded() {
		ps := ByScore(p.Match.Players)
		if ps[0].Name == p.Name {
			// Always gold for the winner
			return "gold"
		} else if ps[1].Name == p.Name {
			// Silver for the second, unless there is a short amount of tryouts
			if p.Match.Kind != "tryout" || len(p.Match.Tournament.Tryouts) <= 4 {
				return "silver"
			}
		} else if ps[2].Name == p.Name && p.Match.Kind == "final" {
			return "bronze"
		}

		return "out"
	}
	return p.PreferredColor
}

// Index returns the index in the current match
func (p *Player) Index() int {
	if p.Match != nil {
		for i, o := range p.Match.Players {
			if p.Name == o.Name {
				return i
			}
		}
	}
	return -1
}

// IsPrefill returns whether the player is a prefill placeholder or not
func (p *Player) IsPrefill() bool {
	return p.Name == ""
}

// Action performs an action for a player
func (p *Player) Action(action, dir string) error {
	// TODO: This could use with a refactoring...
	if dir == "up" {
		switch action {
		case "kills":
			p.AddKill()
		case "shots":
			p.AddShot()
		case "sweeps":
			p.AddSweep()
		case "self":
			p.AddSelf()
		case "explosions":
			p.AddExplosion()
		}
	} else {
		switch action {
		case "kills":
			p.RemoveKill()
		case "shots":
			p.RemoveShot()
		case "sweeps":
			p.RemoveSweep()
		case "self":
			p.RemoveSelf()
		case "explosions":
			p.RemoveExplosion()
		}
	}

	// Save the change to the database
	p.Match.Tournament.Persist()

	return nil
}

// AddShot increases the shot count
func (p *Player) AddShot() {
	p.Shots++
}

// RemoveShot decreases the shot count
// Fails silently if shots are zero.
func (p *Player) RemoveShot() {
	if p.Shots == 0 {
		return
	}
	p.Shots--
}

// AddSweep increases the sweep count, gives three kills and a shot.
func (p *Player) AddSweep() {
	p.Sweeps++
	p.AddShot()
	p.AddKill()
	p.AddKill()
	p.AddKill()
}

// RemoveSweep decreases the sweep count, three kills and a shot
// Fails silently if sweeps are zero.
func (p *Player) RemoveSweep() {
	if p.Sweeps == 0 {
		return
	}
	p.Sweeps--
	p.RemoveShot()
	p.RemoveKill()
	p.RemoveKill()
	p.RemoveKill()
}

// AddKill increases the kill count
func (p *Player) AddKill(kills ...int) {
	// This is basically only to help out with testing.
	// Adding an optional argument with the amount of kills lets us just use
	// one call to AddKill() rather than 10.
	if len(kills) > 0 {
		p.Kills += kills[0]
	} else {
		p.Kills++
	}
}

// RemoveKill decreases the kill count
// Fails silently if kills are zero.
func (p *Player) RemoveKill() {
	if p.Kills == 0 {
		return
	}
	p.Kills--
}

// AddSelf increases the self count, decreases the kill, and gives a shot
func (p *Player) AddSelf() {
	p.Self++
	p.RemoveKill()
	p.AddShot()
}

// RemoveSelf decreases the self count and a shot
// Fails silently if selfs are zero.
func (p *Player) RemoveSelf() {
	if p.Self == 0 {
		return
	}
	p.Self--
	p.AddKill()
	p.RemoveShot()
}

// AddExplosion increases the explosion count, the kill count and gives a shot
func (p *Player) AddExplosion() {
	p.Explosions++
	p.AddShot()
	p.AddKill()
}

// RemoveExplosion decreases the explosion count, a shot and a kill
// Fails silently if Explosions are zero.
func (p *Player) RemoveExplosion() {
	if p.Explosions == 0 {
		return
	}
	p.Explosions--
	p.RemoveShot()
	p.RemoveKill()
}

// Reset resets the stats on a Player to 0
//
// It is to be run in Match.Start()
func (p *Player) Reset() {
	p.Shots = 0
	p.Sweeps = 0
	p.Kills = 0
	p.Self = 0
	p.Explosions = 0
	p.Matches = 0
}

// Update updates a player with the scores of another
//
// This is primarily used by the tournament score calculator
func (p *Player) Update(other Player) error {
	p.Shots += other.Shots
	p.Sweeps += other.Sweeps
	p.Kills += other.Kills
	p.Self += other.Self
	p.Explosions += other.Explosions

	// Every call to this method is per match. Count every call
	// as if a match.
	p.Matches++

	return nil
}

// HTML renders the HTML of a player
func (p *Player) HTML() (out string) {
	return
}

// ByScore is a sort.Interface that sorts players by their score
type ByScore []Player

func (s ByScore) Len() int {
	return len(s)

}
func (s ByScore) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByScore) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Score() > s[j].Score()
}

// SortByScore returns a list in order of the score the players have
func SortByScore(ps []Player) []Player {
	sort.Sort(ByScore(ps))
	return ps
}

// ByKills is a sort.Interface that sorts players by their kills
type ByKills []Player

func (s ByKills) Len() int {
	return len(s)

}
func (s ByKills) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByKills) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Kills > s[j].Kills
}

// SortByKills returns a list in order of the kills the players have
func SortByKills(ps []Player) []Player {
	sort.Sort(ByKills(ps))
	return ps
}

// ByRunnerup is a sort.Interface that sorts players by their runnerup status
//
// This is almost exactly the same as score, but the number of matches a player
// has played factors in, and players that have played less matches are sorted
// favorably.
type ByRunnerup []Player

func (s ByRunnerup) Len() int {
	return len(s)

}
func (s ByRunnerup) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByRunnerup) Less(i, j int) bool {
	if s[i].Matches == s[j].Matches {
		// Same as by kills
		return s[i].Score() > s[j].Score()
	}
	// Lower is better - the ones that have not played should be at the top
	return s[i].Matches < s[j].Matches
}

// SortByRunnerup returns a list in order of the kills the players have
func SortByRunnerup(ps []Player) []Player {
	sort.Sort(ByRunnerup(ps))
	return ps
}

// Judge is a Participant that has access to the judge functions
type Judge struct {
}
<commit_msg>Fix nil pointer error for players<commit_after>package main

import (
	"fmt"
	"sort"
)

// Participant someone having a role in the tournament
type Participant interface {
	ID() string
}

// ScoreData is a structured Key/Value pair list for scores
type ScoreData struct {
	Key    string
	Value  int
	Player *Player
}

// Player is a Participant that is actively participating in battles.
type Player struct {
	Name           string `json:"name"`
	PreferredColor string `json:"preferred_color"`
	Shots          int    `json:"shots"`
	Sweeps         int    `json:"sweeps"`
	Kills          int    `json:"kills"`
	Self           int    `json:"self"`
	Explosions     int    `json:"explosions"`
	Matches        int    `json:"matches"`
	Match          *Match `json:"-"`
}

// NewPlayer returns a new instance of a player
func NewPlayer() Player {
	p := Player{}
	return p
}

func (p *Player) String() string {
	IsPointed := "."
	if p.Match != nil {
		IsPointed = "!"
	}
	return fmt.Sprintf(
		"<%s: %dsh %dsw %dk %ds %de %s>",
		p.Name,
		p.Shots,
		p.Sweeps,
		p.Kills,
		p.Self,
		p.Explosions,
		IsPointed,
	)
}

// Score calculates the score to determine runnerup positions.
func (p *Player) Score() (out int) {
	// This algorithm is probably flawed, but at least it should be able to
	// determine who is the most entertaining.
	// When executed, a sweep is basically 11 points since scoring a sweep
	// also comes with a shot and three kills.

	out += p.Sweeps * 5
	out += p.Shots * 3
	out += p.Kills * 2
	out += p.Self
	out += p.Explosions

	return
}

// ScoreData returns this players set of ScoreData
func (p *Player) ScoreData() []ScoreData {
	sd := []ScoreData{
		ScoreData{Key: "kills", Value: p.Kills, Player: p},
		ScoreData{Key: "shots", Value: p.Shots, Player: p},
		ScoreData{Key: "sweeps", Value: p.Sweeps, Player: p},
		ScoreData{Key: "self", Value: p.Self, Player: p},
		ScoreData{Key: "explosions", Value: p.Explosions, Player: p},
	}
	return sd
}

// URL returns the URL to this player
//
// Used for action URLs
func (p *Player) URL() string {
	out := fmt.Sprintf(
		"%s/%d",
		p.Match.URL(),
		p.Index(),
	)
	return out
}

// Classes returns the CSS color classes for the player
func (p *Player) Classes() string {
	if p.IsPrefill() {
		return "prefill"
	}

	if p.Match != nil && p.Match.IsEnded() {
		ps := ByScore(p.Match.Players)
		if ps[0].Name == p.Name {
			// Always gold for the winner
			return "gold"
		} else if ps[1].Name == p.Name {
			// Silver for the second, unless there is a short amount of tryouts
			if p.Match.Kind != "tryout" || len(p.Match.Tournament.Tryouts) <= 4 {
				return "silver"
			}
		} else if ps[2].Name == p.Name && p.Match.Kind == "final" {
			return "bronze"
		}

		return "out"
	}
	return p.PreferredColor
}

// Index returns the index in the current match
func (p *Player) Index() int {
	if p.Match != nil {
		for i, o := range p.Match.Players {
			if p.Name == o.Name {
				return i
			}
		}
	}
	return -1
}

// IsPrefill returns whether the player is a prefill placeholder or not
func (p *Player) IsPrefill() bool {
	return p.Name == ""
}

// Action performs an action for a player
func (p *Player) Action(action, dir string) error {
	// TODO: This could use with a refactoring...
	if dir == "up" {
		switch action {
		case "kills":
			p.AddKill()
		case "shots":
			p.AddShot()
		case "sweeps":
			p.AddSweep()
		case "self":
			p.AddSelf()
		case "explosions":
			p.AddExplosion()
		}
	} else {
		switch action {
		case "kills":
			p.RemoveKill()
		case "shots":
			p.RemoveShot()
		case "sweeps":
			p.RemoveSweep()
		case "self":
			p.RemoveSelf()
		case "explosions":
			p.RemoveExplosion()
		}
	}

	// Save the change to the database
	p.Match.Tournament.Persist()

	return nil
}

// AddShot increases the shot count
func (p *Player) AddShot() {
	p.Shots++
}

// RemoveShot decreases the shot count
// Fails silently if shots are zero.
func (p *Player) RemoveShot() {
	if p.Shots == 0 {
		return
	}
	p.Shots--
}

// AddSweep increases the sweep count, gives three kills and a shot.
func (p *Player) AddSweep() {
	p.Sweeps++
	p.AddShot()
	p.AddKill()
	p.AddKill()
	p.AddKill()
}

// RemoveSweep decreases the sweep count, three kills and a shot
// Fails silently if sweeps are zero.
func (p *Player) RemoveSweep() {
	if p.Sweeps == 0 {
		return
	}
	p.Sweeps--
	p.RemoveShot()
	p.RemoveKill()
	p.RemoveKill()
	p.RemoveKill()
}

// AddKill increases the kill count
func (p *Player) AddKill(kills ...int) {
	// This is basically only to help out with testing.
	// Adding an optional argument with the amount of kills lets us just use
	// one call to AddKill() rather than 10.
	if len(kills) > 0 {
		p.Kills += kills[0]
	} else {
		p.Kills++
	}
}

// RemoveKill decreases the kill count
// Fails silently if kills are zero.
func (p *Player) RemoveKill() {
	if p.Kills == 0 {
		return
	}
	p.Kills--
}

// AddSelf increases the self count, decreases the kill, and gives a shot
func (p *Player) AddSelf() {
	p.Self++
	p.RemoveKill()
	p.AddShot()
}

// RemoveSelf decreases the self count and a shot
// Fails silently if selfs are zero.
func (p *Player) RemoveSelf() {
	if p.Self == 0 {
		return
	}
	p.Self--
	p.AddKill()
	p.RemoveShot()
}

// AddExplosion increases the explosion count, the kill count and gives a shot
func (p *Player) AddExplosion() {
	p.Explosions++
	p.AddShot()
	p.AddKill()
}

// RemoveExplosion decreases the explosion count, a shot and a kill
// Fails silently if Explosions are zero.
func (p *Player) RemoveExplosion() {
	if p.Explosions == 0 {
		return
	}
	p.Explosions--
	p.RemoveShot()
	p.RemoveKill()
}

// Reset resets the stats on a Player to 0
//
// It is to be run in Match.Start()
func (p *Player) Reset() {
	p.Shots = 0
	p.Sweeps = 0
	p.Kills = 0
	p.Self = 0
	p.Explosions = 0
	p.Matches = 0
}

// Update updates a player with the scores of another
//
// This is primarily used by the tournament score calculator
func (p *Player) Update(other Player) error {
	p.Shots += other.Shots
	p.Sweeps += other.Sweeps
	p.Kills += other.Kills
	p.Self += other.Self
	p.Explosions += other.Explosions

	// Every call to this method is per match. Count every call
	// as if a match.
	p.Matches++

	return nil
}

// HTML renders the HTML of a player
func (p *Player) HTML() (out string) {
	return
}

// ByScore is a sort.Interface that sorts players by their score
type ByScore []Player

func (s ByScore) Len() int {
	return len(s)

}
func (s ByScore) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByScore) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Score() > s[j].Score()
}

// SortByScore returns a list in order of the score the players have
func SortByScore(ps []Player) []Player {
	sort.Sort(ByScore(ps))
	return ps
}

// ByKills is a sort.Interface that sorts players by their kills
type ByKills []Player

func (s ByKills) Len() int {
	return len(s)

}
func (s ByKills) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByKills) Less(i, j int) bool {
	// Technically not Less, but we want biggest first...
	return s[i].Kills > s[j].Kills
}

// SortByKills returns a list in order of the kills the players have
func SortByKills(ps []Player) []Player {
	sort.Sort(ByKills(ps))
	return ps
}

// ByRunnerup is a sort.Interface that sorts players by their runnerup status
//
// This is almost exactly the same as score, but the number of matches a player
// has played factors in, and players that have played less matches are sorted
// favorably.
type ByRunnerup []Player

func (s ByRunnerup) Len() int {
	return len(s)

}
func (s ByRunnerup) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]

}
func (s ByRunnerup) Less(i, j int) bool {
	if s[i].Matches == s[j].Matches {
		// Same as by kills
		return s[i].Score() > s[j].Score()
	}
	// Lower is better - the ones that have not played should be at the top
	return s[i].Matches < s[j].Matches
}

// SortByRunnerup returns a list in order of the kills the players have
func SortByRunnerup(ps []Player) []Player {
	sort.Sort(ByRunnerup(ps))
	return ps
}

// Judge is a Participant that has access to the judge functions
type Judge struct {
}
<|endoftext|>