<commit_before>package cli

import (
	"bytes"
	"fmt"
	"log"
	"sort"
	"strings"
)

// HelpFunc is the type of the function that is responsible for generating
// the help output when the CLI must show the general help text.
type HelpFunc func(map[string]CommandFactory) string

// BasicHelpFunc generates some basic help output that is usually good enough
// for most CLI applications.
func BasicHelpFunc(app string) HelpFunc {
	return func(commands map[string]CommandFactory) string {
		var buf bytes.Buffer
		buf.WriteString(fmt.Sprintf(
			"usage: %s [--version] [--help] <command> [<args>]\n\n",
			app))
		buf.WriteString("Available commands are:\n")

		// Get the list of keys so we can sort them, and also get the maximum
		// key length so they can be aligned properly.
		keys := make([]string, 0, len(commands))
		maxKeyLen := 0
		for key, _ := range commands {
			if len(key) > maxKeyLen {
				maxKeyLen = len(key)
			}

			keys = append(keys, key)
		}
		sort.Strings(keys)

		for _, key := range keys {
			commandFunc, ok := commands[key]
			if !ok {
				// This should never happen since we JUST built the list of
				// keys.
				panic("command not found: " + key)
			}

			command, err := commandFunc()
			if err != nil {
				log.Printf("[ERR] cli: Command '%s' failed to load: %s",
					key, err)
				continue
			}

			key = fmt.Sprintf("%s%s", key, strings.Repeat(" ", maxKeyLen-len(key)))
			buf.WriteString(fmt.Sprintf("    %s    %s\n", key, command.Synopsis()))
		}

		return buf.String()
	}
}
<commit_msg>add FilteredHelpFunc to filter commands shown in help<commit_after>package cli

import (
	"bytes"
	"fmt"
	"log"
	"sort"
	"strings"
)

// HelpFunc is the type of the function that is responsible for generating
// the help output when the CLI must show the general help text.
type HelpFunc func(map[string]CommandFactory) string

// BasicHelpFunc generates some basic help output that is usually good enough
// for most CLI applications.
func BasicHelpFunc(app string) HelpFunc {
	return func(commands map[string]CommandFactory) string {
		var buf bytes.Buffer
		buf.WriteString(fmt.Sprintf(
			"usage: %s [--version] [--help] <command> [<args>]\n\n",
			app))
		buf.WriteString("Available commands are:\n")

		// Get the list of keys so we can sort them, and also get the maximum
		// key length so they can be aligned properly.
		keys := make([]string, 0, len(commands))
		maxKeyLen := 0
		for key, _ := range commands {
			if len(key) > maxKeyLen {
				maxKeyLen = len(key)
			}

			keys = append(keys, key)
		}
		sort.Strings(keys)

		for _, key := range keys {
			commandFunc, ok := commands[key]
			if !ok {
				// This should never happen since we JUST built the list of
				// keys.
				panic("command not found: " + key)
			}

			command, err := commandFunc()
			if err != nil {
				log.Printf("[ERR] cli: Command '%s' failed to load: %s",
					key, err)
				continue
			}

			key = fmt.Sprintf("%s%s", key, strings.Repeat(" ", maxKeyLen-len(key)))
			buf.WriteString(fmt.Sprintf("    %s    %s\n", key, command.Synopsis()))
		}

		return buf.String()
	}
}

// FilteredHelpFunc will filter the commands to only include the keys
// in the include parameter.
func FilteredHelpFunc(include []string, f HelpFunc) HelpFunc {
	return func(commands map[string]CommandFactory) string {
		set := make(map[string]struct{})
		for _, k := range include {
			set[k] = struct{}{}
		}

		filtered := make(map[string]CommandFactory)
		for k, f := range commands {
			if _, ok := set[k]; ok {
				filtered[k] = f
			}
		}

		return f(filtered)
	}
}
<|endoftext|>


<commit_before>// Copyright 2012 Jesse van den Kieboom. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flags

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"reflect"
	"strings"
	"unicode/utf8"
)

type alignmentInfo struct {
	maxLongLen      int
	hasShort        bool
	hasValueName    bool
	terminalColumns int
}

func (p *Parser) getAlignmentInfo() alignmentInfo {
	ret := alignmentInfo{
		maxLongLen:      0,
		hasShort:        false,
		hasValueName:    false,
		terminalColumns: getTerminalColumns(),
	}

	if ret.terminalColumns <= 0 {
		ret.terminalColumns = 80
	}

	alfunc := func(index int, grp *Group) {
		for _, info := range grp.Options {
			if info.ShortName != 0 {
				ret.hasShort = true
			}

			lv := utf8.RuneCountInString(info.ValueName)

			if lv != 0 {
				ret.hasValueName = true
			}

			l := utf8.RuneCountInString(info.LongName) + lv

			if l > ret.maxLongLen {
				ret.maxLongLen = l
			}
		}
	}

	if p.currentCommand != nil {
		// Make sure to also check for toplevel arguments for the
		// alignment since they are included in the help output also
		p.eachTopLevelGroup(alfunc)
	}

	p.EachGroup(alfunc)

	return ret
}

func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) {
	line := &bytes.Buffer{}

	distanceBetweenOptionAndDescription := 2
	paddingBeforeOption := 2

	line.WriteString(strings.Repeat(" ", paddingBeforeOption))

	if option.ShortName != 0 {
		line.WriteString("-")
		line.WriteRune(option.ShortName)
	} else if info.hasShort {
		line.WriteString("  ")
	}

	descstart := info.maxLongLen + paddingBeforeOption + distanceBetweenOptionAndDescription

	if info.hasShort {
		descstart += 2
	}

	if info.maxLongLen > 0 {
		descstart += 4
	}

	if info.hasValueName {
		descstart += 3
	}

	if len(option.LongName) > 0 {
		if option.ShortName != 0 {
			line.WriteString(", ")
		} else if info.hasShort {
			line.WriteString("  ")
		}

		line.WriteString("--")
		line.WriteString(option.LongName)
	}

	if !option.isBool() {
		line.WriteString("=")

		if len(option.ValueName) > 0 {
			line.WriteString(option.ValueName)
		}
	}

	written := line.Len()
	line.WriteTo(writer)

	if option.Description != "" {
		dw := descstart - written
		writer.WriteString(strings.Repeat(" ", dw))

		def := ""
		defs := option.Default

		if len(defs) == 0 && !option.isBool() {
			var showdef bool

			switch option.Field.Type.Kind() {
			case reflect.Func, reflect.Ptr:
				showdef = !option.Value.IsNil()
			case reflect.Slice, reflect.String, reflect.Array:
				showdef = option.Value.Len() > 0
			case reflect.Map:
				showdef = !option.Value.IsNil() && option.Value.Len() > 0
			default:
				zeroval := reflect.Zero(option.Field.Type)
				showdef = !reflect.DeepEqual(zeroval.Interface(), option.Value.Interface())
			}

			if showdef {
				def = convertToString(option.Value, option.tag)
			}
		} else if len(defs) != 0 {
			def = strings.Join(defs, ", ")
		}

		var desc string

		if def != "" {
			desc = fmt.Sprintf("%s (%v)", option.Description, def)
		} else {
			desc = option.Description
		}

		writer.WriteString(wrapText(desc,
			info.terminalColumns-descstart,
			strings.Repeat(" ", descstart)))
	}

	writer.WriteString("\n")
}

// WriteHelp writes a help message containing all the possible options and
// their descriptions to the provided writer. Note that the HelpFlag parser
// option provides a convenient way to add a -h/--help option group to the
// command line parser which will automatically show the help messages using
// this method.
func (p *Parser) WriteHelp(writer io.Writer) {
	if writer == nil {
		return
	}

	wr := bufio.NewWriter(writer)
	aligninfo := p.getAlignmentInfo()

	if p.ApplicationName != "" {
		wr.WriteString("Usage:\n")
		fmt.Fprintf(wr, "  %s", p.ApplicationName)

		if p.Usage != "" {
			fmt.Fprintf(wr, " %s", p.Usage)
		}

		if len(p.currentCommandString) > 0 {
			cmdusage := fmt.Sprintf("[%s-OPTIONS]", p.currentCommandString[len(p.currentCommandString)-1])

			if p.currentCommand != nil {
				if us, ok := p.currentCommand.data.(Usage); ok {
					cmdusage = us.Usage()
				}
			}

			fmt.Fprintf(wr, " %s %s",
				strings.Join(p.currentCommandString, " "),
				cmdusage)
		}

		fmt.Fprintln(wr)

		if p.currentCommand != nil && len(p.currentCommand.LongDescription) != 0 {
			fmt.Fprintln(wr)

			t := wrapText(p.currentCommand.LongDescription,
			              aligninfo.terminalColumns,
			              "")

			fmt.Fprintln(wr, t)
		}
	}

	seen := make(map[*Group]bool)

	writeHelp := func(index int, grp *Group) {
		if len(grp.Options) == 0 || seen[grp] {
			return
		}

		seen[grp] = true

		wr.WriteString("\n")

		fmt.Fprintf(wr, "%s:\n", grp.Name)

		for _, info := range grp.Options {
			p.writeHelpOption(wr, info, aligninfo)
		}
	}

	// If there is a command, still write all the toplevel help too
	if p.currentCommand != nil {
		p.eachTopLevelGroup(writeHelp)
	}

	p.EachGroup(writeHelp)

	commander := p.currentCommander()
	names := commander.sortedNames()

	if len(names) > 0 {
		maxnamelen := len(names[0])

		for i := 1; i < len(names); i++ {
			l := len(names[i])

			if l > maxnamelen {
				maxnamelen = l
			}
		}

		fmt.Fprintln(wr)
		fmt.Fprintln(wr, "Available commands:")

		for _, name := range names {
			fmt.Fprintf(wr, "  %s", name)

			cmd := commander.Commands[name]

			if len(cmd.Name) > 0 {
				pad := strings.Repeat(" ", maxnamelen-len(name))
				fmt.Fprintf(wr, "%s  %s", pad, cmd.Name)
			}

			fmt.Fprintln(wr)
		}
	}

	wr.Flush()
}
<commit_msg>Run go fmt<commit_after>// Copyright 2012 Jesse van den Kieboom. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flags

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"reflect"
	"strings"
	"unicode/utf8"
)

type alignmentInfo struct {
	maxLongLen      int
	hasShort        bool
	hasValueName    bool
	terminalColumns int
}

