<commit_before>// +build darwin

package process

import (
	"bytes"
	"fmt"
	"os/exec"
	"strconv"
	"strings"
	"syscall"
	"unsafe"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/internal/common"
	"github.com/shirou/gopsutil/net"
)

// copied from sys/sysctl.h
const (
	CTLKern          = 1  // "high kernel": proc, limits
	KernProc         = 14 // struct: process entries
	KernProcPID      = 1  // by process id
	KernProcProc     = 8  // only return procs
	KernProcAll      = 0  // everything
	KernProcPathname = 12 // path to executable
)

const (
	ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
)

type _Ctype_struct___0 struct {
	Pad uint64
}

// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
}

type MemoryMapsStat struct {
}

func Pids() ([]int32, error) {
	var ret []int32

	pids, err := callPs("pid", 0, false)
	if err != nil {
		return ret, err
	}

	for _, pid := range pids {
		v, err := strconv.Atoi(pid[0])
		if err != nil {
			return ret, err
		}
		ret = append(ret, int32(v))
	}

	return ret, nil
}

func (p *Process) Ppid() (int32, error) {
	r, err := callPs("ppid", p.Pid, false)
	v, err := strconv.Atoi(r[0][0])
	if err != nil {
		return 0, err
	}

	return int32(v), err
}
func (p *Process) Name() (string, error) {
	k, err := p.getKProc()
	if err != nil {
		return "", err
	}

	return common.IntToString(k.Proc.P_comm[:]), nil
}
func (p *Process) Exe() (string, error) {
	return "", common.NotImplementedError
}
func (p *Process) Cmdline() (string, error) {
	r, err := callPs("command", p.Pid, false)
	if err != nil {
		return "", err
	}
	return strings.Join(r[0], " "), err
}
func (p *Process) CreateTime() (int64, error) {
	return 0, common.NotImplementedError
}
func (p *Process) Cwd() (string, error) {
	return "", common.NotImplementedError
}
func (p *Process) Parent() (*Process, error) {
	rr, err := common.CallLsof(invoke, p.Pid, "-FR")
	if err != nil {
		return nil, err
	}
	for _, r := range rr {
		if strings.HasPrefix(r, "p") { // skip if process
			continue
		}
		l := string(r)
		v, err := strconv.Atoi(strings.Replace(l, "R", "", 1))
		if err != nil {
			return nil, err
		}
		return NewProcess(int32(v))
	}
	return nil, fmt.Errorf("could not find parent line")
}
func (p *Process) Status() (string, error) {
	r, err := callPs("state", p.Pid, false)
	if err != nil {
		return "", err
	}

	return r[0][0], err
}
func (p *Process) Uids() ([]int32, error) {
	k, err := p.getKProc()
	if err != nil {
		return nil, err
	}

	uids := make([]int32, 0, 3)

	uids = append(uids, int32(k.Eproc.Pcred.P_ruid), int32(k.Eproc.Ucred.Uid), int32(k.Eproc.Pcred.P_svuid))

	return uids, nil
}
func (p *Process) Gids() ([]int32, error) {
	k, err := p.getKProc()
	if err != nil {
		return nil, err
	}

	gids := make([]int32, 0, 3)
	gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid))

	return gids, nil
}
func (p *Process) Terminal() (string, error) {
	return "", common.NotImplementedError
	/*
		k, err := p.getKProc()
		if err != nil {
			return "", err
		}

		ttyNr := uint64(k.Eproc.Tdev)
		termmap, err := getTerminalMap()
		if err != nil {
			return "", err
		}

		return termmap[ttyNr], nil
	*/
}
func (p *Process) Nice() (int32, error) {
	k, err := p.getKProc()
	if err != nil {
		return 0, err
	}
	return int32(k.Proc.P_nice), nil
}
func (p *Process) IOnice() (int32, error) {
	return 0, common.NotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
	var rlimit []RlimitStat
	return rlimit, common.NotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
	return nil, common.NotImplementedError
}
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
	return nil, common.NotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
	return 0, common.NotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
	r, err := callPs("utime,stime", p.Pid, true)
	if err != nil {
		return 0, err
	}
	return int32(len(r)), nil
}
func (p *Process) Threads() (map[string]string, error) {
	ret := make(map[string]string, 0)
	return ret, common.NotImplementedError
}

func convertCpuTimes(s string) (ret float64, err error) {
	var t int
	var _tmp string
	if strings.Contains(s, ":") {
		_t := strings.Split(s, ":")
		hour, err := strconv.Atoi(_t[0])
		if err != nil {
			return ret, err
		}
		t += hour * 60 * 100
		_tmp = _t[1]
	} else {
		_tmp = s
	}

	_t := strings.Split(_tmp, ".")
	if err != nil {
		return ret, err
	}
	h, err := strconv.Atoi(_t[0])
	t += h * 100
	h, err = strconv.Atoi(_t[1])
	t += h
	return float64(t) / ClockTicks, nil
}
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
	r, err := callPs("utime,stime", p.Pid, false)

	if err != nil {
		return nil, err
	}

	utime, err := convertCpuTimes(r[0][0])
	if err != nil {
		return nil, err
	}
	stime, err := convertCpuTimes(r[0][1])
	if err != nil {
		return nil, err
	}

	ret := &cpu.CPUTimesStat{
		CPU:    "cpu",
		User:   utime,
		System: stime,
	}
	return ret, nil
}
func (p *Process) CPUAffinity() ([]int32, error) {
	return nil, common.NotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
	r, err := callPs("rss,vsize,pagein", p.Pid, false)
	if err != nil {
		return nil, err
	}
	rss, err := strconv.Atoi(r[0][0])
	if err != nil {
		return nil, err
	}
	vms, err := strconv.Atoi(r[0][1])
	if err != nil {
		return nil, err
	}
	pagein, err := strconv.Atoi(r[0][2])
	if err != nil {
		return nil, err
	}

	ret := &MemoryInfoStat{
		RSS:  uint64(rss) * 1024,
		VMS:  uint64(vms) * 1024,
		Swap: uint64(pagein),
	}

	return ret, nil
}
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
	return nil, common.NotImplementedError
}
func (p *Process) MemoryPercent() (float32, error) {
	return 0, common.NotImplementedError
}

func (p *Process) Children() ([]*Process, error) {
	pids, err := common.CallPgrep(invoke, p.Pid)
	if err != nil {
		return nil, err
	}
	ret := make([]*Process, 0, len(pids))
	for _, pid := range pids {
		np, err := NewProcess(pid)
		if err != nil {
			return nil, err
		}
		ret = append(ret, np)
	}
	return ret, nil
}

func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
	return nil, common.NotImplementedError
}

func (p *Process) Connections() ([]net.NetConnectionStat, error) {
	return net.NetConnectionsPid("all", p.Pid)
}

func (p *Process) NetIOCounters(pernic bool) ([]net.NetIOCountersStat, error) {
	return nil, common.NotImplementedError
}

func (p *Process) IsRunning() (bool, error) {
	return true, common.NotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
	var ret []MemoryMapsStat
	return &ret, common.NotImplementedError
}

func copyParams(k *KinfoProc, p *Process) error {

	return nil
}

func processes() ([]Process, error) {
	results := make([]Process, 0, 50)

	mib := []int32{CTLKern, KernProc, KernProcAll, 0}
	buf, length, err := common.CallSyscall(mib)
	if err != nil {
		return results, err
	}

	// get kinfo_proc size
	k := KinfoProc{}
	procinfoLen := int(unsafe.Sizeof(k))
	count := int(length / uint64(procinfoLen))
	/*
		fmt.Println(length, procinfoLen, count)
		b := buf[0*procinfoLen : 0*procinfoLen+procinfoLen]
		fmt.Println(b)
		kk, err := parseKinfoProc(b)
		fmt.Printf("%#v", kk)
	*/

	// parse buf to procs
	for i := 0; i < count; i++ {
		b := buf[i*procinfoLen : i*procinfoLen+procinfoLen]
		k, err := parseKinfoProc(b)
		if err != nil {
			continue
		}
		p, err := NewProcess(int32(k.Proc.P_pid))
		if err != nil {
			continue
		}
		copyParams(&k, p)

		results = append(results, *p)
	}

	return results, nil
}

func parseKinfoProc(buf []byte) (KinfoProc, error) {
	var k KinfoProc
	br := bytes.NewReader(buf)

	err := Read(br, LittleEndian, &k)
	if err != nil {
		return k, err
	}

	return k, nil
}

func (p *Process) getKProc() (*KinfoProc, error) {
	mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
	procK := KinfoProc{}
	length := uint64(unsafe.Sizeof(procK))
	buf := make([]byte, length)
	_, _, syserr := syscall.Syscall6(
		syscall.SYS___SYSCTL,
		uintptr(unsafe.Pointer(&mib[0])),
		uintptr(len(mib)),
		uintptr(unsafe.Pointer(&buf[0])),
		uintptr(unsafe.Pointer(&length)),
		0,
		0)
	if syserr != 0 {
		return nil, syserr
	}
	k, err := parseKinfoProc(buf)
	if err != nil {
		return nil, err
	}

	return &k, nil
}

func NewProcess(pid int32) (*Process, error) {
	p := &Process{Pid: pid}

	return p, nil
}

// call ps command.
// Return value deletes Header line(you must not input wrong arg).
// And splited by Space. Caller have responsibility to manage.
// If passed arg pid is 0, get information from all process.
func callPs(arg string, pid int32, threadOption bool) ([][]string, error) {
	bin, err := exec.LookPath("ps")
	if err != nil {
		return [][]string{}, err
	}

	var cmd []string
	if pid == 0 { // will get from all processes.
		cmd = []string{"-ax", "-o", arg}
	} else if threadOption {
		cmd = []string{"-ax", "-o", arg, "-M", "-p", strconv.Itoa(int(pid))}
	} else {
		cmd = []string{"-ax", "-o", arg, "-p", strconv.Itoa(int(pid))}
	}
	out, err := invoke.Command(bin, cmd...)
	if err != nil {
		return [][]string{}, err
	}
	lines := strings.Split(string(out), "\n")

	var ret [][]string
	for _, l := range lines[1:] {
		var lr []string
		for _, r := range strings.Split(l, " ") {
			if r == "" {
				continue
			}
			lr = append(lr, strings.TrimSpace(r))
		}
		if len(lr) != 0 {
			ret = append(ret, lr)
		}
	}

	return ret, nil
}
<commit_msg>1)fix callps command generate error<commit_after>// +build darwin

package process

import (
	"bytes"
	"fmt"
	"os/exec"
	"strconv"
	"strings"
	"syscall"
	"unsafe"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/internal/common"
	"github.com/shirou/gopsutil/net"
)

// copied from sys/sysctl.h
const (
	CTLKern          = 1  // "high kernel": proc, limits
	KernProc         = 14 // struct: process entries
	KernProcPID      = 1  // by process id
	KernProcProc     = 8  // only return procs
	KernProcAll      = 0  // everything
	KernProcPathname = 12 // path to executable
)

const (
	ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
)

type _Ctype_struct___0 struct {
	Pad uint64
}

// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
}

type MemoryMapsStat struct {
}

func Pids() ([]int32, error) {
	var ret []int32

	pids, err := callPs("pid", 0, false)
	if err != nil {
		return ret, err
	}

	for _, pid := range pids {
		v, err := strconv.Atoi(pid[0])
		if err != nil {
			return ret, err
		}
		ret = append(ret, int32(v))
	}

	return ret, nil
}

