<commit_before>package elements

type Stackable interface {
	Add(*Component)
}

type Element interface {
	Add(Element)
	Next() Element
	Parent(Element)
	Root() Element
}

type DefaultElement struct {
	index int
	stack []Element
	root  Element
}

func (d *DefaultElement) Add(e Element) {
	d.stack = append(d.stack, e)
}

func (d *DefaultElement) Parent(p Element) {
	d.root = p
}

func (d *DefaultElement) Root() Element {
	return d.root
}

func (d *DefaultElement) Next() Element {
	index := d.index

	if len(d.stack) > d.index {
		d.index = d.index + 1
		return d.stack[index]
	}

	return nil
}

func NewDefaultElement() DefaultElement {
	d := DefaultElement{}
	d.stack = make([]Element, 0)
	return d
}

type Component struct {
	DefaultElement
	Typ        string
	Identifier string
	Alias      string
}

func NewComponent(l, r Element, typ, identifier string) Element {
	d := NewDefaultElement()
	if l != nil {
		d.Add(l)
	}
	if r != nil {
		d.Add(r)
	}

	c := &Component{
		DefaultElement: d,
		Typ:            typ,
		Identifier:     identifier,
	}

	return c
}

type Matrix struct {
	DefaultElement
}

func NewMatrix(e1 Element) Element {
	d := NewDefaultElement()
	if e1 != nil {
		d.Add(e1)
	}

	m := &Matrix{
		DefaultElement: d,
	}

	return m
}

type List struct {
	DefaultElement
}

func NewList(e1, e2 Element) Element {
	d := NewDefaultElement()
	d.Add(e1)
	d.Add(e2)

	l := &List{
		DefaultElement: d,
	}

	return l
}
<commit_msg>Added output for add<commit_after>package elements

import "fmt"

type Stackable interface {
	Add(*Component)
}

type Element interface {
	Add(Element)
	Next() Element
	Parent(Element)
	Root() Element
}

type DefaultElement struct {
	index int
	stack []Element
	root  Element
}

func (d *DefaultElement) Add(e Element) {
	fmt.Printf("Add %+v to %+v\n", e, d)
	d.stack = append(d.stack, e)
}

func (d *DefaultElement) Parent(p Element) {
	d.root = p
}

func (d *DefaultElement) Root() Element {
	return d.root
}

func (d *DefaultElement) Next() Element {
	index := d.index

	if len(d.stack) > d.index {
		d.index = d.index + 1
		return d.stack[index]
	}

	return nil
}

func NewDefaultElement() DefaultElement {
	d := DefaultElement{}
	d.stack = make([]Element, 0)
	return d
}

type Component struct {
	DefaultElement
	Typ        string
	Identifier string
	Alias      string
}

func NewComponent(l, r Element, typ, identifier, alias string) Element {
	d := NewDefaultElement()
	if l != nil {
		d.Add(l)
	}
	if r != nil {
		d.Add(r)
	}

	c := &Component{
		DefaultElement: d,
		Typ:            typ,
		Identifier:     identifier,
		Alias:          alias,
	}

	return c
}

type Matrix struct {
	DefaultElement
}

func NewMatrix(e1 Element) Element {
	d := NewDefaultElement()
	if e1 != nil {
		d.Add(e1)
	}

	m := &Matrix{
		DefaultElement: d,
	}

	return m
}

type List struct {
	DefaultElement
}

func NewList(e1, e2 Element) Element {
	d := NewDefaultElement()
	d.Add(e1)
	d.Add(e2)

	l := &List{
		DefaultElement: d,
	}

	return l
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"exec"
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"sort"
	"strings"
	"syscall"
)

type TaskResourceUsage struct {
	// User time, in nanoseconds
	userTime int64

	// System time, in nanoseconds
	systemTime int64

	// The number of times the command was executed
	numInvocations int

	dontPrintAverage bool
}

func (t *TaskResourceUsage) TotalTime() int64 {
	return t.userTime + t.systemTime
}

func (t *TaskResourceUsage) AverageTime() float64 {
	return float64(t.TotalTime()) / float64(t.numInvocations)
}

var taskStats = make(map[string]*TaskResourceUsage)

func addResourceUsage(taskName string, usage *syscall.Rusage) {
	taskRUsage := taskStats[taskName]
	if taskRUsage == nil {
		taskRUsage = &TaskResourceUsage{
			userTime:       0,
			systemTime:     0,
			numInvocations: 0,
		}

		taskStats[taskName] = taskRUsage
	}

	taskRUsage.systemTime += int64(usage.Utime.Sec)*1e9 + int64(usage.Utime.Usec)*1e3
	taskRUsage.userTime += int64(usage.Stime.Sec)*1e9 + int64(usage.Stime.Usec)*1e3
	taskRUsage.numInvocations += 1
}

func addSelf() {
	// Remove any previous stats
	taskStats["(self)"] = nil, false
	taskStats["(self.gc)"] = nil, false

	// Enclose the following 5 lines in a comment
	// if the compiler is unable to find 'syscall.Getrusage'
	var usage syscall.Rusage
	errno := syscall.Getrusage(0, &usage)
	if errno == 0 {
		addResourceUsage("(self)", &usage)
	}

	taskStats["(self.gc)"] = &TaskResourceUsage{
		userTime:         int64(runtime.MemStats.PauseTotalNs),
		systemTime:       0,
		numInvocations:   int(runtime.MemStats.NumGC),
		dontPrintAverage: true,
	}
}

func printTimings(out *os.File) {
	addSelf()

	sortedNames := make([]string, len(taskStats))
	maxNameLength := 0
	{
		i := 0
		for name, _ := range taskStats {
			sortedNames[i] = name
			if len(name) > maxNameLength {
				maxNameLength = len(name)
			}
			i++
		}

		sort.StringSlice(sortedNames).Sort()
	}

	fmt.Fprintf(out, "Run times:\n")
	for _, name := range sortedNames {
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "    %s:", name)
		for i := len(name); i < maxNameLength; i++ {
			buf.WriteString(" ")
		}
		taskRUsage := taskStats[name]
		fmt.Fprintf(&buf, " %.3f secs", float64(taskRUsage.TotalTime())/1e9)
		if taskRUsage.numInvocations >= 2 {
			if !taskRUsage.dontPrintAverage {
				fmt.Fprintf(&buf, " (%d invocations, %.3f secs per invocation)",
					taskRUsage.numInvocations, taskRUsage.AverageTime()/1e9)
			} else {
				fmt.Fprintf(&buf, " (%d invocations)", taskRUsage.numInvocations)
			}
		}

		fmt.Fprintf(out, "%s\n", buf.String())
	}
}

type Executable struct {
	name     string
	noLookup bool
	fullPath string // Cached path obtained by calling 'exec.LookPath(name)'
}

type RunFlags struct {
	stdin, stdout, stderr *os.File
	dontPrintCmd          bool
}

func (e *Executable) runSimply(argv []string, dir string, dontPrintCmd bool) os.Error {
	flags := RunFlags{
		stdin:        os.Stdin,
		stdout:       os.Stdout,
		stderr:       os.Stderr,
		dontPrintCmd: false,
	}

	return e.run_lowLevel(argv, dir, flags)
}

// Runs 'e' as separate process, waits until it finishes,
// and returns the data the process sent to its output(s).
// The argument 'in' comprises the command's input.
func (e *Executable) run(argv []string, dir string, in string, mergeStdoutAndStderr bool) (stdout string, stderr string, err os.Error) {
	stdin_r, stdin_w, err := os.Pipe()
	if err != nil {
		return "", "", err
	}

	stdout_r, stdout_w, err := os.Pipe()
	if err != nil {
		stdin_r.Close()
		stdin_w.Close()
		return "", "", err
	}

	var stderr_r, stderr_w *os.File
	if mergeStdoutAndStderr {
		stderr_r, stderr_w = stdout_r, stdout_w
	} else {
		stderr_r, stderr_w, err = os.Pipe()
		if err != nil {
			stdin_r.Close()
			stdin_w.Close()
			stdout_r.Close()
			stdout_w.Close()
			return "", "", err
		}
	}

	errChan := make(chan os.Error, 3)
	stdoutChan := make(chan []byte, 1)
	stderrChan := make(chan []byte, 1)
	{
		// A goroutine for feeding STDIN
		go func() {
			_, err := stdin_w.WriteString(in)
			if err != nil {
				stdin_w.Close()
			} else {
				err = stdin_w.Close()
			}
			errChan <- err
		}()

		// A goroutine for consuming STDOUT.
		// Note: STDOUT is optionally merged with STDERR.
		go func() {
			stdout, err := ioutil.ReadAll(stdout_r)
			if err != nil {
				stdout_r.Close()
				errChan <- err
			} else {
				err = stdout_r.Close()
				errChan <- err
				stdoutChan <- stdout
			}
		}()

		if !mergeStdoutAndStderr {
			// A goroutine for consuming STDERR
			go func() {
				stderr, err := ioutil.ReadAll(stderr_r)
				if err != nil {
					stderr_r.Close()
					errChan <- err
				} else {
					err = stderr_r.Close()
					errChan <- err
					stderrChan <- stderr
				}
			}()
		} else {
			errChan <- nil
			stderrChan <- make([]byte, 0)
		}
	}

	// Execute the command
	flags := RunFlags{
		stdin:        stdin_r,
		stdout:       stdout_w,
		stderr:       stderr_w,
		dontPrintCmd: true,
	}
	err = e.run_lowLevel(argv, dir, flags)

	// Close our ends of the pipes, so that the I/O goroutines can finish
	stdin_r.Close()
	stdout_w.Close()
	if stderr_w != stdout_w {
		stderr_w.Close()
	}

	if err != nil {
		return "", "", err
	}

	err1 := <-errChan
	err2 := <-errChan
	err3 := <-errChan
	if (err1 != nil) || (err2 != nil) || (err3 != nil) {
		err = err1
		if err == nil {
			err = err2
		}
		if err == nil {
			err = err3
		}
		return "", "", err
	}

	stdout = string(<-stdoutChan)
	stderr = string(<-stderrChan)
	return stdout, stderr, nil
}

// Runs 'e' as a separate process and waits until it finishes
func (e *Executable) run_lowLevel(argv []string, dir string, flags RunFlags) os.Error {
	// Resolve 'e.fullpath' (if not resolved yet)
	if len(e.fullPath) == 0 {
		if (e.noLookup == false) || !strings.HasPrefix(e.name, "./") {
			var err os.Error
			e.fullPath, err = exec.LookPath(e.name)
			if err != nil {
				msg := "failed to lookup executable \"" + e.name + "\": " + err.String()
				return os.NewError(msg)
			}
		} else {
			e.fullPath = e.name
		}
	}

	if dir == "." {
		dir = ""
	}

	if (*flag_verbose && !flags.dontPrintCmd) || *flag_debug {
		if len(dir) == 0 {
			fmt.Fprintf(os.Stdout, "(%s)\n", strings.Join(argv, " "))
		} else {
			fmt.Fprintf(os.Stdout, "(cd %s ; %s)\n", dir, strings.Join(argv, " "))
		}
	}

	procAttr := os.ProcAttr{
		Dir:   dir,
		Files: []*os.File{flags.stdin, flags.stdout, flags.stderr},
	}
	process, err := os.StartProcess(e.fullPath, argv, &procAttr)
	if err != nil {
		return err
	}

	waitMsg, err := process.Wait( /*options*/ os.WRUSAGE)
	if err != nil {
		return err
	}
	if *flag_timings {
		addResourceUsage(e.name, waitMsg.Rusage)
	}
	if !waitMsg.Exited() {
		return os.NewError(fmt.Sprintf("unable to obtain the exit status of \"%s\"", e.name))
	}
	if waitMsg.ExitStatus() != 0 {
		var errMsg string
		if len(dir) == 0 {
			errMsg = fmt.Sprintf("command \"%s\" returned an error", strings.Join(argv, " "))
		} else {
			errMsg = fmt.Sprintf("command \"%s\" run in directory \"%s\" returned an error", strings.Join(argv, " "), dir)
		}
		return os.NewError(errMsg)
	}

	return nil
}
<commit_msg>Update in response of Go release.r58<commit_after>package main

import (
	"bytes"
	"exec"
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"sort"
	"strings"
	"syscall"
)

type TaskResourceUsage struct {
	// User time, in nanoseconds
	userTime int64

	// System time, in nanoseconds
	systemTime int64

	// The number of times the command was executed
	numInvocations int

	dontPrintAverage bool
}

func (t *TaskResourceUsage) TotalTime() int64 {
	return t.userTime + t.systemTime
}

func (t *TaskResourceUsage) AverageTime() float64 {
	return float64(t.TotalTime()) / float64(t.numInvocations)
}

var taskStats = make(map[string]*TaskResourceUsage)

func addResourceUsage(taskName string, usage *syscall.Rusage) {
	taskRUsage := taskStats[taskName]
	if taskRUsage == nil {
		taskRUsage = &TaskResourceUsage{
			userTime:       0,
			systemTime:     0,
			numInvocations: 0,
		}

		taskStats[taskName] = taskRUsage
	}

	taskRUsage.systemTime += int64(usage.Utime.Sec)*1e9 + int64(usage.Utime.Usec)*1e3
	taskRUsage.userTime += int64(usage.Stime.Sec)*1e9 + int64(usage.Stime.Usec)*1e3
	taskRUsage.numInvocations += 1
}