func (p *Parser) getAlignmentInfo() alignmentInfo {
	ret := alignmentInfo{
		maxLongLen:      0,
		hasShort:        false,
		hasValueName:    false,
		terminalColumns: getTerminalColumns(),
	}

	if ret.terminalColumns <= 0 {
		ret.terminalColumns = 80
	}

	alfunc := func(index int, grp *Group) {
		for _, info := range grp.Options {
			if info.ShortName != 0 {
				ret.hasShort = true
			}

			lv := utf8.RuneCountInString(info.ValueName)

			if lv != 0 {
				ret.hasValueName = true
			}

			l := utf8.RuneCountInString(info.LongName) + lv

			if l > ret.maxLongLen {
				ret.maxLongLen = l
			}
		}
	}

	if p.currentCommand != nil {
		// Make sure to also check for toplevel arguments for the
		// alignment since they are included in the help output also
		p.eachTopLevelGroup(alfunc)
	}

	p.EachGroup(alfunc)

	return ret
}

func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) {
	line := &bytes.Buffer{}

	distanceBetweenOptionAndDescription := 2
	paddingBeforeOption := 2

	line.WriteString(strings.Repeat(" ", paddingBeforeOption))

	if option.ShortName != 0 {
		line.WriteString("-")
		line.WriteRune(option.ShortName)
	} else if info.hasShort {
		line.WriteString("  ")
	}

	descstart := info.maxLongLen + paddingBeforeOption + distanceBetweenOptionAndDescription

	if info.hasShort {
		descstart += 2
	}

	if info.maxLongLen > 0 {
		descstart += 4
	}

	if info.hasValueName {
		descstart += 3
	}

	if len(option.LongName) > 0 {
		if option.ShortName != 0 {
			line.WriteString(", ")
		} else if info.hasShort {
			line.WriteString("  ")
		}

		line.WriteString("--")
		line.WriteString(option.LongName)
	}

	if !option.isBool() {
		line.WriteString("=")

		if len(option.ValueName) > 0 {
			line.WriteString(option.ValueName)
		}
	}

	written := line.Len()
	line.WriteTo(writer)

	if option.Description != "" {
		dw := descstart - written
		writer.WriteString(strings.Repeat(" ", dw))

		def := ""
		defs := option.Default

		if len(defs) == 0 && !option.isBool() {
			var showdef bool

			switch option.Field.Type.Kind() {
			case reflect.Func, reflect.Ptr:
				showdef = !option.Value.IsNil()
			case reflect.Slice, reflect.String, reflect.Array:
				showdef = option.Value.Len() > 0
			case reflect.Map:
				showdef = !option.Value.IsNil() && option.Value.Len() > 0
			default:
				zeroval := reflect.Zero(option.Field.Type)
				showdef = !reflect.DeepEqual(zeroval.Interface(), option.Value.Interface())
			}

			if showdef {
				def = convertToString(option.Value, option.tag)
			}
		} else if len(defs) != 0 {
			def = strings.Join(defs, ", ")
		}

		var desc string

		if def != "" {
			desc = fmt.Sprintf("%s (%v)", option.Description, def)
		} else {
			desc = option.Description
		}

		writer.WriteString(wrapText(desc,
			info.terminalColumns-descstart,
			strings.Repeat(" ", descstart)))
	}

	writer.WriteString("\n")
}

// WriteHelp writes a help message containing all the possible options and
// their descriptions to the provided writer. Note that the HelpFlag parser
// option provides a convenient way to add a -h/--help option group to the
// command line parser which will automatically show the help messages using
// this method.
func (p *Parser) WriteHelp(writer io.Writer) {
	if writer == nil {
		return
	}

	wr := bufio.NewWriter(writer)
	aligninfo := p.getAlignmentInfo()

	if p.ApplicationName != "" {
		wr.WriteString("Usage:\n")
		fmt.Fprintf(wr, "  %s", p.ApplicationName)

		if p.Usage != "" {
			fmt.Fprintf(wr, " %s", p.Usage)
		}

		if len(p.currentCommandString) > 0 {
			cmdusage := fmt.Sprintf("[%s-OPTIONS]", p.currentCommandString[len(p.currentCommandString)-1])

			if p.currentCommand != nil {
				if us, ok := p.currentCommand.data.(Usage); ok {
					cmdusage = us.Usage()
				}
			}

			fmt.Fprintf(wr, " %s %s",
				strings.Join(p.currentCommandString, " "),
				cmdusage)
		}

		fmt.Fprintln(wr)

		if p.currentCommand != nil && len(p.currentCommand.LongDescription) != 0 {
			fmt.Fprintln(wr)

			t := wrapText(p.currentCommand.LongDescription,
				aligninfo.terminalColumns,
				"")

			fmt.Fprintln(wr, t)
		}
	}

	seen := make(map[*Group]bool)

	writeHelp := func(index int, grp *Group) {
		if len(grp.Options) == 0 || seen[grp] {
			return
		}

		seen[grp] = true

		wr.WriteString("\n")

		fmt.Fprintf(wr, "%s:\n", grp.Name)

		for _, info := range grp.Options {
			p.writeHelpOption(wr, info, aligninfo)
		}
	}

	// If there is a command, still write all the toplevel help too
	if p.currentCommand != nil {
		p.eachTopLevelGroup(writeHelp)
	}

	p.EachGroup(writeHelp)

	commander := p.currentCommander()
	names := commander.sortedNames()

	if len(names) > 0 {
		maxnamelen := len(names[0])

		for i := 1; i < len(names); i++ {
			l := len(names[i])

			if l > maxnamelen {
				maxnamelen = l
			}
		}

		fmt.Fprintln(wr)
		fmt.Fprintln(wr, "Available commands:")

		for _, name := range names {
			fmt.Fprintf(wr, "  %s", name)

			cmd := commander.Commands[name]

			if len(cmd.Name) > 0 {
				pad := strings.Repeat(" ", maxnamelen-len(name))
				fmt.Fprintf(wr, "%s  %s", pad, cmd.Name)
			}

			fmt.Fprintln(wr)
		}
	}

	wr.Flush()
}
<|endoftext|>


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

package lease_test

import (
	"testing"

	"github.com/googlecloudplatform/gcsfuse/lease"
	. "github.com/jacobsa/ogletest"
)

func TestFileLeaser(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

const limitBytes = 17

type FileLeaserTest struct {
	fl *lease.FileLeaser
}

var _ SetUpInterface = &FileLeaserTest{}

func init() { RegisterTestSuite(&FileLeaserTest{}) }

func (t *FileLeaserTest) SetUp(ti *TestInfo) {
	t.fl = lease.NewFileLeaser("", limitBytes)
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *FileLeaserTest) ReadWriteLeaseInitialState() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) ModifyThenObserveReadWriteLease() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) DowngradeThenObserve() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) DowngradeThenUpgradeThenObserve() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) DowngradeAboveCapacity() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) ReadLeaseEviction() {
	AssertFalse(true, "TODO")
}
<commit_msg>Expanded test names.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lease_test

import (
	"testing"

	"github.com/googlecloudplatform/gcsfuse/lease"
	. "github.com/jacobsa/ogletest"
)

func TestFileLeaser(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

const limitBytes = 17

type FileLeaserTest struct {
	fl *lease.FileLeaser
}

var _ SetUpInterface = &FileLeaserTest{}

func init() { RegisterTestSuite(&FileLeaserTest{}) }

func (t *FileLeaserTest) SetUp(ti *TestInfo) {
	t.fl = lease.NewFileLeaser("", limitBytes)
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *FileLeaserTest) ReadWriteLeaseInitialState() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) ModifyThenObserveReadWriteLease() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) DowngradeThenObserve() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) DowngradeThenUpgradeThenObserve() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) DowngradeAboveCapacity() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) WriteCausesEviction() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) WriteAtCausesEviction() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) TruncateCausesEviction() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) EvictionIsLRU() {
	AssertFalse(true, "TODO")
}

func (t *FileLeaserTest) NothingAvailableToEvict() {
	AssertFalse(true, "TODO")
}
<|endoftext|>


<commit_before>package easyhmac

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
)

// SignedMessage contains a payload and a signature with the hmac secret
type SignedMessage struct {
	Payload   []byte `json:"p"`
	Signature []byte `json:"s"`
	Secret    string
}

// Encode marshals the data to JSON and url-safe base64 encodes it
func (sm *SignedMessage) Encode() (message string, err error) {

	msg, err := json.Marshal(sm)
	if err != nil {
		return
	}

	message = base64.URLEncoding.EncodeToString(msg)

	return

}

// Decode will unencode the url-safe base64 message and unmarshal to JSON
func (sm *SignedMessage) Decode(message string) (err error) {

	// Decode message
	msg, err := base64.URLEncoding.DecodeString(message)
	if err != nil {
		return
	}

	// Unmarshal JSON into struct
	err = json.Unmarshal(msg, sm)
	if err != nil {
		return
	}

	return

}

// Sign creates a HMAC signature for the message
func (sm *SignedMessage) Sign() {

	mac := hmac.New(sha256.New, []byte(sm.Secret))
	mac.Write(sm.Payload)

	sm.Signature = []byte(base64.StdEncoding.EncodeToString(mac.Sum(nil)))

}

// CheckSignature takes the base64 encoded message and signature
func (sm *SignedMessage) Verify() bool {

	mac := hmac.New(sha256.New, []byte(sm.Secret))
	mac.Write(sm.Payload)

	expected := []byte(base64.StdEncoding.EncodeToString(mac.Sum(nil)))

	return hmac.Equal(sm.Signature, expected)

}
<commit_msg>unexport signature in struct<commit_after>package easyhmac

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
)

// SignedMessage contains a payload and a signature with the hmac secret
type SignedMessage struct {
	Payload   []byte `json:"p"`
	signature []byte `json:"s"`
	Secret    string
}

// Encode marshals the data to JSON and url-safe base64 encodes it
func (sm *SignedMessage) Encode() (message string, err error) {

	msg, err := json.Marshal(sm)
	if err != nil {
		return
	}

	message = base64.URLEncoding.EncodeToString(msg)

	return

}

// Decode will unencode the url-safe base64 message and unmarshal to JSON
func (sm *SignedMessage) Decode(message string) (err error) {

	// Decode message
	msg, err := base64.URLEncoding.DecodeString(message)
	if err != nil {
		return
	}

	// Unmarshal JSON into struct
	err = json.Unmarshal(msg, sm)
	if err != nil {
		return
	}

	return

}

// Sign creates a HMAC signature for the message
func (sm *SignedMessage) Sign() {

	mac := hmac.New(sha256.New, []byte(sm.Secret))
	mac.Write(sm.Payload)

	sm.signature = []byte(base64.StdEncoding.EncodeToString(mac.Sum(nil)))

}

// CheckSignature takes the base64 encoded message and signature
func (sm *SignedMessage) Verify() bool {

	mac := hmac.New(sha256.New, []byte(sm.Secret))
	mac.Write(sm.Payload)

	expected := []byte(base64.StdEncoding.EncodeToString(mac.Sum(nil)))

	return hmac.Equal(sm.signature, expected)

}
<|endoftext|>


<commit_before>package rmq

import "fmt"

