<commit_before>package plugins

import (
	"fmt"
	"strings"
	"time"

	"github.com/belak/irc"
	"github.com/belak/seabird/bot"
	"github.com/jmoiron/sqlx"
)

func init() {
	bot.RegisterPlugin("remind", NewReminderPlugin)
}

type ReminderPlugin struct {
	db *sqlx.DB
}

type reminder struct {
	ID           int64
	Target       string
	TargetType   string `db:"target_type"`
	Content      string
	ReminderTime time.Time `db:"reminder_time"`
}

func NewReminderPlugin(b *bot.Bot) (bot.Plugin, error) {
	b.LoadPlugin("db")
	p := &ReminderPlugin{b.Plugins["db"].(*sqlx.DB)}

	b.BasicMux.Event("001", p.InitialDispatch)
	b.BasicMux.Event("JOIN", p.JoinDispatch)
	b.CommandMux.Event("remind", p.RemindCommand, &bot.HelpInfo{
		Usage:       "<duration> <message>",
		Description: "Remind yourself to do something.",
	})

	return nil, nil
}

func (p *ReminderPlugin) dispatch(b *bot.Bot, r *reminder) {
	// Because time.Sleep handles negative values (and 0) by simply
	// returning, this will be handled correctly even with negative
	// durations.
	waitDur := r.ReminderTime.Sub(time.Now())

	// Try to sleep this goroutine until the message needs to be delivered
	time.Sleep(waitDur)

	// Send the message
	b.Send(&irc.Message{
		Command: "PRIVMSG",
		Params:  []string{r.Target, r.Content},
	})

	// Nuke the reminder now that it's been sent
	_, err := p.db.Exec("DELETE FROM reminders WHERE id=$1", r.ID)
	if err != nil {
		fmt.Println(err)
		return
	}
}

// InitialDispatch is used to send private messages to users on connection. We
// can't queue up the channels yet because we haven't joined them.
func (p *ReminderPlugin) InitialDispatch(b *bot.Bot, m *irc.Message) {
	reminders := []*reminder{}
	err := p.db.Select(reminders, "SELECT * FROM reminders WHERE target_type=$1", "private")
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, r := range reminders {
		go p.dispatch(b, r)
	}
}

// When we join a channel, we need to see if there are any reminders to be
// queued up.
func (p *ReminderPlugin) JoinDispatch(b *bot.Bot, m *irc.Message) {
	// If it's not the bot, we ignore it.
	if m.Prefix.Name != b.CurrentNick() || len(m.Params) < 1 {
		return
	}

	reminders := []*reminder{}
	err := p.db.Select(reminders, "SELECT * FROM reminders WHERE target_type=$1 AND target=$2", "public", m.Params[0])
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, r := range reminders {
		go p.dispatch(b, r)
	}
}

func (p *ReminderPlugin) RemindCommand(b *bot.Bot, m *irc.Message) {
	split := strings.SplitN(m.Trailing(), " ", 2)
	if len(split) != 2 {
		b.MentionReply(m, "Not enough args")
		return
	}

	dur, err := time.ParseDuration(split[0])
	if err != nil {
		b.MentionReply(m, "Invalid duration: %s", err)
		return
	}

	r := &reminder{
		Target:       m.Prefix.Name,
		TargetType:   "private",
		Content:      split[1],
		ReminderTime: time.Now().Add(dur),
	}

	if m.FromChannel() {
		// If it was from a channel, we need to prepend the user's name.
		r.Target = m.Params[0]
		r.TargetType = "public"
		r.Content = m.Prefix.Name + ": " + r.Content
	}

	result, err := p.db.Exec(
		"INSERT INTO reminders (target, target_type, content, reminder_time) VALUES ($1, $2, $3, $4)",
		r.Target, r.TargetType, r.Content, r.ReminderTime)
	if err != nil {
		b.MentionReply(m, "Failed to store reminder: %s", err)
		return
	}

	r.ID, err = result.LastInsertId()
	if err != nil {
		b.MentionReply(m, "Failed to get ID of stored reminder. This event may be fired a second time after the bot is restarted: %s", err)
	}

	go p.dispatch(b, r)
}
<commit_msg>Fix a few crashes in the remind plugin<commit_after>package plugins

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/belak/irc"
	"github.com/belak/seabird/bot"
	"github.com/jmoiron/sqlx"
)

func init() {
	bot.RegisterPlugin("remind", NewReminderPlugin)
}

type ReminderPlugin struct {
	db *sqlx.DB
}

type reminder struct {
	ID           int64
	Target       string
	TargetType   string `db:"target_type"`
	Content      string
	ReminderTime time.Time `db:"reminder_time"`
}

func NewReminderPlugin(b *bot.Bot) (bot.Plugin, error) {
	b.LoadPlugin("db")
	p := &ReminderPlugin{b.Plugins["db"].(*sqlx.DB)}

	if p.db.DriverName() != "postgres" {
		return nil, errors.New("The reminder plugin must be used with postgres")
	}

	b.BasicMux.Event("001", p.InitialDispatch)
	b.BasicMux.Event("JOIN", p.JoinDispatch)
	b.CommandMux.Event("remind", p.RemindCommand, &bot.HelpInfo{
		Usage:       "<duration> <message>",
		Description: "Remind yourself to do something.",
	})

	return nil, nil
}

func (p *ReminderPlugin) dispatch(b *bot.Bot, r *reminder) {
	// Because time.Sleep handles negative values (and 0) by simply
	// returning, this will be handled correctly even with negative
	// durations.
	waitDur := r.ReminderTime.Sub(time.Now())

	// Try to sleep this goroutine until the message needs to be delivered
	time.Sleep(waitDur)

	// Send the message
	b.Send(&irc.Message{
		Prefix:  &irc.Prefix{},
		Command: "PRIVMSG",
		Params:  []string{r.Target, r.Content},
	})

	// Nuke the reminder now that it's been sent
	_, err := p.db.Exec("DELETE FROM reminders WHERE id=$1", r.ID)
	if err != nil {
		fmt.Println(err)
		return
	}
}

// InitialDispatch is used to send private messages to users on connection. We
// can't queue up the channels yet because we haven't joined them.
func (p *ReminderPlugin) InitialDispatch(b *bot.Bot, m *irc.Message) {
	reminders := []*reminder{}
	err := p.db.Select(&reminders, "SELECT * FROM reminders WHERE target_type=$1", "private")
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, r := range reminders {
		go p.dispatch(b, r)
	}
}

// When we join a channel, we need to see if there are any reminders to be
// queued up.
func (p *ReminderPlugin) JoinDispatch(b *bot.Bot, m *irc.Message) {
	// If it's not the bot, we ignore it.
	if m.Prefix.Name != b.CurrentNick() || len(m.Params) < 1 {
		return
	}

	reminders := []*reminder{}
	err := p.db.Select(&reminders, "SELECT * FROM reminders WHERE target_type=$1 AND target=$2", "public", m.Params[0])
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, r := range reminders {
		go p.dispatch(b, r)
	}
}

func (p *ReminderPlugin) RemindCommand(b *bot.Bot, m *irc.Message) {
	split := strings.SplitN(m.Trailing(), " ", 2)
	if len(split) != 2 {
		b.MentionReply(m, "Not enough args")
		return
	}

	dur, err := time.ParseDuration(split[0])
	if err != nil {
		b.MentionReply(m, "Invalid duration: %s", err)
		return
	}

	r := &reminder{
		Target:       m.Prefix.Name,
		TargetType:   "private",
		Content:      split[1],
		ReminderTime: time.Now().Add(dur),
	}

	if m.FromChannel() {
		// If it was from a channel, we need to prepend the user's name.
		r.Target = m.Params[0]
		r.TargetType = "public"
		r.Content = m.Prefix.Name + ": " + r.Content
	}

	// pq doesn't support .LastInsertId so we need to do this
	var rowID int64
	err = p.db.QueryRow(
		"INSERT INTO reminders (target, target_type, content, reminder_time) VALUES ($1, $2, $3, $4) RETURNING id",
		r.Target, r.TargetType, r.Content, r.ReminderTime).Scan(&rowID)
	if err != nil {
		b.MentionReply(m, "Failed to store reminder: %s", err)
		return
	}

	r.ID = rowID

	go p.dispatch(b, r)
}
<|endoftext|>


<commit_before>// Package create is used for copying skeleton app
// to a requested destination.
// Herewith, import path of the skeleton app is expected
// to be rewritten to a new one.
package create

import (
	"os"
	"path/filepath"

	"github.com/anonx/sunplate/command"
	"github.com/anonx/sunplate/generation/output"
	"github.com/anonx/sunplate/log"
	p "github.com/anonx/sunplate/path"
)

// result represents objects found when scanning a skeleton directory.
// There are a few possible kind of them: directories, static files,
// go source files (that require additional processing of their content).
type result struct {
	dirs, files, srcs map[string]string // Keys are full paths, values are relative ones.
}

// Start is an entry point of the command.
func Start(action string, params command.Data) {
	oldImport := p.SunplateImport("skeleton")
	newImport := p.AbsoluteImport(params.Default(action, "./"))

	inputDir := p.SunplateDir("skeleton")
	outputDir := p.PackageDir(newImport)

	rs, fn := walkFunc(inputDir)
	filepath.Walk(inputDir, fn)

	for _, v := range rs.dirs {
		t := output.Type{}
		t.CreateDir(filepath.Join(outputDir, v))
	}

	for k, v := range rs.files {
		copyFile(k, filepath.Join(outputDir, v))
	}

	for k, v := range rs.srcs {
		copyModifiedFile(k, filepath.Join(outputDir, v), map[string]string{
			oldImport: newImport,
		})
	}

	log.Info.Printf(info, newImport, newImport)
}

// walkFunc returns a result instance and a function that may be used for validation
// of found elements. Successfully validated ones are stored to the returned result.
func walkFunc(dir string) (result, func(string, os.FileInfo, error) error) {
	rs := result{
		dirs:  map[string]string{},
		files: map[string]string{},
		srcs:  map[string]string{},
	}

	return rs, func(path string, info os.FileInfo, err error) error {
		// Make sure there are no any errors.
		if err != nil {
			log.Warn.Printf(`An error occured while scanning a skeleton: "%s".`, err)
			return err
		}

		relPath := p.Prefixless(path, dir)

		// Check whether current element is a directory.
		if info.IsDir() {
			rs.dirs[path] = relPath
			return err
		}

		// Find out whether it is a static file or a go source.
		if filepath.Ext(path) == ".go" {
			rs.srcs[path] = relPath
			return err
		}

		// If it is a static file, add it to the list.
		rs.files[path] = relPath
		return err
	}
}

var info = `Your application is ready:
	%s
You can run it with:
	sunplate run %s
`
<commit_msg>Make sure dir doesn't exist before creating a project<commit_after>// Package create is used for copying skeleton app
// to a requested destination.
// Herewith, import path of the skeleton app is expected
// to be rewritten to a new one.
package create

import (
	"os"
	"path/filepath"

	"github.com/anonx/sunplate/command"
	"github.com/anonx/sunplate/generation/output"
	"github.com/anonx/sunplate/log"
	p "github.com/anonx/sunplate/path"
)

// result represents objects found when scanning a skeleton directory.
// There are a few possible kind of them: directories, static files,
// go source files (that require additional processing of their content).
type result struct {
	dirs, files, srcs map[string]string // Keys are full paths, values are relative ones.
}

// Start is an entry point of the command.
func Start(action string, params command.Data) {
	oldImport := p.SunplateImport("skeleton")
	newImport := p.AbsoluteImport(params.Default(action, "./"))

	inputDir := p.SunplateDir("skeleton")
	outputDir := p.PackageDir(newImport)

	// Make sure the output directory does not exist yet.
	if _, err := os.Stat(outputDir); !os.IsNotExist(err) {
		log.Error.Fatalf(`Abort: Import path "%s" already exists.`, newImport)
	}

	rs, fn := walkFunc(inputDir)
	filepath.Walk(inputDir, fn)

	for _, v := range rs.dirs {
		t := output.Type{}
		t.CreateDir(filepath.Join(outputDir, v))
	}

	for k, v := range rs.files {
		copyFile(k, filepath.Join(outputDir, v))
	}

	for k, v := range rs.srcs {
		copyModifiedFile(k, filepath.Join(outputDir, v), map[string]string{
			oldImport: newImport,
		})
	}

	log.Info.Printf(info, newImport, newImport)
}