func (p *Process) Ppid() (int32, error) {
	r, err := callPs("ppid", p.Pid, false)
	v, err := strconv.Atoi(r[0][0])
	if err != nil {
		return 0, err
	}

	return int32(v), err
}
func (p *Process) Name() (string, error) {
	k, err := p.getKProc()
	if err != nil {
		return "", err
	}

	return common.IntToString(k.Proc.P_comm[:]), nil
}
func (p *Process) Exe() (string, error) {
	return "", common.NotImplementedError
}
func (p *Process) Cmdline() (string, error) {
	r, err := callPs("command", p.Pid, false)
	if err != nil {
		return "", err
	}
	return strings.Join(r[0], " "), err
}
func (p *Process) CreateTime() (int64, error) {
	return 0, common.NotImplementedError
}
func (p *Process) Cwd() (string, error) {
	return "", common.NotImplementedError
}
func (p *Process) Parent() (*Process, error) {
	rr, err := common.CallLsof(invoke, p.Pid, "-FR")
	if err != nil {
		return nil, err
	}
	for _, r := range rr {
		if strings.HasPrefix(r, "p") { // skip if process
			continue
		}
		l := string(r)
		v, err := strconv.Atoi(strings.Replace(l, "R", "", 1))
		if err != nil {
			return nil, err
		}
		return NewProcess(int32(v))
	}
	return nil, fmt.Errorf("could not find parent line")
}
func (p *Process) Status() (string, error) {
	r, err := callPs("state", p.Pid, false)
	if err != nil {
		return "", err
	}

	return r[0][0], err
}
func (p *Process) Uids() ([]int32, error) {
	k, err := p.getKProc()
	if err != nil {
		return nil, err
	}

	uids := make([]int32, 0, 3)

	uids = append(uids, int32(k.Eproc.Pcred.P_ruid), int32(k.Eproc.Ucred.Uid), int32(k.Eproc.Pcred.P_svuid))

	return uids, nil
}
func (p *Process) Gids() ([]int32, error) {
	k, err := p.getKProc()
	if err != nil {
		return nil, err
	}

	gids := make([]int32, 0, 3)
	gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid))

	return gids, nil
}
func (p *Process) Terminal() (string, error) {
	return "", common.NotImplementedError
	/*
		k, err := p.getKProc()
		if err != nil {
			return "", err
		}

		ttyNr := uint64(k.Eproc.Tdev)
		termmap, err := getTerminalMap()
		if err != nil {
			return "", err
		}

		return termmap[ttyNr], nil
	*/
}
func (p *Process) Nice() (int32, error) {
	k, err := p.getKProc()
	if err != nil {
		return 0, err
	}
	return int32(k.Proc.P_nice), nil
}
func (p *Process) IOnice() (int32, error) {
	return 0, common.NotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
	var rlimit []RlimitStat
	return rlimit, common.NotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
	return nil, common.NotImplementedError
}
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
	return nil, common.NotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
	return 0, common.NotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
	r, err := callPs("utime,stime", p.Pid, true)
	if err != nil {
		return 0, err
	}
	return int32(len(r)), nil
}
func (p *Process) Threads() (map[string]string, error) {
	ret := make(map[string]string, 0)
	return ret, common.NotImplementedError
}

func convertCpuTimes(s string) (ret float64, err error) {
	var t int
	var _tmp string
	if strings.Contains(s, ":") {
		_t := strings.Split(s, ":")
		hour, err := strconv.Atoi(_t[0])
		if err != nil {
			return ret, err
		}
		t += hour * 60 * 100
		_tmp = _t[1]
	} else {
		_tmp = s
	}

	_t := strings.Split(_tmp, ".")
	if err != nil {
		return ret, err
	}
	h, err := strconv.Atoi(_t[0])
	t += h * 100
	h, err = strconv.Atoi(_t[1])
	t += h
	return float64(t) / ClockTicks, nil
}
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
	r, err := callPs("utime,stime", p.Pid, false)

	if err != nil {
		return nil, err
	}

	utime, err := convertCpuTimes(r[0][0])
	if err != nil {
		return nil, err
	}
	stime, err := convertCpuTimes(r[0][1])
	if err != nil {
		return nil, err
	}

	ret := &cpu.CPUTimesStat{
		CPU:    "cpu",
		User:   utime,
		System: stime,
	}
	return ret, nil
}
func (p *Process) CPUAffinity() ([]int32, error) {
	return nil, common.NotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
	r, err := callPs("rss,vsize,pagein", p.Pid, false)
	if err != nil {
		return nil, err
	}
	rss, err := strconv.Atoi(r[0][0])
	if err != nil {
		return nil, err
	}
	vms, err := strconv.Atoi(r[0][1])
	if err != nil {
		return nil, err
	}
	pagein, err := strconv.Atoi(r[0][2])
	if err != nil {
		return nil, err
	}

	ret := &MemoryInfoStat{
		RSS:  uint64(rss) * 1024,
		VMS:  uint64(vms) * 1024,
		Swap: uint64(pagein),
	}

	return ret, nil
}
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
	return nil, common.NotImplementedError
}
func (p *Process) MemoryPercent() (float32, error) {
	return 0, common.NotImplementedError
}

func (p *Process) Children() ([]*Process, error) {
	pids, err := common.CallPgrep(invoke, p.Pid)
	if err != nil {
		return nil, err
	}
	ret := make([]*Process, 0, len(pids))
	for _, pid := range pids {
		np, err := NewProcess(pid)
		if err != nil {
			return nil, err
		}
		ret = append(ret, np)
	}
	return ret, nil
}

func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
	return nil, common.NotImplementedError
}

func (p *Process) Connections() ([]net.NetConnectionStat, error) {
	return net.NetConnectionsPid("all", p.Pid)
}

func (p *Process) NetIOCounters(pernic bool) ([]net.NetIOCountersStat, error) {
	return nil, common.NotImplementedError
}

func (p *Process) IsRunning() (bool, error) {
	return true, common.NotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
	var ret []MemoryMapsStat
	return &ret, common.NotImplementedError
}

func copyParams(k *KinfoProc, p *Process) error {

	return nil
}

func processes() ([]Process, error) {
	results := make([]Process, 0, 50)

	mib := []int32{CTLKern, KernProc, KernProcAll, 0}
	buf, length, err := common.CallSyscall(mib)
	if err != nil {
		return results, err
	}

	// get kinfo_proc size
	k := KinfoProc{}
	procinfoLen := int(unsafe.Sizeof(k))
	count := int(length / uint64(procinfoLen))
	/*
		fmt.Println(length, procinfoLen, count)
		b := buf[0*procinfoLen : 0*procinfoLen+procinfoLen]
		fmt.Println(b)
		kk, err := parseKinfoProc(b)
		fmt.Printf("%#v", kk)
	*/

	// parse buf to procs
	for i := 0; i < count; i++ {
		b := buf[i*procinfoLen : i*procinfoLen+procinfoLen]
		k, err := parseKinfoProc(b)
		if err != nil {
			continue
		}
		p, err := NewProcess(int32(k.Proc.P_pid))
		if err != nil {
			continue
		}
		copyParams(&k, p)

		results = append(results, *p)
	}

	return results, nil
}

func parseKinfoProc(buf []byte) (KinfoProc, error) {
	var k KinfoProc
	br := bytes.NewReader(buf)

	err := Read(br, LittleEndian, &k)
	if err != nil {
		return k, err
	}

	return k, nil
}

func (p *Process) getKProc() (*KinfoProc, error) {
	mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
	procK := KinfoProc{}
	length := uint64(unsafe.Sizeof(procK))
	buf := make([]byte, length)
	_, _, syserr := syscall.Syscall6(
		syscall.SYS___SYSCTL,
		uintptr(unsafe.Pointer(&mib[0])),
		uintptr(len(mib)),
		uintptr(unsafe.Pointer(&buf[0])),
		uintptr(unsafe.Pointer(&length)),
		0,
		0)
	if syserr != 0 {
		return nil, syserr
	}
	k, err := parseKinfoProc(buf)
	if err != nil {
		return nil, err
	}

	return &k, nil
}

func NewProcess(pid int32) (*Process, error) {
	p := &Process{Pid: pid}

	return p, nil
}

// call ps command.
// Return value deletes Header line(you must not input wrong arg).
// And splited by Space. Caller have responsibility to manage.
// If passed arg pid is 0, get information from all process.
func callPs(arg string, pid int32, threadOption bool) ([][]string, error) {
	bin, err := exec.LookPath("ps")
	if err != nil {
		return [][]string{}, err
	}

	var cmd []string
	if pid == 0 { // will get from all processes.
		cmd = []string{"-ax", "-o", arg}
	} else if threadOption {
		cmd = []string{"-x", "-o", arg, "-M", "-p", strconv.Itoa(int(pid))}
	} else {
		cmd = []string{"-x", "-o", arg, "-p", strconv.Itoa(int(pid))}
	}
	out, err := invoke.Command(bin, cmd...)
	if err != nil {
		return [][]string{}, err
	}
	lines := strings.Split(string(out), "\n")

	var ret [][]string
	for _, l := range lines[1:] {
		var lr []string
		for _, r := range strings.Split(l, " ") {
			if r == "" {
				continue
			}
			lr = append(lr, strings.TrimSpace(r))
		}
		if len(lr) != 0 {
			ret = append(ret, lr)
		}
	}

	return ret, nil
}
<|endoftext|>


<commit_before>package web

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"

	"github.com/codegangsta/cli"
	log "github.com/golang/glog"
	"github.com/micro/go-micro/client"
	"github.com/micro/go-micro/errors"
	"github.com/micro/go-micro/registry"
	"github.com/serenize/snaker"

	"golang.org/x/net/context"
)

var (
	Address = ":8082"
)

func format(v *registry.Value) string {
	if v == nil || len(v.Values) == 0 {
		return "{}"
	}
	var f []string
	for _, k := range v.Values {
		f = append(f, formatEndpoint(k, 0))
	}
	return fmt.Sprintf("{\n%s}", strings.Join(f, ""))
}

func formatEndpoint(v *registry.Value, r int) string {
	// default format is tabbed plus the value plus new line
	fparts := []string{"", "%s %s", "\n"}
	for i := 0; i < r+1; i++ {
		fparts[0] += "\t"
	}
	// its just a primitive of sorts so return
	if len(v.Values) == 0 {
		return fmt.Sprintf(strings.Join(fparts, ""), snaker.CamelToSnake(v.Name), v.Type)
	}

	// this thing has more things, it's complex
	fparts[1] += " {"

	vals := []interface{}{snaker.CamelToSnake(v.Name), v.Type}

	for _, val := range v.Values {
		fparts = append(fparts, "%s")
		vals = append(vals, formatEndpoint(val, r+1))
	}

	// at the end
	l := len(fparts) - 1
	for i := 0; i < r+1; i++ {
		fparts[l] += "\t"
	}
	fparts = append(fparts, "}\n")

	return fmt.Sprintf(strings.Join(fparts, ""), vals...)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	render(w, r, indexTemplate, nil)
}

func registryHandler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	svc := r.Form.Get("service")

	if len(svc) > 0 {
		s, err := registry.GetService(svc)
		if err != nil {
			http.Error(w, "Error occurred:"+err.Error(), 500)
			return
		}

		if r.Header.Get("Content-Type") == "application/json" {
			b, err := json.Marshal(map[string]interface{}{
				"services": s,
			})
			if err != nil {
				http.Error(w, "Error occurred:"+err.Error(), 500)
				return
			}
			w.Header().Set("Content-Type", "application/json")
			w.Write(b)
			return
		}

		render(w, r, serviceTemplate, s)
		return
	}

	services, err := registry.ListServices()
	if err != nil {
		http.Error(w, "Error occurred:"+err.Error(), 500)
		return
	}

	if r.Header.Get("Content-Type") == "application/json" {
		b, err := json.Marshal(map[string]interface{}{
			"services": services,
		})
		if err != nil {
			http.Error(w, "Error occurred:"+err.Error(), 500)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(b)
		return
	}

	render(w, r, registryTemplate, services)
}

func queryHandler(w http.ResponseWriter, r *http.Request) {
	render(w, r, queryTemplate, nil)
}

func rpcHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}
	defer r.Body.Close()

	var service, method string
	var request interface{}

	// response content type
	w.Header().Set("Content-Type", "application/json")

	switch r.Header.Get("Content-Type") {
	case "application/json":
		b, err := ioutil.ReadAll(r.Body)
		if err != nil {
			e := errors.BadRequest("go.micro.api", err.Error())
			w.WriteHeader(400)
			w.Write([]byte(e.Error()))
			return
		}

		var body map[string]interface{}
		err = json.Unmarshal(b, &body)
		if err != nil {
			e := errors.BadRequest("go.micro.api", err.Error())
			w.WriteHeader(400)
			w.Write([]byte(e.Error()))
			return
		}

		service = body["service"].(string)
		method = body["method"].(string)
		request = body["request"]
	default:
		r.ParseForm()
		service = r.Form.Get("service")
		method = r.Form.Get("method")
		json.Unmarshal([]byte(r.Form.Get("request")), &request)
	}

	var response map[string]interface{}
	req := client.NewJsonRequest(service, method, request)
	err := client.Call(context.Background(), req, &response)
	if err != nil {
		log.Errorf("Error calling %s.%s: %v", service, method, err)
		ce := errors.Parse(err.Error())
		switch ce.Code {
		case 0:
			w.WriteHeader(500)
		default:
			w.WriteHeader(int(ce.Code))
		}
		w.Write([]byte(ce.Error()))
		return
	}

	b, _ := json.Marshal(response)
	w.Header().Set("Content-Length", strconv.Itoa(len(b)))
	w.Write(b)
}

func render(w http.ResponseWriter, r *http.Request, tmpl string, data interface{}) {
	t, err := template.New("template").Funcs(template.FuncMap{
		"format": format,
	}).Parse(layoutTemplate)
	if err != nil {
		http.Error(w, "Error occurred:"+err.Error(), 500)
		return
	}
	t, err = t.Parse(tmpl)
	if err != nil {
		http.Error(w, "Error occurred:"+err.Error(), 500)
		return
	}
	if err := t.ExecuteTemplate(w, "layout", data); err != nil {
		http.Error(w, "Error occurred:"+err.Error(), 500)
	}
}

func run() {
	http.HandleFunc("/", indexHandler)
	http.HandleFunc("/registry", registryHandler)
	http.HandleFunc("/rpc", rpcHandler)
	http.HandleFunc("/query", queryHandler)

	if err := http.ListenAndServe(Address, nil); err != nil {
		log.Fatal(err)
	}
}

func Commands() []cli.Command {
	return []cli.Command{
		{
			Name:  "web",
			Usage: "Run the micro web app",
			Action: func(c *cli.Context) {
				run()
			},
		},
	}
}
<commit_msg>Set access allow origin to anything for web<commit_after>package web

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"

	"github.com/codegangsta/cli"
	log "github.com/golang/glog"
	"github.com/micro/go-micro/client"
	"github.com/micro/go-micro/errors"
	"github.com/micro/go-micro/registry"
	"github.com/serenize/snaker"

	"golang.org/x/net/context"
)

var (
	Address = ":8082"
)

type server struct{}

func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	http.DefaultServeMux.ServeHTTP(w, r)
}

func format(v *registry.Value) string {
	if v == nil || len(v.Values) == 0 {
		return "{}"
	}
	var f []string
	for _, k := range v.Values {
		f = append(f, formatEndpoint(k, 0))
	}
	return fmt.Sprintf("{\n%s}", strings.Join(f, ""))
}

func formatEndpoint(v *registry.Value, r int) string {
	// default format is tabbed plus the value plus new line
	fparts := []string{"", "%s %s", "\n"}
	for i := 0; i < r+1; i++ {
		fparts[0] += "\t"
	}
	// its just a primitive of sorts so return
	if len(v.Values) == 0 {
		return fmt.Sprintf(strings.Join(fparts, ""), snaker.CamelToSnake(v.Name), v.Type)
	}

	// this thing has more things, it's complex
	fparts[1] += " {"

	vals := []interface{}{snaker.CamelToSnake(v.Name), v.Type}

	for _, val := range v.Values {
		fparts = append(fparts, "%s")
		vals = append(vals, formatEndpoint(val, r+1))
	}

	// at the end
	l := len(fparts) - 1
	for i := 0; i < r+1; i++ {
		fparts[l] += "\t"
	}
	fparts = append(fparts, "}\n")

	return fmt.Sprintf(strings.Join(fparts, ""), vals...)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	render(w, r, indexTemplate, nil)
}

func registryHandler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	svc := r.Form.Get("service")

	if len(svc) > 0 {
		s, err := registry.GetService(svc)
		if err != nil {
			http.Error(w, "Error occurred:"+err.Error(), 500)
			return
		}

		if r.Header.Get("Content-Type") == "application/json" {
			b, err := json.Marshal(map[string]interface{}{
				"services": s,
			})
			if err != nil {
				http.Error(w, "Error occurred:"+err.Error(), 500)
				return
			}
			w.Header().Set("Content-Type", "application/json")
			w.Write(b)
			return
		}

		render(w, r, serviceTemplate, s)
		return
	}

	services, err := registry.ListServices()
	if err != nil {
		http.Error(w, "Error occurred:"+err.Error(), 500)
		return
	}

	if r.Header.Get("Content-Type") == "application/json" {
		b, err := json.Marshal(map[string]interface{}{
			"services": services,
		})
		if err != nil {
			http.Error(w, "Error occurred:"+err.Error(), 500)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(b)
		return
	}

	render(w, r, registryTemplate, services)
}

func queryHandler(w http.ResponseWriter, r *http.Request) {
	render(w, r, queryTemplate, nil)
}

func rpcHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}
	defer r.Body.Close()

	var service, method string
	var request interface{}

	// response content type
	w.Header().Set("Content-Type", "application/json")

	switch r.Header.Get("Content-Type") {
	case "application/json":
		b, err := ioutil.ReadAll(r.Body)
		if err != nil {
			e := errors.BadRequest("go.micro.api", err.Error())
			w.WriteHeader(400)
			w.Write([]byte(e.Error()))
			return
		}

		var body map[string]interface{}
		err = json.Unmarshal(b, &body)
		if err != nil {
			e := errors.BadRequest("go.micro.api", err.Error())
			w.WriteHeader(400)
			w.Write([]byte(e.Error()))
			return
		}

		service = body["service"].(string)
		method = body["method"].(string)
		request = body["request"]
	default:
		r.ParseForm()
		service = r.Form.Get("service")
		method = r.Form.Get("method")
		json.Unmarshal([]byte(r.Form.Get("request")), &request)
	}

	var response map[string]interface{}
	req := client.NewJsonRequest(service, method, request)
	err := client.Call(context.Background(), req, &response)
	if err != nil {
		log.Errorf("Error calling %s.%s: %v", service, method, err)
		ce := errors.Parse(err.Error())
		switch ce.Code {
		case 0:
			w.WriteHeader(500)
		default:
			w.WriteHeader(int(ce.Code))
		}
		w.Write([]byte(ce.Error()))
		return
	}

	b, _ := json.Marshal(response)
	w.Header().Set("Content-Length", strconv.Itoa(len(b)))
	w.Write(b)
}

func render(w http.ResponseWriter, r *http.Request, tmpl string, data interface{}) {
	t, err := template.New("template").Funcs(template.FuncMap{
		"format": format,
	}).Parse(layoutTemplate)
	if err != nil {
		http.Error(w, "Error occurred:"+err.Error(), 500)
		return
	}
	t, err = t.Parse(tmpl)
	if err != nil {
		http.Error(w, "Error occurred:"+err.Error(), 500)
		return
	}
	if err := t.ExecuteTemplate(w, "layout", data); err != nil {
		http.Error(w, "Error occurred:"+err.Error(), 500)
	}
}

func run() {
	http.HandleFunc("/", indexHandler)
	http.HandleFunc("/registry", registryHandler)
	http.HandleFunc("/rpc", rpcHandler)
	http.HandleFunc("/query", queryHandler)

	if err := http.ListenAndServe(Address, &server{}); err != nil {
		log.Fatal(err)
	}
}

func Commands() []cli.Command {
	return []cli.Command{
		{
			Name:  "web",
			Usage: "Run the micro web app",
			Action: func(c *cli.Context) {
				run()
			},
		},
	}
}
<|endoftext|>


<commit_before>// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"exec"
	"flag"
	"http"
	"io"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strconv"
	"template"
)

var (
	httpListen = flag.String("http", "127.0.0.1:3999", "host:port to listen on")
	htmlOutput = flag.Bool("html", false, "render program output as HTML")
)

var (
	// a source of numbers, for naming temporary files
	uniq = make(chan int)
	// the architecture-identifying character of the tool chain, 5, 6, or 8
	archChar string
)

func main() {
	flag.Parse()

	// set archChar
	switch runtime.GOARCH {
	case "arm":
		archChar = "5"
	case "amd64":
		archChar = "6"
	case "386":
		archChar = "8"
	default:
		log.Fatalln("unrecognized GOARCH:", runtime.GOARCH)
	}

	// source of unique numbers
	go func() {
		for i := 0; ; i++ {
			uniq <- i
		}
	}()

	http.HandleFunc("/", FrontPage)
	http.HandleFunc("/compile", Compile)
	log.Fatal(http.ListenAndServe(*httpListen, nil))
}

// FrontPage is an HTTP handler that renders the goplay interface.
// If a filename is supplied in the path component of the URI,
// its contents will be put in the interface's text area.
// Otherwise, the default "hello, world" program is displayed.
func FrontPage(w http.ResponseWriter, req *http.Request) {
	data, err := ioutil.ReadFile(req.URL.Path[1:])
	if err != nil {
		data = helloWorld
	}
	frontPage.Execute(w, data)
}

// Compile is an HTTP handler that reads Go source code from the request,
// compiles and links the code (returning any errors), runs the program,
// and sends the program's output as the HTTP response.
func Compile(w http.ResponseWriter, req *http.Request) {
	// x is the base name for .go, .6, executable files
	x := os.TempDir() + "/compile" + strconv.Itoa(<-uniq)
	src := x + ".go"
	obj := x + "." + archChar
	bin := x
	if runtime.GOOS == "windows" {
		bin += ".exe"
	}

	// write request Body to x.go
	f, err := os.Create(src)
	if err != nil {
		error(w, nil, err)
		return
	}
	defer os.Remove(src)
	defer f.Close()
	_, err = io.Copy(f, req.Body)
	if err != nil {
		error(w, nil, err)
		return
	}
	f.Close()

	// build x.go, creating x.6
	out, err := run(archChar+"g", "-o", obj, src)
	defer os.Remove(obj)
	if err != nil {
		error(w, out, err)
		return
	}

	// link x.6, creating x (the program binary)
	out, err = run(archChar+"l", "-o", bin, obj)
	defer os.Remove(bin)
	if err != nil {
		error(w, out, err)
		return
	}

	// run x
	out, err = run(bin)
	if err != nil {
		error(w, out, err)
	}

	// write the output of x as the http response
	if *htmlOutput {
		w.Write(out)
	} else {
		output.Execute(w, out)
	}
}

// error writes compile, link, or runtime errors to the HTTP connection.
// The JavaScript interface uses the 404 status code to identify the error.
func error(w http.ResponseWriter, out []byte, err os.Error) {
	w.WriteHeader(404)
	if out != nil {
		output.Execute(w, out)
	} else {
		output.Execute(w, err.String())
	}
}

// run executes the specified command and returns its output and an error.
func run(cmd ...string) ([]byte, os.Error) {
	return exec.Command(cmd[0], cmd[1:]...).CombinedOutput()
}

var frontPage = template.Must(template.New("frontPage").Parse(frontPageText)) // HTML template
var output = template.Must(template.New("output").Parse(outputText))          // HTML template

var outputText = `<pre>{{html .}}</pre>`