type TestConnection struct {
	queues map[string]*TestQueue
}

func NewTestConnection() TestConnection {
	return TestConnection{
		queues: map[string]*TestQueue{},
	}
}

func (connection TestConnection) OpenQueue(name string) Queue {
	if queue, ok := connection.queues[name]; ok {
		return queue
	}

	queue := NewTestQueue(name)
	connection.queues[name] = queue
	return queue
}

func (connection TestConnection) CollectStats(queueList []string) Stats {
	return Stats{}
}

func (connection TestConnection) GetDeliveries(queueName string) []string {
	queue, ok := connection.queues[queueName]
	if !ok {
		return []string{}
	}

	return queue.LastDeliveries
}

func (connection TestConnection) GetDelivery(queueName string, index int) string {
	queue, ok := connection.queues[queueName]
	if !ok || index < 0 || index >= len(queue.LastDeliveries) {
		return fmt.Sprintf("rmq.TestConnection: delivery not found: %s[%d]", queueName, index)
	}

	return queue.LastDeliveries[index]
}

func (connection TestConnection) Reset() {
	for _, queue := range connection.queues {
		queue.Reset()
	}
}

func (connection TestConnection) GetOpenQueues() []string {
	return []string{}
}
<commit_msg>use sync.Map in TestConnection to avoid concurrent access issues<commit_after>package rmq

import (
	"fmt"
	"sync"
)

type TestConnection struct {
	queues *sync.Map
}

func NewTestConnection() TestConnection {
	return TestConnection{
		queues: &sync.Map{},
	}
}

func (connection TestConnection) OpenQueue(name string) Queue {
	queue, _ := connection.queues.LoadOrStore(name, NewTestQueue(name))
	return queue.(*TestQueue)
}

func (connection TestConnection) CollectStats(queueList []string) Stats {
	return Stats{}
}

func (connection TestConnection) GetDeliveries(queueName string) []string {
	queue, ok := connection.queues.Load(queueName)
	if !ok {
		return []string{}
	}

	return queue.(*TestQueue).LastDeliveries
}

func (connection TestConnection) GetDelivery(queueName string, index int) string {
	queue, ok := connection.queues.Load(queueName)
	if !ok || index < 0 || index >= len(queue.(*TestQueue).LastDeliveries) {
		return fmt.Sprintf("rmq.TestConnection: delivery not found: %s[%d]", queueName, index)
	}

	return queue.(*TestQueue).LastDeliveries[index]
}

func (connection TestConnection) Reset() {
	connection.queues.Range(func(_, v interface{}) bool {
		v.(*TestQueue).Reset()
		return true
	})
}

func (connection TestConnection) GetOpenQueues() []string {
	return []string{}
}
<|endoftext|>


<commit_before>package network_test

import (
//	"encoding/json"
//	"fmt"
//	"github.com/APTrust/exchange/models"
	"github.com/APTrust/exchange/network"
//	"github.com/APTrust/exchange/testdata"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
//	"net/url"
//	"os"
//	"strings"
	"testing"
//	"time"
)

var objectTypes = []network.PharosObjectType{
	network.PharosIntellectualObject,
	network.PharosInstitution,
	network.PharosGenericFile,
	network.PharosPremisEvent,
	network.PharosWorkItem,
}

func TestNewPharosResponse(t *testing.T) {
	for _, objType := range objectTypes {
		resp := network.NewPharosResponse(objType)
		assert.NotNil(t, resp)
		assert.Equal(t, objType, resp.ObjectType())
		assert.Equal(t, 0, resp.Count)
		assert.Nil(t, resp.Next)
		assert.Nil(t, resp.Previous)
	}
}