func addSelf() {
	// Remove any previous stats
	taskStats["(self)"] = nil, false
	taskStats["(self.gc)"] = nil, false

	// Enclose the following 5 lines in a comment
	// if the compiler is unable to find 'syscall.Getrusage'
	var usage syscall.Rusage
	errno := syscall.Getrusage(0, &usage)
	if errno == 0 {
		addResourceUsage("(self)", &usage)
	}

	taskStats["(self.gc)"] = &TaskResourceUsage{
		userTime:         int64(runtime.MemStats.PauseTotalNs),
		systemTime:       0,
		numInvocations:   int(runtime.MemStats.NumGC),
		dontPrintAverage: true,
	}
}

func printTimings(out *os.File) {
	addSelf()

	sortedNames := make([]string, len(taskStats))
	maxNameLength := 0
	{
		i := 0
		for name, _ := range taskStats {
			sortedNames[i] = name
			if len(name) > maxNameLength {
				maxNameLength = len(name)
			}
			i++
		}

		sort.StringArray(sortedNames).Sort()
	}

	fmt.Fprintf(out, "Run times:\n")
	for _, name := range sortedNames {
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "    %s:", name)
		for i := len(name); i < maxNameLength; i++ {
			buf.WriteString(" ")
		}
		taskRUsage := taskStats[name]
		fmt.Fprintf(&buf, " %.3f secs", float64(taskRUsage.TotalTime())/1e9)
		if taskRUsage.numInvocations >= 2 {
			if !taskRUsage.dontPrintAverage {
				fmt.Fprintf(&buf, " (%d invocations, %.3f secs per invocation)",
					taskRUsage.numInvocations, taskRUsage.AverageTime()/1e9)
			} else {
				fmt.Fprintf(&buf, " (%d invocations)", taskRUsage.numInvocations)
			}
		}

		fmt.Fprintf(out, "%s\n", buf.String())
	}
}

type Executable struct {
	name     string
	noLookup bool
	fullPath string // Cached path obtained by calling 'exec.LookPath(name)'
}

type RunFlags struct {
	stdin, stdout, stderr *os.File
	dontPrintCmd          bool
}

func (e *Executable) runSimply(argv []string, dir string, dontPrintCmd bool) os.Error {
	flags := RunFlags{
		stdin:        os.Stdin,
		stdout:       os.Stdout,
		stderr:       os.Stderr,
		dontPrintCmd: false,
	}

	return e.run_lowLevel(argv, dir, flags)
}

// Runs 'e' as separate process, waits until it finishes,
// and returns the data the process sent to its output(s).
// The argument 'in' comprises the command's input.
func (e *Executable) run(argv []string, dir string, in string, mergeStdoutAndStderr bool) (stdout string, stderr string, err os.Error) {
	stdin_r, stdin_w, err := os.Pipe()
	if err != nil {
		return "", "", err
	}

	stdout_r, stdout_w, err := os.Pipe()
	if err != nil {
		stdin_r.Close()
		stdin_w.Close()
		return "", "", err
	}

	var stderr_r, stderr_w *os.File
	if mergeStdoutAndStderr {
		stderr_r, stderr_w = stdout_r, stdout_w
	} else {
		stderr_r, stderr_w, err = os.Pipe()
		if err != nil {
			stdin_r.Close()
			stdin_w.Close()
			stdout_r.Close()
			stdout_w.Close()
			return "", "", err
		}
	}

	errChan := make(chan os.Error, 3)
	stdoutChan := make(chan []byte, 1)
	stderrChan := make(chan []byte, 1)
	{
		// A goroutine for feeding STDIN
		go func() {
			_, err := stdin_w.WriteString(in)
			if err != nil {
				stdin_w.Close()
			} else {
				err = stdin_w.Close()
			}
			errChan <- err
		}()

		// A goroutine for consuming STDOUT.
		// Note: STDOUT is optionally merged with STDERR.
		go func() {
			stdout, err := ioutil.ReadAll(stdout_r)
			if err != nil {
				stdout_r.Close()
				errChan <- err
			} else {
				err = stdout_r.Close()
				errChan <- err
				stdoutChan <- stdout
			}
		}()

		if !mergeStdoutAndStderr {
			// A goroutine for consuming STDERR
			go func() {
				stderr, err := ioutil.ReadAll(stderr_r)
				if err != nil {
					stderr_r.Close()
					errChan <- err
				} else {
					err = stderr_r.Close()
					errChan <- err
					stderrChan <- stderr
				}
			}()
		} else {
			errChan <- nil
			stderrChan <- make([]byte, 0)
		}
	}

	// Execute the command
	flags := RunFlags{
		stdin:        stdin_r,
		stdout:       stdout_w,
		stderr:       stderr_w,
		dontPrintCmd: true,
	}
	err = e.run_lowLevel(argv, dir, flags)

	// Close our ends of the pipes, so that the I/O goroutines can finish
	stdin_r.Close()
	stdout_w.Close()
	if stderr_w != stdout_w {
		stderr_w.Close()
	}

	if err != nil {
		return "", "", err
	}

	err1 := <-errChan
	err2 := <-errChan
	err3 := <-errChan
	if (err1 != nil) || (err2 != nil) || (err3 != nil) {
		err = err1
		if err == nil {
			err = err2
		}
		if err == nil {
			err = err3
		}
		return "", "", err
	}

	stdout = string(<-stdoutChan)
	stderr = string(<-stderrChan)
	return stdout, stderr, nil
}

// Runs 'e' as a separate process and waits until it finishes
func (e *Executable) run_lowLevel(argv []string, dir string, flags RunFlags) os.Error {
	// Resolve 'e.fullpath' (if not resolved yet)
	if len(e.fullPath) == 0 {
		if (e.noLookup == false) || !strings.HasPrefix(e.name, "./") {
			var err os.Error
			e.fullPath, err = exec.LookPath(e.name)
			if err != nil {
				msg := "failed to lookup executable \"" + e.name + "\": " + err.String()
				return os.NewError(msg)
			}
		} else {
			e.fullPath = e.name
		}
	}

	if dir == "." {
		dir = ""
	}

	if (*flag_verbose && !flags.dontPrintCmd) || *flag_debug {
		if len(dir) == 0 {
			fmt.Fprintf(os.Stdout, "(%s)\n", strings.Join(argv, " "))
		} else {
			fmt.Fprintf(os.Stdout, "(cd %s ; %s)\n", dir, strings.Join(argv, " "))
		}
	}

	procAttr := os.ProcAttr{
		Dir:   dir,
		Files: []*os.File{flags.stdin, flags.stdout, flags.stderr},
	}
	process, err := os.StartProcess(e.fullPath, argv, &procAttr)
	if err != nil {
		return err
	}

	waitMsg, err := process.Wait( /*options*/ os.WRUSAGE)
	if err != nil {
		return err
	}
	if *flag_timings {
		addResourceUsage(e.name, waitMsg.Rusage)
	}
	if !waitMsg.Exited() {
		return os.NewError(fmt.Sprintf("unable to obtain the exit status of \"%s\"", e.name))
	}
	if waitMsg.ExitStatus() != 0 {
		var errMsg string
		if len(dir) == 0 {
			errMsg = fmt.Sprintf("command \"%s\" returned an error", strings.Join(argv, " "))
		} else {
			errMsg = fmt.Sprintf("command \"%s\" run in directory \"%s\" returned an error", strings.Join(argv, " "), dir)
		}
		return os.NewError(errMsg)
	}

	return nil
}
<|endoftext|>


<commit_before>package manager

import (
	"encoding/base64"
	"fmt"

	"errors"

	"github.com/coreos/dex/client"
	pcrypto "github.com/coreos/dex/pkg/crypto"
	"github.com/coreos/dex/pkg/log"
	"github.com/coreos/dex/repo"
	"github.com/coreos/go-oidc/oidc"
	"golang.org/x/crypto/bcrypt"
)

const (
	// Blowfish, the algorithm underlying bcrypt, has a maximum
	// password length of 72. We explicitly track and check this
	// since the bcrypt library will silently ignore portions of
	// a password past the first 72 characters.
	maxSecretLength = 72
)

type SecretGenerator func() ([]byte, error)

func DefaultSecretGenerator() ([]byte, error) {
	return pcrypto.RandBytes(maxSecretLength)
}

func CompareHashAndPassword(hashedPassword, password []byte) error {
	if len(password) > maxSecretLength {
		return errors.New("password length greater than max secret length")
	}
	return bcrypt.CompareHashAndPassword(hashedPassword, password)
}

// ClientManager performs client-related "business-logic" functions on client and related objects.
// This is in contrast to the Repos which perform little more than CRUD operations.
type ClientManager struct {
	clientRepo        client.ClientRepo
	begin             repo.TransactionFactory
	secretGenerator   SecretGenerator
	clientIDGenerator func(string) (string, error)
}

type ManagerOptions struct {
	SecretGenerator   func() ([]byte, error)
	ClientIDGenerator func(string) (string, error)
}

func NewClientManager(clientRepo client.ClientRepo, txnFactory repo.TransactionFactory, options ManagerOptions) *ClientManager {
	if options.SecretGenerator == nil {
		options.SecretGenerator = DefaultSecretGenerator
	}
	if options.ClientIDGenerator == nil {
		options.ClientIDGenerator = oidc.GenClientID
	}
	return &ClientManager{
		clientRepo:        clientRepo,
		begin:             txnFactory,
		secretGenerator:   options.SecretGenerator,
		clientIDGenerator: options.ClientIDGenerator,
	}
}

func NewClientManagerFromClients(clientRepo client.ClientRepo, txnFactory repo.TransactionFactory, clients []client.Client, options ManagerOptions) (*ClientManager, error) {
	clientManager := NewClientManager(clientRepo, txnFactory, options)
	tx, err := clientManager.begin()
	if err != nil {
		return nil, err
	}
	defer tx.Rollback()

	for _, c := range clients {
		if c.Credentials.Secret == "" {
			return nil, fmt.Errorf("client %q has no secret", c.Credentials.ID)
		}

		cli, err := clientManager.generateClientCredentials(c)
		if err != nil {
			return nil, err
		}

		_, err = clientRepo.New(tx, cli)
		if err != nil {
			return nil, err
		}
	}
	if err := tx.Commit(); err != nil {
		return nil, err
	}
	return clientManager, nil
}

func (m *ClientManager) New(cli client.Client) (*oidc.ClientCredentials, error) {
	tx, err := m.begin()
	if err != nil {
		return nil, err
	}
	defer tx.Rollback()

	c, err := m.generateClientCredentials(cli)
	if err != nil {
		return nil, err
	}

	creds := c.Credentials

	// Save Client
	_, err = m.clientRepo.New(tx, c)
	if err != nil {
		return nil, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, err
	}

	// Returns creds with unhashed secret
	return &creds, nil
}

func (m *ClientManager) Get(id string) (client.Client, error) {
	return m.clientRepo.Get(nil, id)
}

func (m *ClientManager) All() ([]client.Client, error) {
	return m.clientRepo.All(nil)
}

func (m *ClientManager) Metadata(clientID string) (*oidc.ClientMetadata, error) {
	c, err := m.clientRepo.Get(nil, clientID)
	if err != nil {
		return nil, err
	}

	return &c.Metadata, nil
}

func (m *ClientManager) IsDexAdmin(clientID string) (bool, error) {
	c, err := m.clientRepo.Get(nil, clientID)
	if err != nil {
		return false, err
	}

	return c.Admin, nil
}

func (m *ClientManager) SetDexAdmin(clientID string, isAdmin bool) error {
	tx, err := m.begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	c, err := m.clientRepo.Get(tx, clientID)
	if err != nil {
		return err
	}

	c.Admin = isAdmin
	err = m.clientRepo.Update(tx, c)
	if err != nil {
		return err
	}

	err = tx.Commit()
	if err != nil {
		return err
	}
	return nil
}

func (m *ClientManager) Authenticate(creds oidc.ClientCredentials) (bool, error) {
	clientSecret, err := m.clientRepo.GetSecret(nil, creds.ID)
	if err != nil || clientSecret == nil {
		return false, nil
	}

	dec, err := base64.URLEncoding.DecodeString(creds.Secret)
	if err != nil {
		log.Errorf("error Decoding client creds: %v", err)
		return false, nil
	}

	ok := CompareHashAndPassword(clientSecret, dec) == nil
	return ok, nil
}

func (m *ClientManager) generateClientCredentials(cli client.Client) (client.Client, error) {
	// Generate Client ID
	if len(cli.Metadata.RedirectURIs) < 1 {
		return cli, errors.New("no client redirect url given")
	}
	clientID, err := m.clientIDGenerator(cli.Metadata.RedirectURIs[0].Host)
	if err != nil {
		return cli, err
	}

	// Generate Secret
	secret, err := m.secretGenerator()
	if err != nil {
		return cli, err
	}
	clientSecret := base64.URLEncoding.EncodeToString(secret)
	cli.Credentials = oidc.ClientCredentials{
		ID:     clientID,
		Secret: clientSecret,
	}
	return cli, nil
}
<commit_msg>client: generateClientCreds -> addClientCreds<commit_after>package manager