var frontPageText = `<!doctype html>

<textarea autofocus="true" id="edit" spellcheck="false" onkeydown="keyHandler(event);" onkeyup="autocompile();">{{printf "%s" . |html}}</textarea>

(Shift-Enter to compile and run.)
<input type="checkbox" id="autocompile" value="checked" /> Compile and run after each keystroke

`

var helloWorld = []byte(`package main

import "fmt"

func main() {
	fmt.Println("hello, world")
}
`)
<commit_msg>misc/goplay: another template fix<commit_after>// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"exec"
	"flag"
	"http"
	"io"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strconv"
	"template"
)

var (
	httpListen = flag.String("http", "127.0.0.1:3999", "host:port to listen on")
	htmlOutput = flag.Bool("html", false, "render program output as HTML")
)

var (
	// a source of numbers, for naming temporary files
	uniq = make(chan int)
	// the architecture-identifying character of the tool chain, 5, 6, or 8
	archChar string
)

func main() {
	flag.Parse()

	// set archChar
	switch runtime.GOARCH {
	case "arm":
		archChar = "5"
	case "amd64":
		archChar = "6"
	case "386":
		archChar = "8"
	default:
		log.Fatalln("unrecognized GOARCH:", runtime.GOARCH)
	}

	// source of unique numbers
	go func() {
		for i := 0; ; i++ {
			uniq <- i
		}
	}()

	http.HandleFunc("/", FrontPage)
	http.HandleFunc("/compile", Compile)
	log.Fatal(http.ListenAndServe(*httpListen, nil))
}

// FrontPage is an HTTP handler that renders the goplay interface.
// If a filename is supplied in the path component of the URI,
// its contents will be put in the interface's text area.
// Otherwise, the default "hello, world" program is displayed.
func FrontPage(w http.ResponseWriter, req *http.Request) {
	data, err := ioutil.ReadFile(req.URL.Path[1:])
	if err != nil {
		data = helloWorld
	}
	frontPage.Execute(w, data)
}

// Compile is an HTTP handler that reads Go source code from the request,
// compiles and links the code (returning any errors), runs the program,
// and sends the program's output as the HTTP response.
func Compile(w http.ResponseWriter, req *http.Request) {
	// x is the base name for .go, .6, executable files
	x := os.TempDir() + "/compile" + strconv.Itoa(<-uniq)
	src := x + ".go"
	obj := x + "." + archChar
	bin := x
	if runtime.GOOS == "windows" {
		bin += ".exe"
	}

	// write request Body to x.go
	f, err := os.Create(src)
	if err != nil {
		error(w, nil, err)
		return
	}
	defer os.Remove(src)
	defer f.Close()
	_, err = io.Copy(f, req.Body)
	if err != nil {
		error(w, nil, err)
		return
	}
	f.Close()

	// build x.go, creating x.6
	out, err := run(archChar+"g", "-o", obj, src)
	defer os.Remove(obj)
	if err != nil {
		error(w, out, err)
		return
	}

	// link x.6, creating x (the program binary)
	out, err = run(archChar+"l", "-o", bin, obj)
	defer os.Remove(bin)
	if err != nil {
		error(w, out, err)
		return
	}

	// run x
	out, err = run(bin)
	if err != nil {
		error(w, out, err)
	}

	// write the output of x as the http response
	if *htmlOutput {
		w.Write(out)
	} else {
		output.Execute(w, out)
	}
}

// error writes compile, link, or runtime errors to the HTTP connection.
// The JavaScript interface uses the 404 status code to identify the error.
func error(w http.ResponseWriter, out []byte, err os.Error) {
	w.WriteHeader(404)
	if out != nil {
		output.Execute(w, out)
	} else {
		output.Execute(w, err.String())
	}
}

// run executes the specified command and returns its output and an error.
func run(cmd ...string) ([]byte, os.Error) {
	return exec.Command(cmd[0], cmd[1:]...).CombinedOutput()
}

var frontPage = template.Must(template.New("frontPage").Parse(frontPageText)) // HTML template
var output = template.Must(template.New("output").Parse(outputText))          // HTML template

var outputText = `<pre>{{printf "%s" . |html}}</pre>`

var frontPageText = `<!doctype html>

<textarea autofocus="true" id="edit" spellcheck="false" onkeydown="keyHandler(event);" onkeyup="autocompile();">{{printf "%s" . |html}}</textarea>

(Shift-Enter to compile and run.)
<input type="checkbox" id="autocompile" value="checked" /> Compile and run after each keystroke

`

var helloWorld = []byte(`package main

import "fmt"

func main() {
	fmt.Println("hello, world")
}
`)
<|endoftext|>


<commit_before>package web

import (
	"encoding/json"
	"log"
	"time"

	"github.com/gocraft/web"
	"github.com/varunamachi/orek/data"
)

type Context struct {
	SessionUser  data.User
	CreationTime time.Duration
}

func checkSession(context *Context) bool {
	return true
}

func (c *Context) SessionChecker(rw web.ResponseWriter,
	req *web.Request,
	next web.NextMiddlewareFunc) {
	//get the session ID
	//see if it is still valid
	//put the user and session objects into the context object
	next(rw, req)
}

func (c *Context) Login(resp web.ResponseWriter, req *web.Request) {
	//Get the user name and password from the request
	//Authenticate the user and create the user object, put the user into
	// context
	//Check if the current session already registered to some other login
	//if so expire this session
	//Create a new session in the session table
	//	userName := req.FormValue("userName")
	//	password := req.FormValue("password")
	//	sessionId := req.FormValue("sessionId")
	//	data.DataSource().GetUser("varun").FirstName

	//	data.DataSource().GetUser(
}

func (c *Context) Logout(resp web.ResponseWriter, req *web.Request) {
	//resp.Write
}