func TestRawResponseData(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(institutionGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.InstitutionGet("college.edu")

	// Should be able to call repeatedly without error.
	// Incorrect implementation would try to read from
	// closed network socket.
	for i := 0; i < 3; i++ {
		bytes, err := resp.RawResponseData()
		assert.NotNil(t, bytes)
		assert.NotEmpty(t, bytes)
		assert.Nil(t, err)
	}
}

func TestObjectType(t *testing.T) {
	for _, objType := range objectTypes {
		resp := network.NewPharosResponse(objType)
		assert.Equal(t, objType, resp.ObjectType())
	}
}

func TestHasNextPage(t *testing.T) {
	resp := network.NewPharosResponse(network.PharosInstitution)
	assert.False(t, resp.HasNextPage())
	link := "http://example.com"
	resp.Next = &link
	assert.True(t, resp.HasNextPage())
}

func TestHasPreviousPage(t *testing.T) {
	resp := network.NewPharosResponse(network.PharosInstitution)
	assert.False(t, resp.HasPreviousPage())
	link := "http://example.com"
	resp.Previous = &link
	assert.True(t, resp.HasPreviousPage())
}

func TestParamsForNextPage(t *testing.T) {
	resp := network.NewPharosResponse(network.PharosInstitution)
	link := "http://example.com?name=college.edu&page=6&per_page=20"
	resp.Next = &link
	params := resp.ParamsForNextPage()
	assert.Equal(t, 3, len(params))
	assert.Equal(t, "college.edu", params.Get("name"))
	assert.Equal(t, "6", params.Get("page"))
	assert.Equal(t, "20", params.Get("per_page"))
}

func TestParamsForPreviousPage(t *testing.T) {
	resp := network.NewPharosResponse(network.PharosInstitution)
	link := "http://example.com?name=college.edu&page=6&per_page=20"
	resp.Previous = &link
	params := resp.ParamsForPreviousPage()
	assert.Equal(t, 3, len(params))
	assert.Equal(t, "college.edu", params.Get("name"))
	assert.Equal(t, "6", params.Get("page"))
	assert.Equal(t, "20", params.Get("per_page"))
}

func TestInstitution(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(institutionGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.InstitutionGet("college.edu")
	assert.NotNil(t, resp.Institution())
}

func TestInstitutions(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(institutionListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.InstitutionList(nil)
	assert.NotEmpty(t, resp.Institutions())
}

func TestIntellectualObject(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(intellectualObjectGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.IntellectualObjectGet("college.edu/object")
	assert.NotNil(t, resp.IntellectualObject())
}

func TestIntellectualObjects(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(intellectualObjectListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.IntellectualObjectList(nil)
	assert.NotEmpty(t, resp.IntellectualObjects())
}

func TestGenericFile(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(genericFileGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.GenericFileGet("college.edu/object/file.xml")
	assert.NotNil(t, resp.GenericFile())
}

func TestGenericFiles(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(genericFileListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.GenericFileList(nil)
	assert.NotEmpty(t, resp.GenericFiles())
}

func TestPremisEvent(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(premisEventGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.PremisEventGet("000000000000-0000-0000-0000-00000000")
	assert.NotNil(t, resp.PremisEvent())
}

func TestPremisEvents(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(premisEventListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.PremisEventList(nil)
	assert.NotEmpty(t, resp.PremisEvents())
}

func TestWorkItem(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(workItemGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.WorkItemGet(1000)
	assert.NotNil(t, resp.WorkItem())
}

func TestWorkItems(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(workItemListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.WorkItemList(nil)
	assert.NotEmpty(t, resp.WorkItems())
}
<commit_msg>Removed unused imports<commit_after>package network_test

import (
	"github.com/APTrust/exchange/network"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	"testing"
)

var objectTypes = []network.PharosObjectType{
	network.PharosIntellectualObject,
	network.PharosInstitution,
	network.PharosGenericFile,
	network.PharosPremisEvent,
	network.PharosWorkItem,
}

func TestNewPharosResponse(t *testing.T) {
	for _, objType := range objectTypes {
		resp := network.NewPharosResponse(objType)
		assert.NotNil(t, resp)
		assert.Equal(t, objType, resp.ObjectType())
		assert.Equal(t, 0, resp.Count)
		assert.Nil(t, resp.Next)
		assert.Nil(t, resp.Previous)
	}
}

func TestRawResponseData(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(institutionGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.InstitutionGet("college.edu")

	// Should be able to call repeatedly without error.
	// Incorrect implementation would try to read from
	// closed network socket.
	for i := 0; i < 3; i++ {
		bytes, err := resp.RawResponseData()
		assert.NotNil(t, bytes)
		assert.NotEmpty(t, bytes)
		assert.Nil(t, err)
	}
}

func TestObjectType(t *testing.T) {
	for _, objType := range objectTypes {
		resp := network.NewPharosResponse(objType)
		assert.Equal(t, objType, resp.ObjectType())
	}
}

func TestHasNextPage(t *testing.T) {
	resp := network.NewPharosResponse(network.PharosInstitution)
	assert.False(t, resp.HasNextPage())
	link := "http://example.com"
	resp.Next = &link
	assert.True(t, resp.HasNextPage())
}

func TestHasPreviousPage(t *testing.T) {
	resp := network.NewPharosResponse(network.PharosInstitution)
	assert.False(t, resp.HasPreviousPage())
	link := "http://example.com"
	resp.Previous = &link
	assert.True(t, resp.HasPreviousPage())
}

func TestParamsForNextPage(t *testing.T) {
	resp := network.NewPharosResponse(network.PharosInstitution)
	link := "http://example.com?name=college.edu&page=6&per_page=20"
	resp.Next = &link
	params := resp.ParamsForNextPage()
	assert.Equal(t, 3, len(params))
	assert.Equal(t, "college.edu", params.Get("name"))
	assert.Equal(t, "6", params.Get("page"))
	assert.Equal(t, "20", params.Get("per_page"))
}

func TestParamsForPreviousPage(t *testing.T) {
	resp := network.NewPharosResponse(network.PharosInstitution)
	link := "http://example.com?name=college.edu&page=6&per_page=20"
	resp.Previous = &link
	params := resp.ParamsForPreviousPage()
	assert.Equal(t, 3, len(params))
	assert.Equal(t, "college.edu", params.Get("name"))
	assert.Equal(t, "6", params.Get("page"))
	assert.Equal(t, "20", params.Get("per_page"))
}

func TestInstitution(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(institutionGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.InstitutionGet("college.edu")
	assert.NotNil(t, resp.Institution())
}

func TestInstitutions(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(institutionListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.InstitutionList(nil)
	assert.NotEmpty(t, resp.Institutions())
}

func TestIntellectualObject(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(intellectualObjectGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.IntellectualObjectGet("college.edu/object")
	assert.NotNil(t, resp.IntellectualObject())
}

func TestIntellectualObjects(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(intellectualObjectListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.IntellectualObjectList(nil)
	assert.NotEmpty(t, resp.IntellectualObjects())
}

func TestGenericFile(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(genericFileGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.GenericFileGet("college.edu/object/file.xml")
	assert.NotNil(t, resp.GenericFile())
}

func TestGenericFiles(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(genericFileListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.GenericFileList(nil)
	assert.NotEmpty(t, resp.GenericFiles())
}

func TestPremisEvent(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(premisEventGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.PremisEventGet("000000000000-0000-0000-0000-00000000")
	assert.NotNil(t, resp.PremisEvent())
}

func TestPremisEvents(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(premisEventListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.PremisEventList(nil)
	assert.NotEmpty(t, resp.PremisEvents())
}

func TestWorkItem(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(workItemGetHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.WorkItemGet(1000)
	assert.NotNil(t, resp.WorkItem())
}

func TestWorkItems(t *testing.T) {
	testServer := httptest.NewServer(http.HandlerFunc(workItemListHander))
	defer testServer.Close()
	client, err := network.NewPharosClient(testServer.URL, "v1", "user", "key")
	if err != nil {
		t.Error(err)
		return
	}
	resp := client.WorkItemList(nil)
	assert.NotEmpty(t, resp.WorkItems())
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"runtime"
	"strconv"
	"strings"
)

type TAnswerRuntime struct {
	Memheap    uint64 `json:"memheap"`
	Memidle    uint64 `json:"memidle"`
	Meminuse   uint64 `json:"meminuse"`
	Goroutines int    `json:"goroutines"`
	NextGC     uint64 `json:"nextgc"`
}

type TAnswerStat struct {
	Ip            string     `json:"ip"`
	Traffic       TIpTraffic `json:"stat"`
	Limit         TIpTraffic `json:"limit"`
	OffCountStart int        `json:"offstart"`
	OffCountStop  int        `json:"offstop"`
	SpeedUp       string     `json:"speedup"`
	SpeedDown     string     `json:"speeddown"`
}

type TAnswerLimitAdd struct {
	Ip    string     `json:"ip"`
	Limit TIpTraffic `json:"limit_add"`
}

type TAnswerError struct {
	Error string `json:"error"`
}

func IPV4AddrToInt(addr string) (uint32, error) {
	parts := strings.Split(addr, ".")
	var ip uint32
	part, err := strconv.Atoi(parts[0])
	ip |= uint32(part) << 24
	part, err = strconv.Atoi(parts[1])
	ip |= uint32(part) << 16
	part, err = strconv.Atoi(parts[2])
	ip |= uint32(part) << 8
	part, err = strconv.Atoi(parts[3])
	ip |= uint32(part)
	return ip, err
}

func httpGetRuntime(w http.ResponseWriter, r *http.Request) {
	var vAnswer TAnswerRuntime

	memStats := runtime.MemStats{}
	runtime.ReadMemStats(&memStats)

	vAnswer.Memheap = memStats.HeapSys
	vAnswer.Memidle = memStats.HeapIdle
	vAnswer.Meminuse = memStats.HeapInuse
	vAnswer.Goroutines = runtime.NumGoroutine()
	vAnswer.NextGC = memStats.NextGC

	js, _ := json.Marshal(vAnswer)

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

func httpGetStat(w http.ResponseWriter, r *http.Request) {
	var vAnswer TAnswerStat
	var vError TAnswerError
	var js []byte
	w.Header().Set("Content-Type", "application/json")
	v := r.URL.Query()
	ip_adr := v.Get("ip")
	ip, err := IPV4AddrToInt(ip_adr)
	if err != nil {
		vError.Error = fmt.Sprintf("ip format error %s", ip_adr)
		js, _ = json.Marshal(vError)
	} else {
		response := GetIpInfo(uint32(ip))
		if response.Found {
			vAnswer.Ip = ip_adr
			vAnswer.Limit = response.IpRec.Limit
			vAnswer.OffCountStart = response.IpRec.OffCountStart
			vAnswer.OffCountStop = response.IpRec.OffCountStop
			vAnswer.SpeedUp = response.IpRec.SpeedUp
			vAnswer.SpeedDown = response.IpRec.SpeedDown
			vAnswer.Traffic = response.IpRec.Traffic
			js, _ = json.Marshal(vAnswer)

		} else {
			vError.Error = fmt.Sprintf("%s not found", ip_adr)
			js, _ = json.Marshal(vError)
		}
	}

	w.Write(js)
}

func httpAddLimit(w http.ResponseWriter, r *http.Request) {
	var vAnswer TAnswerLimitAdd
	var vError TAnswerError
	var js []byte
	w.Header().Set("Content-Type", "application/json")
	v := r.URL.Query()
	ip_adr := v.Get("ip")
	ip, err := IPV4AddrToInt(ip_adr)
	if err != nil {
		vError.Error = fmt.Sprintf("ip format error %s", ip_adr)
		js, _ = json.Marshal(vError)
	} else {
		traf, err := strconv.Atoi(v.Get("limit"))
		if err != nil {
			vError.Error = fmt.Sprintf("limit error %s", v.Get("limit"))
			js, _ = json.Marshal(vError)
		} else {
			AddLimitToIp(ip, TIpTraffic(traf))
			vAnswer.Ip = ip_adr
			vAnswer.Limit = TIpTraffic(traf)
			js, _ = json.Marshal(vAnswer)
		}
	}
	w.Write(js)
}

func httpSetLimit(w http.ResponseWriter, r *http.Request) {
	var vAnswer TAnswerStat
	var vError TAnswerError
	var js []byte
	var rec TipRecord
	w.Header().Set("Content-Type", "application/json")
	v := r.URL.Query()
	ip_adr := v.Get("ip")
	IPAddress := net.ParseIP(ip_adr)

	if IPAddress == nil {
		vError.Error = fmt.Sprintf("ip format error %s", ip_adr)
		js, _ = json.Marshal(vError)
	} else {
		traf, err := strconv.Atoi(v.Get("limit"))
		if err != nil {
			vError.Error = fmt.Sprintf("limit error %s", v.Get("limit"))
			js, _ = json.Marshal(vError)
		} else {
			offstart, err := strconv.Atoi(v.Get("offstart"))
			if err != nil {
				vError.Error = fmt.Sprintf("offstart error %s", v.Get("offstart"))
				js, _ = json.Marshal(vError)
			} else {
				offstop, err := strconv.Atoi(v.Get("offstop"))
				if err != nil {
					vError.Error = fmt.Sprintf("offstop error %s", v.Get("offstop"))
					js, _ = json.Marshal(vError)
				} else {
					rec.Limit = TIpTraffic(traf)
					rec.OffCountStart = offstart
					rec.OffCountStop = offstop
					rec.SpeedUp = v.Get("speedup")
					rec.SpeedDown = v.Get("speeddown")
					SetLimitToIp(netIpToInt(IPAddress), rec)
					vAnswer.Ip = ip_adr
					vAnswer.Traffic = rec.Traffic
					vAnswer.Limit = rec.Limit
					vAnswer.OffCountStart = rec.OffCountStart
					vAnswer.OffCountStop = rec.OffCountStop
					vAnswer.SpeedUp = rec.SpeedUp
					vAnswer.SpeedDown = rec.SpeedDown
					js, _ = json.Marshal(vAnswer)
				}
			}
		}
	}
	w.Write(js)
}
<commit_msg>* проверка ip адреса<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"runtime"
	"strconv"
)

type TAnswerRuntime struct {
	Memheap    uint64 `json:"memheap"`
	Memidle    uint64 `json:"memidle"`
	Meminuse   uint64 `json:"meminuse"`
	Goroutines int    `json:"goroutines"`
	NextGC     uint64 `json:"nextgc"`
}

type TAnswerStat struct {
	Ip            string     `json:"ip"`
	Traffic       TIpTraffic `json:"stat"`
	Limit         TIpTraffic `json:"limit"`
	OffCountStart int        `json:"offstart"`
	OffCountStop  int        `json:"offstop"`
	SpeedUp       string     `json:"speedup"`
	SpeedDown     string     `json:"speeddown"`
}

type TAnswerLimitAdd struct {
	Ip    string     `json:"ip"`
	Limit TIpTraffic `json:"limit_add"`
}

type TAnswerError struct {
	Error string `json:"error"`
}

func httpGetRuntime(w http.ResponseWriter, r *http.Request) {
	var vAnswer TAnswerRuntime

	memStats := runtime.MemStats{}
	runtime.ReadMemStats(&memStats)

	vAnswer.Memheap = memStats.HeapSys
	vAnswer.Memidle = memStats.HeapIdle
	vAnswer.Meminuse = memStats.HeapInuse
	vAnswer.Goroutines = runtime.NumGoroutine()
	vAnswer.NextGC = memStats.NextGC

	js, _ := json.Marshal(vAnswer)

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

func httpGetStat(w http.ResponseWriter, r *http.Request) {
	var vAnswer TAnswerStat
	var vError TAnswerError
	var js []byte
	w.Header().Set("Content-Type", "application/json")
	v := r.URL.Query()
	ip_adr := v.Get("ip")
	IPAddress := net.ParseIP(ip_adr)
	if IPAddress == nil {
		vError.Error = fmt.Sprintf("ip format error %s", ip_adr)
		js, _ = json.Marshal(vError)
	} else {
		response := GetIpInfo(netIpToInt(IPAddress))
		if response.Found {
			vAnswer.Ip = ip_adr
			vAnswer.Limit = response.IpRec.Limit
			vAnswer.OffCountStart = response.IpRec.OffCountStart
			vAnswer.OffCountStop = response.IpRec.OffCountStop
			vAnswer.SpeedUp = response.IpRec.SpeedUp
			vAnswer.SpeedDown = response.IpRec.SpeedDown
			vAnswer.Traffic = response.IpRec.Traffic
			js, _ = json.Marshal(vAnswer)

		} else {
			vError.Error = fmt.Sprintf("%s not found", ip_adr)
			js, _ = json.Marshal(vError)
		}
	}

	w.Write(js)
}

func httpAddLimit(w http.ResponseWriter, r *http.Request) {
	var vAnswer TAnswerLimitAdd
	var vError TAnswerError
	var js []byte
	w.Header().Set("Content-Type", "application/json")
	v := r.URL.Query()
	ip_adr := v.Get("ip")
	IPAddress := net.ParseIP(ip_adr)
	if IPAddress == nil {
		vError.Error = fmt.Sprintf("ip format error %s", ip_adr)
		js, _ = json.Marshal(vError)
	} else {
		traf, err := strconv.Atoi(v.Get("limit"))
		if err != nil {
			vError.Error = fmt.Sprintf("limit error %s", v.Get("limit"))
			js, _ = json.Marshal(vError)
		} else {
			AddLimitToIp(netIpToInt(IPAddress), TIpTraffic(traf))
			vAnswer.Ip = ip_adr
			vAnswer.Limit = TIpTraffic(traf)
			js, _ = json.Marshal(vAnswer)
		}
	}
	w.Write(js)
}

func httpSetLimit(w http.ResponseWriter, r *http.Request) {
	var vAnswer TAnswerStat
	var vError TAnswerError
	var js []byte
	var rec TipRecord
	w.Header().Set("Content-Type", "application/json")
	v := r.URL.Query()
	ip_adr := v.Get("ip")
	IPAddress := net.ParseIP(ip_adr)

	if IPAddress == nil {
		vError.Error = fmt.Sprintf("ip format error %s", ip_adr)
		js, _ = json.Marshal(vError)
	} else {
		traf, err := strconv.Atoi(v.Get("limit"))
		if err != nil {
			vError.Error = fmt.Sprintf("limit error %s", v.Get("limit"))
			js, _ = json.Marshal(vError)
		} else {
			offstart, err := strconv.Atoi(v.Get("offstart"))
			if err != nil {
				vError.Error = fmt.Sprintf("offstart error %s", v.Get("offstart"))
				js, _ = json.Marshal(vError)
			} else {
				offstop, err := strconv.Atoi(v.Get("offstop"))
				if err != nil {
					vError.Error = fmt.Sprintf("offstop error %s", v.Get("offstop"))
					js, _ = json.Marshal(vError)
				} else {
					rec.Limit = TIpTraffic(traf)
					rec.OffCountStart = offstart
					rec.OffCountStop = offstop
					rec.SpeedUp = v.Get("speedup")
					rec.SpeedDown = v.Get("speeddown")
					SetLimitToIp(netIpToInt(IPAddress), rec)
					vAnswer.Ip = ip_adr
					vAnswer.Traffic = rec.Traffic
					vAnswer.Limit = rec.Limit
					vAnswer.OffCountStart = rec.OffCountStart
					vAnswer.OffCountStop = rec.OffCountStop
					vAnswer.SpeedUp = rec.SpeedUp
					vAnswer.SpeedDown = rec.SpeedDown
					js, _ = json.Marshal(vAnswer)
				}
			}
		}
	}
	w.Write(js)
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package json

import (
	"github.com/uber/jaeger/model"

	"github.com/uber/jaeger/model/json"
)

// FromDomain converts model.Trace into json.Trace format.
// It assumes that the domain model is valid, namely that all enums
// have valid values, so that it does not need to check for errors.
func FromDomain(trace *model.Trace) *json.Trace {
	return fromDomain{}.fromDomain(trace)
}

type fromDomain struct{}

func (fd fromDomain) fromDomain(trace *model.Trace) *json.Trace {
	jSpans := make([]json.Span, len(trace.Spans))
	processes := &processHashtable{}
	var traceID json.TraceID
	for i, span := range trace.Spans {
		if i == 0 {
			traceID = json.TraceID(span.TraceID.String())
		}
		processID := json.ProcessID(processes.getKey(span.Process))
		jSpans[i] = fd.convertSpan(span, processID)
	}
	jTrace := &json.Trace{
		TraceID:   traceID,
		Spans:     jSpans,
		Processes: fd.convertProcesses(processes.getMapping()),
		Warnings:  trace.Warnings,
	}
	return jTrace
}

func (fd fromDomain) convertSpan(span *model.Span, processID json.ProcessID) json.Span {
	return json.Span{
		TraceID:       json.TraceID(span.TraceID.String()),
		SpanID:        json.SpanID(span.SpanID.String()),
		Flags:         span.Flags,
		OperationName: span.OperationName,
		References:    fd.convertReferences(span),
		StartTime:     span.StartTime,
		Duration:      span.Duration,
		Tags:          fd.convertKeyValues(span.Tags),
		Logs:          fd.convertLogs(span.Logs),
		ProcessID:     processID,
		Warnings:      span.Warnings,
	}
}

func (fd fromDomain) convertReferences(span *model.Span) []json.Reference {
	length := len(span.References)
	if span.ParentSpanID != 0 {
		length++
	}
	out := make([]json.Reference, 0, length)
	if span.ParentSpanID != 0 {
		out = append(out, json.Reference{
			RefType: json.ChildOf,
			TraceID: json.TraceID(span.TraceID.String()),
			SpanID:  json.SpanID(span.ParentSpanID.String()),
		})
	}
	for _, ref := range span.References {
		out = append(out, json.Reference{
			RefType: fd.convertRefType(ref.RefType),
			TraceID: json.TraceID(ref.TraceID.String()),
			SpanID:  json.SpanID(ref.SpanID.String()),
		})
	}
	return out
}

func (fd fromDomain) convertRefType(refType model.SpanRefType) json.ReferenceType {
	if refType == model.FollowsFrom {
		return json.FollowsFrom
	}
	return json.ChildOf
}

func (fd fromDomain) convertKeyValues(keyValues model.KeyValues) []json.KeyValue {
	out := make([]json.KeyValue, len(keyValues))
	for i, kv := range keyValues {
		var value interface{}
		switch kv.VType {
		case model.StringType:
			value = kv.VStr
		case model.BoolType:
			value = kv.Bool()
		case model.Int64Type:
			value = kv.Int64()
		case model.Float64Type:
			value = kv.Float64()
		case model.BinaryType:
			value = kv.Binary()
		}
		out[i] = json.KeyValue{
			Key:   kv.Key,
			Type:  json.ValueType(kv.VType.String()),
			Value: value,
		}
	}
	return out
}

func (fd fromDomain) convertLogs(logs []model.Log) []json.Log {
	out := make([]json.Log, len(logs))
	for i, log := range logs {
		out[i] = json.Log{
			Timestamp: log.Timestamp,
			Fields:    fd.convertKeyValues(log.Fields),
		}
	}
	return out
}

func (fd fromDomain) convertProcesses(processes map[string]*model.Process) map[json.ProcessID]json.Process {
	out := make(map[json.ProcessID]json.Process)
	for key, process := range processes {
		out[json.ProcessID(key)] = fd.convertProcess(process)
	}
	return out
}

func (fd fromDomain) convertProcess(process *model.Process) json.Process {
	return json.Process{
		ServiceName: process.ServiceName,
		Tags:        fd.convertKeyValues(process.Tags),
	}
}

// DependenciesFromDomain converts []model.DependencyLink into []json.DependencyLink format.
// It assumes that the domain model is valid, namely that all enums
// have valid values, so that it does not need to check for errors.
func DependenciesFromDomain(dependencyLinks []model.DependencyLink) []json.DependencyLink {
	retMe := make([]json.DependencyLink, 0, len(dependencyLinks))
	for _, dependencyLink := range dependencyLinks {
		retMe = append(
			retMe,
			json.DependencyLink{
				Parent:    dependencyLink.Parent,
				Child:     dependencyLink.Child,
				CallCount: dependencyLink.CallCount,
			},
		)
	}
	return retMe
}
<commit_msg>removing a comment that does not apply to its relative function (#32)<commit_after>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package json

import (
	"github.com/uber/jaeger/model"

	"github.com/uber/jaeger/model/json"
)

// FromDomain converts model.Trace into json.Trace format.
// It assumes that the domain model is valid, namely that all enums
// have valid values, so that it does not need to check for errors.
func FromDomain(trace *model.Trace) *json.Trace {
	return fromDomain{}.fromDomain(trace)
}

type fromDomain struct{}

func (fd fromDomain) fromDomain(trace *model.Trace) *json.Trace {
	jSpans := make([]json.Span, len(trace.Spans))
	processes := &processHashtable{}
	var traceID json.TraceID
	for i, span := range trace.Spans {
		if i == 0 {
			traceID = json.TraceID(span.TraceID.String())
		}
		processID := json.ProcessID(processes.getKey(span.Process))
		jSpans[i] = fd.convertSpan(span, processID)
	}
	jTrace := &json.Trace{
		TraceID:   traceID,
		Spans:     jSpans,
		Processes: fd.convertProcesses(processes.getMapping()),
		Warnings:  trace.Warnings,
	}
	return jTrace
}

func (fd fromDomain) convertSpan(span *model.Span, processID json.ProcessID) json.Span {
	return json.Span{
		TraceID:       json.TraceID(span.TraceID.String()),
		SpanID:        json.SpanID(span.SpanID.String()),
		Flags:         span.Flags,
		OperationName: span.OperationName,
		References:    fd.convertReferences(span),
		StartTime:     span.StartTime,
		Duration:      span.Duration,
		Tags:          fd.convertKeyValues(span.Tags),
		Logs:          fd.convertLogs(span.Logs),
		ProcessID:     processID,
		Warnings:      span.Warnings,
	}
}

func (fd fromDomain) convertReferences(span *model.Span) []json.Reference {
	length := len(span.References)
	if span.ParentSpanID != 0 {
		length++
	}
	out := make([]json.Reference, 0, length)
	if span.ParentSpanID != 0 {
		out = append(out, json.Reference{
			RefType: json.ChildOf,
			TraceID: json.TraceID(span.TraceID.String()),
			SpanID:  json.SpanID(span.ParentSpanID.String()),
		})
	}
	for _, ref := range span.References {
		out = append(out, json.Reference{
			RefType: fd.convertRefType(ref.RefType),
			TraceID: json.TraceID(ref.TraceID.String()),
			SpanID:  json.SpanID(ref.SpanID.String()),
		})
	}
	return out
}

func (fd fromDomain) convertRefType(refType model.SpanRefType) json.ReferenceType {
	if refType == model.FollowsFrom {
		return json.FollowsFrom
	}
	return json.ChildOf
}

func (fd fromDomain) convertKeyValues(keyValues model.KeyValues) []json.KeyValue {
	out := make([]json.KeyValue, len(keyValues))
	for i, kv := range keyValues {
		var value interface{}
		switch kv.VType {
		case model.StringType:
			value = kv.VStr
		case model.BoolType:
			value = kv.Bool()
		case model.Int64Type:
			value = kv.Int64()
		case model.Float64Type:
			value = kv.Float64()
		case model.BinaryType:
			value = kv.Binary()
		}
		out[i] = json.KeyValue{
			Key:   kv.Key,
			Type:  json.ValueType(kv.VType.String()),
			Value: value,
		}
	}
	return out
}

func (fd fromDomain) convertLogs(logs []model.Log) []json.Log {
	out := make([]json.Log, len(logs))
	for i, log := range logs {
		out[i] = json.Log{
			Timestamp: log.Timestamp,
			Fields:    fd.convertKeyValues(log.Fields),
		}
	}
	return out
}

func (fd fromDomain) convertProcesses(processes map[string]*model.Process) map[json.ProcessID]json.Process {
	out := make(map[json.ProcessID]json.Process)
	for key, process := range processes {
		out[json.ProcessID(key)] = fd.convertProcess(process)
	}
	return out
}

func (fd fromDomain) convertProcess(process *model.Process) json.Process {
	return json.Process{
		ServiceName: process.ServiceName,
		Tags:        fd.convertKeyValues(process.Tags),
	}
}

// DependenciesFromDomain converts []model.DependencyLink into []json.DependencyLink format.
func DependenciesFromDomain(dependencyLinks []model.DependencyLink) []json.DependencyLink {
	retMe := make([]json.DependencyLink, 0, len(dependencyLinks))
	for _, dependencyLink := range dependencyLinks {
		retMe = append(
			retMe,
			json.DependencyLink{
				Parent:    dependencyLink.Parent,
				Child:     dependencyLink.Child,
				CallCount: dependencyLink.CallCount,
			},
		)
	}
	return retMe
}
<|endoftext|>


<commit_before>package user

import (
	"net/http"
	"xorkevin.dev/governor"
	"xorkevin.dev/governor/service/user/model"
	"xorkevin.dev/governor/util/rank"
)

type (
	// ResUserGetPublic holds the public fields of a user
	ResUserGetPublic struct {
		Userid       string   `json:"userid"`
		Username     string   `json:"username"`
		AuthTags     []string `json:"auth_tags"`
		FirstName    string   `json:"first_name"`
		LastName     string   `json:"last_name"`
		CreationTime int64    `json:"creation_time"`
	}
)

func getUserPublicFields(m *usermodel.Model, roles []string) *ResUserGetPublic {
	return &ResUserGetPublic{
		Userid:       m.Userid,
		Username:     m.Username,
		AuthTags:     roles,
		FirstName:    m.FirstName,
		LastName:     m.LastName,
		CreationTime: m.CreationTime,
	}
}

type (
	// ResUserGet holds all the fields of a user
	ResUserGet struct {
		ResUserGetPublic
		Email string `json:"email"`
	}
)

func getUserFields(m *usermodel.Model, roles []string) *ResUserGet {
	return &ResUserGet{
		ResUserGetPublic: *getUserPublicFields(m, roles),
		Email:            m.Email,
	}
}

// GetByIDPublic gets and returns the public fields of the user
func (s *service) GetByIDPublic(userid string) (*ResUserGetPublic, error) {
	m, err := s.users.GetByID(userid)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(userid)
	if err != nil {
		return nil, err
	}
	return getUserPublicFields(m, roles.ToSlice()), nil
}

// GetByID gets and returns all fields of the user
func (s *service) GetByID(userid string) (*ResUserGet, error) {
	m, err := s.users.GetByID(userid)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(userid)
	if err != nil {
		return nil, err
	}
	return getUserFields(m, roles.ToSlice()), nil
}

// GetByUsernamePublic gets and returns the public fields of the user
func (s *service) GetByUsernamePublic(username string) (*ResUserGetPublic, error) {
	m, err := s.users.GetByUsername(username)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(m.Userid)
	if err != nil {
		return nil, err
	}
	return getUserPublicFields(m, roles.ToSlice()), nil
}

// GetByUsername gets and returns all fields of the user
func (s *service) GetByUsername(username string) (*ResUserGet, error) {
	m, err := s.users.GetByUsername(username)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(m.Userid)
	if err != nil {
		return nil, err
	}
	return getUserFields(m, roles.ToSlice()), nil
}

// GetByEmail gets and returns all fields of the user
func (s *service) GetByEmail(email string) (*ResUserGet, error) {
	m, err := s.users.GetByEmail(email)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(m.Userid)
	if err != nil {
		return nil, err
	}
	return getUserFields(m, roles.ToSlice()), nil
}

type (
	resUserRoles struct {
		Roles []string `json:"roles"`
	}
)

// GetUserRoles returns a list of user roles
func (s *service) GetUserRoles(userid string, amount, offset int) (*resUserRoles, error) {
	roles, err := s.roles.GetRoles(userid, amount, offset)
	if err != nil {
		return nil, err
	}
	return &resUserRoles{
		Roles: roles.ToSlice(),
	}, nil
}

// GetUserRolesIntersect returns the intersected roles of a user
func (s *service) GetUserRolesIntersect(userid string, roleset rank.Rank) (*resUserRoles, error) {
	roles, err := s.roles.IntersectRoles(userid, roleset)
	if err != nil {
		return nil, err
	}
	return &resUserRoles{
		Roles: roles.ToSlice(),
	}, nil
}

type (
	resUserInfo struct {
		Userid   string `json:"userid"`
		Username string `json:"username"`
		Email    string `json:"email"`
	}

	resUserInfoList struct {
		Users []resUserInfo `json:"users"`
	}
)

// GetInfoAll gets and returns info for all users
func (s *service) GetInfoAll(amount int, offset int) (*resUserInfoList, error) {
	infoSlice, err := s.users.GetGroup(amount, offset)
	if err != nil {
		return nil, err
	}

	info := make([]resUserInfo, 0, len(infoSlice))
	for _, i := range infoSlice {
		info = append(info, resUserInfo{
			Userid:   i.Userid,
			Username: i.Username,
			Email:    i.Email,
		})
	}

	return &resUserInfoList{
		Users: info,
	}, nil
}

type (
	resUserInfoPublic struct {
		Userid    string `json:"userid"`
		Username  string `json:"username"`
		FirstName string `json:"first_name"`
		LastName  string `json:"last_name"`
	}

	resUserInfoListPublic struct {
		Users []resUserInfoPublic `json:"users"`
	}
)

// GetInfoBulkPublic gets and returns public info for users
func (s *service) GetInfoBulkPublic(userids []string) (*resUserInfoListPublic, error) {
	infoSlice, err := s.users.GetBulk(userids)
	if err != nil {
		return nil, err
	}

	info := make([]resUserInfoPublic, 0, len(infoSlice))
	for _, i := range infoSlice {
		info = append(info, resUserInfoPublic{
			Userid:    i.Userid,
			Username:  i.Username,
			FirstName: i.FirstName,
			LastName:  i.LastName,
		})
	}

	return &resUserInfoListPublic{
		Users: info,
	}, nil
}

type (
	resUserList struct {
		Users []string `json:"users"`
	}
)

// GetIDsByRole retrieves a list of user ids by role
func (s *service) GetIDsByRole(role string, amount int, offset int) (*resUserList, error) {
	userids, err := s.roles.GetByRole(role, amount, offset)
	if err != nil {
		return nil, err
	}
	return &resUserList{
		Users: userids,
	}, nil
}
<commit_msg>Remove last usage of auth_tags<commit_after>package user

import (
	"net/http"
	"xorkevin.dev/governor"
	"xorkevin.dev/governor/service/user/model"
	"xorkevin.dev/governor/util/rank"
)

type (
	// ResUserGetPublic holds the public fields of a user
	ResUserGetPublic struct {
		Userid       string   `json:"userid"`
		Username     string   `json:"username"`
		Roles        []string `json:"roles"`
		FirstName    string   `json:"first_name"`
		LastName     string   `json:"last_name"`
		CreationTime int64    `json:"creation_time"`
	}
)

func getUserPublicFields(m *usermodel.Model, roles []string) *ResUserGetPublic {
	return &ResUserGetPublic{
		Userid:       m.Userid,
		Username:     m.Username,
		Roles:        roles,
		FirstName:    m.FirstName,
		LastName:     m.LastName,
		CreationTime: m.CreationTime,
	}
}

type (
	// ResUserGet holds all the fields of a user
	ResUserGet struct {
		ResUserGetPublic
		Email string `json:"email"`
	}
)

func getUserFields(m *usermodel.Model, roles []string) *ResUserGet {
	return &ResUserGet{
		ResUserGetPublic: *getUserPublicFields(m, roles),
		Email:            m.Email,
	}
}

// GetByIDPublic gets and returns the public fields of the user
func (s *service) GetByIDPublic(userid string) (*ResUserGetPublic, error) {
	m, err := s.users.GetByID(userid)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(userid)
	if err != nil {
		return nil, err
	}
	return getUserPublicFields(m, roles.ToSlice()), nil
}

// GetByID gets and returns all fields of the user
func (s *service) GetByID(userid string) (*ResUserGet, error) {
	m, err := s.users.GetByID(userid)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(userid)
	if err != nil {
		return nil, err
	}
	return getUserFields(m, roles.ToSlice()), nil
}

// GetByUsernamePublic gets and returns the public fields of the user
func (s *service) GetByUsernamePublic(username string) (*ResUserGetPublic, error) {
	m, err := s.users.GetByUsername(username)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(m.Userid)
	if err != nil {
		return nil, err
	}
	return getUserPublicFields(m, roles.ToSlice()), nil
}

// GetByUsername gets and returns all fields of the user
func (s *service) GetByUsername(username string) (*ResUserGet, error) {
	m, err := s.users.GetByUsername(username)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(m.Userid)
	if err != nil {
		return nil, err
	}
	return getUserFields(m, roles.ToSlice()), nil
}

// GetByEmail gets and returns all fields of the user
func (s *service) GetByEmail(email string) (*ResUserGet, error) {
	m, err := s.users.GetByEmail(email)
	if err != nil {
		if governor.ErrorStatus(err) == http.StatusNotFound {
			return nil, governor.NewErrorUser("", 0, err)
		}
		return nil, err
	}
	roles, err := s.roles.GetRoleSummary(m.Userid)
	if err != nil {
		return nil, err
	}
	return getUserFields(m, roles.ToSlice()), nil
}

type (
	resUserRoles struct {
		Roles []string `json:"roles"`
	}
)

// GetUserRoles returns a list of user roles
func (s *service) GetUserRoles(userid string, amount, offset int) (*resUserRoles, error) {
	roles, err := s.roles.GetRoles(userid, amount, offset)
	if err != nil {
		return nil, err
	}
	return &resUserRoles{
		Roles: roles.ToSlice(),
	}, nil
}

// GetUserRolesIntersect returns the intersected roles of a user
func (s *service) GetUserRolesIntersect(userid string, roleset rank.Rank) (*resUserRoles, error) {
	roles, err := s.roles.IntersectRoles(userid, roleset)
	if err != nil {
		return nil, err
	}
	return &resUserRoles{
		Roles: roles.ToSlice(),
	}, nil
}

type (
	resUserInfo struct {
		Userid   string `json:"userid"`
		Username string `json:"username"`
		Email    string `json:"email"`
	}

	resUserInfoList struct {
		Users []resUserInfo `json:"users"`
	}
)

// GetInfoAll gets and returns info for all users
func (s *service) GetInfoAll(amount int, offset int) (*resUserInfoList, error) {
	infoSlice, err := s.users.GetGroup(amount, offset)
	if err != nil {
		return nil, err
	}

	info := make([]resUserInfo, 0, len(infoSlice))
	for _, i := range infoSlice {
		info = append(info, resUserInfo{
			Userid:   i.Userid,
			Username: i.Username,
			Email:    i.Email,
		})
	}

	return &resUserInfoList{
		Users: info,
	}, nil
}

type (
	resUserInfoPublic struct {
		Userid    string `json:"userid"`
		Username  string `json:"username"`
		FirstName string `json:"first_name"`
		LastName  string `json:"last_name"`
	}

	resUserInfoListPublic struct {
		Users []resUserInfoPublic `json:"users"`
	}
)

// GetInfoBulkPublic gets and returns public info for users
func (s *service) GetInfoBulkPublic(userids []string) (*resUserInfoListPublic, error) {
	infoSlice, err := s.users.GetBulk(userids)
	if err != nil {
		return nil, err
	}

	info := make([]resUserInfoPublic, 0, len(infoSlice))
	for _, i := range infoSlice {
		info = append(info, resUserInfoPublic{
			Userid:    i.Userid,
			Username:  i.Username,
			FirstName: i.FirstName,
			LastName:  i.LastName,
		})
	}

	return &resUserInfoListPublic{
		Users: info,
	}, nil
}

type (
	resUserList struct {
		Users []string `json:"users"`
	}
)

// GetIDsByRole retrieves a list of user ids by role
func (s *service) GetIDsByRole(role string, amount int, offset int) (*resUserList, error) {
	userids, err := s.roles.GetByRole(role, amount, offset)
	if err != nil {
		return nil, err
	}
	return &resUserList{
		Users: userids,
	}, nil
}
<|endoftext|>


<commit_before>package controllers

import (
    "encoding/json"
    "github.com/orc/db"
    "github.com/orc/utils"
    "io/ioutil"
    "net/http"
    "strconv"
    "time"
    "fmt"
)

func (c *BaseController) Index() *IndexController {
    return new(IndexController)
}

type IndexController struct {
    Controller
}

func (this *IndexController) Index() {
    this.Response.Header().Set("Content-Type", "text/html; charset=utf-8")
    model := this.GetModel("events")
    this.Render([]string{"mvc/views/login.html", "mvc/views/index.html"}, "index", map[string]interface{}{"events": Model{
        ColModel:  model.GetColModel(),
        TableName: model.GetTableName(),
        ColNames:  model.GetColNames(),
        Caption:   model.GetCaption()}})
}

func (this *IndexController) Init(runTest bool) {
    if !runTest {
        return
    }

    for i, v := range db.Tables {
        db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s CASCADE;", v), nil)
        db.Exec(fmt.Sprintf("DROP SEQUENCE IF EXISTS %s_id_seq;", v), nil)
        db.QueryCreateTable_(this.GetModel(db.Tables[i]))
    }
}

func (this *IndexController) LoadContestsFromCats() {
    url := "http://imcs.dvfu.ru/cats/main.pl?f=contests;filter=unfinished;json=1"
    result, err := http.Get(url)
    if utils.HandleErr("[loadContestsFromCats] http.Get(url): ", err, this.Response) {
        return
    }
    defer result.Body.Close()

    body, err := ioutil.ReadAll(result.Body)
    if utils.HandleErr("[loadContestsFromCats] ioutil.ReadAll(data.Body): ", err, this.Response) {
        return
    }

    var data map[string]interface{}
    err = json.Unmarshal(body, &data)
    if utils.HandleErr("[loadContestsFromCats] json.Unmarshal(body, &data): ", err, this.Response) {
        return
    }

    for _, v := range data["contests"].([]interface{}) {
        contest := v.(map[string]interface{})
        event := this.GetModel("events")
        time_, err := time.Parse("20060102T150405", contest["start_time"].(string))
        if utils.HandleErr("[loadContestsFromCats] time.Parse: ", err, this.Response) {
            continue
        }
        start_date, err := time.Parse("02.01.2006 15:04", contest["start_date"].(string))
        if utils.HandleErr("[loadContestsFromCats] time.Parse: ", err, this.Response) {
            continue
        }
        finish_date, err := time.Parse("02.01.2006 15:04", contest["finish_date"].(string))
        if utils.HandleErr("[loadContestsFromCats] time.Parse: ", err, this.Response) {
            continue
        }
        event.LoadModelData(map[string]interface{}{
            "name":        contest["name"],
            "date_start":  start_date.Format("2006-01-02 15:04:05"),
            "date_finish": finish_date.Format("2006-01-02 15:04:05"),
            "time":        time_.Format("15:04:05"),
            "url":         "http://imcs.dvfu.ru/cats/main.pl?f=contests;cid="+strconv.Itoa(int(contest["id"].(float64))),
        })
        err = db.QueryInsert_(event, "").Scan()
    }

}

func (this *IndexController) CreateRegistrationEvent() {

    var event_id int
    events := this.GetModel("events")
    events.LoadModelData(map[string]interface{}{"name": "Регистрация для входа в систему", "date_start": "2006-01-02", "date_finish": "2006-01-02", "time": "00:00:00"})
    db.QueryInsert_(events, "RETURNING id").Scan(&event_id)

    var form_id1 int
    forms := this.GetModel("forms")
    forms.LoadModelData(map[string]interface{}{"name": "Регистрационные данные"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id1)

    eventsForms := this.GetModel("events_forms")
    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id1, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    var param_text_type_id int
    paramTypes := this.GetModel("param_types")
    paramTypes.LoadModelData(map[string]interface{}{"name": "text"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_text_type_id)

    var param_pass_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "password"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_pass_type_id)

    params := this.GetModel("params")
    params.LoadModelData(map[string]interface{}{
        "name":          "Логин",
        "form_id":       form_id1,
        "param_type_id": param_text_type_id,
        "identifier":    2})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Пароль",
        "form_id":       form_id1,
        "param_type_id": param_pass_type_id,
        "identifier":    3})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Подтвердите пароль",
        "form_id":       form_id1,
        "param_type_id": param_pass_type_id,
        "identifier":    4})
    db.QueryInsert_(params, "").Scan()

    var param_email_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "email"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_email_type_id)

    params.LoadModelData(map[string]interface{}{
        "name":          "E-mail",
        "form_id":       form_id1,
        "param_type_id": param_text_type_id,
        "identifier":    5})
    db.QueryInsert_(params, "").Scan()

    var form_id3 int
    forms.LoadModelData(map[string]interface{}{"name": "Общие сведения"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id3)

    params.LoadModelData(map[string]interface{}{
        "name":          "Фамилия",
        "form_id":       form_id3,
        "param_type_id": param_text_type_id,
        "identifier":    6})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Имя",
        "form_id":       form_id3,
        "param_type_id": param_text_type_id,
        "identifier":    7})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Отчество",
        "form_id":       form_id3,
        "param_type_id": param_text_type_id,
        "identifier":    8})
    db.QueryInsert_(params, "").Scan()

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id3, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    /* Турнир юных программистов */

    events.LoadModelData(map[string]interface{}{
        "name": "Турнир юных программистов",
        "date_start": "2015-04-25",
        "date_finish": "2015-04-25",
        "time": "10:00:00",
        "url": "http://imcs.dvfu.ru/cats/main.pl?f=problems;cid=990998"})
    db.QueryInsert_(events, "RETURNING id").Scan(&event_id)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id3, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    var form_id4 int
    forms.LoadModelData(map[string]interface{}{"name": "Домашний адрес и телефоны"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id4)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id4, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    var param_region_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "region"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_region_type_id)

    var param_city_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "city"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_city_type_id)

    var param_street_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "street"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_street_type_id)

    var param_building_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "building"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_building_type_id)

    var param_phon_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "phon"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_phon_type_id)

    params.LoadModelData(map[string]interface{}{
        "name":          "Регион",
        "form_id":       form_id4,
        "param_type_id": param_region_type_id,
        "identifier":    9})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Город",
        "form_id":       form_id4,
        "param_type_id": param_city_type_id,
        "identifier":    10})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Улица",
        "form_id":       form_id4,
        "param_type_id": param_street_type_id,
        "identifier":    11})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Дом",
        "form_id":       form_id4,
        "param_type_id": param_building_type_id,
        "identifier":    12})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Контактный телефон",
        "form_id":       form_id4,
        "param_type_id": param_phon_type_id,
        "identifier":    13})
    db.QueryInsert_(params, "").Scan()

    var form_id5 int
    forms.LoadModelData(map[string]interface{}{"name": "Образование"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id5)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id5, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Учебное заведение",
        "form_id":       form_id5,
        "param_type_id": param_text_type_id,
        "identifier":    14})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Класс",
        "form_id":       form_id5,
        "param_type_id": param_text_type_id,
        "identifier":    15})
    db.QueryInsert_(params, "").Scan()

    var form_id6 int
    forms.LoadModelData(map[string]interface{}{"name": "Участие в мероприятии"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id6)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id6, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Тип участия (очное/дистанционное)",
        "form_id":       form_id6,
        "param_type_id": param_text_type_id,
        "identifier":    16})
    db.QueryInsert_(params, "").Scan()
}
<commit_msg>correct contest: add 'квартира' and 'Данные о руководителе'<commit_after>package controllers

import (
    "encoding/json"
    "github.com/orc/db"
    "github.com/orc/utils"
    "io/ioutil"
    "net/http"
    "strconv"
    "time"
    "fmt"
)

func (c *BaseController) Index() *IndexController {
    return new(IndexController)
}

type IndexController struct {
    Controller
}

func (this *IndexController) Index() {
    this.Response.Header().Set("Content-Type", "text/html; charset=utf-8")
    model := this.GetModel("events")
    this.Render([]string{"mvc/views/login.html", "mvc/views/index.html"}, "index", map[string]interface{}{"events": Model{
        ColModel:  model.GetColModel(),
        TableName: model.GetTableName(),
        ColNames:  model.GetColNames(),
        Caption:   model.GetCaption()}})
}

func (this *IndexController) Init(runTest bool) {
    if !runTest {
        return
    }

    for i, v := range db.Tables {
        db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s CASCADE;", v), nil)
        db.Exec(fmt.Sprintf("DROP SEQUENCE IF EXISTS %s_id_seq;", v), nil)
        db.QueryCreateTable_(this.GetModel(db.Tables[i]))
    }
}

func (this *IndexController) LoadContestsFromCats() {
    url := "http://imcs.dvfu.ru/cats/main.pl?f=contests;filter=unfinished;json=1"
    result, err := http.Get(url)
    if utils.HandleErr("[loadContestsFromCats] http.Get(url): ", err, this.Response) {
        return
    }
    defer result.Body.Close()

    body, err := ioutil.ReadAll(result.Body)
    if utils.HandleErr("[loadContestsFromCats] ioutil.ReadAll(data.Body): ", err, this.Response) {
        return
    }

    var data map[string]interface{}
    err = json.Unmarshal(body, &data)
    if utils.HandleErr("[loadContestsFromCats] json.Unmarshal(body, &data): ", err, this.Response) {
        return
    }

    for _, v := range data["contests"].([]interface{}) {
        contest := v.(map[string]interface{})
        event := this.GetModel("events")
        time_, err := time.Parse("20060102T150405", contest["start_time"].(string))
        if utils.HandleErr("[loadContestsFromCats] time.Parse: ", err, this.Response) {
            continue
        }
        start_date, err := time.Parse("02.01.2006 15:04", contest["start_date"].(string))
        if utils.HandleErr("[loadContestsFromCats] time.Parse: ", err, this.Response) {
            continue
        }
        finish_date, err := time.Parse("02.01.2006 15:04", contest["finish_date"].(string))
        if utils.HandleErr("[loadContestsFromCats] time.Parse: ", err, this.Response) {
            continue
        }
        event.LoadModelData(map[string]interface{}{
            "name":        contest["name"],
            "date_start":  start_date.Format("2006-01-02 15:04:05"),
            "date_finish": finish_date.Format("2006-01-02 15:04:05"),
            "time":        time_.Format("15:04:05"),
            "url":         "http://imcs.dvfu.ru/cats/main.pl?f=contests;cid="+strconv.Itoa(int(contest["id"].(float64))),
        })
        err = db.QueryInsert_(event, "").Scan()
    }

}

func (this *IndexController) CreateRegistrationEvent() {

    var event_id int
    events := this.GetModel("events")
    events.LoadModelData(map[string]interface{}{"name": "Регистрация для входа в систему", "date_start": "2006-01-02", "date_finish": "2006-01-02", "time": "00:00:00"})
    db.QueryInsert_(events, "RETURNING id").Scan(&event_id)

    var form_id1 int
    forms := this.GetModel("forms")
    forms.LoadModelData(map[string]interface{}{"name": "Регистрационные данные"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id1)

    eventsForms := this.GetModel("events_forms")
    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id1, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    var param_text_type_id int
    paramTypes := this.GetModel("param_types")
    paramTypes.LoadModelData(map[string]interface{}{"name": "text"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_text_type_id)

    var param_pass_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "password"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_pass_type_id)

    params := this.GetModel("params")
    params.LoadModelData(map[string]interface{}{
        "name":          "Логин",
        "form_id":       form_id1,
        "param_type_id": param_text_type_id,
        "identifier":    2})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Пароль",
        "form_id":       form_id1,
        "param_type_id": param_pass_type_id,
        "identifier":    3})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Подтвердите пароль",
        "form_id":       form_id1,
        "param_type_id": param_pass_type_id,
        "identifier":    4})
    db.QueryInsert_(params, "").Scan()

    var param_email_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "email"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_email_type_id)

    params.LoadModelData(map[string]interface{}{
        "name":          "E-mail",
        "form_id":       form_id1,
        "param_type_id": param_text_type_id,
        "identifier":    5})
    db.QueryInsert_(params, "").Scan()

    var form_id3 int
    forms.LoadModelData(map[string]interface{}{"name": "Общие сведения"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id3)

    params.LoadModelData(map[string]interface{}{
        "name":          "Фамилия",
        "form_id":       form_id3,
        "param_type_id": param_text_type_id,
        "identifier":    6})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Имя",
        "form_id":       form_id3,
        "param_type_id": param_text_type_id,
        "identifier":    7})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Отчество",
        "form_id":       form_id3,
        "param_type_id": param_text_type_id,
        "identifier":    8})
    db.QueryInsert_(params, "").Scan()

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id3, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    /* Турнир юных программистов */

    events.LoadModelData(map[string]interface{}{
        "name": "Турнир юных программистов",
        "date_start": "2015-04-25",
        "date_finish": "2015-04-25",
        "time": "10:00:00",
        "url": "http://imcs.dvfu.ru/cats/main.pl?f=problems;cid=990998"})
    db.QueryInsert_(events, "RETURNING id").Scan(&event_id)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id3, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    var form_id4 int
    forms.LoadModelData(map[string]interface{}{"name": "Домашний адрес и телефоны"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id4)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id4, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    var param_region_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "region"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_region_type_id)

    var param_city_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "city"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_city_type_id)

    var param_street_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "street"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_street_type_id)

    var param_building_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "building"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_building_type_id)

    var param_phon_type_id int
    paramTypes.LoadModelData(map[string]interface{}{"name": "phon"})
    db.QueryInsert_(paramTypes, "RETURNING id").Scan(&param_phon_type_id)

    params.LoadModelData(map[string]interface{}{
        "name":          "Регион",
        "form_id":       form_id4,
        "param_type_id": param_region_type_id,
        "identifier":    9})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Город",
        "form_id":       form_id4,
        "param_type_id": param_city_type_id,
        "identifier":    10})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Улица",
        "form_id":       form_id4,
        "param_type_id": param_street_type_id,
        "identifier":    11})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Дом",
        "form_id":       form_id4,
        "param_type_id": param_building_type_id,
        "identifier":    12})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Квартира",
        "form_id":       form_id4,
        "param_type_id": param_building_type_id,
        "identifier":    13})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Контактный телефон",
        "form_id":       form_id4,
        "param_type_id": param_phon_type_id,
        "identifier":    14})
    db.QueryInsert_(params, "").Scan()

    var form_id5 int
    forms.LoadModelData(map[string]interface{}{"name": "Образование"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id5)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id5, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Учебное заведение",
        "form_id":       form_id5,
        "param_type_id": param_text_type_id,
        "identifier":    15})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Класс",
        "form_id":       form_id5,
        "param_type_id": param_text_type_id,
        "identifier":    16})
    db.QueryInsert_(params, "").Scan()

    var form_id6 int
    forms.LoadModelData(map[string]interface{}{"name": "Участие в мероприятии"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id6)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id6, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Тип участия (очное/дистанционное)",
        "form_id":       form_id6,
        "param_type_id": param_text_type_id,
        "identifier":    17})
    db.QueryInsert_(params, "").Scan()

    var form_id7 int
    forms.LoadModelData(map[string]interface{}{"name": "Руководитель"})
    db.QueryInsert_(forms, "RETURNING id").Scan(&form_id7)

    eventsForms.LoadModelData(map[string]interface{}{"form_id": form_id7, "event_id": event_id})
    db.QueryInsert_(eventsForms, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Фамилия",
        "form_id":       form_id7,
        "param_type_id": param_text_type_id,
        "identifier":    18})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Имя",
        "form_id":       form_id7,
        "param_type_id": param_text_type_id,
        "identifier":    19})
    db.QueryInsert_(params, "").Scan()

    params.LoadModelData(map[string]interface{}{
        "name":          "Отчество",
        "form_id":       form_id7,
        "param_type_id": param_text_type_id,
        "identifier":    20})
    db.QueryInsert_(params, "").Scan()
}
<|endoftext|>