// walkFunc returns a result instance and a function that may be used for validation
// of found elements. Successfully validated ones are stored to the returned result.
func walkFunc(dir string) (result, func(string, os.FileInfo, error) error) {
	rs := result{
		dirs:  map[string]string{},
		files: map[string]string{},
		srcs:  map[string]string{},
	}

	return rs, func(path string, info os.FileInfo, err error) error {
		// Make sure there are no any errors.
		if err != nil {
			log.Warn.Printf(`An error occured while scanning a skeleton: "%s".`, err)
			return err
		}

		relPath := p.Prefixless(path, dir)

		// Check whether current element is a directory.
		if info.IsDir() {
			rs.dirs[path] = relPath
			return err
		}

		// Find out whether it is a static file or a go source.
		if filepath.Ext(path) == ".go" {
			rs.srcs[path] = relPath
			return err
		}

		// If it is a static file, add it to the list.
		rs.files[path] = relPath
		return err
	}
}

var info = `Your application "%s" is ready:
You can run it with:
	sunplate run %s
`
<|endoftext|>


<commit_before>package plugins

import (
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/josledp/termcolor"
)

//Aws is the plugin struct
type Aws struct {
	role   string
	expire time.Time
}

//Name returns the plugin name
func (Aws) Name() string {
	return "aws"
}

//Load is the load function of the plugin
func (a *Aws) Load(options map[string]interface{}) error {
	role := os.Getenv("AWS_ROLE")
	if role != "" {
		tmp := strings.Split(role, ":")
		role = tmp[0]
		tmp = strings.Split(tmp[1], "-")
		role += ":" + tmp[2]
	}
	a.role = role
	iExpire, _ := strconv.ParseInt(os.Getenv("AWS_SESSION_EXPIRE"), 10, 0)
	a.expire = time.Unix(iExpire, int64(0))
	return nil
}

//Get returns the string to use in the prompt
func (a Aws) Get(format func(string, ...termcolor.Mode) string) (string, []termcolor.Mode) {
	if a.role != "" {
		t := termcolor.FgGreen
		d := time.Until(a.expire).Seconds()
		if d < 0 {
			t = termcolor.FgRed
		} else if d < 1800 {
			t = termcolor.FgBlue
		} else if d < 600 {
			t = termcolor.FgYellow
		}
		return format(a.role, t), []termcolor.Mode{t}
	}
	return "", nil
}
<commit_msg>remove extra mode from aws role<commit_after>package plugins

import (
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/josledp/termcolor"
)

//Aws is the plugin struct
type Aws struct {
	role   string
	expire time.Time
}

//Name returns the plugin name
func (Aws) Name() string {
	return "aws"
}

//Load is the load function of the plugin
func (a *Aws) Load(options map[string]interface{}) error {
	role := os.Getenv("AWS_ROLE")
	if role != "" {
		tmp := strings.Split(role, ":")
		role = tmp[0]
		tmp = strings.Split(tmp[1], "-")
		role += ":" + tmp[2]
	}
	a.role = role
	iExpire, _ := strconv.ParseInt(os.Getenv("AWS_SESSION_EXPIRE"), 10, 0)
	a.expire = time.Unix(iExpire, int64(0))
	return nil
}