import (
	"encoding/base64"
	"fmt"

	"errors"

	"github.com/coreos/dex/client"
	pcrypto "github.com/coreos/dex/pkg/crypto"
	"github.com/coreos/dex/pkg/log"
	"github.com/coreos/dex/repo"
	"github.com/coreos/go-oidc/oidc"
	"golang.org/x/crypto/bcrypt"
)

const (
	// Blowfish, the algorithm underlying bcrypt, has a maximum
	// password length of 72. We explicitly track and check this
	// since the bcrypt library will silently ignore portions of
	// a password past the first 72 characters.
	maxSecretLength = 72
)

type SecretGenerator func() ([]byte, error)

func DefaultSecretGenerator() ([]byte, error) {
	return pcrypto.RandBytes(maxSecretLength)
}

func CompareHashAndPassword(hashedPassword, password []byte) error {
	if len(password) > maxSecretLength {
		return errors.New("password length greater than max secret length")
	}
	return bcrypt.CompareHashAndPassword(hashedPassword, password)
}

// ClientManager performs client-related "business-logic" functions on client and related objects.
// This is in contrast to the Repos which perform little more than CRUD operations.
type ClientManager struct {
	clientRepo        client.ClientRepo
	begin             repo.TransactionFactory
	secretGenerator   SecretGenerator
	clientIDGenerator func(string) (string, error)
}

type ManagerOptions struct {
	SecretGenerator   func() ([]byte, error)
	ClientIDGenerator func(string) (string, error)
}

func NewClientManager(clientRepo client.ClientRepo, txnFactory repo.TransactionFactory, options ManagerOptions) *ClientManager {
	if options.SecretGenerator == nil {
		options.SecretGenerator = DefaultSecretGenerator
	}
	if options.ClientIDGenerator == nil {
		options.ClientIDGenerator = oidc.GenClientID
	}
	return &ClientManager{
		clientRepo:        clientRepo,
		begin:             txnFactory,
		secretGenerator:   options.SecretGenerator,
		clientIDGenerator: options.ClientIDGenerator,
	}
}

func NewClientManagerFromClients(clientRepo client.ClientRepo, txnFactory repo.TransactionFactory, clients []client.Client, options ManagerOptions) (*ClientManager, error) {
	clientManager := NewClientManager(clientRepo, txnFactory, options)
	tx, err := clientManager.begin()
	if err != nil {
		return nil, err
	}
	defer tx.Rollback()

	for _, c := range clients {
		if c.Credentials.Secret == "" {
			return nil, fmt.Errorf("client %q has no secret", c.Credentials.ID)
		}

		err := clientManager.addClientCredentials(&c)
		if err != nil {
			return nil, err
		}

		_, err = clientRepo.New(tx, c)
		if err != nil {
			return nil, err
		}
	}
	if err := tx.Commit(); err != nil {
		return nil, err
	}
	return clientManager, nil
}

func (m *ClientManager) New(cli client.Client) (*oidc.ClientCredentials, error) {
	tx, err := m.begin()
	if err != nil {
		return nil, err
	}
	defer tx.Rollback()

	err = m.addClientCredentials(&cli)
	if err != nil {
		return nil, err
	}

	creds := cli.Credentials

	// Save Client
	_, err = m.clientRepo.New(tx, cli)
	if err != nil {
		return nil, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, err
	}

	// Returns creds with unhashed secret
	return &creds, nil
}

func (m *ClientManager) Get(id string) (client.Client, error) {
	return m.clientRepo.Get(nil, id)
}

func (m *ClientManager) All() ([]client.Client, error) {
	return m.clientRepo.All(nil)
}

func (m *ClientManager) Metadata(clientID string) (*oidc.ClientMetadata, error) {
	c, err := m.clientRepo.Get(nil, clientID)
	if err != nil {
		return nil, err
	}

	return &c.Metadata, nil
}

func (m *ClientManager) IsDexAdmin(clientID string) (bool, error) {
	c, err := m.clientRepo.Get(nil, clientID)
	if err != nil {
		return false, err
	}

	return c.Admin, nil
}

func (m *ClientManager) SetDexAdmin(clientID string, isAdmin bool) error {
	tx, err := m.begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	c, err := m.clientRepo.Get(tx, clientID)
	if err != nil {
		return err
	}

	c.Admin = isAdmin
	err = m.clientRepo.Update(tx, c)
	if err != nil {
		return err
	}

	err = tx.Commit()
	if err != nil {
		return err
	}
	return nil
}

func (m *ClientManager) Authenticate(creds oidc.ClientCredentials) (bool, error) {
	clientSecret, err := m.clientRepo.GetSecret(nil, creds.ID)
	if err != nil || clientSecret == nil {
		return false, nil
	}

	dec, err := base64.URLEncoding.DecodeString(creds.Secret)
	if err != nil {
		log.Errorf("error Decoding client creds: %v", err)
		return false, nil
	}

	ok := CompareHashAndPassword(clientSecret, dec) == nil
	return ok, nil
}

func (m *ClientManager) addClientCredentials(cli *client.Client) error {
	// Generate Client ID
	if len(cli.Metadata.RedirectURIs) < 1 {
		return errors.New("no client redirect url given")
	}
	clientID, err := m.clientIDGenerator(cli.Metadata.RedirectURIs[0].Host)
	if err != nil {
		return err
	}

	// Generate Secret
	secret, err := m.secretGenerator()
	if err != nil {
		return err
	}
	clientSecret := base64.URLEncoding.EncodeToString(secret)
	cli.Credentials = oidc.ClientCredentials{
		ID:     clientID,
		Secret: clientSecret,
	}
	return nil
}
<|endoftext|>


<commit_before>package api

import (
	"github.com/hashicorp/nomad/api/contexts"
)

type Search struct {
	client *Client
}

// Search returns a handle on the Search endpoints
func (c *Client) Search() *Search {
	return &Search{client: c}
}

// PrefixSearch returns a list of matches for a particular context and prefix. If a
// context is not specified, matches for all contexts are returned.
func (s *Search) PrefixSearch(prefix string, context contexts.Context) (*SearchResponse, error) {
	var resp SearchResponse
	req := &SearchRequest{Prefix: prefix, Context: context}

	_, err := s.client.write("/v1/search", req, &resp, nil)
	if err != nil {
		return nil, err
	}

	return &resp, nil
}

type SearchRequest struct {
	Prefix  string
	Context contexts.Context
}

type SearchResponse struct {
	Matches     map[contexts.Context][]string
	Truncations map[contexts.Context]bool
	QueryMeta
}
<commit_msg>update comment for revised contexts<commit_after>package api

import (
	"github.com/hashicorp/nomad/api/contexts"
)

type Search struct {
	client *Client
}

// Search returns a handle on the Search endpoints
func (c *Client) Search() *Search {
	return &Search{client: c}
}

// PrefixSearch returns a list of matches for a particular context and prefix.
func (s *Search) PrefixSearch(prefix string, context contexts.Context) (*SearchResponse, error) {
	var resp SearchResponse
	req := &SearchRequest{Prefix: prefix, Context: context}

	_, err := s.client.write("/v1/search", req, &resp, nil)
	if err != nil {
		return nil, err
	}

	return &resp, nil
}

type SearchRequest struct {
	Prefix  string
	Context contexts.Context
}

type SearchResponse struct {
	Matches     map[contexts.Context][]string
	Truncations map[contexts.Context]bool
	QueryMeta
}
<|endoftext|>


<commit_before>// Public domain 2014, author: Sonia Keys.

// Exit provides a way to exit from a program that runs deferred functions,
// logs a message to stderr, and then exits with an operating system exit code.
//
// The following example program is in source subdirectory "example".
//
//   package main
//
//   import (
//      "fmt"
//
//      "github.com/soniakeys/exit"
//   )
//
//   func main() {
//     defer exit.Handler() // do this once at the beginning of the program
//     f()
//     fmt.Println("f returned")
//   }
//
//   func f() {
//      defer fmt.Println("f cleanup")
//      fmt.Println("f attempt")
//      if !false {
//         exit.Log("Fatal error in f") // use exit.Log anywhere
//      }
//      fmt.Println("f completed")
//   }
//
// This prints "f attempt" and "f cleanup" to stdout, logs "Fatal error in f"
// to stderr, and exits with a program exit code of 1.
package exit

import (
	"fmt"
	"log"
	"os"

	"golang.org/x/crypto/ssh/terminal"
)

// Exit specifies an exit code and logger for logging a final message.
//
// If Logger is nil, the log package default logger is used.
type Exit struct {
	ExitCode int
	*log.Logger
}

// Default holds Exit setting for the Log and Logf functions.
var Default = Exit{ExitCode: 1}

type msg struct {
	Exit
	string
}

// Handler is the fatal error handler.  Defer at the start of main() before
// calling any of Code, Log, Logf, Exit.Log, or Exit.Logf.
//
// When Handler is deferred first, Go ensures that all other deferred functions
// are run first.  Handler then handles paincs originating from Code, Log,
// Logf, Exit.Log, or Exit.Logf by logging a message and then exiting with
// an exit code.
//
// There are a couple of frills.  Empty messages are not logged; the program
// simply exits with the specifed code.  With non-empty messages, if a logger
// is not specified and stderr seems to be directed to a terminal, Handler sets
// logging flags 0 to suppress the usual date and time stamp.
func Handler() {
	err := recover()
	if err == nil {
		return
	}
	m, ok := err.(msg)
	if !ok {
		panic(err)
	}
	if m.string > "\n" {
		switch {
		case m.Logger != nil:
			m.Logger.Print(m.string)
		case terminal.IsTerminal(int(os.Stderr.Fd())):
			log.SetFlags(0)
			fallthrough
		default:
			log.Print(m.string)
		}
	}
	os.Exit(m.ExitCode)
}

// Log runs any deferred functions, logs a message as with log.Println,
// then exits the program with an exit code.
//
// The logger and exit code used are those of exit.Default.
func Log(args ...interface{}) {
	panic(msg{Default, fmt.Sprintln(args...)})
}

// Logf calls any deferred functions, logs a message as with log.Printf,
// then exits the program with an exit code.
//
// The logger and exit code used are those of exit.Default.
func Logf(format string, args ...interface{}) {
	panic(msg{Default, fmt.Sprintf(format, args...)})
}

// Code runs any deferred functions, then exits the program with the given
// exit code.
func Code(code int) {
	Default.ExitCode = code
	panic(msg{Default, ""})
}

// Log runs any deferred functions, logs a message as with log.Println,
// then exits the program with an exit code.
//
// The logger and exit code used are those of the receiver x.
func (x Exit) Log(args ...interface{}) {
	panic(msg{x, fmt.Sprintln(args...)})
}

// Logf calls any deferred functions, logs a message as with log.Printf,
// then exits the program with an exit code.
//
// The logger and exit code used are those of the receiver x.
func (x Exit) Logf(format string, args ...interface{}) {
	panic(msg{x, fmt.Sprintf(format, args...)})
}
<commit_msg>misspell<commit_after>// Public domain 2014, author: Sonia Keys.

// Exit provides a way to exit from a program that runs deferred functions,
// logs a message to stderr, and then exits with an operating system exit code.
//
// The following example program is in source subdirectory "example".
//
//   package main
//
//   import (
//      "fmt"
//
//      "github.com/soniakeys/exit"
//   )
//
//   func main() {
//     defer exit.Handler() // do this once at the beginning of the program
//     f()
//     fmt.Println("f returned")
//   }
//
//   func f() {
//      defer fmt.Println("f cleanup")
//      fmt.Println("f attempt")
//      if !false {
//         exit.Log("Fatal error in f") // use exit.Log anywhere
//      }
//      fmt.Println("f completed")
//   }
//
// This prints "f attempt" and "f cleanup" to stdout, logs "Fatal error in f"
// to stderr, and exits with a program exit code of 1.
package exit

import (
	"fmt"
	"log"
	"os"

	"golang.org/x/crypto/ssh/terminal"
)

// Exit specifies an exit code and logger for logging a final message.
//
// If Logger is nil, the log package default logger is used.
type Exit struct {
	ExitCode int
	*log.Logger
}

// Default holds Exit setting for the Log and Logf functions.
var Default = Exit{ExitCode: 1}

type msg struct {
	Exit
	string
}

// Handler is the fatal error handler.  Defer at the start of main() before
// calling any of Code, Log, Logf, Exit.Log, or Exit.Logf.
//
// When Handler is deferred first, Go ensures that all other deferred functions
// are run first.  Handler then handles paincs originating from Code, Log,
// Logf, Exit.Log, or Exit.Logf by logging a message and then exiting with
// an exit code.
//
// There are a couple of frills.  Empty messages are not logged; the program
// simply exits with the specified code.  With non-empty messages, if a logger
// is not specified and stderr seems to be directed to a terminal, Handler sets
// logging flags 0 to suppress the usual date and time stamp.
func Handler() {
	err := recover()
	if err == nil {
		return
	}
	m, ok := err.(msg)
	if !ok {
		panic(err)
	}
	if m.string > "\n" {
		switch {
		case m.Logger != nil:
			m.Logger.Print(m.string)
		case terminal.IsTerminal(int(os.Stderr.Fd())):
			log.SetFlags(0)
			fallthrough
		default:
			log.Print(m.string)
		}
	}
	os.Exit(m.ExitCode)
}