<commit_before>package services

import (
	"context"
	"time"

	log "github.com/inconshreveable/log15"
	"github.com/kevinburke/rickover/models/queued_jobs"
	"github.com/kevinburke/rickover/newmodels"
)

// ArchiveStuckJobs marks as failed any queued jobs with an updated_at
// timestamp older than the olderThan value.
func ArchiveStuckJobs(ctx context.Context, logger log.Logger, olderThan time.Duration) error {
	var olderThanTime time.Time
	if olderThan >= 0 {
		olderThanTime = time.Now().Add(-1 * olderThan)
	} else {
		olderThanTime = time.Now().Add(olderThan)
	}
	getCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
	jobs, err := queued_jobs.GetOldInProgressJobs(getCtx, olderThanTime)
	cancel()
	if err != nil {
		return err
	}
	for _, qj := range jobs {
		// bad to cancel this halfway through, give it time to run regardless fo
		// the server state.
		handleCtx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
		defer cancel()
		err = HandleStatusCallback(handleCtx, logger, qj.ID, qj.Name, newmodels.ArchivedJobStatusFailed, qj.Attempts, true)
		if err == nil {
			logger.Info("found stuck job and marked it as failed", "id", qj.ID.String())
		} else {
			// We don't want to return an error here since there may easily be
			// race/idempotence errors with a stuck job watcher. If it errors
			// we'll grab it with the next cron.
			logger.Error("found stuck job but could not process it", "id", qj.ID.String(), "err", err)
		}
	}
	return nil
}