//Get returns the string to use in the prompt
func (a Aws) Get(format func(string, ...termcolor.Mode) string) (string, []termcolor.Mode) {
	if a.role != "" {
		t := termcolor.FgGreen
		d := time.Until(a.expire).Seconds()
		if d < 0 {
			t = termcolor.FgRed
		} else if d < 1800 {
			t = termcolor.FgBlue
		} else if d < 600 {
			t = termcolor.FgYellow
		}
		return format(a.role, t), nil
	}
	return "", nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.

package lb

import (
	"github.com/hashicorp/terraform/helper/schema"

	"github.com/oracle/terraform-provider-baremetal/client"
	"github.com/oracle/terraform-provider-baremetal/crud"
)

func LoadBalancerBackendSetResource() *schema.Resource {
	return &schema.Resource{
		Create: createLoadBalancerBackendSet,
		Read:   readLoadBalancerBackendSet,
		Update: updateLoadBalancerBackendSet,
		Delete: deleteLoadBalancerBackendSet,
		Schema: map[string]*schema.Schema{
			"load_balancer_id": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"backendset_name": {
				Type:     schema.TypeString,
				Required: true,
			},
			"policy": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"health_checker":    HealthCheckerSchema,
			"ssl_configuration": SSLConfigSchema,
			"backend": {
				Type:     schema.TypeList,
				Computed: true,
				Elem:     LoadBalancerBackendResource(),
			},
			// internal for work request access
			"state": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func createLoadBalancerBackendSet(d *schema.ResourceData, m interface{}) (e error) {
	sync := &LoadBalancerBackendSetResourceCrud{}
	sync.D = d
	sync.Client = m.(client.BareMetalClient)
	return crud.CreateResource(d, sync)
}

func readLoadBalancerBackendSet(d *schema.ResourceData, m interface{}) (e error) {
	sync := &LoadBalancerBackendSetResourceCrud{}
	sync.D = d
	sync.Client = m.(client.BareMetalClient)
	return crud.ReadResource(sync)
}

func updateLoadBalancerBackendSet(d *schema.ResourceData, m interface{}) (e error) {
	sync := &LoadBalancerBackendSetResourceCrud{}
	sync.D = d
	sync.Client = m.(client.BareMetalClient)
	return crud.UpdateResource(d, sync)
}

func deleteLoadBalancerBackendSet(d *schema.ResourceData, m interface{}) (e error) {
	sync := &LoadBalancerBackendSetResourceCrud{}
	sync.D = d
	sync.Client = m.(client.BareMetalClient)
	return crud.DeleteResource(d, sync)
}
<commit_msg>Redo schemas so resources can be laid out in a .tf format and updated appropriately. This breaks everything, we need to go back and fix the crud pieces of this too<commit_after>// Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.

package lb

import (
	"github.com/hashicorp/terraform/helper/schema"

	"github.com/oracle/terraform-provider-baremetal/client"
	"github.com/oracle/terraform-provider-baremetal/crud"
)

func LoadBalancerBackendSetResource() *schema.Resource {
	return &schema.Resource{
		Create: createLoadBalancerBackendSet,
		Read:   readLoadBalancerBackendSet,
		Update: updateLoadBalancerBackendSet,
		Delete: deleteLoadBalancerBackendSet,
		Schema: map[string]*schema.Schema{
			"load_balancer_id": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"policy": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"health_checker":    HealthCheckerSchema,
			"ssl_configuration": SSLConfigSchema,
			"backend": {
				Type:     schema.TypeList,
				Computed: true,
				Elem:     LoadBalancerBackendResource(),
			},
			// internal for work request access
			"state": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func createLoadBalancerBackendSet(d *schema.ResourceData, m interface{}) (e error) {
	sync := &LoadBalancerBackendSetResourceCrud{}
	sync.D = d
	sync.Client = m.(client.BareMetalClient)
	return crud.CreateResource(d, sync)
}

func readLoadBalancerBackendSet(d *schema.ResourceData, m interface{}) (e error) {
	sync := &LoadBalancerBackendSetResourceCrud{}
	sync.D = d
	sync.Client = m.(client.BareMetalClient)
	return crud.ReadResource(sync)
}

func updateLoadBalancerBackendSet(d *schema.ResourceData, m interface{}) (e error) {
	sync := &LoadBalancerBackendSetResourceCrud{}
	sync.D = d
	sync.Client = m.(client.BareMetalClient)
	return crud.UpdateResource(d, sync)
}

func deleteLoadBalancerBackendSet(d *schema.ResourceData, m interface{}) (e error) {
	sync := &LoadBalancerBackendSetResourceCrud{}
	sync.D = d
	sync.Client = m.(client.BareMetalClient)
	return crud.DeleteResource(d, sync)
}
<|endoftext|>


<commit_before>/*
Package render implements a simple wrapper around Webkit that primarily allows for the capture of screenshots.

This package will typically only compile on a modern Linux distribution and requires a running X server. A utility binary is also provided.

*/
package render

import (
	"errors"
	"fmt"
	"github.com/auroralaboratories/go-webkit2/webkit2"
	"github.com/auroralaboratories/gotk3/glib"
	"github.com/auroralaboratories/gotk3/gtk"
	"github.com/fsnotify/fsnotify"
	"github.com/sqs/gojs"
	"image"
	"log"
	"os"
	"reflect"
	"runtime"
	"sync"
	"time"
)

var (
	// ErrLoadFailed signifies that Webkit reports failure of of the page load
	ErrLoadFailed = errors.New("load-failed")
	// ErrViewClosed signifies that the View has already been closed, not further operations allowed
	ErrViewClosed = errors.New("view-closed")
	// ErrTimeout signifies that the supplied timeout has been triggered
	ErrTimeout = errors.New("timeout")
	// ErrNoImage signifies that snapshot did not return a usable image
	ErrNoImage = errors.New("no-image")
	// ErrNoTiming signifies that no timing information is available
	ErrNoTiming = errors.New("load-not-timed")
	// ErrNoX signifies that we did not find a usable X display server
	ErrNoX = errors.New("no-x-display")
)

var gtkOnce sync.Once

func newTimeout(t *time.Duration) chan bool {
	timeout := make(chan bool, 1)
	if t != nil && *t != 0 {
		go func() {
			time.Sleep(*t)
			timeout <- true
		}()
	}
	return timeout
}

type View struct {
	*webkit2.WebView
	load        chan struct{}
	lastLoadErr error
	closed      bool

	loadRequested *time.Time
	loadStarted   *time.Time
	loadFinished  *time.Time
}

func (v *View) TimeToStart() (time.Duration, error) {
	if v.loadRequested == nil || v.loadStarted == nil {
		return 0, ErrNoTiming
	}

	return v.loadStarted.Sub(*v.loadRequested), nil
}

func (v *View) TimeToLoad() (time.Duration, error) {
	if v.loadStarted == nil || v.loadFinished == nil {
		return 0, ErrNoTiming
	}

	return v.loadFinished.Sub(*v.loadStarted), nil
}

func (v *View) TimeToFinish() (time.Duration, error) {
	if v.loadRequested == nil || v.loadFinished == nil {
		return 0, ErrNoTiming
	}

	return v.loadFinished.Sub(*v.loadRequested), nil
}

func (v *View) LoadURI(url string) error {
	if v.closed {
		return ErrViewClosed
	}

	v.load = make(chan struct{}, 1)
	v.lastLoadErr = nil
	v.loadRequested = nil
	v.loadStarted = nil
	v.loadFinished = nil

	glib.IdleAdd(func() bool {
		t := time.Now()
		v.loadRequested = &t
		v.WebView.LoadURI(url)
		return false
	})

	return nil
}

func (v *View) LoadHTML(content, baseURI string) error {
	if v.closed {
		return ErrViewClosed
	}

	v.load = make(chan struct{}, 1)
	v.lastLoadErr = nil
	v.loadRequested = nil
	v.loadStarted = nil
	v.loadFinished = nil

	glib.IdleAdd(func() bool {
		t := time.Now()
		v.loadRequested = &t
		v.WebView.LoadHTML(content, baseURI)
		return false
	})

	return nil
}

func (v *View) NewSnapshot(t *time.Duration) (result *image.RGBA, err error) {
	if v.closed {
		return nil, ErrViewClosed
	}

	resultChan := make(chan *image.RGBA, 1)
	errChan := make(chan error, 1)
	timeout := newTimeout(t)

	glib.IdleAdd(func() bool {
		v.GetSnapshot(func(img *image.RGBA, err error) {
			if err != nil {
				errChan <- err
				return
			}
			if img == nil {
				errChan <- ErrNoImage
				return
			}

			resultChan <- img
		})
		return false
	})

	select {
	case result = <-resultChan:
		return result, nil
	case err = <-errChan:
		return nil, err
	case <-timeout:
		return nil, ErrTimeout
	}
}

func (v *View) EvaluateJavaScript(script string, t *time.Duration) (result interface{}, err error) {
	if v.closed {
		return nil, ErrViewClosed
	}

	resultChan := make(chan interface{}, 1)
	errChan := make(chan error, 1)
	timeout := newTimeout(t)

	glib.IdleAdd(func() bool {
		v.WebView.RunJavaScript(script, func(result *gojs.Value, err error) {
			if err == nil {
				goval, err := result.GoValue()
				if err != nil {
					errChan <- err
					return
				}
				// Patch the value type to int64 if a whole number
				if goval != nil && (reflect.TypeOf(goval).Kind() == reflect.Float64) {
					f := goval.(float64)
					if i := int64(f); float64(i) == f {
						goval = i
					}
				}

				resultChan <- goval
			} else {
				errChan <- err
			}
			return
		})
		return false
	})

	select {
	case result = <-resultChan:
		return result, nil
	case err = <-errChan:
		return nil, err
	case <-timeout:
		return nil, ErrTimeout
	}
}

// Wait for the current page to finish loading.
func (v *View) Wait(t *time.Duration) error {
	if v.closed {
		return ErrViewClosed
	}

	timeout := newTimeout(t)

	select {
	case <-timeout:
		return ErrTimeout
	case <-v.load:
		return v.lastLoadErr
	}

}

func (v *View) Close() {
	if v.closed {
		return
	}

	v.closed = true
	v.Destroy()
}

type Renderer struct {
	sync.Mutex
}

const envDisplay = "DISPLAY"
const xLockParent = "/tmp"

func (r *Renderer) waitForX() error {
	d := os.Getenv(envDisplay)
	if d == "" {
		return fmt.Errorf("No %s variable set for X", envDisplay)
	}

	if len(d) < 2 {
		return fmt.Errorf("%s variable %q is malformed", envDisplay, d)
	}
	n := d[1:]

	f := fmt.Sprintf("%s/.X%s-lock", xLockParent, n)

	w, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}
	defer w.Close()

	t := 10 * time.Second
	timeout := newTimeout(&t)
	found := make(chan struct{})

	go func() {
		for {
			select {
			case event := <-w.Events:
				if event.Op&fsnotify.Create == fsnotify.Create {
					if event.Name == f {
						// got it
						close(found)
					}
				}
			case err := <-w.Errors:
				if err != nil {
					panic(err)
				} // else the watcher was closed
			}
		}
	}()

	err = w.Add(xLockParent)
	if err != nil {
		return err
	}

	if _, err := os.Stat(f); os.IsNotExist(err) {
		log.Printf("Waiting on %s", f)
		select {
		case <-timeout:
			return ErrNoX
		case <-found:
			return nil
		}

	}

	return nil
}

// NewRenderer creates a new GTK based rendering context
func NewRenderer() (*Renderer, error) {
	r := Renderer{}

	if err := r.waitForX(); err != nil {
		return nil, err
	}

	r.start()

	return &r, nil
}

// Ensure that the GTK+ main loop has started. If it has already been
func (r *Renderer) start() {
	gtkOnce.Do(func() {
		gtk.Init(nil)
		go func() {
			runtime.LockOSThread()
			gtk.Main()
		}()
	})
}

// NewView creates a new Webkit view
func (r *Renderer) NewView(appName, appVersion string, autoLoadImages, consoleStdout bool) *View {
	c := make(chan *View, 1)

	r.Lock()

	glib.IdleAdd(func() bool {
		webView := webkit2.NewWebView()
		settings := webView.Settings()
		settings.SetAutoLoadImages(autoLoadImages)
		settings.SetEnableWriteConsoleMessagesToStdout(consoleStdout)
		settings.SetUserAgentWithApplicationDetails(appName, appVersion)
		v := &View{WebView: webView}
		loadChangedHandler, _ := webView.Connect("load-changed", func(_ *glib.Object, loadEvent webkit2.LoadEvent) {
			t := time.Now()
			switch loadEvent {
			case webkit2.LoadStarted:
				v.loadStarted = &t
			case webkit2.LoadFinished:
				v.loadFinished = &t
				v.load <- struct{}{}
			}
		})
		webView.Connect("load-failed", func() {
			v.lastLoadErr = ErrLoadFailed
			webView.HandlerDisconnect(loadChangedHandler)
		})
		c <- v
		return false
	})

	r.Unlock()

	return <-c
}
<commit_msg>Fixed wait for X spin<commit_after>/*
Package render implements a simple wrapper around Webkit that primarily allows for the capture of screenshots.

This package will typically only compile on a modern Linux distribution and requires a running X server. A utility binary is also provided.

*/
package render

import (
	"errors"
	"fmt"
	"github.com/auroralaboratories/go-webkit2/webkit2"
	"github.com/auroralaboratories/gotk3/glib"
	"github.com/auroralaboratories/gotk3/gtk"
	"github.com/fsnotify/fsnotify"
	"github.com/sqs/gojs"
	"image"
	"log"
	"os"
	"reflect"
	"runtime"
	"sync"
	"time"
)

var (
	// ErrLoadFailed signifies that Webkit reports failure of of the page load
	ErrLoadFailed = errors.New("load-failed")
	// ErrViewClosed signifies that the View has already been closed, not further operations allowed
	ErrViewClosed = errors.New("view-closed")
	// ErrTimeout signifies that the supplied timeout has been triggered
	ErrTimeout = errors.New("timeout")
	// ErrNoImage signifies that snapshot did not return a usable image
	ErrNoImage = errors.New("no-image")
	// ErrNoTiming signifies that no timing information is available
	ErrNoTiming = errors.New("load-not-timed")
	// ErrNoX signifies that we did not find a usable X display server
	ErrNoX = errors.New("no-x-display")
)

var gtkOnce sync.Once

func newTimeout(t *time.Duration) chan bool {
	timeout := make(chan bool, 1)
	if t != nil && *t != 0 {
		go func() {
			time.Sleep(*t)
			timeout <- true
		}()
	}
	return timeout
}

type View struct {
	*webkit2.WebView
	load        chan struct{}
	lastLoadErr error
	closed      bool

	loadRequested *time.Time
	loadStarted   *time.Time
	loadFinished  *time.Time
}

func (v *View) TimeToStart() (time.Duration, error) {
	if v.loadRequested == nil || v.loadStarted == nil {
		return 0, ErrNoTiming
	}

	return v.loadStarted.Sub(*v.loadRequested), nil
}

func (v *View) TimeToLoad() (time.Duration, error) {
	if v.loadStarted == nil || v.loadFinished == nil {
		return 0, ErrNoTiming
	}

	return v.loadFinished.Sub(*v.loadStarted), nil
}

func (v *View) TimeToFinish() (time.Duration, error) {
	if v.loadRequested == nil || v.loadFinished == nil {
		return 0, ErrNoTiming
	}

	return v.loadFinished.Sub(*v.loadRequested), nil
}

func (v *View) LoadURI(url string) error {
	if v.closed {
		return ErrViewClosed
	}

	v.load = make(chan struct{}, 1)
	v.lastLoadErr = nil
	v.loadRequested = nil
	v.loadStarted = nil
	v.loadFinished = nil

	glib.IdleAdd(func() bool {
		t := time.Now()
		v.loadRequested = &t
		v.WebView.LoadURI(url)
		return false
	})

	return nil
}

func (v *View) LoadHTML(content, baseURI string) error {
	if v.closed {
		return ErrViewClosed
	}

	v.load = make(chan struct{}, 1)
	v.lastLoadErr = nil
	v.loadRequested = nil
	v.loadStarted = nil
	v.loadFinished = nil

	glib.IdleAdd(func() bool {
		t := time.Now()
		v.loadRequested = &t
		v.WebView.LoadHTML(content, baseURI)
		return false
	})

	return nil
}

func (v *View) NewSnapshot(t *time.Duration) (result *image.RGBA, err error) {
	if v.closed {
		return nil, ErrViewClosed
	}

	resultChan := make(chan *image.RGBA, 1)
	errChan := make(chan error, 1)
	timeout := newTimeout(t)

	glib.IdleAdd(func() bool {
		v.GetSnapshot(func(img *image.RGBA, err error) {
			if err != nil {
				errChan <- err
				return
			}
			if img == nil {
				errChan <- ErrNoImage
				return
			}

			resultChan <- img
		})
		return false
	})

	select {
	case result = <-resultChan:
		return result, nil
	case err = <-errChan:
		return nil, err
	case <-timeout:
		return nil, ErrTimeout
	}
}

func (v *View) EvaluateJavaScript(script string, t *time.Duration) (result interface{}, err error) {
	if v.closed {
		return nil, ErrViewClosed
	}

	resultChan := make(chan interface{}, 1)
	errChan := make(chan error, 1)
	timeout := newTimeout(t)

	glib.IdleAdd(func() bool {
		v.WebView.RunJavaScript(script, func(result *gojs.Value, err error) {
			if err == nil {
				goval, err := result.GoValue()
				if err != nil {
					errChan <- err
					return
				}
				// Patch the value type to int64 if a whole number
				if goval != nil && (reflect.TypeOf(goval).Kind() == reflect.Float64) {
					f := goval.(float64)
					if i := int64(f); float64(i) == f {
						goval = i
					}
				}

				resultChan <- goval
			} else {
				errChan <- err
			}
			return
		})
		return false
	})

	select {
	case result = <-resultChan:
		return result, nil
	case err = <-errChan:
		return nil, err
	case <-timeout:
		return nil, ErrTimeout
	}
}

// Wait for the current page to finish loading.
func (v *View) Wait(t *time.Duration) error {
	if v.closed {
		return ErrViewClosed
	}

	timeout := newTimeout(t)

	select {
	case <-timeout:
		return ErrTimeout
	case <-v.load:
		return v.lastLoadErr
	}

}

func (v *View) Close() {
	if v.closed {
		return
	}

	v.closed = true
	v.Destroy()
}

type Renderer struct {
	sync.Mutex
}

const envDisplay = "DISPLAY"
const xLockParent = "/tmp"

func (r *Renderer) waitForX() error {
	d := os.Getenv(envDisplay)
	if d == "" {
		return fmt.Errorf("No %s variable set for X", envDisplay)
	}

	if len(d) < 2 {
		return fmt.Errorf("%s variable %q is malformed", envDisplay, d)
	}
	n := d[1:]

	f := fmt.Sprintf("%s/.X%s-lock", xLockParent, n)

	w, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}
	defer w.Close()

	t := 10 * time.Second
	timeout := newTimeout(&t)
	found := make(chan struct{})

	go func() {
		for {
			select {
			case event, ok := <-w.Events:
				if !ok {
					return
				}
				if event.Op&fsnotify.Create == fsnotify.Create {
					if event.Name == f {
						// got it
						close(found)
						return
					}
				}
			case err, ok := <-w.Errors:
				if !ok {
					return
				}
				panic(err)
			}
		}
	}()

	err = w.Add(xLockParent)
	if err != nil {
		return err
	}

	if _, err := os.Stat(f); os.IsNotExist(err) {
		log.Printf("Waiting on %s", f)
		select {
		case <-timeout:
			return ErrNoX
		case <-found:
			return nil
		}

	}

	return nil
}

// NewRenderer creates a new GTK based rendering context
func NewRenderer() (*Renderer, error) {
	r := Renderer{}

	if err := r.waitForX(); err != nil {
		return nil, err
	}

	r.start()

	return &r, nil
}

// Ensure that the GTK+ main loop has started. If it has already been
func (r *Renderer) start() {
	gtkOnce.Do(func() {
		gtk.Init(nil)
		go func() {
			runtime.LockOSThread()
			gtk.Main()
		}()
	})
}

// NewView creates a new Webkit view
func (r *Renderer) NewView(appName, appVersion string, autoLoadImages, consoleStdout bool) *View {
	c := make(chan *View, 1)

	r.Lock()

	glib.IdleAdd(func() bool {
		webView := webkit2.NewWebView()
		settings := webView.Settings()
		settings.SetAutoLoadImages(autoLoadImages)
		settings.SetEnableWriteConsoleMessagesToStdout(consoleStdout)
		settings.SetUserAgentWithApplicationDetails(appName, appVersion)
		v := &View{WebView: webView}
		loadChangedHandler, _ := webView.Connect("load-changed", func(_ *glib.Object, loadEvent webkit2.LoadEvent) {
			t := time.Now()
			switch loadEvent {
			case webkit2.LoadStarted:
				v.loadStarted = &t
			case webkit2.LoadFinished:
				v.loadFinished = &t
				v.load <- struct{}{}
			}
		})
		webView.Connect("load-failed", func() {
			v.lastLoadErr = ErrLoadFailed
			webView.HandlerDisconnect(loadChangedHandler)
		})
		c <- v
		return false
	})

	r.Unlock()

	return <-c
}
<|endoftext|>


<commit_before>package ale

import (
	"bytes"
	"fmt"
	"html/template"
	"net/http"
	"os"

	"github.com/oxtoacart/bpool"
	"github.com/pkg/errors"
)

// BufPoolSize is the size of the BufferPool.
var BufPoolSize = 32

// BufPoolAlloc is the maximum size of each buffer.
var BufPoolAlloc = 10 * 1024

var bufpool *bpool.SizedBufferPool

func initBufPool() {
	bufpool = bpool.NewSizedBufferPool(BufPoolSize, BufPoolAlloc)
}

func getBuf() *bytes.Buffer {
	if bufpool == nil {
		initBufPool()
	}
	return bufpool.Get()
}

func putBuf(b *bytes.Buffer) {
	bufpool.Put(b)
}

func (s *Server) template(name string) (*template.Template, error) {
	if s.TemplateDir == "" {
		return nil, errors.Errorf("No TemplateDir specified")
	}
	tmplFile := s.TemplateDir + "/" + name
	if _, err := os.Stat(tmplFile); err != nil {
		return nil, errors.Wrapf(err, "Unable to read requested template `%s'", tmplFile)
	}
	t := template.New("")
	if s.View.FuncMap != nil {
		t = t.Funcs(s.View.FuncMap)
	}
	_, err := t.ParseFiles(tmplFile)
	if err != nil {
		return nil, errors.Wrapf(err, "Unable to parse template '%s'", tmplFile)
	}
	libPath := s.TemplateDir + "/lib"
	if _, err := os.Stat(libPath); err != nil && !os.IsNotExist(err) {
		return nil, errors.Wrapf(err, "Unable to read templates lib `%s`", libPath)
	} else if err == nil {
		_, err := t.ParseGlob(libPath + "/*")
		if err != nil {
			return nil, errors.Wrapf(err, "Error parsing templates in '%s'", libPath)
		}
	}
	return t, nil
}

// Render renders the page
func (s *Server) Render(w ResponseWriter, r *http.Request) {
	if w.Written() {
		return
	}
	if err := s.renderTemplate(w, r); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "Error executing template: %s\n", err)
	}
}

func (s *Server) renderTemplate(w ResponseWriter, r *http.Request) error {
	view := GetView(r)
	viewName := view.View
	if viewName == "" {
		return errors.Errorf("No view defined for %s", r.URL.Path)
	}
	tmplName := view.Template
	if tmplName == "" {
		tmplName = viewName
	}

	t, err := s.template(viewName)
	if err != nil {
		return err
	}
	if view.FuncMap != nil {
		t.Funcs(view.FuncMap)
	}
	buf := getBuf()
	defer putBuf(buf)
	if err := t.ExecuteTemplate(buf, tmplName, GetStash(r)); err != nil {
		return err
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	buf.WriteTo(w)
	return nil
}
<commit_msg>Set content type for errors, so gzip doesn't break stuff<commit_after>package ale

import (
	"bytes"
	"fmt"
	"html/template"
	"net/http"
	"os"

	"github.com/oxtoacart/bpool"
	"github.com/pkg/errors"
)

// BufPoolSize is the size of the BufferPool.
var BufPoolSize = 32

// BufPoolAlloc is the maximum size of each buffer.
var BufPoolAlloc = 10 * 1024

var bufpool *bpool.SizedBufferPool

func initBufPool() {
	bufpool = bpool.NewSizedBufferPool(BufPoolSize, BufPoolAlloc)
}

func getBuf() *bytes.Buffer {
	if bufpool == nil {
		initBufPool()
	}
	return bufpool.Get()
}

func putBuf(b *bytes.Buffer) {
	bufpool.Put(b)
}

func (s *Server) template(name string) (*template.Template, error) {
	if s.TemplateDir == "" {
		return nil, errors.Errorf("No TemplateDir specified")
	}
	tmplFile := s.TemplateDir + "/" + name
	if _, err := os.Stat(tmplFile); err != nil {
		return nil, errors.Wrapf(err, "Unable to read requested template `%s'", tmplFile)
	}
	t := template.New("")
	if s.View.FuncMap != nil {
		t = t.Funcs(s.View.FuncMap)
	}
	_, err := t.ParseFiles(tmplFile)
	if err != nil {
		return nil, errors.Wrapf(err, "Unable to parse template '%s'", tmplFile)
	}
	libPath := s.TemplateDir + "/lib"
	if _, err := os.Stat(libPath); err != nil && !os.IsNotExist(err) {
		return nil, errors.Wrapf(err, "Unable to read templates lib `%s`", libPath)
	} else if err == nil {
		_, err := t.ParseGlob(libPath + "/*")
		if err != nil {
			return nil, errors.Wrapf(err, "Error parsing templates in '%s'", libPath)
		}
	}
	return t, nil
}

// Render renders the page
func (s *Server) Render(w ResponseWriter, r *http.Request) {
	if w.Written() {
		return
	}
	if err := s.renderTemplate(w, r); err != nil {
		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "Error executing template: %s\n", err)
	}
}

func (s *Server) renderTemplate(w ResponseWriter, r *http.Request) error {
	view := GetView(r)
	viewName := view.View
	if viewName == "" {
		return errors.Errorf("No view defined for %s", r.URL.Path)
	}
	tmplName := view.Template
	if tmplName == "" {
		tmplName = viewName
	}

	t, err := s.template(viewName)
	if err != nil {
		return err
	}
	if view.FuncMap != nil {
		t.Funcs(view.FuncMap)
	}
	buf := getBuf()
	defer putBuf(buf)
	if err := t.ExecuteTemplate(buf, tmplName, GetStash(r)); err != nil {
		return err
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	buf.WriteTo(w)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"log"
	"testing"
)

var sut pokenv

func init() {
	sut = pokenv{
		environment: make(map[string][]string),
		registry:    mock,
	}
	log.SetOutput(ioutil.Discard)
}

func TestProcessLineValue(t *testing.T) {
	sut.currentVariable = "TESTING"
	sut.addCurrent("")

	sut.processLine(" value # comment")
	assertEquals(t, "value", sut.environment[sut.currentVariable][0])
}

func TestProcessLineSection(t *testing.T) {
	sut.processLine("[ A SECTION ]")
	assertEquals(t, "ASECTION", sut.currentVariable)
}

func TestProcessTestFile(t *testing.T) {
	sut.importEnv(PATH_MACHINE, `data/setvar.txt`)
	assertEquals(t, "valueline1", mock.env["POKE_SECTION"])
}

func assertEquals(t *testing.T, expected string, actual string) {
	if actual != expected {
		t.Errorf("Expected: %q, was: %q", expected, actual)
	}
}

func TestCheckPath(t *testing.T) {
	paths := []string{
		`c:\Windows`,
		`c:\Windows\system32`,
		`%windir%`,
		`%windir%\system32`,
		`.`,
	}
	for _, path := range paths {
		if isPathInvalid(path) {
			t.Errorf("Invalid path:", path)
		}
	}
}
<commit_msg>skip test on non-windows os<commit_after>package main

import (
	"io/ioutil"
	"log"
	"runtime"
	"testing"
)

var sut pokenv

func init() {
	sut = pokenv{
		environment: make(map[string][]string),
		registry:    mock,
	}
	log.SetOutput(ioutil.Discard)
}

func TestProcessLineValue(t *testing.T) {
	sut.currentVariable = "TESTING"
	sut.addCurrent("")

	sut.processLine(" value # comment")
	assertEquals(t, "value", sut.environment[sut.currentVariable][0])
}

func TestProcessLineSection(t *testing.T) {
	sut.processLine("[ A SECTION ]")
	assertEquals(t, "ASECTION", sut.currentVariable)
}

func TestProcessTestFile(t *testing.T) {
	sut.importEnv(PATH_MACHINE, `data/setvar.txt`)
	assertEquals(t, "valueline1", mock.env["POKE_SECTION"])
}

func assertEquals(t *testing.T, expected string, actual string) {
	if actual != expected {
		t.Errorf("Expected: %q, was: %q", expected, actual)
	}
}

func TestCheckPath(t *testing.T) {
	if runtime.GOOS == "windows" {
		paths := []string{
			`c:\Windows`,
			`c:\Windows\system32`,
			`%windir%`,
			`%windir%\system32`,
			`.`,
		}
		for _, path := range paths {
			if isPathInvalid(path) {
				t.Errorf("Invalid path:", path)
			}
		}
	} else {
		t.Skip("Cannot test windows paths")
	}
}
<|endoftext|>


<commit_before>package daemon

import (
	"encoding/json"
	"errors"
	"net"
	"os"
	"os/signal"
	"time"

	log "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/Sirupsen/logrus"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/codegangsta/cli"
	"github.com/socketplane/socketplane/datastore"
)

type Daemon struct {
	Configuration *Configuration
	Connections   map[string]*Connection
	cC            chan *ConnectionContext
}

func NewDaemon() *Daemon {
	return &Daemon{
		&Configuration{},
		map[string]*Connection{},
		make(chan *ConnectionContext),
	}
}

func (d *Daemon) Run(ctx *cli.Context) {
	if ctx.Bool("debug") {
		log.SetLevel(log.DebugLevel)
	}
	bootstrapNode := ctx.Bool("bootstrap")
	serialChan := make(chan bool)
	bindChan = make(chan string)

	var bindInterface string
	go ServeAPI(d)

	go func() {
		if ctx.String("iface") != "auto" {
			bindInterface = ctx.String("iface")
		} else {
			intf := identifyInterfaceToBind()
			if intf != nil {
				bindInterface = intf.Name
			}
		}
		if bindInterface != "" {
			log.Printf("Binding to %s", bindInterface)
		} else {
			log.Errorf("Unable to identify any Interface to Bind to. Going with Defaults")
		}
		Bonjour(bindInterface)
		if clusterListener == "" {
			bindChan <- bindInterface
		}
	}()

	go func() {
		for {
			bindInterface = <-bindChan
			if bindInterface == clusterListener {
				continue
			}
			once := true
			if clusterListener != "" {
				once = false
				datastore.Leave()
				time.Sleep(time.Second * 5)
			}
			clusterListener = bindInterface
			datastore.Init(clusterListener, bootstrapNode)
			if !bootstrapNode && once {
				serialChan <- true
			}
		}
	}()

	go func() {
		if !bootstrapNode {
			log.Printf("Non-Bootstrap node waiting on peer discovery")
			<-serialChan
			log.Printf("Non-Bootstrap node admitted into cluster")
		}
		err := CreateBridge()
		if err != nil {
			log.Error(err.Error)
		}
		d.populateConnections()
		_, err = CreateDefaultNetwork()
		if err != nil {
			log.Error(err.Error)
		}
	}()

	go RunConnectionHandler(d)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for _ = range c {
			os.Exit(0)
		}
	}()
	select {}
}

var bindChan chan string
var clusterListener string

func ConfigureClusterListenerPort(listen string) error {
	iface, err := net.InterfaceByName(listen)
	if err != nil {
		return err
	}
	if iface.Flags&net.FlagUp == 0 {
		return errors.New("Interface is down")
	}
	bindChan <- listen
	return nil
}

func identifyInterfaceToBind() *net.Interface {
	// If the user isnt binding an interface using --iface option and let the daemon to
	// identify the interface, the daemon will try its best to identify the best interface
	// for the job.
	// In a few auto-install / zerotouch config scenarios, eligible interfaces may
	// be identified after the socketplane daemon is up and running.

	for {
		var intf *net.Interface
		if clusterListener != "" {
			intf, _ = net.InterfaceByName(clusterListener)
		} else {
			intf = InterfaceToBind()
		}
		if intf != nil {
			return intf
		}
		time.Sleep(time.Second * 5)
		log.Infof("Identifying interface to bind ... Use --iface option for static binding")
	}
	return nil
}

func (d *Daemon) populateConnections() {
	for key, val := range ContextCache {
		connection := &Connection{}
		err := json.Unmarshal([]byte(val), connection)
		if err == nil {
			d.Connections[key] = connection
		}
	}
}
<commit_msg>Resolving a consul flap issue introduced by recent branch merge<commit_after>package daemon

import (
	"encoding/json"
	"errors"
	"net"
	"os"
	"os/signal"
	"time"

	log "github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/Sirupsen/logrus"
	"github.com/socketplane/socketplane/Godeps/_workspace/src/github.com/codegangsta/cli"
	"github.com/socketplane/socketplane/datastore"
)

type Daemon struct {
	Configuration *Configuration
	Connections   map[string]*Connection
	cC            chan *ConnectionContext
}

func NewDaemon() *Daemon {
	return &Daemon{
		&Configuration{},
		map[string]*Connection{},
		make(chan *ConnectionContext),
	}
}

func (d *Daemon) Run(ctx *cli.Context) {
	if ctx.Bool("debug") {
		log.SetLevel(log.DebugLevel)
	}
	bootstrapNode := ctx.Bool("bootstrap")
	serialChan := make(chan bool)

	go ServeAPI(d)
	go func() {
		var bindInterface string
		if ctx.String("iface") != "auto" {
			bindInterface = ctx.String("iface")
		} else {
			intf := identifyInterfaceToBind()
			if intf != nil {
				bindInterface = intf.Name
			}
		}
		if bindInterface != "" {
			log.Printf("Binding to %s", bindInterface)
		} else {
			log.Errorf("Unable to identify any Interface to Bind to. Going with Defaults")
		}
		datastore.Init(bindInterface, bootstrapNode)
		Bonjour(bindInterface)
		if !bootstrapNode {
			serialChan <- true
		}
	}()

	/*
		TODO : Enable this while addressing #69
		go func() {
			for {
				bindInterface = <-bindChan
				if bindInterface == clusterListener {
					continue
				}
				once := true
				if clusterListener != "" {
					once = false
					datastore.Leave()
					time.Sleep(time.Second * 5)
				}
				clusterListener = bindInterface
				datastore.Init(clusterListener, bootstrapNode)
				if !bootstrapNode && once {
					serialChan <- true
				}
			}
		}()
	*/
	go func() {
		if !bootstrapNode {
			log.Printf("Non-Bootstrap node waiting on peer discovery")
			<-serialChan
			log.Printf("Non-Bootstrap node admitted into cluster")
		}
		err := CreateBridge()
		if err != nil {
			log.Error(err.Error)
		}
		d.populateConnections()
		_, err = CreateDefaultNetwork()
		if err != nil {
			log.Error(err.Error)
		}
	}()

	go RunConnectionHandler(d)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for _ = range c {
			os.Exit(0)
		}
	}()
	select {}
}

var bindChan chan string
var clusterListener string

func ConfigureClusterListenerPort(listen string) error {
	iface, err := net.InterfaceByName(listen)
	if err != nil {
		return err
	}
	if iface.Flags&net.FlagUp == 0 {
		return errors.New("Interface is down")
	}
	// TODO : enable this while addressing #69
	// bindChan <- listen
	return nil
}

func identifyInterfaceToBind() *net.Interface {
	// If the user isnt binding an interface using --iface option and let the daemon to
	// identify the interface, the daemon will try its best to identify the best interface
	// for the job.
	// In a few auto-install / zerotouch config scenarios, eligible interfaces may
	// be identified after the socketplane daemon is up and running.

	for {
		var intf *net.Interface
		if clusterListener != "" {
			intf, _ = net.InterfaceByName(clusterListener)
		} else {
			intf = InterfaceToBind()
		}
		if intf != nil {
			return intf
		}
		time.Sleep(time.Second * 5)
		log.Infof("Identifying interface to bind ... Use --iface option for static binding")
	}
	return nil
}

func (d *Daemon) populateConnections() {
	for key, val := range ContextCache {
		connection := &Connection{}
		err := json.Unmarshal([]byte(val), connection)
		if err == nil {
			d.Connections[key] = connection
		}
	}
}
<|endoftext|>


<commit_before>package emil

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"time"
)

type positionKey string

// PositionEntry is an entry in the PositionDb
type PositionEntry struct {
	Position      *position
	Dtm           int
	PrevPositions map[positionKey]*Move
	NextPositions map[positionKey]*Move
}

// NewPositionEntry ceates a new *PositionEntry
func NewPositionEntry(p *position) *PositionEntry {
	return &PositionEntry{
		Position:      p,
		Dtm:           initial,
		PrevPositions: make(map[positionKey]*Move),
		NextPositions: make(map[positionKey]*Move)}
}

func (entry *PositionEntry) addMoveToNextPosition(next *position, m *Move) {
}

// PositionDb to query for mate in 1,2, etc.
type PositionDb struct {
	Positions map[positionKey]*PositionEntry
}

func (db *PositionDb) addPosition(p *position) {
	if _, ok := db.Positions[p.key()]; ok {
		panic("key exsists in db " + p.key())
	}
	entry := NewPositionEntry(p)
	db.retrogradeAnalysisStep0(entry)
	db.Positions[p.key()] = entry
}

func (db *PositionDb) AddPrevPositions() {
	for key, entry := range db.Positions {
		for nextKey, moveToNext := range entry.NextPositions {
			nextPosition := PositionFromKey(string(nextKey))
			nextEntry, ok := db.Positions[nextPosition.key()]
			if ok {
				nextEntry.PrevPositions[key] = moveToNext
			}
		}
	}
}

// generate all moves
func (db *PositionDb) retrogradeAnalysisStep0(entry *PositionEntry) {
	moves := GenerateMoves(entry.Position)
	other := otherPlayer(entry.Position.player)
	for _, move := range moves {
		nextBoard := entry.Position.board.DoMove(move)
		nextPosition := NewPosition(nextBoard, other)
		entry.NextPositions[nextPosition.key()] = move
	}
}

// NewPositionDB creates a new *PositionDB
func NewPositionDB() *PositionDb {
	return &PositionDb{
		Positions: make(map[positionKey]*PositionEntry)}
}

func (db *PositionDb) FillWithKRKPositions() {
	var err error

	for wk := A1; wk <= H8; wk++ {
		//for wk := E3; wk <= E3; wk++ {
		if DEBUG {
			fmt.Printf("White king on %s\n", BoardSquares[wk])
		}
		for wr := A1; wr <= H8; wr++ {
			for bk := A1; bk <= H8; bk++ {

				board := NewBoard()

				err = board.Setup(WhiteKing, wk)
				if err != nil {
					continue
				}

				err = board.Setup(WhiteRock, wr)
				if err != nil {
					continue
				}

				err = board.Setup(BlackKing, bk)
				if err != nil {
					continue
				}

				err = board.kingsToClose()
				if err != nil {
					continue
				}

				db.addPosition(NewPosition(board, WHITE))
				db.addPosition(NewPosition(board, BLACK))
			}
		}
	}
}

// SaveEndGameDb saves the an end game DB for KRK to file
func (db *PositionDb) SavePositionDb(file string) error {
	fmt.Println("WriteDataToFile: ", file)

	start := time.Now()
	fmt.Printf("json.MarshalIndent\n")
	b, err := json.MarshalIndent(db, "", "  ")
	if err != nil {
		return err
	}
	end := time.Now()
	fmt.Printf("json.MarshalIndent %v\n", end.Sub(start))

	start = time.Now()
	fmt.Printf("ioutil.WriteFile\n")
	err = ioutil.WriteFile(file, b, 0666)
	end = time.Now()
	fmt.Printf("ioutil.WriteFile %v, error=%v\n", end.Sub(start), err)
	return err
}
<commit_msg>LoadPositionDb<commit_after>package emil

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"time"
)