// Log runs any deferred functions, logs a message as with log.Println,
// then exits the program with an exit code.
//
// The logger and exit code used are those of exit.Default.
func Log(args ...interface{}) {
	panic(msg{Default, fmt.Sprintln(args...)})
}

// Logf calls any deferred functions, logs a message as with log.Printf,
// then exits the program with an exit code.
//
// The logger and exit code used are those of exit.Default.
func Logf(format string, args ...interface{}) {
	panic(msg{Default, fmt.Sprintf(format, args...)})
}

// Code runs any deferred functions, then exits the program with the given
// exit code.
func Code(code int) {
	Default.ExitCode = code
	panic(msg{Default, ""})
}

// Log runs any deferred functions, logs a message as with log.Println,
// then exits the program with an exit code.
//
// The logger and exit code used are those of the receiver x.
func (x Exit) Log(args ...interface{}) {
	panic(msg{x, fmt.Sprintln(args...)})
}

// Logf calls any deferred functions, logs a message as with log.Printf,
// then exits the program with an exit code.
//
// The logger and exit code used are those of the receiver x.
func (x Exit) Logf(format string, args ...interface{}) {
	panic(msg{x, fmt.Sprintf(format, args...)})
}
<|endoftext|>


<commit_before>// Package symexpr implements symbolic equations as an AST.
// It aims to provide ease of dynamic manipulation of the tree.
//
// This work comes out of my Masters thesis at Binghamton University
// and is geared towards Symbolic Regression.
//
package symexpr

import (
	"math"
)

type ExprType int

const (
	NULL      ExprType = iota
	CONSTANT           // indexed constant, useful for regression tasks
	CONSTANTF          // floating point constant
	TIME               // useful when looking at time series and RK4 integration
	SYSTEM             // i use this like a variable that changes between experiments, but not with time (mass,size,etc.)
	VAR                // a canonical variable

	NEG
	ABS
	SQRT
	SIN
	COS
	TAN
	EXP
	LOG
	POWI // Expr^Integer
	POWF // Expr^Float

	POWE // Expr^Expr
	DIV

	ADD // these can have more than two child nodes
	MUL // this eases simplification

	EXPR_MAX
	STARTVAR // for serialization reduction of variables
)

// Expr is the interface to all node types for the AST of mathematical expression
//
type Expr interface {

	// types.go (this file)
	ExprType() ExprType
	Clone() Expr

	// stats.go
	Size() int
	Depth() int
	Height() int
	NumChildren() int
	CalcExprStats(currDepth int) (mySize int)

	// compare.go
	AmILess(rhs Expr) bool
	AmIEqual(rhs Expr) bool
	AmISame(rhs Expr) bool       // equality without coefficient values/index
	AmIAlmostSame(rhs Expr) bool // adds flexibility to mul comparison to AmISame
	Sort()

	// has.go
	HasVar() bool
	HasVarI(i int) bool
	NumVar() int

	// DFS for a floating point valued ConstantF
	HasConst() bool
	// DFS for a indexed valued Constant
	HasConstI(i int) bool
	// Counts the number of indexed Constant nodes
	NumConstants() int

	// convert.go

	// Converts indexed Constant nodes to ConstantF nodes
	// using the input slice as the values for replacement
	ConvertToConstantFs(cs []float64) Expr
	// DFS converting float valued constants to indexed constants
	// the input should be an empty slice
	// the output is an appended slice the size = |ConstantF| in the tree
	ConvertToConstants(cs []float64) ([]float64, Expr)
	//   IndexConstants( ci int ) int

	// getset.go
	// DFS retrieval of a node by index
	GetExpr(pos *int) Expr
	// DFS replacement of a node and it's subtree
	// replaced is used to discontinue the DFS after replacement
	// replace_me gets triggered when pos == 0 and informs the parent node to replace the respective child node
	SetExpr(pos *int, e Expr) (replace_me, replaced bool)

	// print.go

	// prints the AST
	String() string

	// creates an integer representation of the AST in ~prefix notation
	// The input is an empty slice, output is the representation.
	// The output is generally the ExprType integer value
	// Associative operators (+ & *) also include the number of children.
	// The terminal nodes include the index when appropriate.
	Serial([]int) []int

	// Pretty print acts like String, but replaces the internal indexed
	// formatting with user specified strings and values
	PrettyPrint(dnames, snames []string, cvals []float64) string
	// 	WriteString( buf *bytes.Buffer )

	// Similar to PrettyPrint, but in latex format
	Latex(dnames, snames []string, cvals []float64) string

	// eval.go
	// Evaluates an expression at one point
	// t is a time value
	// x are the input Var values
	// c are the indexed Constant values
	// s are the indexed System values
	// the output is the result of DFS evaluation
	Eval(t float64, x, c, s []float64) float64

	// simp.go
	Simplify(rules SimpRules) Expr

	// deriv.go
	// Calculate the derivative w.r.t. Var_i
	DerivVar(i int) Expr
	// Calculate the derivative w.r.t. Constant_i
	DerivConst(i int) Expr
}

type ExprArray []Expr

func (p ExprArray) Len() int      { return len(p) }
func (p ExprArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p ExprArray) Less(i, j int) bool {
	if p[i] == nil && p[j] == nil {
		return false
	}
	if p[i] == nil {
		return false
	}
	if p[j] == nil {
		return true
	}
	return p[i].AmILess(p[j])
}

// Null Leaf  (shouldn't really appear)
// This is a sample for the other node types
type Null struct {
	ExprStats
}

func NewNull() Expr                { return new(Null) }
func (n *Null) ExprType() ExprType { return NULL }
func (n *Null) Clone() Expr        { return &Null{ExprStats{0, 0, 0, 0}} }

func (n *Null) CalcExprStats(currDepth int) (mySize int) {
	n.depth = currDepth + 1
	n.height = 0
	n.size = 0
	n.numchld = 0
	return n.size
}

func (n *Null) AmILess(r Expr) bool       { return NULL < r.ExprType() }
func (n *Null) AmIEqual(r Expr) bool      { return r.ExprType() == NULL }
func (n *Null) AmISame(r Expr) bool       { return r.ExprType() == NULL }
func (n *Null) AmIAlmostSame(r Expr) bool { return r.ExprType() == NULL }
func (n *Null) Sort()                     { return }

func (n *Null) HasVar() bool         { return false }
func (n *Null) HasVarI(i int) bool   { return false }
func (n *Null) NumVar() int          { return 0 }
func (n *Null) HasConst() bool       { return false }
func (n *Null) HasConstI(i int) bool { return false }
func (n *Null) NumConstants() int    { return 0 }

func (n *Null) ConvertToConstantFs(cs []float64) Expr             { return n }
func (n *Null) ConvertToConstants(cs []float64) ([]float64, Expr) { return cs, n }

func (n *Null) GetExpr(pos *int) Expr {
	if (*pos) == 0 {
		return n
	}
	(*pos)--
	return nil
}
func (n *Null) SetExpr(pos *int, e Expr) (replace_me, replaced bool) {
	if (*pos) == 0 {
		return true, false
	}
	(*pos)--
	return false, false
}

func (n *Null) String() string                                              { return "NULL" }
func (n *Null) Serial(sofar []int) []int                                    { return append(sofar, int(NULL)) }
func (n *Null) PrettyPrint(dnames, snames []string, cvals []float64) string { return "NULL" }
func (n *Null) Latex(dnames, snames []string, cvals []float64) string       { return "NULL" }

func (n *Null) Eval(t float64, x, c, s []float64) float64 { return math.NaN() }

func (n *Null) Simplify(rules SimpRules) Expr { return n }

func (n *Null) DerivConst(i int) Expr { return &ConstantF{F: 0} }
func (n *Null) DerivVar(i int) Expr   { return &ConstantF{F: 0} }
<commit_msg>added named range ends to const ExprType<commit_after>// Package symexpr implements symbolic equations as an AST.
// It aims to provide ease of dynamic manipulation of the tree.
//
// This work comes out of my Masters thesis at Binghamton University
// and is geared towards Symbolic Regression.
//
package symexpr

import (
	"math"
)

type ExprType int

const (
	NULL ExprType = iota

	STARTLEAF
	CONSTANT  // indexed constant, useful for non-linear regression tasks
	CONSTANTF // floating point constant
	TIME      // useful when looking at time series and RK4 integration
	SYSTEM    // i use this like a variable that changes between experiments, but not with time (mass,size,etc.)
	VAR       // a canonical variable
	LASTLEAF

	STARTFUNC
	NEG
	ABS
	SQRT
	SIN
	COS
	TAN
	EXP
	LOG
	LASTFUNC

	POWI // Expr^Integer
	POWF // Expr^Float
	POWE // Expr^Expr
	DIV  // Expr/Expr

	ADD // these can have more than two child nodes
	MUL // this eases sorting and simplification

	EXPR_MAX
	STARTVAR // for serialization reduction of variables
)

// Expr is the interface to all node types for the AST of mathematical expression
//
type Expr interface {

	// types.go (this file)
	ExprType() ExprType
	Clone() Expr

	// stats.go
	Size() int
	Depth() int
	Height() int
	NumChildren() int
	CalcExprStats(currDepth int) (mySize int)

	// compare.go
	AmILess(rhs Expr) bool
	AmIEqual(rhs Expr) bool
	AmISame(rhs Expr) bool       // equality without coefficient values/index
	AmIAlmostSame(rhs Expr) bool // adds flexibility to mul comparison to AmISame
	Sort()

	// has.go
	HasVar() bool
	HasVarI(i int) bool
	NumVar() int

	// DFS for a floating point valued ConstantF
	HasConst() bool
	// DFS for a indexed valued Constant
	HasConstI(i int) bool
	// Counts the number of indexed Constant nodes
	NumConstants() int

	// convert.go

	// Converts indexed Constant nodes to ConstantF nodes
	// using the input slice as the values for replacement
	ConvertToConstantFs(cs []float64) Expr
	// DFS converting float valued constants to indexed constants
	// the input should be an empty slice
	// the output is an appended slice the size = |ConstantF| in the tree
	ConvertToConstants(cs []float64) ([]float64, Expr)
	//   IndexConstants( ci int ) int

	// getset.go
	// DFS retrieval of a node by index
	GetExpr(pos *int) Expr
	// DFS replacement of a node and it's subtree
	// replaced is used to discontinue the DFS after replacement
	// replace_me gets triggered when pos == 0 and informs the parent node to replace the respective child node
	SetExpr(pos *int, e Expr) (replace_me, replaced bool)

	// print.go

	// prints the AST
	String() string

	// creates an integer representation of the AST in ~prefix notation
	// The input is an empty slice, output is the representation.
	// The output is generally the ExprType integer value
	// Associative operators (+ & *) also include the number of children.
	// The terminal nodes include the index when appropriate.
	Serial([]int) []int

	// Pretty print acts like String, but replaces the internal indexed
	// formatting with user specified strings and values
	PrettyPrint(dnames, snames []string, cvals []float64) string
	// 	WriteString( buf *bytes.Buffer )

	// Similar to PrettyPrint, but in latex format
	Latex(dnames, snames []string, cvals []float64) string

	// eval.go
	// Evaluates an expression at one point
	// t is a time value
	// x are the input Var values
	// c are the indexed Constant values
	// s are the indexed System values
	// the output is the result of DFS evaluation
	Eval(t float64, x, c, s []float64) float64

	// simp.go
	Simplify(rules SimpRules) Expr

	// deriv.go
	// Calculate the derivative w.r.t. Var_i
	DerivVar(i int) Expr
	// Calculate the derivative w.r.t. Constant_i
	DerivConst(i int) Expr
}

type ExprArray []Expr

func (p ExprArray) Len() int      { return len(p) }
func (p ExprArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p ExprArray) Less(i, j int) bool {
	if p[i] == nil && p[j] == nil {
		return false
	}
	if p[i] == nil {
		return false
	}
	if p[j] == nil {
		return true
	}
	return p[i].AmILess(p[j])
}

// Null Leaf  (shouldn't really appear)
// This is a sample for the other node types
type Null struct {
	ExprStats
}

func NewNull() Expr                { return new(Null) }
func (n *Null) ExprType() ExprType { return NULL }
func (n *Null) Clone() Expr        { return &Null{ExprStats{0, 0, 0, 0}} }

func (n *Null) CalcExprStats(currDepth int) (mySize int) {
	n.depth = currDepth + 1
	n.height = 0
	n.size = 0
	n.numchld = 0
	return n.size
}

func (n *Null) AmILess(r Expr) bool       { return NULL < r.ExprType() }
func (n *Null) AmIEqual(r Expr) bool      { return r.ExprType() == NULL }
func (n *Null) AmISame(r Expr) bool       { return r.ExprType() == NULL }
func (n *Null) AmIAlmostSame(r Expr) bool { return r.ExprType() == NULL }
func (n *Null) Sort()                     { return }