// WatchStuckJobs polls the queued_jobs table for stuck jobs (defined as
// in-progress jobs that haven't been updated in oldDuration time), and marks
// them as failed.
func WatchStuckJobs(ctx context.Context, logger log.Logger, interval time.Duration, olderThan time.Duration) {
	ticker := time.NewTicker(interval)
	defer ticker.Stop()
	for {
		err := ArchiveStuckJobs(ctx, logger, olderThan)
		if err != nil {
			logger.Error("could not archive stuck jobs", "err", err)
		}
		select {
		case <-ticker.C:
		case <-ctx.Done():
			return
		}
	}
}
<commit_msg>services: wrap ArchiveStuckJobs query in error<commit_after>package services

import (
	"context"
	"fmt"
	"time"

	log "github.com/inconshreveable/log15"
	"github.com/kevinburke/rickover/models/queued_jobs"
	"github.com/kevinburke/rickover/newmodels"
)

// ArchiveStuckJobs marks as failed any queued jobs with an updated_at
// timestamp older than the olderThan value.
func ArchiveStuckJobs(ctx context.Context, logger log.Logger, olderThan time.Duration) error {
	var olderThanTime time.Time
	if olderThan >= 0 {
		olderThanTime = time.Now().Add(-1 * olderThan)
	} else {
		olderThanTime = time.Now().Add(olderThan)
	}
	getCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
	jobs, err := queued_jobs.GetOldInProgressJobs(getCtx, olderThanTime)
	cancel()
	if err != nil {
		return fmt.Errorf("could not retrieve in progress jobs: %w", err)
	}
	for _, qj := range jobs {
		// bad to cancel this halfway through, give it time to run regardless fo
		// the server state.
		handleCtx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
		defer cancel()
		err = HandleStatusCallback(handleCtx, logger, qj.ID, qj.Name, newmodels.ArchivedJobStatusFailed, qj.Attempts, true)
		if err == nil {
			logger.Info("found stuck job and marked it as failed", "id", qj.ID.String())
		} else {
			// We don't want to return an error here since there may easily be
			// race/idempotence errors with a stuck job watcher. If it errors
			// we'll grab it with the next cron.
			logger.Error("found stuck job but could not process it", "id", qj.ID.String(), "err", err)
		}
	}
	return nil
}

// WatchStuckJobs polls the queued_jobs table for stuck jobs (defined as
// in-progress jobs that haven't been updated in oldDuration time), and marks
// them as failed.
func WatchStuckJobs(ctx context.Context, logger log.Logger, interval time.Duration, olderThan time.Duration) {
	ticker := time.NewTicker(interval)
	defer ticker.Stop()
	for {
		err := ArchiveStuckJobs(ctx, logger, olderThan)
		if err != nil {
			logger.Error("could not archive stuck jobs", "err", err)
		}
		select {
		case <-ticker.C:
		case <-ctx.Done():
			return
		}
	}
}
<|endoftext|>