type positionKey string

// PositionEntry is an entry in the PositionDb
type PositionEntry struct {
	Position      *position
	Dtm           int
	PrevPositions map[positionKey]*Move
	NextPositions map[positionKey]*Move
}

// NewPositionEntry ceates a new *PositionEntry
func NewPositionEntry(p *position) *PositionEntry {
	return &PositionEntry{
		Position:      p,
		Dtm:           initial,
		PrevPositions: make(map[positionKey]*Move),
		NextPositions: make(map[positionKey]*Move)}
}

func (entry *PositionEntry) addMoveToNextPosition(next *position, m *Move) {
}

// PositionDb to query for mate in 1,2, etc.
type PositionDb struct {
	Positions map[positionKey]*PositionEntry
}

func (db *PositionDb) addPosition(p *position) {
	if _, ok := db.Positions[p.key()]; ok {
		panic("key exsists in db " + p.key())
	}
	entry := NewPositionEntry(p)
	db.retrogradeAnalysisStep0(entry)
	db.Positions[p.key()] = entry
}

func (db *PositionDb) AddPrevPositions() {
	for key, entry := range db.Positions {
		for nextKey, moveToNext := range entry.NextPositions {
			nextPosition := PositionFromKey(string(nextKey))
			nextEntry, ok := db.Positions[nextPosition.key()]
			if ok {
				nextEntry.PrevPositions[key] = moveToNext
			}
		}
	}
}