func (n *Null) HasVar() bool         { return false }
func (n *Null) HasVarI(i int) bool   { return false }
func (n *Null) NumVar() int          { return 0 }
func (n *Null) HasConst() bool       { return false }
func (n *Null) HasConstI(i int) bool { return false }
func (n *Null) NumConstants() int    { return 0 }

func (n *Null) ConvertToConstantFs(cs []float64) Expr             { return n }
func (n *Null) ConvertToConstants(cs []float64) ([]float64, Expr) { return cs, n }

func (n *Null) GetExpr(pos *int) Expr {
	if (*pos) == 0 {
		return n
	}
	(*pos)--
	return nil
}
func (n *Null) SetExpr(pos *int, e Expr) (replace_me, replaced bool) {
	if (*pos) == 0 {
		return true, false
	}
	(*pos)--
	return false, false
}

func (n *Null) String() string                                              { return "NULL" }
func (n *Null) Serial(sofar []int) []int                                    { return append(sofar, int(NULL)) }
func (n *Null) PrettyPrint(dnames, snames []string, cvals []float64) string { return "NULL" }
func (n *Null) Latex(dnames, snames []string, cvals []float64) string       { return "NULL" }

func (n *Null) Eval(t float64, x, c, s []float64) float64 { return math.NaN() }

func (n *Null) Simplify(rules SimpRules) Expr { return n }

func (n *Null) DerivConst(i int) Expr { return &ConstantF{F: 0} }
func (n *Null) DerivVar(i int) Expr   { return &ConstantF{F: 0} }
<|endoftext|>


<commit_before>package api

import (
	"fmt"
	"net/http"

	htr "github.com/julienschmidt/httprouter"

	"github.com/synapse-garden/mf-proto/db"
)

func Source(d db.DB) API {
	return func(r *htr.Router) error {
		r.GET("/source", handleSource)
		return nil
	}
}

func handleSource(w http.ResponseWriter, r *http.Request, ps htr.Params) {
	fmt.Fprint(w, `---     S Y N A P S E G A R D E N      ---
            MF-Proto v0.3.0
         © SynapseGarden 2015
 Licensed under Affero GNU Public License
                version 3
https://github.com/synapse-garden/mf-proto
---                                    ---
`)
}
<commit_msg>Move source text to const<commit_after>package api

import (
	"fmt"
	"net/http"

	htr "github.com/julienschmidt/httprouter"

	"github.com/synapse-garden/mf-proto/db"
)

const source = `---     S Y N A P S E G A R D E N      ---
            MF-Proto v0.3.0
         © SynapseGarden 2015
 Licensed under Affero GNU Public License
                version 3
https://github.com/synapse-garden/mf-proto
---                                    ---
`

func Source(d db.DB) API {
	return func(r *htr.Router) error {
		r.GET("/source", handleSource)
		return nil
	}
}

func handleSource(w http.ResponseWriter, r *http.Request, ps htr.Params) {
	fmt.Fprint(w, source)
}
<|endoftext|>


<commit_before>package main

import (
	"compress/bzip2"
	"flag"
	"fmt"
	"github.com/semanticize/dumpparser/hash"
	"github.com/semanticize/dumpparser/hash/countmin"
	"github.com/semanticize/dumpparser/nlp"
	"github.com/semanticize/dumpparser/storage"
	"github.com/semanticize/dumpparser/wikidump"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"sync"
)

func open(path string) (r io.ReadCloser, err error) {
	r, err = os.Open(path)
	if err == nil && filepath.Ext(path) == ".bz2" {
		r = struct {
			io.Reader
			io.Closer
		}{bzip2.NewReader(r), r}
	}
	return
}

var download = flag.String("download", "",
	"download Wikipedia dump (e.g., 'enwiki')")
var nrows = flag.Uint("nrows", 16, "number of rows in count-min sketch")
var ncols = flag.Uint("ncols", 262144, "number of columns in count-min sketch")
var maxNGram = flag.Uint("ngram", 7, "max. length of n-grams")