func (c *Context) GetAllUsers(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	users, err := data.DataSource().GetAllUsers()
	if err == nil {
		err = encoder.Encode(users)
		if err != nil {
			err = encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal user list"})
		}
	} else {
		err = encoder.Encode(OrekError{
			"DataSourceError",
			"Failed retrieve user list from datasource"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetUser(resp web.ResponseWriter, req *web.Request) {
	userName := req.PathParams["userName"]
	user, err := data.DataSource().GetUser(userName)
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(user)
		if err != nil {
			err = encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal user details"})
		}
	} else {
		err = encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch user detail from data source"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) CreateUser(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	decoder := json.NewDecoder(req.Body)
	var user data.User
	var err error = nil
	if err = decoder.Decode(&user); err == nil {
		err = data.DataSource().CreateOrUpdateUser(&user)
		if err != nil {
			err = encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal user creation result"})
		}
	} else {
		err = encoder.Encode(OrekError{
			"UnmarshalError",
			"Failed to create user from given information"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) DeleteUser(resp web.ResponseWriter, req *web.Request) {
	userName := req.PathParams["userName"]
	encoder := json.NewEncoder(resp)
	var err error = nil
	if len(userName) > 0 {
		err = data.DataSource().DeleteUser(userName)
		if err != nil {
			err = encoder.Encode(OrekError{
				"DataSourceError",
				"Failed to delete user"})
		}

	} else {
		err = encoder.Encode(OrekError{
			"ArgumentError",
			"Invalid user name given for deletion"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetAllSources(resp web.ResponseWriter, req *web.Request) {
	sources, err := data.DataSource().GetAllSources()
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(sources)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal source list"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch list of source from database"})

	}
	if err == nil {
		log.Print(err)
	}
}

func (c *Context) GetSource(resp web.ResponseWriter, req *web.Request) {
	sourceName := req.PathParams["sourceName"]
	sourceOwner := req.PathParams["sourceOwner"]
	encoder := json.NewEncoder(resp)
	source, err := data.DataSource().GetSource(sourceName, sourceOwner)
	if err == nil {
		err = encoder.Encode(source)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal source information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch source information from database"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetSourceWithId(resp web.ResponseWriter, req *web.Request) {
	sourceId := req.PathParams["sourceId"]
	encoder := json.NewEncoder(resp)
	source, err := data.DataSource().GetSourceWithId(sourceId)
	if err == nil {
		err = encoder.Encode(source)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal source information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch source information from database"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) CreateOrUpdateSource(resp web.ResponseWriter, req *web.Request) {
	decoder := json.NewDecoder(req.Body)
	encoder := json.NewEncoder(resp)
	var source data.Source
	err := decoder.Decode(&source)
	if err == nil {
		err = data.DataSource().CreateOrUpdateSource(&source)
		if err != nil {
			encoder.Encode(OrekError{
				"DataSourceError",
				"Failed to add source to database"})
		}
	} else {
		encoder.Encode(OrekError{
			"UnamarshalError",
			"Could not decode the given source information"})
	}
	if err != nil {
		log.Print(err)
	}

}

func (c *Context) DeleteSource(resp web.ResponseWriter, req *web.Request) {
	sourceId := req.PathParams["sourceId"]
	err := data.DataSource().DeleteSource(sourceId)
	encoder := json.NewEncoder(resp)
	if err != nil {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Could not delete the source with given id"})
		log.Print(err)
	}
}

func (c *Context) GetAllVariables(resp web.ResponseWriter, req *web.Request) {
	vars, err := data.DataSource().GetAllVariables()
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(vars)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Could not encode the list of variables"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Could not get list of variables from DB"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetVariable(resp web.ResponseWriter, req *web.Request) {
	variableName := req.PathParams["variableName"]
	sourceId := req.PathParams["sourceId"]
	variable, err := data.DataSource().GetVariable(sourceId, variableName)
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(variable)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode variable information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch information about the given variable"})

	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetVariableWithId(resp web.ResponseWriter, req *web.Request) {
	variableId := req.PathParams["variableId"]
	variable, err := data.DataSource().GetVariableWithId(variableId)
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(variable)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode variable information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch information about the given variable"})

	}
	if err != nil {
		log.Print(err)
	}

}

func (c *Context) CreateOrUpdateVariable(resp web.ResponseWriter, req *web.Request) {
	decoder := json.NewDecoder(req.Body)
	encoder := json.NewEncoder(resp)
	var variable data.Variable
	err := decoder.Decode(&variable)
	if err == nil {
		err := data.DataSource().CreateOrUpdateVariable(&variable)
		if err != nil {
			encoder.Encode(OrekError{
				"DataSourceError",
				"Failed to create/update given variable"})
		}
	} else {
		encoder.Encode(OrekError{
			"UnmarshalError",
			"Failed to unmarshal variable information"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) DeleteVariable(resp web.ResponseWriter, req *web.Request) {
	variableId := req.PathParams["variableId"]
	encoder := json.NewEncoder(resp)
	err := data.DataSource().DeleteVariable(variableId)
	if err != nil {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to delete give variable"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetAllUserGroups(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	groups, err := data.DataSource().GetAllUserGroups()
	if err == nil {
		err = encoder.Encode(groups)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed marshal user group list"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Could not fetch list of user groups from database"})
	}
}

func (c *Context) GetUserGroup(resp web.ResponseWriter, req *web.Request) {
	groupName := req.PathParams["groupName"]
	encoder := json.NewEncoder(resp)
	group, err := data.DataSource().GetUserGroup(groupName)
	if err == nil {
		err = encoder.Encode(group)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode user information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch user group information"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) CreateOrUpdateUserGroup(resp web.ResponseWriter,
	req *web.Request) {
	decoder := json.NewDecoder(req.Body)
	encoder := json.NewEncoder(resp)
	var group data.UserGroup
	err := decoder.Decode(&group)
	if err == nil {
		err = data.DataSource().CreateOrUpdateUserGroup(&group)
		if err != nil {
			encoder.Encode(OrekError{
				"DataSourceError",
				"Failed to create/update user group info."})
		}
	} else {
		encoder.Encode(OrekError{
			"UnamrshalError",
			"Failed to decode user group info for create/update"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) DeleteUserGroup(resp web.ResponseWriter, req *web.Request) {

}

func (c *Context) GetAllVariableGroups(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetVariableGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetVariableGroupWithId(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) CreateOrUpdateVariableGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) DeleteVariableGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) AddUserToGroup(resp web.ResponseWriter, req *web.Request) {

}

func (c *Context) RemoveUserFromGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetUsersInGroup(resp web.ResponseWriter, req *web.Request) {

}

func (c *Context) GetGroupsForUser(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) AddVariableToGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) RemoveVariableFromGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetVariablesInGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetGroupsForVariable(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) AddVariableValue(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) ClearValuesForVariable(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetValuesForVariable(resp web.ResponseWriter,
	req *web.Request) {

}

func Setup() error {

	return nil
}
<commit_msg>APIs for variable groups<commit_after>package web

import (
	"encoding/json"
	"log"
	"time"

	"github.com/gocraft/web"
	"github.com/varunamachi/orek/data"
)

type Context struct {
	SessionUser  data.User
	CreationTime time.Duration
}

func checkSession(context *Context) bool {
	return true
}

func (c *Context) SessionChecker(rw web.ResponseWriter,
	req *web.Request,
	next web.NextMiddlewareFunc) {
	//get the session ID
	//see if it is still valid
	//put the user and session objects into the context object
	next(rw, req)
}

func (c *Context) Login(resp web.ResponseWriter, req *web.Request) {
	//Get the user name and password from the request
	//Authenticate the user and create the user object, put the user into
	// context
	//Check if the current session already registered to some other login
	//if so expire this session
	//Create a new session in the session table
	//	userName := req.FormValue("userName")
	//	password := req.FormValue("password")
	//	sessionId := req.FormValue("sessionId")
	//	data.DataSource().GetUser("varun").FirstName

	//	data.DataSource().GetUser(
}

func (c *Context) Logout(resp web.ResponseWriter, req *web.Request) {
	//resp.Write
}

func (c *Context) GetAllUsers(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	users, err := data.DataSource().GetAllUsers()
	if err == nil {
		err = encoder.Encode(users)
		if err != nil {
			err = encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal user list"})
		}
	} else {
		err = encoder.Encode(OrekError{
			"DataSourceError",
			"Failed retrieve user list from datasource"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetUser(resp web.ResponseWriter, req *web.Request) {
	userName := req.PathParams["userName"]
	user, err := data.DataSource().GetUser(userName)
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(user)
		if err != nil {
			err = encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal user details"})
		}
	} else {
		err = encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch user detail from data source"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) CreateUser(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	decoder := json.NewDecoder(req.Body)
	var user data.User
	var err error = nil
	if err = decoder.Decode(&user); err == nil {
		err = data.DataSource().CreateOrUpdateUser(&user)
		if err != nil {
			err = encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal user creation result"})
		}
	} else {
		err = encoder.Encode(OrekError{
			"UnmarshalError",
			"Failed to create user from given information"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) DeleteUser(resp web.ResponseWriter, req *web.Request) {
	userName := req.PathParams["userName"]
	encoder := json.NewEncoder(resp)
	var err error = nil
	if len(userName) > 0 {
		err = data.DataSource().DeleteUser(userName)
		if err != nil {
			err = encoder.Encode(OrekError{
				"DataSourceError",
				"Failed to delete user"})
		}

	} else {
		err = encoder.Encode(OrekError{
			"ArgumentError",
			"Invalid user name given for deletion"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetAllSources(resp web.ResponseWriter, req *web.Request) {
	sources, err := data.DataSource().GetAllSources()
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(sources)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal source list"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch list of source from database"})

	}
	if err == nil {
		log.Print(err)
	}
}

func (c *Context) GetSource(resp web.ResponseWriter, req *web.Request) {
	sourceName := req.PathParams["sourceName"]
	sourceOwner := req.PathParams["sourceOwner"]
	encoder := json.NewEncoder(resp)
	source, err := data.DataSource().GetSource(sourceName, sourceOwner)
	if err == nil {
		err = encoder.Encode(source)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal source information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch source information from database"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetSourceWithId(resp web.ResponseWriter, req *web.Request) {
	sourceId := req.PathParams["sourceId"]
	encoder := json.NewEncoder(resp)
	source, err := data.DataSource().GetSourceWithId(sourceId)
	if err == nil {
		err = encoder.Encode(source)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to marshal source information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch source information from database"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) CreateOrUpdateSource(resp web.ResponseWriter, req *web.Request) {
	decoder := json.NewDecoder(req.Body)
	encoder := json.NewEncoder(resp)
	var source data.Source
	err := decoder.Decode(&source)
	if err == nil {
		err = data.DataSource().CreateOrUpdateSource(&source)
		if err != nil {
			encoder.Encode(OrekError{
				"DataSourceError",
				"Failed to add source to database"})
		}
	} else {
		encoder.Encode(OrekError{
			"UnamarshalError",
			"Could not decode the given source information"})
	}
	if err != nil {
		log.Print(err)
	}

}

func (c *Context) DeleteSource(resp web.ResponseWriter, req *web.Request) {
	sourceId := req.PathParams["sourceId"]
	err := data.DataSource().DeleteSource(sourceId)
	encoder := json.NewEncoder(resp)
	if err != nil {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Could not delete the source with given id"})
		log.Print(err)
	}
}

func (c *Context) GetAllVariables(resp web.ResponseWriter, req *web.Request) {
	vars, err := data.DataSource().GetAllVariables()
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(vars)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Could not encode the list of variables"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Could not get list of variables from DB"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetVariable(resp web.ResponseWriter, req *web.Request) {
	variableName := req.PathParams["variableName"]
	sourceId := req.PathParams["sourceId"]
	variable, err := data.DataSource().GetVariable(sourceId, variableName)
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(variable)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode variable information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch information about the given variable"})

	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetVariableWithId(resp web.ResponseWriter, req *web.Request) {
	variableId := req.PathParams["variableId"]
	variable, err := data.DataSource().GetVariableWithId(variableId)
	encoder := json.NewEncoder(resp)
	if err == nil {
		err = encoder.Encode(variable)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode variable information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch information about the given variable"})

	}
	if err != nil {
		log.Print(err)
	}

}

func (c *Context) CreateOrUpdateVariable(resp web.ResponseWriter, req *web.Request) {
	decoder := json.NewDecoder(req.Body)
	encoder := json.NewEncoder(resp)
	var variable data.Variable
	err := decoder.Decode(&variable)
	if err == nil {
		err := data.DataSource().CreateOrUpdateVariable(&variable)
		if err != nil {
			encoder.Encode(OrekError{
				"DataSourceError",
				"Failed to create/update given variable"})
		}
	} else {
		encoder.Encode(OrekError{
			"UnmarshalError",
			"Failed to unmarshal variable information"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) DeleteVariable(resp web.ResponseWriter, req *web.Request) {
	variableId := req.PathParams["variableId"]
	encoder := json.NewEncoder(resp)
	err := data.DataSource().DeleteVariable(variableId)
	if err != nil {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to delete give variable"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetAllUserGroups(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	groups, err := data.DataSource().GetAllUserGroups()
	if err == nil {
		err = encoder.Encode(groups)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed marshal user group list"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Could not fetch list of user groups from database"})
	}
}

func (c *Context) GetUserGroup(resp web.ResponseWriter, req *web.Request) {
	groupName := req.PathParams["groupName"]
	encoder := json.NewEncoder(resp)
	group, err := data.DataSource().GetUserGroup(groupName)
	if err == nil {
		err = encoder.Encode(group)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode user information"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch user group information"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) CreateOrUpdateUserGroup(resp web.ResponseWriter,
	req *web.Request) {
	decoder := json.NewDecoder(req.Body)
	encoder := json.NewEncoder(resp)
	var group data.UserGroup
	err := decoder.Decode(&group)
	if err == nil {
		err = data.DataSource().CreateOrUpdateUserGroup(&group)
		if err != nil {
			encoder.Encode(OrekError{
				"DataSourceError",
				"Failed to create/update user group info."})
		}
	} else {
		encoder.Encode(OrekError{
			"UnamrshalError",
			"Failed to decode user group info for create/update"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) DeleteUserGroup(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	groupName := req.PathParams["groupName"]
	err := data.DataSource().DeleteUserGroup(groupName)
	if err != nil {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to delete given user"})
		log.Print(err)
	}
}

func (c *Context) GetAllVariableGroups(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	varGroups, err := data.DataSource().GetAllVariables()
	if err == nil {
		err = encoder.Encode(varGroups)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode variable group list"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch all variable groups"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetVariableGroup(resp web.ResponseWriter, req *web.Request) {
	varGroupName := req.PathParams["varGroupName"]
	owner := req.PathParams["owner"]
	encoder := json.NewEncoder(resp)
	varGroup, err := data.DataSource().GetVariableGroup(varGroupName, owner)
	if err == nil {
		err = encoder.Encode(varGroup)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode the var group list"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch variable group with give info"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) GetVariableGroupWithId(resp web.ResponseWriter, req *web.Request) {
	varGroupId := req.PathParams["varGroupId"]
	encoder := json.NewEncoder(resp)
	varGroup, err := data.DataSource().GetVariableGroupWithId(varGroupId)
	if err == nil {
		err = encoder.Encode(varGroup)
		if err != nil {
			encoder.Encode(OrekError{
				"MarshalError",
				"Failed to encode the var group list"})
		}
	} else {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to fetch variable group with give info"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) CreateOrUpdateVariableGroup(resp web.ResponseWriter, req *web.Request) {
	decoder := json.NewDecoder(req.Body)
	encoder := json.NewEncoder(resp)
	var varGroup data.VariableGroup
	err := decoder.Decode(&varGroup)
	if err == nil {
		err = data.DataSource().CreateOrUpdateVariableGroup(&varGroup)
		if err != nil {
			encoder.Encode(OrekError{
				"DataSourceError",
				"Failed create/update variable group"})
		}
	} else {
		encoder.Encode(OrekError{
			"UnmarshalError",
			"Failed decode variable group info"})
	}
	if err != nil {
		log.Print(err)
	}
}

func (c *Context) DeleteVariableGroup(resp web.ResponseWriter, req *web.Request) {
	encoder := json.NewEncoder(resp)
	varGroupId := req.PathParams["varGroupId"]
	err := data.DataSource().DeleteVariableGroup(varGroupId)
	if err != nil {
		encoder.Encode(OrekError{
			"DataSourceError",
			"Failed to delete variable group"})
		log.Print(err)
	}
}

func (c *Context) AddUserToGroup(resp web.ResponseWriter, req *web.Request) {

}

func (c *Context) RemoveUserFromGroup(resp web.ResponseWriter, req *web.Request) {

}

func (c *Context) GetUsersInGroup(resp web.ResponseWriter, req *web.Request) {

}

func (c *Context) GetGroupsForUser(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) AddVariableToGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) RemoveVariableFromGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetVariablesInGroup(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetGroupsForVariable(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) AddVariableValue(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) ClearValuesForVariable(resp web.ResponseWriter,
	req *web.Request) {

}

func (c *Context) GetValuesForVariable(resp web.ResponseWriter,
	req *web.Request) {

}

func Setup() error {

	return nil
}
<|endoftext|>


<commit_before>package bruxism

import (
	"fmt"
	"strings"
)

const commandDelimeter = "!"

// CommandHelpFunc is the function signature for command help methods.
type CommandHelpFunc func(bot *Bot, service Service, message Message) (string, string)

// CommandMessageFunc is the function signature for bot message commands.
type CommandMessageFunc func(bot *Bot, service Service, message Message, args string, parts []string)

// NewCommandHelp creates a new Command Help function.
func NewCommandHelp(args, help string) CommandHelpFunc {
	return func(bot *Bot, service Service, message Message) (string, string) {
		return args, help
	}
}

// MatchesCommandString returns true if a message matches a command.
// Commands will be matched ignoring case with a prefix if they are not private messages.
func MatchesCommandString(service Service, commandString string, private bool, message string) bool {
	lowerMessage := strings.ToLower(strings.TrimSpace(message))
	lowerPrefix := strings.ToLower(service.CommandPrefix())

	if strings.HasPrefix(lowerMessage, lowerPrefix) {
		lowerMessage = lowerMessage[len(lowerPrefix):]
	} else if !private {
		return false
	}

	lowerMessage = strings.TrimSpace(lowerMessage)
	lowerCommand := strings.ToLower(commandString)

	return lowerMessage == lowerCommand || strings.HasPrefix(lowerMessage, lowerCommand+" ")
}

// MatchesCommand returns true if a message matches a command.
func MatchesCommand(service Service, commandString string, message Message) bool {
	// Deleted messages can't trigger commands.
	if message.Type() == MessageTypeDelete {
		return false
	}
	return MatchesCommandString(service, commandString, service.IsPrivate(message), message.Message())
}

// ParseCommandStringPrefix will strip all prefixes from a message string, and return that string, and a space separated tokenized version of that string.
func ParseCommandStringPrefix(prefix, message string) (string, []string) {
	message = strings.TrimSpace(message)

	lowerMessage := strings.ToLower(message)
	lowerPrefix := strings.ToLower(prefix)

	if strings.HasPrefix(lowerMessage, lowerPrefix) {
		message = message[len(lowerPrefix):]
	}
	rest := strings.Fields(message)

	if len(rest) > 1 {
		rest = rest[1:]
		return strings.Join(rest, " "), rest
	}
	return "", []string{}
}

// ParseCommandString will strip all prefixes from a message string, and return that string, and a space separated tokenized version of that string.
func ParseCommandString(service Service, message string) (string, []string) {
	return ParseCommandStringPrefix(service.CommandPrefix(), message)
}

// ParseCommand parses a message.
func ParseCommand(service Service, message Message) (string, []string) {
	return ParseCommandString(service, message.Message())
}

// CommandHelp is a helper message that creates help text for a command.
// eg. CommandHelp(service, "foo", "<bar>", "Foo bar baz") will return:
//     !foo <bar> - Foo bar baz
// The string is automatatically styled in Discord.
func CommandHelp(service Service, command, arguments, help string) []string {
	ticks := ""
	if service.Name() == DiscordServiceName {
		ticks = "`"
	}

	if arguments != "" {
		return []string{fmt.Sprintf("%s%s%s %s%s - %s", ticks, service.CommandPrefix(), command, arguments, ticks, help)}
	}
	return []string{fmt.Sprintf("%s%s%s%s - %s", ticks, service.CommandPrefix(), command, ticks, help)}
}

type command struct {
	message CommandMessageFunc
	help    CommandHelpFunc
}

// CommandPlugin is a plugin that can have commands registered and will handle messages matching that command by calling functions.
type CommandPlugin struct {
	commands map[string]*command
}

// Name returns the name of the plugin.
func (p *CommandPlugin) Name() string {
	return "Command"
}

// Load will load plugin state from a byte array.
func (p *CommandPlugin) Load(bot *Bot, service Service, data []byte) error {
	// TODO: Add a generic data store backed by json.
	return nil
}

// Save will save plugin state to a byte array.
func (p *CommandPlugin) Save() ([]byte, error) {
	// TODO: Add a generic data store backed by json.
	return nil, nil
}

// Help returns a list of help strings that are printed when the user requests them.
func (p *CommandPlugin) Help(bot *Bot, service Service, message Message, detailed bool) []string {
	if detailed {
		return nil
	}
	help := []string{}
	for commandString, command := range p.commands {
		if command.help != nil {
			arguments, h := command.help(bot, service, message)
			help = append(help, CommandHelp(service, commandString, arguments, h)...)
		}
	}
	return help
}

// Message handler.
// Iterates over the registered commands and executes them if the message matches.
func (p *CommandPlugin) Message(bot *Bot, service Service, message Message) {
	defer MessageRecover()
	if !service.IsMe(message) {
		for commandString, command := range p.commands {
			if MatchesCommand(service, commandString, message) {
				args, parts := ParseCommand(service, message)
				command.message(bot, service, message, args, parts)
				return
			}
		}
	}
}

// AddCommand adds a command.
func (p *CommandPlugin) AddCommand(commandString string, message CommandMessageFunc, help CommandHelpFunc) {
	p.commands[commandString] = &command{
		message: message,
		help:    help,
	}
}

// Stats will return the stats for a plugin.
func (p *CommandPlugin) Stats(bot *Bot, service Service, message Message) []string {
	return nil
}

// NewCommandPlugin will create a new command plugin.
func NewCommandPlugin() *CommandPlugin {
	return &CommandPlugin{make(map[string]*command)}
}
<commit_msg>Support prefixes on Matching commands.<commit_after>package bruxism

import (
	"fmt"
	"strings"
)

const commandDelimeter = "!"

// CommandHelpFunc is the function signature for command help methods.
type CommandHelpFunc func(bot *Bot, service Service, message Message) (string, string)

// CommandMessageFunc is the function signature for bot message commands.
type CommandMessageFunc func(bot *Bot, service Service, message Message, args string, parts []string)

// NewCommandHelp creates a new Command Help function.
func NewCommandHelp(args, help string) CommandHelpFunc {
	return func(bot *Bot, service Service, message Message) (string, string) {
		return args, help
	}
}

// MatchesCommandStringPrefix returns true if a message matches a command.
// Commands will be matched ignoring case with a prefix if they are not private messages.
func MatchesCommandStringPrefix(prefix, commandString string, private bool, message string) bool {
	lowerMessage := strings.ToLower(strings.TrimSpace(message))
	lowerPrefix := strings.ToLower(prefix)

	if strings.HasPrefix(lowerMessage, lowerPrefix) {
		lowerMessage = lowerMessage[len(lowerPrefix):]
	} else if !private {
		return false
	}

	lowerMessage = strings.TrimSpace(lowerMessage)
	lowerCommand := strings.ToLower(commandString)

	return lowerMessage == lowerCommand || strings.HasPrefix(lowerMessage, lowerCommand+" ")
}

// MatchesCommandString returns true if a message matches a command.
// Commands will be matched ignoring case with a prefix if they are not private messages.
func MatchesCommandString(service Service, commandString string, private bool, message string) bool {
	return MatchesCommandStringPrefix(service.CommandPrefix(), commandString, private, message)
}

// MatchesCommand returns true if a message matches a command.
func MatchesCommand(service Service, commandString string, message Message) bool {
	// Deleted messages can't trigger commands.
	if message.Type() == MessageTypeDelete {
		return false
	}
	return MatchesCommandString(service, commandString, service.IsPrivate(message), message.Message())
}

// ParseCommandStringPrefix will strip all prefixes from a message string, and return that string, and a space separated tokenized version of that string.
func ParseCommandStringPrefix(prefix, message string) (string, []string) {
	message = strings.TrimSpace(message)

	lowerMessage := strings.ToLower(message)
	lowerPrefix := strings.ToLower(prefix)

	if strings.HasPrefix(lowerMessage, lowerPrefix) {
		message = message[len(lowerPrefix):]
	}
	rest := strings.Fields(message)

	if len(rest) > 1 {
		rest = rest[1:]
		return strings.Join(rest, " "), rest
	}
	return "", []string{}
}

// ParseCommandString will strip all prefixes from a message string, and return that string, and a space separated tokenized version of that string.
func ParseCommandString(service Service, message string) (string, []string) {
	return ParseCommandStringPrefix(service.CommandPrefix(), message)
}

// ParseCommand parses a message.
func ParseCommand(service Service, message Message) (string, []string) {
	return ParseCommandString(service, message.Message())
}

// CommandHelp is a helper message that creates help text for a command.
// eg. CommandHelp(service, "foo", "<bar>", "Foo bar baz") will return:
//     !foo <bar> - Foo bar baz
// The string is automatatically styled in Discord.
func CommandHelp(service Service, command, arguments, help string) []string {
	ticks := ""
	if service.Name() == DiscordServiceName {
		ticks = "`"
	}

	if arguments != "" {
		return []string{fmt.Sprintf("%s%s%s %s%s - %s", ticks, service.CommandPrefix(), command, arguments, ticks, help)}
	}
	return []string{fmt.Sprintf("%s%s%s%s - %s", ticks, service.CommandPrefix(), command, ticks, help)}
}

type command struct {
	message CommandMessageFunc
	help    CommandHelpFunc
}

// CommandPlugin is a plugin that can have commands registered and will handle messages matching that command by calling functions.
type CommandPlugin struct {
	commands map[string]*command
}

// Name returns the name of the plugin.
func (p *CommandPlugin) Name() string {
	return "Command"
}

// Load will load plugin state from a byte array.
func (p *CommandPlugin) Load(bot *Bot, service Service, data []byte) error {
	// TODO: Add a generic data store backed by json.
	return nil
}

// Save will save plugin state to a byte array.
func (p *CommandPlugin) Save() ([]byte, error) {
	// TODO: Add a generic data store backed by json.
	return nil, nil
}

// Help returns a list of help strings that are printed when the user requests them.
func (p *CommandPlugin) Help(bot *Bot, service Service, message Message, detailed bool) []string {
	if detailed {
		return nil
	}
	help := []string{}
	for commandString, command := range p.commands {
		if command.help != nil {
			arguments, h := command.help(bot, service, message)
			help = append(help, CommandHelp(service, commandString, arguments, h)...)
		}
	}
	return help
}

// Message handler.
// Iterates over the registered commands and executes them if the message matches.
func (p *CommandPlugin) Message(bot *Bot, service Service, message Message) {
	defer MessageRecover()
	if !service.IsMe(message) {
		for commandString, command := range p.commands {
			if MatchesCommand(service, commandString, message) {
				args, parts := ParseCommand(service, message)
				command.message(bot, service, message, args, parts)
				return
			}
		}
	}
}

// AddCommand adds a command.
func (p *CommandPlugin) AddCommand(commandString string, message CommandMessageFunc, help CommandHelpFunc) {
	p.commands[commandString] = &command{
		message: message,
		help:    help,
	}
}

// Stats will return the stats for a plugin.
func (p *CommandPlugin) Stats(bot *Bot, service Service, message Message) []string {
	return nil
}

// NewCommandPlugin will create a new command plugin.
func NewCommandPlugin() *CommandPlugin {
	return &CommandPlugin{make(map[string]*command)}
}
<|endoftext|>


<commit_before>// $G $D/$F.go && $L $F.$A && ./$A.out

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import "os"
import "runtime"

var	randx	int;

func
nrand(n int) int {
	randx += 10007;
	if randx >= 1000000 {
		randx -= 1000000;
	}
	return randx%n;
}

type	Chan struct {
	sc,rc	chan int;	// send and recv chan
	sv,rv	int;		// send and recv seq
}

var
(
	nproc		int;
	cval		int;
	end		int	= 10000;
	totr,tots	int;
	nc		*Chan;
)

func
init() {
	nc = new(Chan);
}

func
mkchan(c,n int) []*Chan {
	ca := make([]*Chan, n);
	for i:=0; i<n; i++ {
		cval = cval+100;
		ch := new(Chan);
		ch.sc = make(chan int, c);
		ch.rc = ch.sc;
		ch.sv = cval;
		ch.rv = cval;
		ca[i] = ch;
	}
	return ca;
}

func
expect(v, v0 int) (newv int) {
	if v == v0 {
		if v%100 == 75 {
			return end;
		}
		return v+1;
	}
	panic("got ", v, " expected ", v0+1, "\n");
}

func (c *Chan) send() bool {
//	print("send ", c.sv, "\n");
	tots++;
	c.sv = expect(c.sv, c.sv);
	if c.sv == end {
		c.sc = nil;
		return true;
	}
	return false;
}

func
send(c *Chan) {
	nproc++;	// total goroutines running
	for {
		for r:=nrand(10); r>=0; r-- {
			runtime.Gosched();
		}
		c.sc <- c.sv;
		if c.send() {
			break;
		}
	}
	nproc--;
}

func (c *Chan) recv(v int) bool {
//	print("recv ", v, "\n");
	totr++;
	c.rv = expect(c.rv, v);
	if c.rv == end {
		c.rc = nil;
		return true;
	}
	return false;
}

func
recv(c *Chan) {
	var v int;

	nproc++;	// total goroutines running
	for {
		for r:=nrand(10); r>=0; r-- {
			runtime.Gosched();
		}
		v = <-c.rc;
		if c.recv(v) {
			break;
		}
	}
	nproc--;
}

func
sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan) {
	var v int;

	nproc++;	// total goroutines running
	a := 0;		// local chans running

	if r0.rc != nil { a++ }
	if r1.rc != nil { a++ }
	if r2.rc != nil { a++ }
	if r3.rc != nil { a++ }
	if s0.sc != nil { a++ }
	if s1.sc != nil { a++ }
	if s2.sc != nil { a++ }
	if s3.sc != nil { a++ }

	for {
		for r:=nrand(5); r>=0; r-- {
			runtime.Gosched();
		}

		select {
		case v = <-r0.rc:
			if r0.recv(v) {
				a--;
			}
		case v = <-r1.rc:
			if r1.recv(v) {
				a--;
			}
		case v = <-r2.rc:
			if r2.recv(v) {
				a--;
			}
		case v = <-r3.rc:
			if r3.recv(v) {
				a--;
			}
		case s0.sc <- s0.sv:
			if s0.send() {
				a--;
			}
		case s1.sc <- s1.sv:
			if s1.send() {
				a--;
			}
		case s2.sc <- s2.sv:
			if s2.send() {
				a--;
			}
		case s3.sc <- s3.sv:
			if s3.send() {
				a--;
			}
		}
		if a == 0 {
			break;
		}
	}
	nproc--;
}

// direct send to direct recv
func
test1(c *Chan) {
	go send(c);
	go recv(c);
}

// direct send to select recv
func
test2(c int) {
	ca := mkchan(c,4);

	go send(ca[0]);
	go send(ca[1]);
	go send(ca[2]);
	go send(ca[3]);

	go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
}

// select send to direct recv
func
test3(c int) {
	ca := mkchan(c,4);

	go recv(ca[0]);
	go recv(ca[1]);
	go recv(ca[2]);
	go recv(ca[3]);

	go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
}

// select send to select recv
func
test4(c int) {
	ca := mkchan(c,4);

	go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
	go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
}

func
test5(c int) {
	ca := mkchan(c,8);

	go sel(ca[4],ca[5],ca[6],ca[7], ca[0],ca[1],ca[2],ca[3]);
	go sel(ca[0],ca[1],ca[2],ca[3], ca[4],ca[5],ca[6],ca[7]);
}

func
test6(c int) {
	ca := mkchan(c,12);

	go send(ca[4]);
	go send(ca[5]);
	go send(ca[6]);
	go send(ca[7]);

	go recv(ca[8]);
	go recv(ca[9]);
	go recv(ca[10]);
	go recv(ca[11]);

	go sel(ca[4],ca[5],ca[6],ca[7], ca[0],ca[1],ca[2],ca[3]);
	go sel(ca[0],ca[1],ca[2],ca[3], ca[8],ca[9],ca[10],ca[11]);
}

// wait for outstanding tests to finish
func
wait() {
	runtime.Gosched();
	for nproc != 0 {
		runtime.Gosched();
	}
}

// run all tests with specified buffer size
func
tests(c int) {
	ca := mkchan(c,4);
	test1(ca[0]);
	test1(ca[1]);
	test1(ca[2]);
	test1(ca[3]);
	wait();

	test2(c);
	wait();

	test3(c);
	wait();

	test4(c);
	wait();

	test5(c);
	wait();

	test6(c);
	wait();
}

// run all test with 4 buffser sizes
func
main() {

	tests(0);
	tests(1);
	tests(10);
	tests(100);

	t :=	4 *			// buffer sizes
		(	4*4 +		// tests 1,2,3,4 channels
			8 +		// test 5 channels
			12 ) *		// test 6 channels
		76;			// sends/recvs on a channel

	if tots != t || totr != t {
		print("tots=", tots, " totr=", totr, " sb=", t, "\n");
		os.Exit(1);
	}
	os.Exit(0);
}
<commit_msg>Add explicit locking.<commit_after>// $G $D/$F.go && $L $F.$A && ./$A.out

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import "os"
import "runtime"
import "sync"

var	randx	int;

func
nrand(n int) int {
	randx += 10007;
	if randx >= 1000000 {
		randx -= 1000000;
	}
	return randx%n;
}

type	Chan struct {
	sc,rc	chan int;	// send and recv chan
	sv,rv	int;		// send and recv seq
}

var
(
	nproc		int;
	nprocLock	sync.Mutex;
	cval		int;
	end		int	= 10000;
	totr,tots	int;
	totLock		sync.Mutex;
	nc		*Chan;
)

func
init() {
	nc = new(Chan);
}

func changeNproc(adjust int) int {
	nprocLock.Lock()
	nproc += adjust
	ret := nproc
	nprocLock.Unlock()
	return ret
}

func
mkchan(c,n int) []*Chan {
	ca := make([]*Chan, n);
	for i:=0; i<n; i++ {
		cval = cval+100;
		ch := new(Chan);
		ch.sc = make(chan int, c);
		ch.rc = ch.sc;
		ch.sv = cval;
		ch.rv = cval;
		ca[i] = ch;
	}
	return ca;
}

func
expect(v, v0 int) (newv int) {
	if v == v0 {
		if v%100 == 75 {
			return end;
		}
		return v+1;
	}
	panic("got ", v, " expected ", v0+1, "\n");
}

func (c *Chan) send() bool {
//	print("send ", c.sv, "\n");
	totLock.Lock();
	tots++;
	totLock.Unlock();
	c.sv = expect(c.sv, c.sv);
	if c.sv == end {
		c.sc = nil;
		return true;
	}
	return false;
}

func
send(c *Chan) {
	for {
		for r:=nrand(10); r>=0; r-- {
			runtime.Gosched();
		}
		c.sc <- c.sv;
		if c.send() {
			break;
		}
	}
	changeNproc(-1)
}

func (c *Chan) recv(v int) bool {
//	print("recv ", v, "\n");
	totLock.Lock();
	totr++;
	totLock.Unlock();
	c.rv = expect(c.rv, v);
	if c.rv == end {
		c.rc = nil;
		return true;
	}
	return false;
}

func
recv(c *Chan) {
	var v int;

	for {
		for r:=nrand(10); r>=0; r-- {
			runtime.Gosched();
		}
		v = <-c.rc;
		if c.recv(v) {
			break;
		}
	}
	changeNproc(-1);
}

func
sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan) {
	var v int;

	a := 0;		// local chans running

	if r0.rc != nil { a++ }
	if r1.rc != nil { a++ }
	if r2.rc != nil { a++ }
	if r3.rc != nil { a++ }
	if s0.sc != nil { a++ }
	if s1.sc != nil { a++ }
	if s2.sc != nil { a++ }
	if s3.sc != nil { a++ }

	for {
		for r:=nrand(5); r>=0; r-- {
			runtime.Gosched();
		}

		select {
		case v = <-r0.rc:
			if r0.recv(v) {
				a--;
			}
		case v = <-r1.rc:
			if r1.recv(v) {
				a--;
			}
		case v = <-r2.rc:
			if r2.recv(v) {
				a--;
			}
		case v = <-r3.rc:
			if r3.recv(v) {
				a--;
			}
		case s0.sc <- s0.sv:
			if s0.send() {
				a--;
			}
		case s1.sc <- s1.sv:
			if s1.send() {
				a--;
			}
		case s2.sc <- s2.sv:
			if s2.send() {
				a--;
			}
		case s3.sc <- s3.sv:
			if s3.send() {
				a--;
			}
		}
		if a == 0 {
			break;
		}
	}
	changeNproc(-1);
}

// direct send to direct recv
func
test1(c *Chan) {
	changeNproc(2)
	go send(c);
	go recv(c);
}

// direct send to select recv
func
test2(c int) {
	ca := mkchan(c,4);

	changeNproc(4)
	go send(ca[0]);
	go send(ca[1]);
	go send(ca[2]);
	go send(ca[3]);

	changeNproc(1)
	go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
}

// select send to direct recv
func
test3(c int) {
	ca := mkchan(c,4);

	changeNproc(4)
	go recv(ca[0]);
	go recv(ca[1]);
	go recv(ca[2]);
	go recv(ca[3]);

	changeNproc(1)
	go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
}

// select send to select recv
func
test4(c int) {
	ca := mkchan(c,4);

	changeNproc(2)
	go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
	go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
}

func
test5(c int) {
	ca := mkchan(c,8);

	changeNproc(2)
	go sel(ca[4],ca[5],ca[6],ca[7], ca[0],ca[1],ca[2],ca[3]);
	go sel(ca[0],ca[1],ca[2],ca[3], ca[4],ca[5],ca[6],ca[7]);
}

func
test6(c int) {
	ca := mkchan(c,12);

	changeNproc(4)
	go send(ca[4]);
	go send(ca[5]);
	go send(ca[6]);
	go send(ca[7]);

	changeNproc(4)
	go recv(ca[8]);
	go recv(ca[9]);
	go recv(ca[10]);
	go recv(ca[11]);

	changeNproc(2)
	go sel(ca[4],ca[5],ca[6],ca[7], ca[0],ca[1],ca[2],ca[3]);
	go sel(ca[0],ca[1],ca[2],ca[3], ca[8],ca[9],ca[10],ca[11]);
}

// wait for outstanding tests to finish
func
wait() {
	runtime.Gosched();
	for changeNproc(0) != 0 {
		runtime.Gosched();
	}
}

// run all tests with specified buffer size
func
tests(c int) {
	ca := mkchan(c,4);
	test1(ca[0]);
	test1(ca[1]);
	test1(ca[2]);
	test1(ca[3]);
	wait();

	test2(c);
	wait();

	test3(c);
	wait();

	test4(c);
	wait();

	test5(c);
	wait();

	test6(c);
	wait();
}

// run all test with 4 buffser sizes
func
main() {

	tests(0);
	tests(1);
	tests(10);
	tests(100);

	t :=	4 *			// buffer sizes
		(	4*4 +		// tests 1,2,3,4 channels
			8 +		// test 5 channels
			12 ) *		// test 6 channels
		76;			// sends/recvs on a channel

	if tots != t || totr != t {
		print("tots=", tots, " totr=", totr, " sb=", t, "\n");
		os.Exit(1);
	}
	os.Exit(0);
}
<|endoftext|>


<commit_before>package web

import (
	"net/http"

	"github.com/gophergala/goffee/web/controllers"
	"github.com/gorilla/sessions"
	"github.com/hypebeast/gojistatic"
	"github.com/zenazn/goji"
	"github.com/zenazn/goji/web"
)

var store = sessions.NewCookieStore([]byte("something-very-secret"))

// SessionMiddleware adds session support to Goffee
func SessionMiddleware(c *web.C, h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		// Get a session. We're ignoring the error resulted from decoding an
		// existing session: Get() always returns a session, even if empty.
		session, _ := store.Get(r, "goffee-session")

		// Set some session values.
		session.Values["foo"] = "bar"
		session.Values[42] = 43

		// Save it.
		session.Save(r, w)

		h.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}

// StartServer starts the web server
func StartServer() {
	goji.Use(gojistatic.Static("web/public", gojistatic.StaticOptions{SkipLogging: true}))
	goji.Use(SessionMiddleware)

	goji.Get("/", controllers.Home)

	goji.Get("/ip", controllers.IP)

	goji.Get("/oauth/authorize", controllers.OAuthAuthorize)
	goji.Get("/oauth/callback", controllers.OAuthCallback)

	goji.Get("/checks", controllers.ChecksIndex)

	goji.Serve()
}
<commit_msg>Delete some sample code<commit_after>package web

import (
	"net/http"

	"github.com/gophergala/goffee/web/controllers"
	"github.com/gorilla/sessions"
	"github.com/hypebeast/gojistatic"
	"github.com/zenazn/goji"
	"github.com/zenazn/goji/web"
)

var store = sessions.NewCookieStore([]byte("something-very-secret"))

// SessionMiddleware adds session support to Goffee
func SessionMiddleware(c *web.C, h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		// Get a session. We're ignoring the error resulted from decoding an
		// existing session: Get() always returns a session, even if empty.
		session, _ := store.Get(r, "goffee-session")

		// Save it.
		session.Save(r, w)

		h.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}

// StartServer starts the web server
func StartServer() {
	goji.Use(gojistatic.Static("web/public", gojistatic.StaticOptions{SkipLogging: true}))
	goji.Use(SessionMiddleware)

	goji.Get("/", controllers.Home)

	goji.Get("/ip", controllers.IP)

	goji.Get("/oauth/authorize", controllers.OAuthAuthorize)
	goji.Get("/oauth/callback", controllers.OAuthCallback)

	goji.Get("/checks", controllers.ChecksIndex)

	goji.Serve()
}
<|endoftext|>


<commit_before>package main

import "github.com/genghisjahn/textlength"
import "fmt"
import "net/http"
import "html/template"
import "time"
import "strings"

var items []textlength.TextLengthItem

func main() {
	items, _ = textlength.BuildItems(10000)
	fmt.Printf("Text Length web server is running. %v\n", time.Now())
	fmt.Printf("Navigate your browser to http://localhost:8888/query/\n")
	http.HandleFunc("/process/", processHandler)
	http.HandleFunc("/query/", queryHandler)
	http.ListenAndServe("localhost:8888", nil)
}

func processHandler(rw http.ResponseWriter, req *http.Request) {
	text := strings.TrimSpace(req.PostFormValue("text"))
	fmt.Printf("Processing text: {%v} at %v.\n", text, time.Now())
	result := textlength.ProcessText(text, items)
	fmt.Fprintf(rw, "%v", result)
	fmt.Printf("Returned {%v} at %v.\n", result, time.Now())
}

func queryHandler(rw http.ResponseWriter, req *http.Request) {
	fmt.Printf("Request recieved for index.html at %v\n", time.Now())
	t, _ := template.ParseFiles("index.html")
	t.Execute(rw, t)
}
<commit_msg>remove /query/ from that this takes care of #11<commit_after>package main

import "github.com/genghisjahn/textlength"
import "fmt"
import "net/http"
import "html/template"
import "time"
import "strings"

var items []textlength.TextLengthItem

func main() {
	items, _ = textlength.BuildItems(10000)
	fmt.Printf("Text Length web server is running. %v\n", time.Now())
	fmt.Printf("Navigate your browser to http://localhost:8888/query/\n")
	http.HandleFunc("/process/", processHandler)
	http.HandleFunc("/", queryHandler)
	http.ListenAndServe("localhost:8888", nil)
}

func processHandler(rw http.ResponseWriter, req *http.Request) {
	text := strings.TrimSpace(req.PostFormValue("text"))
	fmt.Printf("Processing text: {%v} at %v.\n", text, time.Now())
	result := textlength.ProcessText(text, items)
	fmt.Fprintf(rw, "%v", result)
	fmt.Printf("Returned {%v} at %v.\n", result, time.Now())
}

func queryHandler(rw http.ResponseWriter, req *http.Request) {
	fmt.Printf("Request recieved for index.html at %v\n", time.Now())
	t, _ := template.ParseFiles("index.html")
	t.Execute(rw, t)
}
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Dgraph Labs, Inc. and Contributors
 *
 * 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 z

import (
	"fmt"
	"math"
	"strings"

	"github.com/dustin/go-humanize"
)

// Creates bounds for an histogram. The bounds are powers of two of the form
// [2^min_exponent, ..., 2^max_exponent].
func HistogramBounds(minExponent, maxExponent uint32) []float64 {
	var bounds []float64
	for i := minExponent; i <= maxExponent; i++ {
		bounds = append(bounds, float64(int(1)<<i))
	}
	return bounds
}

// HistogramData stores the information needed to represent the sizes of the keys and values
// as a histogram.
type HistogramData struct {
	Bounds         []float64
	Count          int64
	CountPerBucket []int64
	Min            int64
	Max            int64
	Sum            int64
}

// NewHistogramData returns a new instance of HistogramData with properly initialized fields.
func NewHistogramData(bounds []float64) *HistogramData {
	return &HistogramData{
		Bounds:         bounds,
		CountPerBucket: make([]int64, len(bounds)+1),
		Max:            0,
		Min:            math.MaxInt64,
	}
}

func (histogram *HistogramData) Copy() *HistogramData {
	if histogram == nil {
		return nil
	}
	return &HistogramData{
		Bounds:         append([]float64{}, histogram.Bounds...),
		CountPerBucket: append([]int64{}, histogram.CountPerBucket...),
		Count:          histogram.Count,
		Min:            histogram.Min,
		Max:            histogram.Max,
		Sum:            histogram.Sum,
	}
}

// Update changes the Min and Max fields if value is less than or greater than the current values.
func (histogram *HistogramData) Update(value int64) {
	if histogram == nil {
		return
	}
	if value > histogram.Max {
		histogram.Max = value
	}
	if value < histogram.Min {
		histogram.Min = value
	}

	histogram.Sum += value
	histogram.Count++

	for index := 0; index <= len(histogram.Bounds); index++ {
		// Allocate value in the last buckets if we reached the end of the Bounds array.
		if index == len(histogram.Bounds) {
			histogram.CountPerBucket[index]++
			break
		}

		if value < int64(histogram.Bounds[index]) {
			histogram.CountPerBucket[index]++
			break
		}
	}
}

// Mean returns the mean value for the histogram.
func (histogram *HistogramData) Mean() float64 {
	if histogram.Count == 0 {
		return 0
	}
	return float64(histogram.Sum) / float64(histogram.Count)
}

// String converts the histogram data into human-readable string.
func (histogram *HistogramData) String() string {
	if histogram == nil {
		return ""
	}
	var b strings.Builder

	b.WriteString("\n -- Histogram: \n")
	b.WriteString(fmt.Sprintf("Min value: %d \n", histogram.Min))
	b.WriteString(fmt.Sprintf("Max value: %d \n", histogram.Max))
	b.WriteString(fmt.Sprintf("Mean: %.2f ", histogram.Mean()))

	numBounds := len(histogram.Bounds)
	for index, count := range histogram.CountPerBucket {
		if count == 0 {
			continue
		}

		// The last bucket represents the bucket that contains the range from
		// the last bound up to infinity so it's processed differently than the
		// other buckets.
		if index == len(histogram.CountPerBucket)-1 {
			lowerBound := uint64(histogram.Bounds[numBounds-1])
			page := float64(count*100) / float64(histogram.Count)
			b.WriteString(fmt.Sprintf("[%s, %s) %d %.2f%% \n",
				humanize.IBytes(lowerBound), "infinity", count, page))
			continue
		}

		upperBound := uint64(histogram.Bounds[index])
		lowerBound := uint64(0)
		if index > 0 {
			lowerBound = uint64(histogram.Bounds[index-1])
		}

		page := float64(count*100) / float64(histogram.Count)
		b.WriteString(fmt.Sprintf("[%s, %s) %d %.2f%% \n",
			humanize.IBytes(lowerBound), humanize.IBytes(upperBound), count, page))
	}
	b.WriteString(" --\n")
	return b.String()
}
<commit_msg>Forgot a newline<commit_after>/*
 * Copyright 2020 Dgraph Labs, Inc. and Contributors
 *
 * 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 z

import (
	"fmt"
	"math"
	"strings"

	"github.com/dustin/go-humanize"
)

// Creates bounds for an histogram. The bounds are powers of two of the form
// [2^min_exponent, ..., 2^max_exponent].
func HistogramBounds(minExponent, maxExponent uint32) []float64 {
	var bounds []float64
	for i := minExponent; i <= maxExponent; i++ {
		bounds = append(bounds, float64(int(1)<<i))
	}
	return bounds
}

// HistogramData stores the information needed to represent the sizes of the keys and values
// as a histogram.
type HistogramData struct {
	Bounds         []float64
	Count          int64
	CountPerBucket []int64
	Min            int64
	Max            int64
	Sum            int64
}

// NewHistogramData returns a new instance of HistogramData with properly initialized fields.
func NewHistogramData(bounds []float64) *HistogramData {
	return &HistogramData{
		Bounds:         bounds,
		CountPerBucket: make([]int64, len(bounds)+1),
		Max:            0,
		Min:            math.MaxInt64,
	}
}

func (histogram *HistogramData) Copy() *HistogramData {
	if histogram == nil {
		return nil
	}
	return &HistogramData{
		Bounds:         append([]float64{}, histogram.Bounds...),
		CountPerBucket: append([]int64{}, histogram.CountPerBucket...),
		Count:          histogram.Count,
		Min:            histogram.Min,
		Max:            histogram.Max,
		Sum:            histogram.Sum,
	}
}

// Update changes the Min and Max fields if value is less than or greater than the current values.
func (histogram *HistogramData) Update(value int64) {
	if histogram == nil {
		return
	}
	if value > histogram.Max {
		histogram.Max = value
	}
	if value < histogram.Min {
		histogram.Min = value
	}

	histogram.Sum += value
	histogram.Count++

	for index := 0; index <= len(histogram.Bounds); index++ {
		// Allocate value in the last buckets if we reached the end of the Bounds array.
		if index == len(histogram.Bounds) {
			histogram.CountPerBucket[index]++
			break
		}

		if value < int64(histogram.Bounds[index]) {
			histogram.CountPerBucket[index]++
			break
		}
	}
}

// Mean returns the mean value for the histogram.
func (histogram *HistogramData) Mean() float64 {
	if histogram.Count == 0 {
		return 0
	}
	return float64(histogram.Sum) / float64(histogram.Count)
}

// String converts the histogram data into human-readable string.
func (histogram *HistogramData) String() string {
	if histogram == nil {
		return ""
	}
	var b strings.Builder

	b.WriteString("\n -- Histogram: \n")
	b.WriteString(fmt.Sprintf("Min value: %d \n", histogram.Min))
	b.WriteString(fmt.Sprintf("Max value: %d \n", histogram.Max))
	b.WriteString(fmt.Sprintf("Mean: %.2f \n", histogram.Mean()))

	numBounds := len(histogram.Bounds)
	for index, count := range histogram.CountPerBucket {
		if count == 0 {
			continue
		}

		// The last bucket represents the bucket that contains the range from
		// the last bound up to infinity so it's processed differently than the
		// other buckets.
		if index == len(histogram.CountPerBucket)-1 {
			lowerBound := uint64(histogram.Bounds[numBounds-1])
			page := float64(count*100) / float64(histogram.Count)
			b.WriteString(fmt.Sprintf("[%s, %s) %d %.2f%% \n",
				humanize.IBytes(lowerBound), "infinity", count, page))
			continue
		}

		upperBound := uint64(histogram.Bounds[index])
		lowerBound := uint64(0)
		if index > 0 {
			lowerBound = uint64(histogram.Bounds[index-1])
		}

		page := float64(count*100) / float64(histogram.Count)
		b.WriteString(fmt.Sprintf("[%s, %s) %d %.2f%% \n",
			humanize.IBytes(lowerBound), humanize.IBytes(upperBound), count, page))
	}
	b.WriteString(" --\n")
	return b.String()
}
<|endoftext|>