// generate all moves
func (db *PositionDb) retrogradeAnalysisStep0(entry *PositionEntry) {
	moves := GenerateMoves(entry.Position)
	other := otherPlayer(entry.Position.player)
	for _, move := range moves {
		nextBoard := entry.Position.board.DoMove(move)
		nextPosition := NewPosition(nextBoard, other)
		entry.NextPositions[nextPosition.key()] = move
	}
}

// NewPositionDB creates a new *PositionDB
func NewPositionDB() *PositionDb {
	return &PositionDb{
		Positions: make(map[positionKey]*PositionEntry)}
}

func (db *PositionDb) FillWithKRKPositions() {
	var err error

	for wk := A1; wk <= H8; wk++ {
		//for wk := E3; wk <= E3; wk++ {
		if DEBUG {
			fmt.Printf("White king on %s\n", BoardSquares[wk])
		}
		for wr := A1; wr <= H8; wr++ {
			for bk := A1; bk <= H8; bk++ {

				board := NewBoard()

				err = board.Setup(WhiteKing, wk)
				if err != nil {
					continue
				}

				err = board.Setup(WhiteRock, wr)
				if err != nil {
					continue
				}

				err = board.Setup(BlackKing, bk)
				if err != nil {
					continue
				}

				err = board.kingsToClose()
				if err != nil {
					continue
				}

				db.addPosition(NewPosition(board, WHITE))
				db.addPosition(NewPosition(board, BLACK))
			}
		}
	}
}

// SaveEndGameDb saves the an end game DB for KRK to file
func (db *PositionDb) SavePositionDb(file string) error {
	fmt.Println("WriteDataToFile: ", file)

	start := time.Now()
	fmt.Printf("json.MarshalIndent\n")
	b, err := json.MarshalIndent(db, "", "  ")
	if err != nil {
		return err
	}
	end := time.Now()
	fmt.Printf("json.MarshalIndent %v\n", end.Sub(start))

	start = time.Now()
	fmt.Printf("ioutil.WriteFile\n")
	err = ioutil.WriteFile(file, b, 0666)
	end = time.Now()
	fmt.Printf("ioutil.WriteFile %v, error=%v\n", end.Sub(start), err)
	return err
}
func LoadPositionDb(file string) (db *PositionDb, err error) {
	fmt.Println("LoadDataFromFile: ", file)

	start := time.Now()
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return db, err
	}
	end := time.Now()
	fmt.Printf("ioutil.ReadFile %v,b=%d, error=%v\n", end.Sub(start), len(b), err)

	data := NewPositionDB()
	start = time.Now()
	err = json.Unmarshal(b, data)
	if err != nil {
		return db, err
	}
	end = time.Now()
	fmt.Printf("json.Unmarshal%v\n", end.Sub(start))
	return data, err
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

	"github.com/jessevdk/go-flags"
	"github.com/mackerelio/checkers"
)

var opts struct {
	StateDir        string  `short:"s" long:"state-dir" default:"/var/mackerel-cache/check-log" value-name:"DIR" description:"Dir to keep state files under"`
	LogFile         string  `short:"f" long:"log-file" value-name:"FILE" description:"Path to log file"`
	Pattern         string  `short:"q" long:"pattern" required:"true" value-name:"PAT" description:"Pattern to search for"`
	Exclude         string  `short:"E" long:"exclude" value-name:"PAT" description:"Pattern to exclude from matching"`
	WarnOver        int64   `short:"w" long:"warning-over" default:"0" description:"Trigger a warning if matched lines is over a number"`
	CritOver        int64   `short:"c" long:"critical-over" default:"0" description:"Trigger a critical if matched lines is over a number"`
	WarnLevel       float64 `long:"warning-level" value-name:"N" description:"Warning level if pattern has a group"`
	CritLevel       float64 `long:"critical-level" value-name:"N" description:"Critical level if pattern has a group"`
	CaseInsensitive bool    `short:"i" long:"icase" description:"Run a case insensitive match"`
	FilePattern     string  `short:"F" long:"filepattern" value-name:"FILE" description:"Check a pattern of files, instead of one file"`
	ReturnContent   bool    `short:"r" long:"return" description:"Return matched line"`
}

func main() {
	ckr := run(os.Args[1:])
	ckr.Name = "LOG"
	ckr.Exit()
}