func main() {
	log.SetPrefix("dumpparser ")

	var err error
	check := func() {
		if err != nil {
			log.Fatal(err)
		}
	}

	flag.Parse()
	args := flag.Args()

	var dbpath, inputpath string
	if *download != "" {
		if len(args) != 1 {
			fmt.Fprintf(os.Stderr,
				"usage: %s -download=wikiname model.db\n", os.Args[0])
			os.Exit(1)
		}
		inputpath, err = wikidump.Download(*download, true)
		check()
		dbpath = args[0]
	} else {
		if len(args) != 2 {
			fmt.Fprintf(os.Stderr, "usage: %s wikidump model.db\n", os.Args[0])
			os.Exit(1)
		}
		inputpath, dbpath = args[0], args[1]
	}

	f, err := open(inputpath)
	check()
	defer f.Close()

	log.Printf("Creating database at %s", dbpath)
	db, err := storage.MakeDB(dbpath, true)
	check()

	// The numbers here are completely arbitrary.
	nworkers := runtime.GOMAXPROCS(0)
	articles := make(chan *wikidump.Page, 10*nworkers)
	links := make(chan map[wikidump.Link]int, 10*nworkers)
	redirects := make(chan *wikidump.Redirect, 100)

	var wg sync.WaitGroup

	// Collect redirects.
	wg.Add(1)
	redirmap := make(map[string]string)
	go func() {
		for r := range redirects {
			redirmap[r.Title] = r.Target
		}
		wg.Done()
	}()

	// Clean up and tokenize articles, extract links, count n-grams.
	maxN := int(*maxNGram)
	counters := make([]*countmin.Sketch, nworkers)

	var worker sync.WaitGroup
	worker.Add(nworkers)
	log.Printf("%d workers", nworkers)
	for i := 0; i < nworkers; i++ {
		counters[i] = countmin.New(int(*nrows), int(*ncols))

		go func(ngramcount *countmin.Sketch) {
			for a := range articles {
				text := wikidump.Cleanup(a.Text)
				links <- wikidump.ExtractLinks(text)

				tokens := nlp.Tokenize(text)
				for _, h := range hash.NGrams(tokens, 1, maxN) {
					ngramcount.Add1(h)
				}
			}
			worker.Done()
		}(counters[i])
	}

	wg.Add(1)
	go func() {
		worker.Wait()
		close(links)

		for i := 1; i < nworkers; i++ {
			counters[0].Sum(counters[i])
		}
		counters = counters[:1]

		wg.Done()
	}()

	// Collect links and store them in the database.
	wg.Add(1)
	done := make(chan struct{})
	go func() {
		ins := storage.MustPrepare(db,
			`insert or ignore into linkstats values (?,?,0)`)
		update := storage.MustPrepare(db,
			`update linkstats set count = count + ? where ngramhash = ? and target = ?`)

		for linkFreq := range links {
			for link, freq := range linkFreq {
				tokens := nlp.Tokenize(link.Anchor)
				n := min(maxN, len(tokens))
				hashes := hash.NGrams(tokens, n, n)
				count := float64(freq)
				if len(hashes) > 1 {
					count = 1 / float64(len(hashes))
				}
				for _, h := range hashes {
					_, err = ins.Exec(h, link.Target)
					check()
					_, err = update.Exec(count, h, link.Target)
					check()
				}
			}
		}
		wg.Done()
	}()

	go wikidump.GetPages(f, articles, redirects)

	wg.Wait()
	close(done)

	log.Printf("Processing %d redirects", len(redirmap))
	storage.ProcessRedirects(db, redirmap)

	log.Println("Finalizing database")
	err = storage.Finalize(db)
	check()
	db.Close()
	check()
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
<commit_msg>split link-storing function off from main<commit_after>package main

import (
	"compress/bzip2"
	"database/sql"
	"flag"
	"fmt"
	"github.com/semanticize/dumpparser/hash"
	"github.com/semanticize/dumpparser/hash/countmin"
	"github.com/semanticize/dumpparser/nlp"
	"github.com/semanticize/dumpparser/storage"
	"github.com/semanticize/dumpparser/wikidump"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"sync"
)

func open(path string) (r io.ReadCloser, err error) {
	r, err = os.Open(path)
	if err == nil && filepath.Ext(path) == ".bz2" {
		r = struct {
			io.Reader
			io.Closer
		}{bzip2.NewReader(r), r}
	}
	return
}

var download = flag.String("download", "",
	"download Wikipedia dump (e.g., 'enwiki')")
var nrows = flag.Uint("nrows", 16, "number of rows in count-min sketch")
var ncols = flag.Uint("ncols", 262144, "number of columns in count-min sketch")
var maxNGram = flag.Uint("ngram", 7, "max. length of n-grams")

func main() {
	log.SetPrefix("dumpparser ")

	var err error
	check := func() {
		if err != nil {
			log.Fatal(err)
		}
	}

	flag.Parse()
	args := flag.Args()

	var dbpath, inputpath string
	if *download != "" {
		if len(args) != 1 {
			fmt.Fprintf(os.Stderr,
				"usage: %s -download=wikiname model.db\n", os.Args[0])
			os.Exit(1)
		}
		inputpath, err = wikidump.Download(*download, true)
		check()
		dbpath = args[0]
	} else {
		if len(args) != 2 {
			fmt.Fprintf(os.Stderr, "usage: %s wikidump model.db\n", os.Args[0])
			os.Exit(1)
		}
		inputpath, dbpath = args[0], args[1]
	}

	f, err := open(inputpath)
	check()
	defer f.Close()

	log.Printf("Creating database at %s", dbpath)
	db, err := storage.MakeDB(dbpath, true)
	check()

	// The numbers here are completely arbitrary.
	nworkers := runtime.GOMAXPROCS(0)
	articles := make(chan *wikidump.Page, 10*nworkers)
	links := make(chan map[wikidump.Link]int, 10*nworkers)
	redirects := make(chan *wikidump.Redirect, 100)

	var wg sync.WaitGroup

	// Collect redirects.
	wg.Add(1)
	redirmap := make(map[string]string)
	go func() {
		for r := range redirects {
			redirmap[r.Title] = r.Target
		}
		wg.Done()
	}()

	// Clean up and tokenize articles, extract links, count n-grams.
	maxN := int(*maxNGram)
	counters := make([]*countmin.Sketch, nworkers)

	var worker sync.WaitGroup
	worker.Add(nworkers)
	log.Printf("%d workers", nworkers)
	for i := 0; i < nworkers; i++ {
		counters[i] = countmin.New(int(*nrows), int(*ncols))

		go func(ngramcount *countmin.Sketch) {
			for a := range articles {
				text := wikidump.Cleanup(a.Text)
				links <- wikidump.ExtractLinks(text)

				tokens := nlp.Tokenize(text)
				for _, h := range hash.NGrams(tokens, 1, maxN) {
					ngramcount.Add1(h)
				}
			}
			worker.Done()
		}(counters[i])
	}

	wg.Add(1)
	go func() {
		worker.Wait()
		close(links)

		for i := 1; i < nworkers; i++ {
			counters[0].Sum(counters[i])
		}
		counters = counters[:1]

		wg.Done()
	}()

	// Collect links and store them in the database.
	wg.Add(1)
	done := make(chan struct{})
	go func() {

		storeLinks(db, links, maxN)
		wg.Done()
	}()

	go wikidump.GetPages(f, articles, redirects)

	wg.Wait()
	close(done)

	log.Printf("Processing %d redirects", len(redirmap))
	storage.ProcessRedirects(db, redirmap)

	log.Println("Finalizing database")
	err = storage.Finalize(db)
	check()
	db.Close()
	check()
}

func storeLinks(db *sql.DB, links <-chan map[wikidump.Link]int,
	maxN int) (err error) {

	ins, err := db.Prepare(
		`insert or ignore into linkstats values (?,?,0)`)
	if err != nil {
		return
	}
	update, err := db.Prepare(
		`update linkstats set count = count + ?
			where ngramhash = ? and target = ?`)
	if err != nil {
		return
	}

	for linkFreq := range links {
		for link, freq := range linkFreq {
			tokens := nlp.Tokenize(link.Anchor)
			n := min(maxN, len(tokens))
			hashes := hash.NGrams(tokens, n, n)
			count := float64(freq)
			if len(hashes) > 1 {
				count = 1 / float64(len(hashes))
			}
			for _, h := range hashes {
				_, err = ins.Exec(h, link.Target)
				if err != nil {
					return
				}
				_, err = update.Exec(count, h, link.Target)
				if err != nil {
					return
				}
			}
		}
	}
	return
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
<|endoftext|>


<commit_before>/*
Copyright 2020 Google LLC

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

    https://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 e2e

import (
	"context"
	"fmt"
	"regexp"
	"testing"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/GoogleCloudPlatform/gke-managed-certs/e2e/utils"
	"github.com/GoogleCloudPlatform/gke-managed-certs/pkg/utils/errors"
)

// This test creates more certificates than the quota allows and checks
// if there is at least one with an event communicating the Created event,
// and at least one with an event communicating TooManyCertificates. Normally
// every certificate should either receive Created or TooManyCertificates,
// however rarely BackendError can be reported as well, and events are reported
// on a best-effort basis, so the test does not require every event to be present.
func TestEvents_ManagedCertificate(t *testing.T) {
	ctx := context.Background()
	numCerts := 400 // Should be bigger than allowed quota.

	for i := 0; i < numCerts; i++ {
		name := fmt.Sprintf("quota-%d", i)
		if err := errors.IgnoreNotFound(clients.ManagedCertificate.Delete(ctx, name)); err != nil {
			t.Fatal(err)
		}
		if err := clients.ManagedCertificate.Create(ctx, name, []string{"quota.example.com"}); err != nil {
			t.Fatal(err)
		}
		t.Cleanup(func() {
			clients.ManagedCertificate.Delete(ctx, name)
		})
	}

	if err := utils.Retry(func() error {
		foundCreated := false
		foundTooManyCertificates := false

		eventList, err := clients.Event.List(ctx, metav1.ListOptions{})
		if err != nil {
			return err
		}

		for _, event := range eventList.Items {
			nameMatched, err := regexp.MatchString("quota-[0-9]+", event.InvolvedObject.Name)
			if err != nil {
				return err
			}

			if event.InvolvedObject.Kind == "ManagedCertificate" && nameMatched {
				if event.Reason == "Create" {
					foundCreated = true
				}
				if event.Reason == "TooManyCertificates" {
					foundTooManyCertificates = true
				}
			}

			if foundCreated && foundTooManyCertificates {
				break
			}
		}

		if !foundCreated || !foundTooManyCertificates {
			return fmt.Errorf("Create event found: %t, TooManyCertificates event found: %t; want both found", foundCreated, foundTooManyCertificates)
		}

		return nil
	}); err != nil {
		t.Fatal(err)
	}
}

func TestEvents_Ingress(t *testing.T) {
	t.Parallel()

	ctx := context.Background()
	ingressName := "test-events-ingress"

	if err := createIngress(t, ctx, ingressName, 8081, "non-existing-certificate"); err != nil {
		t.Fatalf("createIngress(ingressName=%s): %v", ingressName, err)
	}

	if err := utils.Retry(func() error {
		eventList, err := clients.Event.List(ctx, metav1.ListOptions{})
		if err != nil {
			return err
		}

		for _, event := range eventList.Items {
			if event.InvolvedObject.Kind == "Ingress" && event.InvolvedObject.Name == ingressName && event.Reason == "MissingCertificate" {
				return nil
			}
		}

		return fmt.Errorf("MissingCertificate event not found")
	}); err != nil {
		t.Fatal(err)
	}
}
<commit_msg>In e2e quota tests change the domain name used to generate a big number of ManagedCertificates.<commit_after>/*
Copyright 2020 Google LLC

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

    https://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 e2e

import (
	"context"
	"fmt"
	"regexp"
	"testing"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/GoogleCloudPlatform/gke-managed-certs/e2e/utils"
	"github.com/GoogleCloudPlatform/gke-managed-certs/pkg/utils/errors"
)

// This test creates more certificates than the quota allows and checks
// if there is at least one with an event communicating the Created event,
// and at least one with an event communicating TooManyCertificates. Normally
// every certificate should either receive Created or TooManyCertificates,
// however rarely BackendError can be reported as well, and events are reported
// on a best-effort basis, so the test does not require every event to be present.
func TestEvents_ManagedCertificate(t *testing.T) {
	ctx := context.Background()
	numCerts := 400 // Should be bigger than allowed quota.

	for i := 0; i < numCerts; i++ {
		name := fmt.Sprintf("quota-%d", i)
		if err := errors.IgnoreNotFound(clients.ManagedCertificate.Delete(ctx, name)); err != nil {
			t.Fatal(err)
		}
		if err := clients.ManagedCertificate.Create(ctx, name, []string{fmt.Printf("quota%d.example.com", i)}); err != nil {
			t.Fatal(err)
		}
		t.Cleanup(func() {
			clients.ManagedCertificate.Delete(ctx, name)
		})
	}

	if err := utils.Retry(func() error {
		foundCreated := false
		foundTooManyCertificates := false

		eventList, err := clients.Event.List(ctx, metav1.ListOptions{})
		if err != nil {
			return err
		}

		for _, event := range eventList.Items {
			nameMatched, err := regexp.MatchString("quota-[0-9]+", event.InvolvedObject.Name)
			if err != nil {
				return err
			}

			if event.InvolvedObject.Kind == "ManagedCertificate" && nameMatched {
				if event.Reason == "Create" {
					foundCreated = true
				}
				if event.Reason == "TooManyCertificates" {
					foundTooManyCertificates = true
				}
			}

			if foundCreated && foundTooManyCertificates {
				break
			}
		}

		if !foundCreated || !foundTooManyCertificates {
			return fmt.Errorf("Create event found: %t, TooManyCertificates event found: %t; want both found", foundCreated, foundTooManyCertificates)
		}

		return nil
	}); err != nil {
		t.Fatal(err)
	}
}

func TestEvents_Ingress(t *testing.T) {
	t.Parallel()

	ctx := context.Background()
	ingressName := "test-events-ingress"

	if err := createIngress(t, ctx, ingressName, 8081, "non-existing-certificate"); err != nil {
		t.Fatalf("createIngress(ingressName=%s): %v", ingressName, err)
	}

	if err := utils.Retry(func() error {
		eventList, err := clients.Event.List(ctx, metav1.ListOptions{})
		if err != nil {
			return err
		}

		for _, event := range eventList.Items {
			if event.InvolvedObject.Kind == "Ingress" && event.InvolvedObject.Name == ingressName && event.Reason == "MissingCertificate" {
				return nil
			}
		}

		return fmt.Errorf("MissingCertificate event not found")
	}); err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strings"

	"github.com/chai2010/gettext-go/gettext"

	"github.com/lxc/lxd"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/gnuflag"
)

type launchCmd struct{}

func (c *launchCmd) showByDefault() bool {
	return true
}

func (c *launchCmd) usage() string {
	return gettext.Gettext(
		`Launch a container from a particular image.

lxc launch [remote:]<image> [remote:][<name>] [--ephemeral|-e] [--profile|-p <profile>...] [--config|-c <key=value>...]

Launches a container using the specified image and name.

Not specifying -p will result in the default profile.
Specifying "-p" with no argument will result in no profile.

Example:
lxc launch ubuntu u1`)
}

func (c *launchCmd) flags() {
	massage_args()
	gnuflag.Var(&confArgs, "config", gettext.Gettext("Config key/value to apply to the new container"))
	gnuflag.Var(&confArgs, "c", gettext.Gettext("Config key/value to apply to the new container"))
	gnuflag.Var(&profArgs, "profile", gettext.Gettext("Profile to apply to the new container"))
	gnuflag.Var(&profArgs, "p", gettext.Gettext("Profile to apply to the new container"))
	gnuflag.BoolVar(&ephem, "ephemeral", false, gettext.Gettext("Ephemeral container"))
	gnuflag.BoolVar(&ephem, "e", false, gettext.Gettext("Ephemeral container"))
}

func (c *launchCmd) run(config *lxd.Config, args []string) error {
	if len(args) > 2 || len(args) < 1 {
		return errArgs
	}

	iremote, image := config.ParseRemoteAndContainer(args[0])

	var name string
	var remote string
	if len(args) == 2 {
		remote, name = config.ParseRemoteAndContainer(args[1])
	} else {
		remote, name = config.ParseRemoteAndContainer("")
	}

	d, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	/*
	 * requested_empty_profiles means user requested empty
	 * !requested_empty_profiles but len(profArgs) == 0 means use profile default
	 */
	var resp *lxd.Response
	profiles := []string{}
	for _, p := range profArgs {
		profiles = append(profiles, p)
	}
	if !requested_empty_profiles && len(profiles) == 0 {
		resp, err = d.Init(name, iremote, image, nil, configMap, ephem)
	} else {
		resp, err = d.Init(name, iremote, image, &profiles, configMap, ephem)
	}
	if err != nil {
		return err
	}

	if name == "" {
		if resp.Resources == nil {
			return fmt.Errorf(gettext.Gettext("didn't get any affected image, container or snapshot from server"))
		}

		containers, ok := resp.Resources["containers"]
		if !ok || len(containers) == 0 {
			return fmt.Errorf(gettext.Gettext("didn't get any affected image, container or snapshot from server"))
		}

		var version string
		toScan := strings.Replace(containers[0], "/", " ", -1)
		count, err := fmt.Sscanf(toScan, " %s containers %s", &version, &name)
		if err != nil {
			return err
		}

		if count != 2 {
			return fmt.Errorf(gettext.Gettext("bad number of things scanned from image, container or snapshot"))
		}

		if version != shared.APIVersion {
			return fmt.Errorf(gettext.Gettext("got bad version"))
		}
	}
	fmt.Printf(gettext.Gettext("Creating %s")+" ", name)

	if err = d.WaitForSuccess(resp.Operation); err != nil {
		return err
	}
	fmt.Println(gettext.Gettext("done."))

	fmt.Printf(gettext.Gettext("Starting %s")+" ", name)
	resp, err = d.Action(name, shared.Start, -1, false)
	if err != nil {
		return err
	}

	err = d.WaitForSuccess(resp.Operation)
	if err != nil {
		fmt.Println(gettext.Gettext("error."))
	} else {
		fmt.Println(gettext.Gettext("done."))
	}

	return err
}
<commit_msg>Also tell about --show-log on launch failure<commit_after>package main

import (
	"fmt"
	"strings"

	"github.com/chai2010/gettext-go/gettext"

	"github.com/lxc/lxd"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/gnuflag"
)

type launchCmd struct{}

func (c *launchCmd) showByDefault() bool {
	return true
}

func (c *launchCmd) usage() string {
	return gettext.Gettext(
		`Launch a container from a particular image.

lxc launch [remote:]<image> [remote:][<name>] [--ephemeral|-e] [--profile|-p <profile>...] [--config|-c <key=value>...]

Launches a container using the specified image and name.

Not specifying -p will result in the default profile.
Specifying "-p" with no argument will result in no profile.

Example:
lxc launch ubuntu u1`)
}

func (c *launchCmd) flags() {
	massage_args()
	gnuflag.Var(&confArgs, "config", gettext.Gettext("Config key/value to apply to the new container"))
	gnuflag.Var(&confArgs, "c", gettext.Gettext("Config key/value to apply to the new container"))
	gnuflag.Var(&profArgs, "profile", gettext.Gettext("Profile to apply to the new container"))
	gnuflag.Var(&profArgs, "p", gettext.Gettext("Profile to apply to the new container"))
	gnuflag.BoolVar(&ephem, "ephemeral", false, gettext.Gettext("Ephemeral container"))
	gnuflag.BoolVar(&ephem, "e", false, gettext.Gettext("Ephemeral container"))
}

func (c *launchCmd) run(config *lxd.Config, args []string) error {
	if len(args) > 2 || len(args) < 1 {
		return errArgs
	}

	iremote, image := config.ParseRemoteAndContainer(args[0])

	var name string
	var remote string
	if len(args) == 2 {
		remote, name = config.ParseRemoteAndContainer(args[1])
	} else {
		remote, name = config.ParseRemoteAndContainer("")
	}

	d, err := lxd.NewClient(config, remote)
	if err != nil {
		return err
	}

	/*
	 * requested_empty_profiles means user requested empty
	 * !requested_empty_profiles but len(profArgs) == 0 means use profile default
	 */
	var resp *lxd.Response
	profiles := []string{}
	for _, p := range profArgs {
		profiles = append(profiles, p)
	}
	if !requested_empty_profiles && len(profiles) == 0 {
		resp, err = d.Init(name, iremote, image, nil, configMap, ephem)
	} else {
		resp, err = d.Init(name, iremote, image, &profiles, configMap, ephem)
	}
	if err != nil {
		return err
	}

	if name == "" {
		if resp.Resources == nil {
			return fmt.Errorf(gettext.Gettext("didn't get any affected image, container or snapshot from server"))
		}

		containers, ok := resp.Resources["containers"]
		if !ok || len(containers) == 0 {
			return fmt.Errorf(gettext.Gettext("didn't get any affected image, container or snapshot from server"))
		}

		var version string
		toScan := strings.Replace(containers[0], "/", " ", -1)
		count, err := fmt.Sscanf(toScan, " %s containers %s", &version, &name)
		if err != nil {
			return err
		}

		if count != 2 {
			return fmt.Errorf(gettext.Gettext("bad number of things scanned from image, container or snapshot"))
		}

		if version != shared.APIVersion {
			return fmt.Errorf(gettext.Gettext("got bad version"))
		}
	}
	fmt.Printf(gettext.Gettext("Creating %s")+" ", name)

	if err = d.WaitForSuccess(resp.Operation); err != nil {
		return err
	}
	fmt.Println(gettext.Gettext("done."))

	fmt.Printf(gettext.Gettext("Starting %s")+" ", name)
	resp, err = d.Action(name, shared.Start, -1, false)
	if err != nil {
		return err
	}

	err = d.WaitForSuccess(resp.Operation)
	if err != nil {
		fmt.Println(gettext.Gettext("error."))
		return fmt.Errorf("%s\n"+gettext.Gettext("Try `lxc info --show-log %s` for more info"), err, name)
	}

	fmt.Println(gettext.Gettext("done."))

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/ChimeraCoder/anaconda"
	"github.com/garyburd/go-oauth/oauth"
	tl "github.com/nyanshak/twitterlib"
	"log"
	"net/http"
	"time"
	"os"
	"strings"
	"io/ioutil"
)

var (
	api *anaconda.TwitterApi
	myOauth       *oauth.Client
	myCredentials *oauth.Credentials

	consumerKey = os.Getenv("ECHO_CONSUMER_KEY")
	consumerSecret = os.Getenv("ECHO_CONSUMER_SECRET")
	accessKey = os.Getenv("ECHO_ACCESS_KEY")
	accessSecret = os.Getenv("ECHO_ACCESS_SECRET")

	screenName     = os.Getenv("ECHO_NAME")
	listen         = flag.String("listen", ":8080", "Spec to listen on")
)

func init() {
	flag.Parse()

	if consumerKey == "" || consumerSecret == "" || accessKey == "" || accessSecret == "" {
		log.Fatalln("Credentials invalid: at least one is empty")
	}

	if screenName == "" {
		log.Fatalln("bot username left blank")
	}

	anaconda.SetConsumerKey(consumerKey)
	anaconda.SetConsumerSecret(consumerSecret)
	api = anaconda.NewTwitterApi(accessKey, accessSecret)

	myOauth = &oauth.Client{
		Credentials: oauth.Credentials{
			Token: consumerKey,
			Secret: consumerSecret,
		},
	}

	myCredentials = &oauth.Credentials{
		Token: accessKey,
		Secret: accessSecret,
	}

	go echoer()
}

func echoer() {

	req, err := http.NewRequest("GET", "https://userstream.twitter.com/1.1/user.json?with=user", nil)
	if err != nil {
		log.Fatalln("Failed to create status stream: %s", err)
	}

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", myOauth.AuthorizationHeader(myCredentials, "GET", req.URL, nil))

	conn := tl.NewConnection(0 * time.Second)

	resp, err := conn.Client.Do(req)

	if err != nil {
		log.Fatalln("Error getting status stream: %s", err)
	}

	if resp.StatusCode != 200 {
		body, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		log.Fatalln("Error getting status stream (%d): %s", resp.StatusCode, body)
	}

	conn.Setup(resp.Body)

	for {
		if tweet, err := conn.Next(); err == nil {
			// avoid having bot infinitely retweet itself
			if !strings.EqualFold(tweet.User.ScreenName, screenName) {
				api.PostTweet(tweet.Text, nil)
			}
		} else {
			log.Fatalln("decoding tweet failed: %s", err)
		}
	}
}

func main() {
	err := http.ListenAndServe(*listen, nil)
	if err != nil {
		log.Fatalf("failed to listen: %s", err)
	}
}
<commit_msg>Changing to retweet instead of just tweeting identical message<commit_after>package main

import (
	"flag"
	"github.com/ChimeraCoder/anaconda"
	"github.com/garyburd/go-oauth/oauth"
	tl "github.com/nyanshak/twitterlib"
	"log"
	"net/http"
	"time"
	"os"
	"strings"
	"io/ioutil"
)

var (
	api *anaconda.TwitterApi
	myOauth       *oauth.Client
	myCredentials *oauth.Credentials

	consumerKey = os.Getenv("ECHO_CONSUMER_KEY")
	consumerSecret = os.Getenv("ECHO_CONSUMER_SECRET")
	accessKey = os.Getenv("ECHO_ACCESS_KEY")
	accessSecret = os.Getenv("ECHO_ACCESS_SECRET")

	screenName     = os.Getenv("ECHO_NAME")
	listen         = flag.String("listen", ":8080", "Spec to listen on")
)

func init() {
	flag.Parse()

	if consumerKey == "" || consumerSecret == "" || accessKey == "" || accessSecret == "" {
		log.Fatalln("Credentials invalid: at least one is empty")
	}

	if screenName == "" {
		log.Fatalln("bot username left blank")
	}

	anaconda.SetConsumerKey(consumerKey)
	anaconda.SetConsumerSecret(consumerSecret)
	api = anaconda.NewTwitterApi(accessKey, accessSecret)

	myOauth = &oauth.Client{
		Credentials: oauth.Credentials{
			Token: consumerKey,
			Secret: consumerSecret,
		},
	}

	myCredentials = &oauth.Credentials{
		Token: accessKey,
		Secret: accessSecret,
	}

	go echoer()
}

func echoer() {

	req, err := http.NewRequest("GET", "https://userstream.twitter.com/1.1/user.json?with=user", nil)
	if err != nil {
		log.Fatalln("Failed to create status stream: %s", err)
	}

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", myOauth.AuthorizationHeader(myCredentials, "GET", req.URL, nil))

	conn := tl.NewConnection(0 * time.Second)

	resp, err := conn.Client.Do(req)

	if err != nil {
		log.Fatalln("Error getting status stream: %s", err)
	}

	if resp.StatusCode != 200 {
		body, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		log.Fatalln("Error getting status stream (%d): %s", resp.StatusCode, body)
	}

	conn.Setup(resp.Body)

	for {
		if tweet, err := conn.Next(); err == nil {
			// avoid having bot infinitely retweet itself
			if !strings.EqualFold(tweet.User.ScreenName, screenName) {
				api.Retweet(tweet.Id, false)
			}
		} else {
			log.Fatalln("decoding tweet failed: %s", err)
		}
	}
}

func main() {
	err := http.ListenAndServe(*listen, nil)
	if err != nil {
		log.Fatalf("failed to listen: %s", err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Michael O'Rourke. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package drain

import (
	"bufio"
	"io"
	"os"
)

// Scans all lines from a File into a channel until EOF
//
func FileLinesToChan(fileName string, dest chan<- string) error {
	return FileToChan(fileName, bufio.ScanLines, dest)
}

// Scans all tokens from a File into a channel until EOF
//
func FileToChan(fileName string, split bufio.SplitFunc, dest chan<- string) (err error) {
	var f io.ReadCloser
	if f, err = os.Open(fileName); err != nil {
		return
	}
	defer f.Close()
	err = ReaderToChan(f, split, dest)
	return
}

// Writes all strings from a channel to a File, with trailing newline characters, until the channel is closed.
// Uses the default buffer size.
//
func ChanToFile(source <-chan string, fileName string) error {
	return ChanToFileSize(source, DefaultBufferSize, fileName)
}

// Writes all strings from a channel to a File, with trailing newline characters, until the channel is closed.
// The file will be overwritten if it already exists, or created if it does not.
//
func ChanToFileSize(source <-chan string, bufSize int, fileName string) (err error) {
	var f io.WriteCloser
	if f, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC|os.O_APPEND, 0666); err != nil {
		return
	}
	defer f.Close()
	bw := bufio.NewWriterSize(f, bufSize)
	err = ChanToBufioWriter(source, NewLineString, bw)
	return
}
<commit_msg>- don't truncate by default - don't make world-writable by default<commit_after>// Copyright 2015 Michael O'Rourke. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package drain

import (
	"bufio"
	"io"
	"os"
)

// Scans all lines from a File into a channel until EOF
//
func FileLinesToChan(fileName string, dest chan<- string) error {
	return FileToChan(fileName, bufio.ScanLines, dest)
}

// Scans all tokens from a File into a channel until EOF
//
func FileToChan(fileName string, split bufio.SplitFunc, dest chan<- string) (err error) {
	var f io.ReadCloser
	if f, err = os.Open(fileName); err != nil {
		return
	}
	defer f.Close()
	err = ReaderToChan(f, split, dest)
	return
}

// Writes all strings from a channel to a File, with trailing newline characters, until the channel is closed.
// Uses the default buffer size.
//
func ChanToFile(source <-chan string, fileName string) error {
	return ChanToFileSize(source, DefaultBufferSize, fileName)
}

// Writes all strings from a channel to a File, with trailing newline characters, until the channel is closed.
// The file will be created if it does not exist, and appended to if it already exists.
//
func ChanToFileSize(source <-chan string, bufSize int, fileName string) (err error) {
	var f io.WriteCloser
	if f, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0664); err != nil {
		return
	}
	defer f.Close()
	bw := bufio.NewWriterSize(f, bufSize)
	err = ChanToBufioWriter(source, NewLineString, bw)
	return
}
<|endoftext|>


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

package cache

import (
	"bytes"
	"crypto/md5"
	"encoding/gob"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"time"
)

func init() {
	Register("file", NewFileCache())
}

// FileCacheItem is basic unit of file cache adapter.
// it contains data and expire time.
type FileCacheItem struct {
	Data       interface{}
	Lastaccess int64
	Expired    int64
}

var (
	FileCachePath           string = "cache" // cache directory
	FileCacheFileSuffix     string = ".bin"  // cache file suffix
	FileCacheDirectoryLevel int    = 2       // cache file deep level if auto generated cache files.
	FileCacheEmbedExpiry    int64  = 0       // cache expire time, default is no expire forever.
)

// FileCache is cache adapter for file storage.
type FileCache struct {
	CachePath      string
	FileSuffix     string
	DirectoryLevel int
	EmbedExpiry    int
}

// Create new file cache with no config.
// the level and expiry need set in method StartAndGC as config string.
func NewFileCache() *FileCache {
	//    return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
	return &FileCache{}
}

// Start and begin gc for file cache.
// the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0}
func (this *FileCache) StartAndGC(config string) error {

	var cfg map[string]string
	json.Unmarshal([]byte(config), &cfg)
	//fmt.Println(cfg)
	//fmt.Println(config)
	if _, ok := cfg["CachePath"]; !ok {
		cfg["CachePath"] = FileCachePath
	}
	if _, ok := cfg["FileSuffix"]; !ok {
		cfg["FileSuffix"] = FileCacheFileSuffix
	}
	if _, ok := cfg["DirectoryLevel"]; !ok {
		cfg["DirectoryLevel"] = strconv.Itoa(FileCacheDirectoryLevel)
	}
	if _, ok := cfg["EmbedExpiry"]; !ok {
		cfg["EmbedExpiry"] = strconv.FormatInt(FileCacheEmbedExpiry, 10)
	}
	this.CachePath = cfg["CachePath"]
	this.FileSuffix = cfg["FileSuffix"]
	this.DirectoryLevel, _ = strconv.Atoi(cfg["DirectoryLevel"])
	this.EmbedExpiry, _ = strconv.Atoi(cfg["EmbedExpiry"])

	this.Init()
	return nil
}

// Init will make new dir for file cache if not exist.
func (this *FileCache) Init() {
	app := filepath.Dir(os.Args[0])
	this.CachePath = filepath.Join(app, this.CachePath)
	ok, err := exists(this.CachePath)
	if err != nil { // print error
		//fmt.Println(err)
	}
	if !ok {
		if err = os.Mkdir(this.CachePath, os.ModePerm); err != nil {
			//fmt.Println(err);
		}
	}
	//fmt.Println(this.getCacheFileName("123456"));
}

// get cached file name. it's md5 encoded.
func (this *FileCache) getCacheFileName(key string) string {
	m := md5.New()
	io.WriteString(m, key)
	keyMd5 := hex.EncodeToString(m.Sum(nil))
	cachePath := this.CachePath
	//fmt.Println("cachepath : " , cachePath)
	//fmt.Println("md5" , keyMd5);
	switch this.DirectoryLevel {
	case 2:
		cachePath = filepath.Join(cachePath, keyMd5[0:2], keyMd5[2:4])
	case 1:
		cachePath = filepath.Join(cachePath, keyMd5[0:2])
	}

	ok, err := exists(cachePath)
	if err != nil {
		//fmt.Println(err)
	}
	if !ok {
		if err = os.MkdirAll(cachePath, os.ModePerm); err != nil {
			//fmt.Println(err);
		}
	}
	return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, this.FileSuffix))
}