func regCompileWithCase(ptn string, caseInsensitive bool) (*regexp.Regexp, error) {
	if caseInsensitive {
		ptn = strings.ToLower(ptn)
	}
	return regexp.Compile(ptn)
}

func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	if opts.LogFile == "" && opts.FilePattern == "" {
		return checkers.Unknown("No log file specified")
	}

	patternReg, err := regCompileWithCase(opts.Pattern, opts.CaseInsensitive)
	if err != nil {
		return checkers.Unknown("pattern is invalid")
	}

	var excludeReg *regexp.Regexp
	if opts.Exclude != "" {
		excludeReg, err = regCompileWithCase(opts.Exclude, opts.CaseInsensitive)
		if err != nil {
			return checkers.Unknown("exclude pattern is invalid")
		}
	}

	fileList := []string{}
	if opts.LogFile != "" {
		fileList = append(fileList, opts.LogFile)
	}

	if opts.FilePattern != "" {
		dirStr := filepath.Dir(opts.FilePattern)
		filePat := filepath.Base(opts.FilePattern)
		reg, err := regCompileWithCase(filePat, opts.CaseInsensitive)
		if err != nil {
			return checkers.Unknown("file-pattern is invalid")
		}

		fileInfos, err := ioutil.ReadDir(dirStr)
		if err != nil {
			return checkers.Unknown("cannot read the Directory:" + err.Error())
		}

		for _, fileInfo := range fileInfos {
			if fileInfo.IsDir() {
				continue
			}
			fname := fileInfo.Name()
			if opts.CaseInsensitive {
				fname = strings.ToLower(fname)
			}
			if reg.MatchString(fname) {
				fileList = append(fileList, dirStr+string(filepath.Separator)+fileInfo.Name())
			}
		}
	}

	warnNum := int64(0)
	critNum := int64(0)
	errorOverall := ""

	for _, f := range fileList {
		w, c, errLines, err := searchLog(f, patternReg, excludeReg)
		if err != nil {
			return checkers.Unknown(err.Error())
		}
		warnNum += w
		critNum += c
		if opts.ReturnContent {
			errorOverall += errLines
		}
	}

	checkSt := checkers.OK
	if warnNum > opts.WarnOver {
		checkSt = checkers.WARNING
	}
	if critNum > opts.CritOver {
		checkSt = checkers.CRITICAL
	}
	msg := fmt.Sprintf("%d warnings, %d criticals for pattern %s. %s", warnNum, critNum, opts.Pattern, errorOverall)
	return checkers.NewChecker(checkSt, msg)
}

func searchLog(logFile string, patternReg, excludeReg *regexp.Regexp) (int64, int64, string, error) {
	stateFile := getStateFile(opts.StateDir, logFile)
	skipBytes, err := getBytesToSkip(stateFile)
	if err != nil {
		return 0, 0, "", err
	}
	f, err := os.Open(logFile)
	if err != nil {
		return 0, 0, "", err
	}
	defer f.Close()

	stat, err := f.Stat()
	if err != nil {
		return 0, 0, "", err
	}

	readBytes := int64(0)
	if skipBytes > 0 && stat.Size() >= skipBytes {
		f.Seek(skipBytes, 0)
		readBytes = skipBytes
	}
	warnNum := int64(0)
	critNum := int64(0)
	errLines := ""
	r := bufio.NewReader(f)

	for {
		lineBytes, err := r.ReadBytes('\n')
		readBytes += int64(len(lineBytes))
		if err == io.EOF {
			break
		} else if err != nil {
			return 0, 0, "", err
		}
		line := strings.Trim(string(lineBytes), "\r\n")
		checkLine := line
		if opts.CaseInsensitive {
			checkLine = strings.ToLower(checkLine)
		}
		if patternReg.MatchString(checkLine) && (excludeReg == nil || !excludeReg.MatchString(checkLine)) {
			warnNum++
			critNum++
			errLines += "\n" + line
		}
	}
	err = writeBytesToSkip(stateFile, readBytes)
	return warnNum, critNum, errLines, nil
}

var stateRe = regexp.MustCompile(`^([A-Z]):[/\\]`)

func getStateFile(stateDir, f string) string {
	return filepath.Join(stateDir, stateRe.ReplaceAllString(f, `$1`+string(filepath.Separator)))
}

func getBytesToSkip(f string) (int64, error) {
	_, err := os.Stat(f)
	if err != nil {
		return 0, nil
	}
	b, err := ioutil.ReadFile(f)
	if err != nil {
		return 0, err
	}
	i, err := strconv.Atoi(strings.Trim(string(b), " \r\n"))
	if err != nil {
		return 0, err
	}
	return int64(i), nil
}

func writeBytesToSkip(f string, num int64) error {
	err := os.MkdirAll(filepath.Dir(f), 0755)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(f, []byte(fmt.Sprintf("%d", num)), 0755)
}
<commit_msg>support captured wanrning/critical levels<commit_after>package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

	"github.com/jessevdk/go-flags"
	"github.com/mackerelio/checkers"
)

var opts struct {
	StateDir        string  `short:"s" long:"state-dir" default:"/var/mackerel-cache/check-log" value-name:"DIR" description:"Dir to keep state files under"`
	LogFile         string  `short:"f" long:"log-file" value-name:"FILE" description:"Path to log file"`
	Pattern         string  `short:"q" long:"pattern" required:"true" value-name:"PAT" description:"Pattern to search for"`
	Exclude         string  `short:"E" long:"exclude" value-name:"PAT" description:"Pattern to exclude from matching"`
	WarnOver        int64   `short:"w" long:"warning-over" description:"Trigger a warning if matched lines is over a number"`
	CritOver        int64   `short:"c" long:"critical-over" description:"Trigger a critical if matched lines is over a number"`
	WarnLevel       float64 `long:"warning-level" value-name:"N" description:"Warning level if pattern has a group"`
	CritLevel       float64 `long:"critical-level" value-name:"N" description:"Critical level if pattern has a group"`
	CaseInsensitive bool    `short:"i" long:"icase" description:"Run a case insensitive match"`
	FilePattern     string  `short:"F" long:"filepattern" value-name:"FILE" description:"Check a pattern of files, instead of one file"`
	ReturnContent   bool    `short:"r" long:"return" description:"Return matched line"`
}

func main() {
	ckr := run(os.Args[1:])
	ckr.Name = "LOG"
	ckr.Exit()
}

func regCompileWithCase(ptn string, caseInsensitive bool) (*regexp.Regexp, error) {
	if caseInsensitive {
		ptn = strings.ToLower(ptn)
	}
	return regexp.Compile(ptn)
}

func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	if opts.LogFile == "" && opts.FilePattern == "" {
		return checkers.Unknown("No log file specified")
	}

	patternReg, err := regCompileWithCase(opts.Pattern, opts.CaseInsensitive)
	if err != nil {
		return checkers.Unknown("pattern is invalid")
	}

	var excludeReg *regexp.Regexp
	if opts.Exclude != "" {
		excludeReg, err = regCompileWithCase(opts.Exclude, opts.CaseInsensitive)
		if err != nil {
			return checkers.Unknown("exclude pattern is invalid")
		}
	}

	fileList := []string{}
	if opts.LogFile != "" {
		fileList = append(fileList, opts.LogFile)
	}

	if opts.FilePattern != "" {
		dirStr := filepath.Dir(opts.FilePattern)
		filePat := filepath.Base(opts.FilePattern)
		reg, err := regCompileWithCase(filePat, opts.CaseInsensitive)
		if err != nil {
			return checkers.Unknown("file-pattern is invalid")
		}

		fileInfos, err := ioutil.ReadDir(dirStr)
		if err != nil {
			return checkers.Unknown("cannot read the Directory:" + err.Error())
		}

		for _, fileInfo := range fileInfos {
			if fileInfo.IsDir() {
				continue
			}
			fname := fileInfo.Name()
			if opts.CaseInsensitive {
				fname = strings.ToLower(fname)
			}
			if reg.MatchString(fname) {
				fileList = append(fileList, dirStr+string(filepath.Separator)+fileInfo.Name())
			}
		}
	}

	warnNum := int64(0)
	critNum := int64(0)
	errorOverall := ""

	for _, f := range fileList {
		w, c, errLines, err := searchLog(f, patternReg, excludeReg)
		if err != nil {
			return checkers.Unknown(err.Error())
		}
		warnNum += w
		critNum += c
		if opts.ReturnContent {
			errorOverall += errLines
		}
	}

	checkSt := checkers.OK
	if warnNum > opts.WarnOver {
		checkSt = checkers.WARNING
	}
	if critNum > opts.CritOver {
		checkSt = checkers.CRITICAL
	}
	msg := fmt.Sprintf("%d warnings, %d criticals for pattern %s. %s", warnNum, critNum, opts.Pattern, errorOverall)
	return checkers.NewChecker(checkSt, msg)
}

func searchLog(logFile string, patternReg, excludeReg *regexp.Regexp) (int64, int64, string, error) {
	stateFile := getStateFile(opts.StateDir, logFile)
	skipBytes, err := getBytesToSkip(stateFile)
	if err != nil {
		return 0, 0, "", err
	}
	f, err := os.Open(logFile)
	if err != nil {
		return 0, 0, "", err
	}
	defer f.Close()

	stat, err := f.Stat()
	if err != nil {
		return 0, 0, "", err
	}

	readBytes := int64(0)
	if skipBytes > 0 && stat.Size() >= skipBytes {
		f.Seek(skipBytes, 0)
		readBytes = skipBytes
	}
	warnNum := int64(0)
	critNum := int64(0)
	errLines := ""
	r := bufio.NewReader(f)

	for {
		lineBytes, err := r.ReadBytes('\n')
		readBytes += int64(len(lineBytes))
		if err == io.EOF {
			break
		} else if err != nil {
			return 0, 0, "", err
		}
		line := strings.Trim(string(lineBytes), "\r\n")
		checkLine := line
		if opts.CaseInsensitive {
			checkLine = strings.ToLower(checkLine)
		}
		if matches := patternReg.FindStringSubmatch(checkLine); len(matches) > 0 && (excludeReg == nil || !excludeReg.MatchString(checkLine)) {
			if len(matches) > 1 && (opts.WarnLevel > 0 || opts.CritLevel > 0) {
				level, err := strconv.ParseFloat(matches[1], 64)
				if err != nil {
					warnNum++
					critNum++
					errLines += "\n" + line
				} else {
					levelOver := false
					if level > opts.WarnLevel {
						levelOver = true
						warnNum++
					}
					if level > opts.CritLevel {
						levelOver = true
						critNum++
					}
					if levelOver {
						errLines += "\n" + line
					}
				}
			} else {
				warnNum++
				critNum++
				errLines += "\n" + line
			}
		}
	}
	err = writeBytesToSkip(stateFile, readBytes)
	return warnNum, critNum, errLines, nil
}

var stateRe = regexp.MustCompile(`^([A-Z]):[/\\]`)

func getStateFile(stateDir, f string) string {
	return filepath.Join(stateDir, stateRe.ReplaceAllString(f, `$1`+string(filepath.Separator)))
}

func getBytesToSkip(f string) (int64, error) {
	_, err := os.Stat(f)
	if err != nil {
		return 0, nil
	}
	b, err := ioutil.ReadFile(f)
	if err != nil {
		return 0, err
	}
	i, err := strconv.Atoi(strings.Trim(string(b), " \r\n"))
	if err != nil {
		return 0, err
	}
	return int64(i), nil
}

func writeBytesToSkip(f string, num int64) error {
	err := os.MkdirAll(filepath.Dir(f), 0755)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(f, []byte(fmt.Sprintf("%d", num)), 0755)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	var err error

	if len(args) == 0 {
		return nil, errors.New("Incorrect number of arguments. At least one Meter's name is required.")
	}

	for _,name := range args {
		if len(name) == 0{
			continue
		}
		err = stub.PutState( "kwh_" + name, []byte(strconv.Itoa(0)));
		if err != nil {
			return nil, errors.New("Meter cannot be created")
		}
		err = stub.PutState( name, []byte(strconv.Itoa(0)));
		if err != nil {
			return nil, errors.New("Meter cannot be created")
		}
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) settle(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	//var err error
	var key string
	var val int
	var exchange_rate, previous_val, amount float64

	exchange_rate = 0.1;

	//TODO iteration by id is not an option. you should load keys from fabric
	for i := 1; i < 10; i++ {
		key = strconv.Itoa(i)
		value, err := stub.GetState("kwh_" + key)
		if err != nil {
			continue
		}
		if value == nil {
			continue
		}
		val, _ = strconv.Atoi(string(value))
		amount = float64(val)* -1 * exchange_rate;
		//f := "change"
		//queryArgs := []string{name,string(amount)}
		//_, err := stub.InvokeChaincode("2780b7463c57f343a9e107854c4b53150018cdd8fd74ca970c028de6bfa707f6e9f6cf2b20f0af4fdd04d2167651eb29c7bfabf19e6a93ae2aff65f55202d0e6", f, queryArgs)
		//if err != nil {
		//	errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", err.Error())
		//	fmt.Printf(errStr)
		//	return nil, errors.New(errStr)
		//}
		coins, err := stub.GetState(key)
		if err != nil {
			jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
			return nil, errors.New(jsonResp)
		}
		if(coins == nil){
			previous_val = 0
		}else{
			previous_val, _ = strconv.ParseFloat(string(coins), 64);
		}

		err = stub.PutState(key, []byte(strconv.FormatFloat(amount + previous_val, 'f', 6, 64)))

		if err != nil {
			return nil, err
		}
		err = stub.PutState("kwh_" + key, []byte(strconv.Itoa(0)));
		if err != nil {
			return nil, errors.New("Meter cannot be updated")
		}
	}

	return nil, nil
}

func (t *SimpleChaincode) Invoke(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {

	if function == "settle" {
		return t.settle(stub, args)
	}

	if function != "report" {
		return nil, errors.New("Unimplemented '" + function + "' invoked")
	}

	var name string    // Entities
	var val int // Asset holdings
	var err error

	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2")
	}

	name = args[0]
	val, _ = strconv.Atoi(string(args[1]))

	err = stub.PutState("kwh_" + name, []byte(strconv.Itoa(val)))

	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {

	if function == "balance" {
		return t.balance(stub, args)
	}

	if function != "reported_kwh" {
		return nil, errors.New("Invalid query function name. Expecting \"querybalance\"")
	}
	var name string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the Meter to query")
	}

	name = args[0]

	// Get the state from the ledger
	value, err := stub.GetState("kwh_" + name)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	if value == nil {
		jsonResp := "{\"Error\":\"Nil amount for Meter" + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + name + "\",\"Amount\":\"" + string(value) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return value, nil
}

func (t *SimpleChaincode) balance(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var name string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the Meter to query")
	}

	name = args[0]

	// Get the state from the ledger
	value, err := stub.GetState(name)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	if value == nil {
		jsonResp := "{\"Error\":\"Nil amount for Meter " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + name + "\",\"Amount\":\"" + string(value) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return value, nil
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<commit_msg>move Change method from settle chain code to report<commit_after>package main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	var err error

	if len(args) == 0 {
		return nil, errors.New("Incorrect number of arguments. At least one Meter's name is required.")
	}

	for _,name := range args {
		if len(name) == 0{
			continue
		}
		err = stub.PutState( "kwh_" + name, []byte(strconv.Itoa(0)));
		if err != nil {
			return nil, errors.New("Meter cannot be created")
		}
		err = stub.PutState( name, []byte(strconv.Itoa(0)));
		if err != nil {
			return nil, errors.New("Meter cannot be created")
		}
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) settle(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	//var err error
	var key string
	var val int
	var exchange_rate, previous_val, amount float64

	exchange_rate = 0.1;

	//TODO iteration by id is not an option. you should load keys from fabric
	for i := 1; i < 10; i++ {
		key = strconv.Itoa(i)
		value, err := stub.GetState("kwh_" + key)
		if err != nil {
			continue
		}
		if value == nil {
			continue
		}
		val, _ = strconv.Atoi(string(value))
		amount = float64(val)* -1 * exchange_rate;
		//f := "change"
		//queryArgs := []string{name,string(amount)}
		//_, err := stub.InvokeChaincode("2780b7463c57f343a9e107854c4b53150018cdd8fd74ca970c028de6bfa707f6e9f6cf2b20f0af4fdd04d2167651eb29c7bfabf19e6a93ae2aff65f55202d0e6", f, queryArgs)
		//if err != nil {
		//	errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", err.Error())
		//	fmt.Printf(errStr)
		//	return nil, errors.New(errStr)
		//}
		coins, err := stub.GetState(key)
		if err != nil {
			jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
			return nil, errors.New(jsonResp)
		}
		if(coins == nil){
			previous_val = 0
		}else{
			previous_val, _ = strconv.ParseFloat(string(coins), 64);
		}

		err = stub.PutState(key, []byte(strconv.FormatFloat(amount + previous_val, 'f', 6, 64)))

		if err != nil {
			return nil, err
		}
		err = stub.PutState("kwh_" + key, []byte(strconv.Itoa(0)));
		if err != nil {
			return nil, errors.New("Meter cannot be updated")
		}
	}

	return nil, nil
}

func (t *SimpleChaincode) change(stub *shim.ChaincodeStub,  args []string) ([]byte, error) {

	var name string
	var val, previous_val float64
	var err error

	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2")
	}

	name = args[0]
	// Get the state from the ledger
	value, err := stub.GetState(name)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	previous_val, _ = strconv.ParseFloat(string(value), 64);
	val, _ = strconv.ParseFloat(string(args[1]), 64);

	err = stub.PutState(name, []byte(strconv.FormatFloat(val + previous_val, 'f', 6, 64)))

	if err != nil {
		return nil, err
	}

	return nil, nil
}

func (t *SimpleChaincode) Invoke(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {

	if function == "settle" {
		return t.settle(stub, args)
	}

	if function != "change" {
		return t.change(stub, args)
	}
	if function != "report" {
		return nil, errors.New("Unimplemented '" + function + "' invoked")
	}

	var name string    // Entities
	var val int // Asset holdings
	var err error

	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2")
	}

	name = args[0]
	val, _ = strconv.Atoi(string(args[1]))

	err = stub.PutState("kwh_" + name, []byte(strconv.Itoa(val)))

	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {

	if function == "balance" {
		return t.balance(stub, args)
	}

	if function != "reported_kwh" {
		return nil, errors.New("Invalid query function name. Expecting \"querybalance\"")
	}
	var name string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the Meter to query")
	}

	name = args[0]

	// Get the state from the ledger
	value, err := stub.GetState("kwh_" + name)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	if value == nil {
		jsonResp := "{\"Error\":\"Nil amount for Meter" + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + name + "\",\"Amount\":\"" + string(value) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return value, nil
}

func (t *SimpleChaincode) balance(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var name string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the Meter to query")
	}

	name = args[0]

	// Get the state from the ledger
	value, err := stub.GetState(name)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	if value == nil {
		jsonResp := "{\"Error\":\"Nil amount for Meter " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + name + "\",\"Amount\":\"" + string(value) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return value, nil
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<|endoftext|>


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

/*
Present displays slide presentations and articles. It runs a web server that
presents slide and article files from the current directory.

It may be run as a stand-alone command or an App Engine app.
The stand-alone version permits the execution of programs from within a
presentation. The App Engine version does not provide this functionality.

Usage of present:
  -base="": base path for slide template and static resources
  -http="127.0.0.1:3999": host:port to listen on

You may use the app.yaml file provided in the root of the go.talks repository
to deploy present to App Engine:
	appcfg.py update -A your-app-id -V your-app-version /path/to/go.talks

Input files are named foo.extension, where "extension" defines the format of
the generated output. The supported formats are:
	.slide        // HTML5 slide presentation
	.article      // article format, such as a blog post

The present file format is documented by the present package:
http://godoc.org/code.google.com/p/go.tools/godoc/present
*/
package main
<commit_msg>go.talk/present: fix a link.<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
Present displays slide presentations and articles. It runs a web server that
presents slide and article files from the current directory.

It may be run as a stand-alone command or an App Engine app.
The stand-alone version permits the execution of programs from within a
presentation. The App Engine version does not provide this functionality.

Usage of present:
  -base="": base path for slide template and static resources
  -http="127.0.0.1:3999": host:port to listen on

You may use the app.yaml file provided in the root of the go.talks repository
to deploy present to App Engine:
	appcfg.py update -A your-app-id -V your-app-version /path/to/go.talks

Input files are named foo.extension, where "extension" defines the format of
the generated output. The supported formats are:
	.slide        // HTML5 slide presentation
	.article      // article format, such as a blog post

The present file format is documented by the present package:
http://godoc.org/code.google.com/p/go.tools/present
*/
package main
<|endoftext|>


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

/*
The present file format

Present files have the following format.  The first non-blank non-comment
line is the title, so the header looks like

	Title of document
	Subtitle of document
	15:04 2 Jan 2006
	Tags: foo, bar, baz
	<blank line>
	Author Name
	Job title, Company
	joe@example.com
	http://url/
	@twitter_name

The subtitle, date, and tags lines are optional.

The date line may be written without a time:
	2 Jan 2006
In this case, the time will be interpreted as 10am UTC on that date.

The tags line is a comma-separated list of tags that may be used to categorize
the document.

The author section may contain a mixture of text, twitter names, and links.
For slide presentations, only the plain text lines will be displayed on the
first slide.

Multiple presenters may be specified, separated by a blank line.

After that come slides/sections, each after a blank line:

	* Title of slide or section (must have asterisk)

	Some Text

	** Subsection

	- bullets
	- more bullets
	- a bullet with

	*** Sub-subsection

	Some More text

	  Preformatted text
	  is indented (however you like)

	Further Text, including invocations like:

	.code x.go /^func main/,/^}/
	.play y.go
	.image image.jpg
	.background image.jpg
	.iframe http://foo
	.link http://foo label
	.html file.html
	.caption _Gopher_ by [[https://www.instagram.com/reneefrench/][Renée French]]

	Again, more text

Blank lines are OK (not mandatory) after the title and after the
text.  Text, bullets, and .code etc. are all optional; title is
not.

Lines starting with # in column 1 are commentary.

Fonts:

Within the input for plain text or lists, text bracketed by font
markers will be presented in italic, bold, or program font.
Marker characters are _ (italic), * (bold) and ` (program font).
An opening marker must be preceded by a space or punctuation
character or else be at start of a line; similarly, a closing
marker must be followed by a space or punctuation character or
else be at the end of a line. Unmatched markers appear as plain text.
There must be no spaces between markers. Within marked text,
a single marker character becomes a space and a doubled single
marker quotes the marker character.

	_italic_
	*bold*
	`program`
	Markup—_especially_italic_text_—can easily be overused.
	_Why_use_scoped__ptr_? Use plain ***ptr* instead.

Inline links:

Links can be included in any text with the form [[url][label]], or
[[url]] to use the URL itself as the label.

Functions:

A number of template functions are available through invocations
in the input text. Each such invocation contains a period as the
first character on the line, followed immediately by the name of
the function, followed by any arguments. A typical invocation might
be
	.play demo.go /^func show/,/^}/
(except that the ".play" must be at the beginning of the line and
not be indented like this.)

Here follows a description of the functions:

code:

Injects program source into the output by extracting code from files
and injecting them as HTML-escaped <pre> blocks.  The argument is
a file name followed by an optional address that specifies what
section of the file to display. The address syntax is similar in
its simplest form to that of ed, but comes from sam and is more
general. See
	https://plan9.io/sys/doc/sam/sam.html Table II
for full details. The displayed block is always rounded out to a
full line at both ends.

If no pattern is present, the entire file is displayed.

Any line in the program that ends with the four characters
	OMIT
is deleted from the source before inclusion, making it easy
to write things like
	.code test.go /START OMIT/,/END OMIT/
to find snippets like this
	tedious_code = boring_function()
	// START OMIT
	interesting_code = fascinating_function()
	// END OMIT
and see only this:
	interesting_code = fascinating_function()

Also, inside the displayed text a line that ends
	// HL
will be highlighted in the display; the 'h' key in the browser will
toggle extra emphasis of any highlighted lines. A highlighting mark
may have a suffix word, such as
	// HLxxx
Such highlights are enabled only if the code invocation ends with
"HL" followed by the word:
	.code test.go /^type Foo/,/^}/ HLxxx

The .code function may take one or more flags immediately preceding
the filename. This command shows test.go in an editable text area:
	.code -edit test.go
This command shows test.go with line numbers:
	.code -numbers test.go

play:

The function "play" is the same as "code" but puts a button
on the displayed source so the program can be run from the browser.
Although only the selected text is shown, all the source is included
in the HTML output so it can be presented to the compiler.

link:

Create a hyperlink. The syntax is 1 or 2 space-separated arguments.
The first argument is always the HTTP URL.  If there is a second
argument, it is the text label to display for this link.

	.link http://golang.org golang.org

image:

The template uses the function "image" to inject picture files.

The syntax is simple: 1 or 3 space-separated arguments.
The first argument is always the file name.
If there are more arguments, they are the height and width;
both must be present, or substituted with an underscore.
Replacing a dimension argument with the underscore parameter
preserves the aspect ratio of the image when scaling.

	.image images/betsy.jpg 100 200

	.image images/janet.jpg _ 300

video:

The template uses the function "video" to inject video files.

The syntax is simple: 2 or 4 space-separated arguments.
The first argument is always the file name.
The second argument is always the file content-type.
If there are more arguments, they are the height and width;
both must be present, or substituted with an underscore.
Replacing a dimension argument with the underscore parameter
preserves the aspect ratio of the video when scaling.

	.video videos/evangeline.mp4 video/mp4 400 600

	.video videos/mabel.ogg video/ogg 500 _

background:

The template uses the function "background" to set the background image for
a slide.  The only argument is the file name of the image.

	.background images/susan.jpg

caption:

The template uses the function "caption" to inject figure captions.

The text after ".caption" is embedded in a figcaption element after
processing styling and links as in standard text lines.

	.caption _Gopher_ by [[http://www.reneefrench.com][Renée French]]

iframe:

The function "iframe" injects iframes (pages inside pages).
Its syntax is the same as that of image.

html:

The function html includes the contents of the specified file as
unescaped HTML. This is useful for including custom HTML elements
that cannot be created using only the slide format.
It is your responsibility to make sure the included HTML is valid and safe.

	.html file.html

Presenter notes:

Presenter notes may be enabled by appending the "-notes" flag when you run
your "present" binary.

This will allow you to open a second window by pressing 'N' from your browser
displaying your slides. The second window is completely synced with your main
window, except that presenter notes are only visible on the second window.

Lines that begin with ": " are treated as presenter notes.

	* Title of slide

	Some Text

	: Presenter notes (first paragraph)
	: Presenter notes (subsequent paragraph(s))

Notes may appear anywhere within the slide text. For example:

	* Title of slide

	: Presenter notes (first paragraph)

	Some Text

	: Presenter notes (subsequent paragraph(s))

This has the same result as the example above.

*/
package present // import "golang.org/x/tools/present"
<commit_msg>present: remove mention of non-existing emphasis toggle<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
The present file format

Present files have the following format.  The first non-blank non-comment
line is the title, so the header looks like

	Title of document
	Subtitle of document
	15:04 2 Jan 2006
	Tags: foo, bar, baz
	<blank line>
	Author Name
	Job title, Company
	joe@example.com
	http://url/
	@twitter_name

The subtitle, date, and tags lines are optional.

The date line may be written without a time:
	2 Jan 2006
In this case, the time will be interpreted as 10am UTC on that date.

The tags line is a comma-separated list of tags that may be used to categorize
the document.

The author section may contain a mixture of text, twitter names, and links.
For slide presentations, only the plain text lines will be displayed on the
first slide.

Multiple presenters may be specified, separated by a blank line.

After that come slides/sections, each after a blank line:

	* Title of slide or section (must have asterisk)

	Some Text

	** Subsection

	- bullets
	- more bullets
	- a bullet with

	*** Sub-subsection

	Some More text

	  Preformatted text
	  is indented (however you like)

	Further Text, including invocations like:

	.code x.go /^func main/,/^}/
	.play y.go
	.image image.jpg
	.background image.jpg
	.iframe http://foo
	.link http://foo label
	.html file.html
	.caption _Gopher_ by [[https://www.instagram.com/reneefrench/][Renée French]]

	Again, more text

Blank lines are OK (not mandatory) after the title and after the
text.  Text, bullets, and .code etc. are all optional; title is
not.

Lines starting with # in column 1 are commentary.

Fonts:

Within the input for plain text or lists, text bracketed by font
markers will be presented in italic, bold, or program font.
Marker characters are _ (italic), * (bold) and ` (program font).
An opening marker must be preceded by a space or punctuation
character or else be at start of a line; similarly, a closing
marker must be followed by a space or punctuation character or
else be at the end of a line. Unmatched markers appear as plain text.
There must be no spaces between markers. Within marked text,
a single marker character becomes a space and a doubled single
marker quotes the marker character.

	_italic_
	*bold*
	`program`
	Markup—_especially_italic_text_—can easily be overused.
	_Why_use_scoped__ptr_? Use plain ***ptr* instead.

Inline links:

Links can be included in any text with the form [[url][label]], or
[[url]] to use the URL itself as the label.

Functions:

A number of template functions are available through invocations
in the input text. Each such invocation contains a period as the
first character on the line, followed immediately by the name of
the function, followed by any arguments. A typical invocation might
be
	.play demo.go /^func show/,/^}/
(except that the ".play" must be at the beginning of the line and
not be indented like this.)

Here follows a description of the functions:

code:

Injects program source into the output by extracting code from files
and injecting them as HTML-escaped <pre> blocks.  The argument is
a file name followed by an optional address that specifies what
section of the file to display. The address syntax is similar in
its simplest form to that of ed, but comes from sam and is more
general. See
	https://plan9.io/sys/doc/sam/sam.html Table II
for full details. The displayed block is always rounded out to a
full line at both ends.

If no pattern is present, the entire file is displayed.

Any line in the program that ends with the four characters
	OMIT
is deleted from the source before inclusion, making it easy
to write things like
	.code test.go /START OMIT/,/END OMIT/
to find snippets like this
	tedious_code = boring_function()
	// START OMIT
	interesting_code = fascinating_function()
	// END OMIT
and see only this:
	interesting_code = fascinating_function()

Also, inside the displayed text a line that ends
	// HL
will be highlighted in the display. A highlighting mark may have a
suffix word, such as
	// HLxxx
Such highlights are enabled only if the code invocation ends with
"HL" followed by the word:
	.code test.go /^type Foo/,/^}/ HLxxx

The .code function may take one or more flags immediately preceding
the filename. This command shows test.go in an editable text area:
	.code -edit test.go
This command shows test.go with line numbers:
	.code -numbers test.go

play:

The function "play" is the same as "code" but puts a button
on the displayed source so the program can be run from the browser.
Although only the selected text is shown, all the source is included
in the HTML output so it can be presented to the compiler.

link:

Create a hyperlink. The syntax is 1 or 2 space-separated arguments.
The first argument is always the HTTP URL.  If there is a second
argument, it is the text label to display for this link.

	.link http://golang.org golang.org

image:

The template uses the function "image" to inject picture files.

The syntax is simple: 1 or 3 space-separated arguments.
The first argument is always the file name.
If there are more arguments, they are the height and width;
both must be present, or substituted with an underscore.
Replacing a dimension argument with the underscore parameter
preserves the aspect ratio of the image when scaling.

	.image images/betsy.jpg 100 200

	.image images/janet.jpg _ 300

video:

The template uses the function "video" to inject video files.

The syntax is simple: 2 or 4 space-separated arguments.
The first argument is always the file name.
The second argument is always the file content-type.
If there are more arguments, they are the height and width;
both must be present, or substituted with an underscore.
Replacing a dimension argument with the underscore parameter
preserves the aspect ratio of the video when scaling.

	.video videos/evangeline.mp4 video/mp4 400 600

	.video videos/mabel.ogg video/ogg 500 _

background:

The template uses the function "background" to set the background image for
a slide.  The only argument is the file name of the image.

	.background images/susan.jpg

caption:

The template uses the function "caption" to inject figure captions.

The text after ".caption" is embedded in a figcaption element after
processing styling and links as in standard text lines.

	.caption _Gopher_ by [[http://www.reneefrench.com][Renée French]]

iframe:

The function "iframe" injects iframes (pages inside pages).
Its syntax is the same as that of image.

html:

The function html includes the contents of the specified file as
unescaped HTML. This is useful for including custom HTML elements
that cannot be created using only the slide format.
It is your responsibility to make sure the included HTML is valid and safe.

	.html file.html

Presenter notes:

Presenter notes may be enabled by appending the "-notes" flag when you run
your "present" binary.

This will allow you to open a second window by pressing 'N' from your browser
displaying your slides. The second window is completely synced with your main
window, except that presenter notes are only visible on the second window.

Lines that begin with ": " are treated as presenter notes.

	* Title of slide

	Some Text

	: Presenter notes (first paragraph)
	: Presenter notes (subsequent paragraph(s))

Notes may appear anywhere within the slide text. For example:

	* Title of slide

	: Presenter notes (first paragraph)

	Some Text

	: Presenter notes (subsequent paragraph(s))

This has the same result as the example above.

*/
package present // import "golang.org/x/tools/present"
<|endoftext|>


<commit_before>package golog

// This file runs Go tests for Prolog test files under a 't' directory.
// This gives us an easy way to write many Prolog tests without writing
// a bunch of manual Go tests.  Because the tests are written in Prolog
// they can be reused by other Prolog implementations.

import "os"
import "testing"
import "github.com/mndrix/golog/read"
import "github.com/mndrix/golog/term"
import . "github.com/mndrix/golog/util"

func TestPureProlog(t *testing.T) {
	// find all t/*.pl files
	file, err := os.Open("t")
	MaybePanic(err)
	names, err := file.Readdirnames(-1)

	// run tests found in each file
	for _, name := range names {
		if name[0] == '.' {
			continue // skip hidden files
		}
		openTest := func() *os.File {
			f, err := os.Open("t/" + name)
			MaybePanic(err)
			return f
		}

		// which tests does the file have?
		tests := make([]term.Term, 0)
		terms := read.TermAll_(openTest())
		for _, t := range terms {
			x := t.(term.Callable)
			if x.Indicator() == ":-/2" {
				tests = append(tests, x.Arguments()[0])
			}
		}

		// run each test in this file
		m := NewMachine().Consult(openTest())
		for _, test := range tests {
			x := test.(term.Callable)
			canProve := m.CanProve(test)
			if x.Arity() > 0 && x.Arguments()[0].String() == "fail" {
				if canProve {
					t.Errorf("%s: %s should fail", name, test)
				}
			} else {
				if !canProve {
					t.Errorf("%s: %s failed", name, test)
				}
			}
		}
	}
}
<commit_msg>Run TAP tests that don't have names<commit_after>package golog

// This file runs Go tests for Prolog test files under a 't' directory.
// This gives us an easy way to write many Prolog tests without writing
// a bunch of manual Go tests.  Because the tests are written in Prolog
// they can be reused by other Prolog implementations.

import "os"
import "testing"
import "github.com/mndrix/golog/read"
import "github.com/mndrix/golog/term"
import . "github.com/mndrix/golog/util"

func TestPureProlog(t *testing.T) {
	// find all t/*.pl files
	file, err := os.Open("t")
	MaybePanic(err)
	names, err := file.Readdirnames(-1)

	useModule := read.Term_(`:- use_module(library(tap)).`)
	env := term.NewBindings()

	// run tests found in each file
	for _, name := range names {
		if name[0] == '.' {
			continue // skip hidden files
		}
		//t.Logf("-------------- %s", name)
		openTest := func() *os.File {
			f, err := os.Open("t/" + name)
			MaybePanic(err)
			return f
		}

		// which tests does the file have?
		pastUseModule := false
		tests := make([]term.Term, 0)
		terms := read.TermAll_(openTest())
		for _, s := range terms {
			x := s.(term.Callable)
			if pastUseModule {
				if x.Arity() == 2 && x.Name() == ":-" {
					tests = append(tests, x.Arguments()[0])
				} else {
					tests = append(tests, x)
				}
			} else {
				// look for use_module(library(tap)) declaration
				_, err := s.Unify(env, useModule)
				if err == nil {
					pastUseModule = true
					//t.Logf("found use_module directive")
				}
			}
		}

		// run each test in this file
		m := NewMachine().Consult(openTest())
		for _, test := range tests {
			x := test.(term.Callable)
			//t.Logf("proving: %s", test)
			canProve := m.CanProve(test)
			if x.Arity() > 0 && x.Arguments()[0].String() == "fail" {
				if canProve {
					t.Errorf("%s: %s should fail", name, test)
				}
			} else {
				if !canProve {
					t.Errorf("%s: %s failed", name, test)
				}
			}
		}
	}
}
<|endoftext|>