// Get value from file cache.
// if non-exist or expired, return empty string.
func (this *FileCache) Get(key string) interface{} {
	filename := this.getCacheFileName(key)
	filedata, err := File_get_contents(filename)
	//fmt.Println("get length:" , len(filedata));
	if err != nil {
		return ""
	}
	var to FileCacheItem
	Gob_decode(filedata, &to)
	if to.Expired < time.Now().Unix() {
		return ""
	}
	return to.Data
}

// Put value into file cache.
// timeout means how long to keep this file, unit of ms.
// if timeout equals FileCacheEmbedExpiry(default is 0), cache this item forever.
func (this *FileCache) Put(key string, val interface{}, timeout int64) error {
	gob.Register(val)

	filename := this.getCacheFileName(key)
	var item FileCacheItem
	item.Data = val
	if timeout == FileCacheEmbedExpiry {
		item.Expired = time.Now().Unix() + (86400 * 365 * 10) // ten years
	} else {
		item.Expired = time.Now().Unix() + timeout
	}
	item.Lastaccess = time.Now().Unix()
	data, err := Gob_encode(item)
	if err != nil {
		return err
	}
	err = File_put_contents(filename, data)
	return err
}

// Delete file cache value.
func (this *FileCache) Delete(key string) error {
	filename := this.getCacheFileName(key)
	if ok, _ := exists(filename); ok {
		return os.Remove(filename)
	}
	return nil
}

// Increase cached int value.
// this value is saving forever unless Delete.
func (this *FileCache) Incr(key string) error {
	data := this.Get(key)
	var incr int
	//fmt.Println(reflect.TypeOf(data).Name())
	if reflect.TypeOf(data).Name() != "int" {
		incr = 0
	} else {
		incr = data.(int) + 1
	}
	this.Put(key, incr, FileCacheEmbedExpiry)
	return nil
}

// Decrease cached int value.
func (this *FileCache) Decr(key string) error {
	data := this.Get(key)
	var decr int
	if reflect.TypeOf(data).Name() != "int" || data.(int)-1 <= 0 {
		decr = 0
	} else {
		decr = data.(int) - 1
	}
	this.Put(key, decr, FileCacheEmbedExpiry)
	return nil
}

// Check value is exist.
func (this *FileCache) IsExist(key string) bool {
	filename := this.getCacheFileName(key)
	ret, _ := exists(filename)
	return ret
}

// Clean cached files.
// not implemented.
func (this *FileCache) ClearAll() error {
	//this.CachePath
	return nil
}

// check file exist.
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// Get bytes to file.
// if non-exist, create this file.
func File_get_contents(filename string) ([]byte, error) {
	f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		return []byte(""), err
	}
	defer f.Close()
	stat, err := f.Stat()
	if err != nil {
		return []byte(""), err
	}
	data := make([]byte, stat.Size())
	result, err := f.Read(data)
	if int64(result) == stat.Size() {
		return data, err
	}
	return []byte(""), err
}

// Put bytes to file.
// if non-exist, create this file.
func File_put_contents(filename string, content []byte) error {
	fp, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		return err
	}
	defer fp.Close()
	_, err = fp.Write(content)
	return err
}

// Gob encodes file cache item.
func Gob_encode(data interface{}) ([]byte, error) {
	buf := bytes.NewBuffer(nil)
	enc := gob.NewEncoder(buf)
	err := enc.Encode(data)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), err
}

// Gob decodes file cache item.
func Gob_decode(data []byte, to *FileCacheItem) error {
	buf := bytes.NewBuffer(data)
	dec := gob.NewDecoder(buf)
	return dec.Decode(&to)
}
<commit_msg>Mirror improvement<commit_after>// Copyright 2013 Beego Authors
// Copyright 2014 Unknwon
//
// 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 cache

import (
	"bytes"
	"crypto/md5"
	"encoding/gob"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"time"
)

func init() {
	Register("file", NewFileCache())
}

// FileCacheItem is basic unit of file cache adapter.
// it contains data and expire time.
type FileCacheItem struct {
	Data       interface{}
	Lastaccess int64
	Expired    int64
}

var (
	FileCachePath           string = "cache" // cache directory
	FileCacheFileSuffix     string = ".bin"  // cache file suffix
	FileCacheDirectoryLevel int    = 2       // cache file deep level if auto generated cache files.
	FileCacheEmbedExpiry    int64  = 0       // cache expire time, default is no expire forever.
)

// FileCache is cache adapter for file storage.
type FileCache struct {
	CachePath      string
	FileSuffix     string
	DirectoryLevel int
	EmbedExpiry    int
}

// Create new file cache with no config.
// the level and expiry need set in method StartAndGC as config string.
func NewFileCache() *FileCache {
	//    return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
	return &FileCache{}
}

// Start and begin gc for file cache.
// the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0}
func (this *FileCache) StartAndGC(config string) error {

	var cfg map[string]string
	json.Unmarshal([]byte(config), &cfg)
	//fmt.Println(cfg)
	//fmt.Println(config)
	if _, ok := cfg["CachePath"]; !ok {
		cfg["CachePath"] = FileCachePath
	}
	if _, ok := cfg["FileSuffix"]; !ok {
		cfg["FileSuffix"] = FileCacheFileSuffix
	}
	if _, ok := cfg["DirectoryLevel"]; !ok {
		cfg["DirectoryLevel"] = strconv.Itoa(FileCacheDirectoryLevel)
	}
	if _, ok := cfg["EmbedExpiry"]; !ok {
		cfg["EmbedExpiry"] = strconv.FormatInt(FileCacheEmbedExpiry, 10)
	}
	this.CachePath = cfg["CachePath"]
	this.FileSuffix = cfg["FileSuffix"]
	this.DirectoryLevel, _ = strconv.Atoi(cfg["DirectoryLevel"])
	this.EmbedExpiry, _ = strconv.Atoi(cfg["EmbedExpiry"])

	this.Init()
	return nil
}

// Init will make new dir for file cache if not exist.
func (this *FileCache) Init() {
	app := filepath.Dir(os.Args[0])
	this.CachePath = filepath.Join(app, this.CachePath)
	ok, err := exists(this.CachePath)
	if err != nil { // print error
		//fmt.Println(err)
	}
	if !ok {
		if err = os.Mkdir(this.CachePath, os.ModePerm); err != nil {
			//fmt.Println(err);
		}
	}
	//fmt.Println(this.getCacheFileName("123456"));
}

// get cached file name. it's md5 encoded.
func (this *FileCache) getCacheFileName(key string) string {
	m := md5.Sum([]byte(key))
	keyMd5 := hex.EncodeToString(m[:])
	cachePath := this.CachePath
	//fmt.Println("cachepath : " , cachePath)
	//fmt.Println("md5" , keyMd5);
	switch this.DirectoryLevel {
	case 2:
		cachePath = filepath.Join(cachePath, keyMd5[0:2], keyMd5[2:4])
	case 1:
		cachePath = filepath.Join(cachePath, keyMd5[0:2])
	}

	ok, err := exists(cachePath)
	if err != nil {
		//fmt.Println(err)
	}
	if !ok {
		if err = os.MkdirAll(cachePath, os.ModePerm); err != nil {
			//fmt.Println(err);
		}
	}
	return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, this.FileSuffix))
}

// Get value from file cache.
// if non-exist or expired, return empty string.
func (this *FileCache) Get(key string) interface{} {
	filename := this.getCacheFileName(key)
	filedata, err := File_get_contents(filename)
	//fmt.Println("get length:" , len(filedata));
	if err != nil {
		return ""
	}
	var to FileCacheItem
	Gob_decode(filedata, &to)
	if to.Expired < time.Now().Unix() {
		return ""
	}
	return to.Data
}

// Put value into file cache.
// timeout means how long to keep this file, unit of ms.
// if timeout equals FileCacheEmbedExpiry(default is 0), cache this item forever.
func (this *FileCache) Put(key string, val interface{}, timeout int64) error {
	gob.Register(val)

	filename := this.getCacheFileName(key)
	var item FileCacheItem
	item.Data = val
	if timeout == FileCacheEmbedExpiry {
		item.Expired = time.Now().Unix() + (86400 * 365 * 10) // ten years
	} else {
		item.Expired = time.Now().Unix() + timeout
	}
	item.Lastaccess = time.Now().Unix()
	data, err := Gob_encode(item)
	if err != nil {
		return err
	}
	err = File_put_contents(filename, data)
	return err
}

// Delete file cache value.
func (this *FileCache) Delete(key string) error {
	filename := this.getCacheFileName(key)
	if ok, _ := exists(filename); ok {
		return os.Remove(filename)
	}
	return nil
}

// Increase cached int value.
// this value is saving forever unless Delete.
func (this *FileCache) Incr(key string) error {
	data := this.Get(key)
	var incr int
	//fmt.Println(reflect.TypeOf(data).Name())
	if reflect.TypeOf(data).Name() != "int" {
		incr = 0
	} else {
		incr = data.(int) + 1
	}
	this.Put(key, incr, FileCacheEmbedExpiry)
	return nil
}

// Decrease cached int value.
func (this *FileCache) Decr(key string) error {
	data := this.Get(key)
	var decr int
	if reflect.TypeOf(data).Name() != "int" || data.(int)-1 <= 0 {
		decr = 0
	} else {
		decr = data.(int) - 1
	}
	this.Put(key, decr, FileCacheEmbedExpiry)
	return nil
}

// Check value is exist.
func (this *FileCache) IsExist(key string) bool {
	filename := this.getCacheFileName(key)
	ret, _ := exists(filename)
	return ret
}

// Clean cached files.
// not implemented.
func (this *FileCache) ClearAll() error {
	//this.CachePath
	return nil
}

// check file exist.
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// Get bytes to file.
// if non-exist, create this file.
func File_get_contents(filename string) ([]byte, error) {
	f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		return []byte(""), err
	}
	defer f.Close()
	stat, err := f.Stat()
	if err != nil {
		return []byte(""), err
	}
	data := make([]byte, stat.Size())
	result, err := f.Read(data)
	if int64(result) == stat.Size() {
		return data, err
	}
	return []byte(""), err
}

// Put bytes to file.
// if non-exist, create this file.
func File_put_contents(filename string, content []byte) error {
	fp, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		return err
	}
	defer fp.Close()
	_, err = fp.Write(content)
	return err
}

// Gob encodes file cache item.
func Gob_encode(data interface{}) ([]byte, error) {
	buf := bytes.NewBuffer(nil)
	enc := gob.NewEncoder(buf)
	err := enc.Encode(data)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), err
}

// Gob decodes file cache item.
func Gob_decode(data []byte, to *FileCacheItem) error {
	buf := bytes.NewBuffer(data)
	dec := gob.NewDecoder(buf)
	return dec.Decode(&to)
}
<|endoftext|>


<commit_before>package api

import (
	"errors"
	"fmt"
	"time"

	"github.com/sclevine/agouti/api/internal/bus"
	"github.com/sclevine/agouti/api/internal/service"
)

type Capabilities map[string]interface{}

type WebDriver struct {
	Service interface {
		URL() (string, error)
		Start() error
		Stop() error
	}
	sessions []*Session
}

func NewWebDriver(url string, command []string, timeout ...time.Duration) *WebDriver {
	if len(timeout) == 0 {
		timeout = []time.Duration{5 * time.Second}
	}

	driverService := &service.Service{
		URLTemplate: url,
		CmdTemplate: command,
		Timeout:     timeout[0],
	}

	return &WebDriver{Service: driverService}
}

func (w *WebDriver) Open(desired ...Capabilities) (*Session, error) {
	if len(desired) == 0 {
		desired = append(desired, Capabilities{})
	} else if len(desired) > 1 {
		return nil, errors.New("too many arguments")
	}

	url, err := w.Service.URL()
	if err != nil {
		return nil, fmt.Errorf("cannot retrieve URL: %s", err)
	}

	busClient, err := bus.Connect(url, desired[0])
	if err != nil {
		return nil, fmt.Errorf("failed to connect: %s", err)
	}

	session := &Session{busClient}
	w.sessions = append(w.sessions, session)
	return session, nil
}

func (w *WebDriver) Start() error {
	if err := w.Service.Start(); err != nil {
		return fmt.Errorf("failed to start service: %s", err)
	}

	return nil
}

func (d *WebDriver) Stop() error {
	for _, session := range d.sessions {
		session.Delete()
	}

	if err := d.Service.Stop(); err != nil {
		return fmt.Errorf("failed to stop service: %s", err)
	}

	return nil
}
<commit_msg>Fix name of api.WebDriver#Stop receiver<commit_after>package api

import (
	"errors"
	"fmt"
	"time"

	"github.com/sclevine/agouti/api/internal/bus"
	"github.com/sclevine/agouti/api/internal/service"
)

type Capabilities map[string]interface{}

type WebDriver struct {
	Service interface {
		URL() (string, error)
		Start() error
		Stop() error
	}
	sessions []*Session
}

func NewWebDriver(url string, command []string, timeout ...time.Duration) *WebDriver {
	if len(timeout) == 0 {
		timeout = []time.Duration{5 * time.Second}
	}

	driverService := &service.Service{
		URLTemplate: url,
		CmdTemplate: command,
		Timeout:     timeout[0],
	}

	return &WebDriver{Service: driverService}
}

func (w *WebDriver) Open(desired ...Capabilities) (*Session, error) {
	if len(desired) == 0 {
		desired = append(desired, Capabilities{})
	} else if len(desired) > 1 {
		return nil, errors.New("too many arguments")
	}

	url, err := w.Service.URL()
	if err != nil {
		return nil, fmt.Errorf("cannot retrieve URL: %s", err)
	}

	busClient, err := bus.Connect(url, desired[0])
	if err != nil {
		return nil, fmt.Errorf("failed to connect: %s", err)
	}

	session := &Session{busClient}
	w.sessions = append(w.sessions, session)
	return session, nil
}

func (w *WebDriver) Start() error {
	if err := w.Service.Start(); err != nil {
		return fmt.Errorf("failed to start service: %s", err)
	}

	return nil
}

func (w *WebDriver) Stop() error {
	for _, session := range w.sessions {
		session.Delete()
	}

	if err := w.Service.Stop(); err != nil {
		return fmt.Errorf("failed to stop service: %s", err)
	}

	return nil
}
<|endoftext|>