<commit_before>package main

import (
	"fmt"
	. "hge"
)

var (
	hge *HGE

	spr, spt, tar Sprite
	fnt           *Font
	par           *ParticleSystem

	tex Texture
	snd Effect

	// HGE render target handle
	target Target

	x  = 100.0
	y  = 100.0
	dx = 0.0
	dy = 0.0
)

const (
	speed    = 90
	friction = 0.98
)

func boom() {
	pan := int((x - 256) / 2.56)
	pitch := (dx*dx+dy*dy)*0.0005 + 0.2
	hge.Effect_PlayEx(snd, 100, pan, pitch)
}

// This function will be called by HGE when
// render targets were lost and have been just created
// again. We use it here to update the render
// target's texture handle that changes during recreation.
func GfxRestoreFunc() int {
	if target != 0 {
		tar.SetTexture(hge.Target_GetTexture(target))
	}

	return 0
}

func FrameFunc() int {
	dt := hge.Timer_GetDelta()

	// Process keys
	if hge.Input_GetKeyState(K_ESCAPE) {
		return 1
	}
	if hge.Input_GetKeyState(K_LEFT) {
		dx -= speed * dt
	}
	if hge.Input_GetKeyState(K_RIGHT) {
		dx += speed * dt
	}
	if hge.Input_GetKeyState(K_UP) {
		dy -= speed * dt
	}
	if hge.Input_GetKeyState(K_DOWN) {
		dy += speed * dt
	}

	// Do some movement calculations and collision detection
	dx *= friction
	dy *= friction
	x += dx
	y += dy
	if x > 496 {
		x = 496 - (x - 496)
		dx = -dx
		boom()
	}
	if x < 16 {
		x = 16 + 16 - x
		dx = -dx
		boom()
	}
	if y > 496 {
		y = 496 - (y - 496)
		dy = -dy
		boom()
	}
	if y < 16 {
		y = 16 + 16 - y
		dy = -dy
		boom()
	}

	// Update particle system
	par.Info.Emission = (int)(dx*dx + dy*dy)
	par.MoveTo(x, y)
	par.Update(dt)

	return 0
}

func RenderFunc() int {
	// Render graphics to the texture
	hge.Gfx_BeginScene(target)
	hge.Gfx_Clear(0)
	par.Render()
	spr.Render(x, y)
	hge.Gfx_EndScene()

	// Now put several instances of the rendered texture to the screen
	hge.Gfx_BeginScene()
	hge.Gfx_Clear(0)
	for i := 0.0; i < 6.0; i++ {
		tar.SetColor(Dword(0xFFFFFF | ((int)((5-i)*40+55) << 24)))
		tar.RenderEx(i*100.0, i*50.0, i*Pi/8, 1.0-i*0.1)
	}
	fnt.Printf(5, 5, TEXT_LEFT, "dt:%.3f\nFPS:%d (constant)", hge.Timer_GetDelta(), hge.Timer_GetFPS())
	hge.Gfx_EndScene()

	return 0
}

func main() {
	hge = Create(VERSION)
	defer hge.Release()

	hge.System_SetState(LOGFILE, "hge_tut04.log")
	hge.System_SetState(FRAMEFUNC, FrameFunc)
	hge.System_SetState(RENDERFUNC, RenderFunc)
	hge.System_SetState(GFXRESTOREFUNC, GfxRestoreFunc)
	hge.System_SetState(TITLE, "HGE Tutorial 04 - Using render targets")
	hge.System_SetState(FPS, 100)
	hge.System_SetState(WINDOWED, true)
	hge.System_SetState(SCREENWIDTH, 800)
	hge.System_SetState(SCREENHEIGHT, 600)
	hge.System_SetState(SCREENBPP, 32)

	target = 0

	if hge.System_Initiate() {
		defer hge.System_Shutdown()
		snd = hge.Effect_Load("menu.ogg")
		tex = hge.Texture_Load("particles.png")
		if snd == 0 || tex == 0 {
			// If one of the data files is not found, display
			// an error message and shutdown.
			fmt.Printf("Error: Can't load one of the following files:\nmenu.ogg, particles.png, font1.fnt, font1.png, trail.psi\n")
			return
		}

		// Delete created objects and free loaded resources
		defer hge.Effect_Free(snd)
		defer hge.Texture_Free(tex)

		spr = NewSprite(tex, 96, 64, 32, 32)
		spr.SetColor(0xFFFFA000)
		spr.SetHotSpot(16, 16)

		fnt = NewFont("font1.fnt")

		if fnt == nil {
			fmt.Println("Error: Can't load font1.fnt or font1.png")
			return
		}

		spt = NewSprite(tex, 32, 32, 32, 32)
		spt.SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE)
		spt.SetHotSpot(16, 16)
		par = NewParticleSystem("trail.psi", spt)

		if par == nil {
			fmt.Println("Error: Cannot load trail.psi")
			return
		}
		par.Fire()

		// Create a render target and a sprite for it
		target = hge.Target_Create(512, 512, false)
		defer hge.Target_Free(target)
		tar = NewSprite(hge.Target_GetTexture(target), 0, 0, 512, 512)
		tar.SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE)

		// Let's rock now!
		hge.System_Start()
	}
}
<commit_msg>Fix the logfile name for tutorial04<commit_after>package main

import (
	"fmt"
	. "hge"
)

var (
	hge *HGE

	spr, spt, tar Sprite
	fnt           *Font
	par           *ParticleSystem

	tex Texture
	snd Effect

	// HGE render target handle
	target Target

	x  = 100.0
	y  = 100.0
	dx = 0.0
	dy = 0.0
)

const (
	speed    = 90
	friction = 0.98
)

func boom() {
	pan := int((x - 256) / 2.56)
	pitch := (dx*dx+dy*dy)*0.0005 + 0.2
	hge.Effect_PlayEx(snd, 100, pan, pitch)
}

// This function will be called by HGE when
// render targets were lost and have been just created
// again. We use it here to update the render
// target's texture handle that changes during recreation.
func GfxRestoreFunc() int {
	if target != 0 {
		tar.SetTexture(hge.Target_GetTexture(target))
	}

	return 0
}

func FrameFunc() int {
	dt := hge.Timer_GetDelta()

	// Process keys
	if hge.Input_GetKeyState(K_ESCAPE) {
		return 1
	}
	if hge.Input_GetKeyState(K_LEFT) {
		dx -= speed * dt
	}
	if hge.Input_GetKeyState(K_RIGHT) {
		dx += speed * dt
	}
	if hge.Input_GetKeyState(K_UP) {
		dy -= speed * dt
	}
	if hge.Input_GetKeyState(K_DOWN) {
		dy += speed * dt
	}

	// Do some movement calculations and collision detection
	dx *= friction
	dy *= friction
	x += dx
	y += dy
	if x > 496 {
		x = 496 - (x - 496)
		dx = -dx
		boom()
	}
	if x < 16 {
		x = 16 + 16 - x
		dx = -dx
		boom()
	}
	if y > 496 {
		y = 496 - (y - 496)
		dy = -dy
		boom()
	}
	if y < 16 {
		y = 16 + 16 - y
		dy = -dy
		boom()
	}

	// Update particle system
	par.Info.Emission = (int)(dx*dx + dy*dy)
	par.MoveTo(x, y)
	par.Update(dt)

	return 0
}

func RenderFunc() int {
	// Render graphics to the texture
	hge.Gfx_BeginScene(target)
	hge.Gfx_Clear(0)
	par.Render()
	spr.Render(x, y)
	hge.Gfx_EndScene()

	// Now put several instances of the rendered texture to the screen
	hge.Gfx_BeginScene()
	hge.Gfx_Clear(0)
	for i := 0.0; i < 6.0; i++ {
		tar.SetColor(Dword(0xFFFFFF | ((int)((5-i)*40+55) << 24)))
		tar.RenderEx(i*100.0, i*50.0, i*Pi/8, 1.0-i*0.1)
	}
	fnt.Printf(5, 5, TEXT_LEFT, "dt:%.3f\nFPS:%d (constant)", hge.Timer_GetDelta(), hge.Timer_GetFPS())
	hge.Gfx_EndScene()

	return 0
}

func main() {
	hge = Create(VERSION)
	defer hge.Release()

	hge.System_SetState(LOGFILE, "tutorial04.log")
	hge.System_SetState(FRAMEFUNC, FrameFunc)
	hge.System_SetState(RENDERFUNC, RenderFunc)
	hge.System_SetState(GFXRESTOREFUNC, GfxRestoreFunc)
	hge.System_SetState(TITLE, "HGE Tutorial 04 - Using render targets")
	hge.System_SetState(FPS, 100)
	hge.System_SetState(WINDOWED, true)
	hge.System_SetState(SCREENWIDTH, 800)
	hge.System_SetState(SCREENHEIGHT, 600)
	hge.System_SetState(SCREENBPP, 32)

	target = 0

	if hge.System_Initiate() {
		defer hge.System_Shutdown()
		snd = hge.Effect_Load("menu.ogg")
		tex = hge.Texture_Load("particles.png")
		if snd == 0 || tex == 0 {
			// If one of the data files is not found, display
			// an error message and shutdown.
			fmt.Printf("Error: Can't load one of the following files:\nmenu.ogg, particles.png, font1.fnt, font1.png, trail.psi\n")
			return
		}

		// Delete created objects and free loaded resources
		defer hge.Effect_Free(snd)
		defer hge.Texture_Free(tex)

		spr = NewSprite(tex, 96, 64, 32, 32)
		spr.SetColor(0xFFFFA000)
		spr.SetHotSpot(16, 16)

		fnt = NewFont("font1.fnt")

		if fnt == nil {
			fmt.Println("Error: Can't load font1.fnt or font1.png")
			return
		}

		spt = NewSprite(tex, 32, 32, 32, 32)
		spt.SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE)
		spt.SetHotSpot(16, 16)
		par = NewParticleSystem("trail.psi", spt)

		if par == nil {
			fmt.Println("Error: Cannot load trail.psi")
			return
		}
		par.Fire()

		// Create a render target and a sprite for it
		target = hge.Target_Create(512, 512, false)
		defer hge.Target_Free(target)
		tar = NewSprite(hge.Target_GetTexture(target), 0, 0, 512, 512)
		tar.SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE)

		// Let's rock now!
		hge.System_Start()
	}
}
<|endoftext|>


<commit_before>// Package reboot is a plugin that supports rebooting the host running the worker.
//
// In some cases, especially running without a very tight
// sandbox, this is desirable after specific tests.
//
// In other cases, reboots are useful after a configured uptime, to
// cycle the host's configuration.
//
// To reboot after tasks, users must add the boolean "reboot" payload
// attribute.
package reboot

import (
	"sync"
	"time"

	schematypes "github.com/taskcluster/go-schematypes"
	"github.com/taskcluster/taskcluster-worker/plugins"
	"github.com/taskcluster/taskcluster-worker/runtime"
)

type plugin struct {
	plugins.PluginBase
	environment *runtime.Environment

	// the command to reboot the host
	rebootCommand []string

	// while this is held for reading, there are tasks running
	runningTasks sync.RWMutex
}

type payloadType struct {
	RebootWhenDone bool `json:"reboot"`
}

type config struct {
	RebootAfter   int      `json:"rebootAfter"`
	RebootCommand []string `json:"rebootCommand"`
}

type taskPlugin struct {
	plugins.TaskPluginBase
	plugin         *plugin
	rebootWhenDone bool
}

type pluginProvider struct {
	plugins.PluginProviderBase
}

var payloadSchema = schematypes.Object{
	Properties: schematypes.Properties{
		"reboot": schematypes.Boolean{
			MetaData: schematypes.MetaData{
				Title:       "Reboot machine",
				Description: "If true, reboot the machine after task is finished.",
			},
		},
	},
}

var configSchema = schematypes.Object{
	Properties: schematypes.Properties{
		"rebootAfter": schematypes.Integer{
			MetaData: schematypes.MetaData{
				Title: "Reboot After",
				Description: `When the worker is idle after this many hours, it will reboot.
					If zero, no idle reboot will occur.`,
			},
			Minimum: 0,
			Maximum: 10000,
		},
		"rebootCommand": schematypes.Array{
			MetaData: schematypes.MetaData{
				Title:       "Reboot Command",
				Description: `The command to use to reboot the host, as a list of strings`,
			},
			Items: schematypes.String{},
		},
	},
}

func init() {
	plugins.Register("reboot", pluginProvider{})
}

func (pluginProvider) ConfigSchema() schematypes.Schema {
	return configSchema
}

func (pluginProvider) NewPlugin(options plugins.PluginOptions) (plugins.Plugin, error) {
	var c config
	schematypes.MustValidateAndMap(configSchema, options.Config, &c)

	plugin := &plugin{
		PluginBase:    plugins.PluginBase{},
		environment:   options.Environment,
		rebootCommand: c.RebootCommand,
		runningTasks:  sync.RWMutex{},
	}

	if c.RebootAfter > 0 {
		// After rebootAfter hours, call the reboot method. If the lock is held by one or more
		// running tasks, the reboot will not occur until they finish (but no further tasks will
		// be able to start)
		time.AfterFunc(time.Duration(c.RebootAfter)*time.Second, func() {
			plugin.environment.Monitor.Warn("Host rebootAfter has expired; scheduling reboot")
			plugin.reboot()
		})
	}

	return plugin, nil
}

// Try to reboot the host, waiting until it is running no tasks.  The reboot entails
// signalling the worker, which will begin an orderly shutdown, so no further tasks
// will be started once this function returns.
func (pl *plugin) reboot() {
	// Try to get a write lock on the mutex; this will wait until all read locks
	// (running tasks) are complete, and will preclude any later read locks.
	pl.runningTasks.Lock()

	// By this time, we should have stopped accepting new tasks, so it is safe
	// to unlock and continue any task completion
	defer pl.runningTasks.Unlock()

	// Reboot and/or die trying. The lock is still held, so no other tasks can
	// start while this process plays out
	pl.environment.Monitor.Warn("Initiating reboot")
	initiateReboot(pl.rebootCommand)
}

func (*plugin) PayloadSchema() schematypes.Object {
	return payloadSchema
}

func (pl *plugin) NewTaskPlugin(options plugins.TaskPluginOptions) (plugins.TaskPlugin, error) {
	var p payloadType
	schematypes.MustValidateAndMap(payloadSchema, options.Payload, &p)

	pl.runningTasks.RLock()
	return &taskPlugin{
		TaskPluginBase: plugins.TaskPluginBase{},
		plugin:         pl,
		rebootWhenDone: p.RebootWhenDone,
	}, nil
}

func (tp *taskPlugin) Dispose() error {
	tp.plugin.runningTasks.RUnlock()

	// Note: in a multi-task environment, this will not reboot immediately, but
	// will wait until all tasks are complete.
	if tp.rebootWhenDone {
		tp.plugin.environment.Monitor.Warn("Task specified reboot after completion; scheduling reboot")
		tp.plugin.reboot()
	}

	return nil
}
<commit_msg>reboot after hours, not seconds<commit_after>// Package reboot is a plugin that supports rebooting the host running the worker.
//
// In some cases, especially running without a very tight
// sandbox, this is desirable after specific tests.
//
// In other cases, reboots are useful after a configured uptime, to
// cycle the host's configuration.
//
// To reboot after tasks, users must add the boolean "reboot" payload
// attribute.
package reboot

import (
	"sync"
	"time"

	schematypes "github.com/taskcluster/go-schematypes"
	"github.com/taskcluster/taskcluster-worker/plugins"
	"github.com/taskcluster/taskcluster-worker/runtime"
)

type plugin struct {
	plugins.PluginBase
	environment *runtime.Environment

	// the command to reboot the host
	rebootCommand []string

	// while this is held for reading, there are tasks running
	runningTasks sync.RWMutex
}

type payloadType struct {
	RebootWhenDone bool `json:"reboot"`
}

type config struct {
	RebootAfter   int      `json:"rebootAfter"`
	RebootCommand []string `json:"rebootCommand"`
}

type taskPlugin struct {
	plugins.TaskPluginBase
	plugin         *plugin
	rebootWhenDone bool
}

type pluginProvider struct {
	plugins.PluginProviderBase
}

var payloadSchema = schematypes.Object{
	Properties: schematypes.Properties{
		"reboot": schematypes.Boolean{
			MetaData: schematypes.MetaData{
				Title:       "Reboot machine",
				Description: "If true, reboot the machine after task is finished.",
			},
		},
	},
}

var configSchema = schematypes.Object{
	Properties: schematypes.Properties{
		"rebootAfter": schematypes.Integer{
			MetaData: schematypes.MetaData{
				Title: "Reboot After",
				Description: `When the worker is idle after this many hours, it will reboot.
					If zero, no idle reboot will occur.`,
			},
			Minimum: 0,
			Maximum: 10000,
		},
		"rebootCommand": schematypes.Array{
			MetaData: schematypes.MetaData{
				Title:       "Reboot Command",
				Description: `The command to use to reboot the host, as a list of strings`,
			},
			Items: schematypes.String{},
		},
	},
}

func init() {
	plugins.Register("reboot", pluginProvider{})
}

func (pluginProvider) ConfigSchema() schematypes.Schema {
	return configSchema
}

func (pluginProvider) NewPlugin(options plugins.PluginOptions) (plugins.Plugin, error) {
	var c config
	schematypes.MustValidateAndMap(configSchema, options.Config, &c)

	plugin := &plugin{
		PluginBase:    plugins.PluginBase{},
		environment:   options.Environment,
		rebootCommand: c.RebootCommand,
		runningTasks:  sync.RWMutex{},
	}

	if c.RebootAfter > 0 {
		// After rebootAfter hours, call the reboot method. If the lock is held by one or more
		// running tasks, the reboot will not occur until they finish (but no further tasks will
		// be able to start)
		time.AfterFunc(time.Duration(c.RebootAfter)*time.Hour, func() {
			plugin.environment.Monitor.Warn("Host rebootAfter has expired; scheduling reboot")
			plugin.reboot()
		})
	}

	return plugin, nil
}

// Try to reboot the host, waiting until it is running no tasks.  The reboot entails
// signalling the worker, which will begin an orderly shutdown, so no further tasks
// will be started once this function returns.
func (pl *plugin) reboot() {
	// Try to get a write lock on the mutex; this will wait until all read locks
	// (running tasks) are complete, and will preclude any later read locks.
	pl.runningTasks.Lock()

	// By this time, we should have stopped accepting new tasks, so it is safe
	// to unlock and continue any task completion
	defer pl.runningTasks.Unlock()

	// Reboot and/or die trying. The lock is still held, so no other tasks can
	// start while this process plays out
	pl.environment.Monitor.Warn("Initiating reboot")
	initiateReboot(pl.rebootCommand)
}

func (*plugin) PayloadSchema() schematypes.Object {
	return payloadSchema
}

func (pl *plugin) NewTaskPlugin(options plugins.TaskPluginOptions) (plugins.TaskPlugin, error) {
	var p payloadType
	schematypes.MustValidateAndMap(payloadSchema, options.Payload, &p)

	pl.runningTasks.RLock()
	return &taskPlugin{
		TaskPluginBase: plugins.TaskPluginBase{},
		plugin:         pl,
		rebootWhenDone: p.RebootWhenDone,
	}, nil
}

func (tp *taskPlugin) Dispose() error {
	tp.plugin.runningTasks.RUnlock()

	// Note: in a multi-task environment, this will not reboot immediately, but
	// will wait until all tasks are complete.
	if tp.rebootWhenDone {
		tp.plugin.environment.Monitor.Warn("Task specified reboot after completion; scheduling reboot")
		tp.plugin.reboot()
	}

	return nil
}
<|endoftext|>


<commit_before>package peco

import (
	"os"
	"reflect"
	"time"

	"golang.org/x/net/context"

	"github.com/google/btree"
	"github.com/lestrrat/go-pdebug"
	"github.com/peco/peco/hub"
	"github.com/peco/peco/internal/util"
	"github.com/peco/peco/pipeline"
	"github.com/peco/peco/sig"
	"github.com/pkg/errors"
)

const version = "v0.3.6"

type errIgnorable struct {
	err error
}

func (e errIgnorable) Ignorable() bool { return true }
func (e errIgnorable) Causer() error {
	return e.err
}
func (e errIgnorable) Error() string {
	return e.err.Error()
}
func makeIgnorable(err error) error {
	return errIgnorable{err: err}
}

// Inputseq is a list of keys that the user typed
type Inputseq []string

func (is *Inputseq) Add(s string) {
	*is = append(*is, s)
}

func (is Inputseq) KeyNames() []string {
	return is
}

func (is Inputseq) Len() int {
	return len(is)
}

func (is *Inputseq) Reset() {
	*is = []string(nil)
}

func New() *Peco {
	return &Peco{
		Argv:              os.Args,
		currentLineBuffer: NewMemoryBuffer(), // XXX revisit this
		queryExecDelay:    50 * time.Millisecond,
		readyCh:           make(chan struct{}),
		screen:            &Termbox{},
		selection:         NewSelection(),
	}
}

func (p *Peco) Ready() <-chan struct{} {
	return p.readyCh
}

func (p *Peco) Screen() Screen {
	return p.screen
}

func (p *Peco) Styles() *StyleSet {
	return &p.styles
}

func (p *Peco) Prompt() string {
	return p.prompt
}

func (p *Peco) Inputseq() *Inputseq {
	return &p.inputseq
}

func (p *Peco) Context() context.Context {
	return p.ctx
}

func (p *Peco) LayoutType() string {
	return p.layoutType
}

func (p *Peco) Location() *Location {
	return &p.location
}

func (p *Peco) ResultCh() chan Line {
	return p.resultCh
}

func (p *Peco) SetResultCh(ch chan Line) {
	p.resultCh = ch
}

func (p *Peco) Selection() *Selection {
	return p.selection
}

func (s RangeStart) Valid() bool {
	return s.valid
}

func (s RangeStart) Value() int {
	return s.val
}

func (s *RangeStart) SetValue(n int) {
	s.val = n
	s.valid = true
}

func (s *RangeStart) Reset() {
	s.valid = false
}

func (p *Peco) SelectionRangeStart() *RangeStart {
	return &p.selectionRangeStart
}

func (p *Peco) SingleKeyJumpShowPrefix() bool {
	return p.singleKeyJumpShowPrefix
}

func (p *Peco) SingleKeyJumpPrefixes() []rune {
	return p.singleKeyJumpPrefixes
}

func (p *Peco) SingleKeyJumpMode() bool {
	return p.singleKeyJumpMode
}

func (p *Peco) SetSingleKeyJumpMode(b bool) {
	p.singleKeyJumpMode = b
}

func (p *Peco) ToggleSingleKeyJumpMode() {
	p.singleKeyJumpMode = !p.singleKeyJumpMode
}

func (p *Peco) SingleKeyJumpIndex(ch rune) (uint, bool) {
	// FIXME: use p.keyjump or something instead of p.config
	n, ok := p.config.SingleKeyJump.PrefixMap[ch]
	return n, ok
}

func (p *Peco) Source() pipeline.Source {
	return p.source
}

func (p *Peco) Filters() *FilterSet {
	return &p.filters
}

func (p *Peco) Query() *Query {
	return &p.query
}

func (p *Peco) QueryExecDelay() time.Duration {
	return p.queryExecDelay
}

func (p *Peco) Caret() *Caret {
	return &p.caret
}

func (p *Peco) Hub() *hub.Hub {
	return p.hub
}

func (p *Peco) Err() error {
	return p.err
}

func (p *Peco) Exit(err error) {
	p.err = err
	if cf := p.cancelFunc; cf != nil {
		cf()
	}
}

func (p *Peco) Keymap() Keymap {
	return p.keymap
}

func (p *Peco) Setup() (err error) {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.Setup").BindError(&err)
		defer g.End()
	}

	if err := p.config.Init(); err != nil {
		return errors.Wrap(err, "failed to initialize config")
	}

	if err := parseCommandLine(&p.Options, &p.args, p.Argv); err != nil {
		return errors.Wrap(err, "failed to parse command line")
	}

	// Read config
	if err := readConfig(&p.config, p.Options.OptRcfile); err != nil {
		return errors.Wrap(err, "failed to setup configuration")
	}

	// Take Args, Config, Options, and apply the configuration to
	// the peco object
	if err := p.ApplyConfig(); err != nil {
		return errors.Wrap(err, "failed to apply configuration")
	}

	// XXX p.Keymap et al should be initialized around here
	p.hub = hub.New(5)

	// Setup source buffer
	src, err := p.SetupSource()
	if err != nil {
		return errors.Wrap(err, "failed to setup input source")
	}
	p.source = src
	p.ResetCurrentLineBuffer()
	return nil
}

func (p *Peco) Run(ctx context.Context) (err error) {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.Run").BindError(&err)
		defer g.End()
	}

	if err := p.Setup(); err != nil {
		return errors.Wrap(err, "failed to setup peco")
	}
	// screen.Init must be called within Run() because we
	// want to make sure to call screen.Close() after getting
	// out of Run()
	p.screen.Init()
	defer p.screen.Close()

	var _cancel func()
	ctx, _cancel = context.WithCancel(ctx)
	cancel := func() {
		if pdebug.Enabled {
			pdebug.Printf("Peco.Run cancel called")
		}
		_cancel()
	}

	// keep *this* ctx (not the Background one), as calling `cancel`
	// only affects the wrapped context
	p.ctx = ctx

	// remember this cancel func so p.Exit works (XXX requires locking?)
	p.cancelFunc = cancel

	loopers := []interface {
		Loop(ctx context.Context, cancel func()) error
	}{
		NewInput(p, p.Keymap(), p.screen.PollEvent()),
		NewView(p),
		NewFilter(p),
		sig.New(sig.SigReceivedHandlerFunc(func(sig os.Signal) {
			p.Exit(errors.New("received signal: " + sig.String()))
		})),
	}

	for _, l := range loopers {
		go l.Loop(ctx, cancel)
	}

	if pdebug.Enabled {
		pdebug.Printf("peco is now ready, go go go!")
	}

	close(p.readyCh)
	<-ctx.Done()

	return p.Err()
}

func parseCommandLine(opts *CLIOptions, args *[]string, argv []string) error {
	remaining, err := opts.parse(argv)
	if err != nil {
		return errors.Wrap(err, "failed to parse command line options")
	}

	if opts.OptHelp {
		os.Stdout.Write(opts.help())
		return makeIgnorable(errors.New("user asked to show help message"))
	}

	if opts.OptVersion {
		os.Stdout.Write([]byte("peco version " + version))
		return makeIgnorable(errors.New("user asked to show version"))
	}

	if opts.OptRcfile == "" {
		if file, err := LocateRcfile(locateRcfileIn); err != nil {
			opts.OptRcfile = file
		}
	}

	*args = remaining

	return nil
}

func (p *Peco) SetupSource() (s *Source, err error) {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.SetupSource").BindError(&err)
		defer g.End()
	}

	var in *os.File
	switch {
	case len(p.args) > 1:
		in, err = os.Open(p.args[1])
		if err != nil {
			return nil, errors.Wrap(err, "failed to open file for input")
		}
	case !util.IsTty(os.Stdin.Fd()):
		in = os.Stdin
	default:
		return nil, errors.New("you must supply something to work with via filename or stdin")
	}
	defer in.Close()

	src := NewSource(in, p.enableSep)

	// Block until we receive something from `in`
	if pdebug.Enabled {
		pdebug.Printf("Blocking until we read something in source...")
	}
	go src.Setup(p)
	<-src.Ready()

	return src, nil
}

func readConfig(cfg *Config, filename string) error {
	if filename != "" {
		if err := cfg.ReadFilename(filename); err != nil {
			return errors.Wrap(err, "failed to read config file")
		}
	}

	return nil
}

func (p *Peco) populateCommandList() error {
	for _, v := range p.config.Command {
		if len(v.Args) == 0 {
			continue
		}
		makeCommandAction(&v).Register("ExecuteCommand." + v.Name)
	}

	return nil
}

func (p *Peco) ApplyConfig() error {
	// If layoutType is not set and is set in the config, set it
	if p.layoutType == "" {
		if v := p.config.Layout; v != "" {
			p.layoutType = v
		} else {
			p.layoutType = DefaultLayoutType
		}
	}

	if err := p.populateCommandList(); err != nil {
		return errors.Wrap(err, "failed to populate command list")
	}

	if err := p.populateFilters(); err != nil {
		return errors.Wrap(err, "failed to populate filters")
	}

	if err := p.populateKeymap(); err != nil {
		return errors.Wrap(err, "failed to populate keymap")
	}

	if err := p.populateStyles(); err != nil {
		return errors.Wrap(err, "failed to populate styles")
	}

	return nil
}

func (p *Peco) populateFilters() error {
	p.filters.Add(NewIgnoreCaseFilter())
	p.filters.Add(NewCaseSensitiveFilter())
	p.filters.Add(NewSmartCaseFilter())
	p.filters.Add(NewRegexpFilter())
	return nil
}

func (p *Peco) populateKeymap() error {
	// Create a new keymap object
	k := NewKeymap(p.config.Keymap, p.config.Action)
	if err := k.ApplyKeybinding(); err != nil {
		return errors.Wrap(err, "failed to apply key bindings")
	}
	p.keymap = k
	return nil
}

func (p *Peco) populateStyles() error {
	p.styles = *(p.config.Style)
	return nil
}

func (p *Peco) CurrentLineBuffer() Buffer {
	return p.currentLineBuffer
}

func (p *Peco) SetCurrentLineBuffer(b Buffer) {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.SetCurrentLineBuffer %s", reflect.TypeOf(b).String())
		defer g.End()
	}
	p.currentLineBuffer = b
	p.Hub().SendDraw(false)
}

func (p *Peco) ResetCurrentLineBuffer() {
	p.SetCurrentLineBuffer(p.source)
}

func (p *Peco) ExecQuery() bool {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.ExecQuery")
		defer g.End()
	}

	select {
	case <-p.Ready():
	default:
		if pdebug.Enabled {
			pdebug.Printf("peco is not ready yet, ignoring.")
		}
		return false
	}

	// If this is an empty query, reset the display to show
	// the raw source buffer
	q := p.Query()
	if q.Len() <= 0 {
		if pdebug.Enabled {
			pdebug.Printf("empty query, reset buffer")
		}
		p.ResetCurrentLineBuffer()
		return true
	}

	delay := p.QueryExecDelay()
	if delay <= 0 {
		// No delay, execute immediately
		p.Hub().SendQuery(q.String())
		return true
	}

	p.queryExecMutex.Lock()
	defer p.queryExecMutex.Unlock()

	if p.queryExecTimer != nil {
		return true
	}

	// Wait $delay millisecs before sending the query
	// if a new input comes in, batch them up
	p.queryExecTimer = time.AfterFunc(delay, func() {
		p.Hub().SendQuery(q.String())

		p.queryExecMutex.Lock()
		defer p.queryExecMutex.Unlock()

		p.queryExecTimer = nil
	})
	return true
}

func (p *Peco) collectResults() {
	// In rare cases where the result channel is not setup
	// prior to call to this method, bail out
	if p.resultCh == nil {
		return
	}

	p.selection.Ascend(func(it btree.Item) bool {
		p.resultCh <- it.(Line)
		return true
	})
	close(p.resultCh)
}
<commit_msg>oops<commit_after>package peco

import (
	"os"
	"reflect"
	"time"

	"golang.org/x/net/context"

	"github.com/google/btree"
	"github.com/lestrrat/go-pdebug"
	"github.com/peco/peco/hub"
	"github.com/peco/peco/internal/util"
	"github.com/peco/peco/pipeline"
	"github.com/peco/peco/sig"
	"github.com/pkg/errors"
)

const version = "v0.3.6"

type errIgnorable struct {
	err error
}

func (e errIgnorable) Ignorable() bool { return true }
func (e errIgnorable) Causer() error {
	return e.err
}
func (e errIgnorable) Error() string {
	return e.err.Error()
}
func makeIgnorable(err error) error {
	return errIgnorable{err: err}
}

// Inputseq is a list of keys that the user typed
type Inputseq []string

func (is *Inputseq) Add(s string) {
	*is = append(*is, s)
}

func (is Inputseq) KeyNames() []string {
	return is
}

func (is Inputseq) Len() int {
	return len(is)
}

func (is *Inputseq) Reset() {
	*is = []string(nil)
}

func New() *Peco {
	return &Peco{
		Argv:              os.Args,
		currentLineBuffer: NewMemoryBuffer(), // XXX revisit this
		queryExecDelay:    50 * time.Millisecond,
		readyCh:           make(chan struct{}),
		screen:            &Termbox{},
		selection:         NewSelection(),
	}
}

func (p *Peco) Ready() <-chan struct{} {
	return p.readyCh
}

func (p *Peco) Screen() Screen {
	return p.screen
}

func (p *Peco) Styles() *StyleSet {
	return &p.styles
}

func (p *Peco) Prompt() string {
	return p.prompt
}

func (p *Peco) Inputseq() *Inputseq {
	return &p.inputseq
}

func (p *Peco) Context() context.Context {
	return p.ctx
}

func (p *Peco) LayoutType() string {
	return p.layoutType
}

func (p *Peco) Location() *Location {
	return &p.location
}

func (p *Peco) ResultCh() chan Line {
	return p.resultCh
}

func (p *Peco) SetResultCh(ch chan Line) {
	p.resultCh = ch
}

func (p *Peco) Selection() *Selection {
	return p.selection
}

func (s RangeStart) Valid() bool {
	return s.valid
}

func (s RangeStart) Value() int {
	return s.val
}

func (s *RangeStart) SetValue(n int) {
	s.val = n
	s.valid = true
}

func (s *RangeStart) Reset() {
	s.valid = false
}

func (p *Peco) SelectionRangeStart() *RangeStart {
	return &p.selectionRangeStart
}

func (p *Peco) SingleKeyJumpShowPrefix() bool {
	return p.singleKeyJumpShowPrefix
}

func (p *Peco) SingleKeyJumpPrefixes() []rune {
	return p.singleKeyJumpPrefixes
}

func (p *Peco) SingleKeyJumpMode() bool {
	return p.singleKeyJumpMode
}

func (p *Peco) SetSingleKeyJumpMode(b bool) {
	p.singleKeyJumpMode = b
}

func (p *Peco) ToggleSingleKeyJumpMode() {
	p.singleKeyJumpMode = !p.singleKeyJumpMode
}

func (p *Peco) SingleKeyJumpIndex(ch rune) (uint, bool) {
	// FIXME: use p.keyjump or something instead of p.config
	n, ok := p.config.SingleKeyJump.PrefixMap[ch]
	return n, ok
}

func (p *Peco) Source() pipeline.Source {
	return p.source
}

func (p *Peco) Filters() *FilterSet {
	return &p.filters
}

func (p *Peco) Query() *Query {
	return &p.query
}

func (p *Peco) QueryExecDelay() time.Duration {
	return p.queryExecDelay
}

func (p *Peco) Caret() *Caret {
	return &p.caret
}

func (p *Peco) Hub() *hub.Hub {
	return p.hub
}

func (p *Peco) Err() error {
	return p.err
}

func (p *Peco) Exit(err error) {
	p.err = err
	if cf := p.cancelFunc; cf != nil {
		cf()
	}
}

func (p *Peco) Keymap() Keymap {
	return p.keymap
}

func (p *Peco) Setup() (err error) {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.Setup").BindError(&err)
		defer g.End()
	}

	if err := p.config.Init(); err != nil {
		return errors.Wrap(err, "failed to initialize config")
	}

	if err := parseCommandLine(&p.Options, &p.args, p.Argv); err != nil {
		return errors.Wrap(err, "failed to parse command line")
	}

	// Read config
	if err := readConfig(&p.config, p.Options.OptRcfile); err != nil {
		return errors.Wrap(err, "failed to setup configuration")
	}

	// Take Args, Config, Options, and apply the configuration to
	// the peco object
	if err := p.ApplyConfig(); err != nil {
		return errors.Wrap(err, "failed to apply configuration")
	}

	// XXX p.Keymap et al should be initialized around here
	p.hub = hub.New(5)

	// Setup source buffer
	src, err := p.SetupSource()
	if err != nil {
		return errors.Wrap(err, "failed to setup input source")
	}
	p.source = src
	p.ResetCurrentLineBuffer()
	return nil
}

func (p *Peco) Run(ctx context.Context) (err error) {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.Run").BindError(&err)
		defer g.End()
	}

	if err := p.Setup(); err != nil {
		return errors.Wrap(err, "failed to setup peco")
	}
	// screen.Init must be called within Run() because we
	// want to make sure to call screen.Close() after getting
	// out of Run()
	p.screen.Init()
	defer p.screen.Close()

	var _cancel func()
	ctx, _cancel = context.WithCancel(ctx)
	cancel := func() {
		if pdebug.Enabled {
			pdebug.Printf("Peco.Run cancel called")
		}
		_cancel()
	}

	// keep *this* ctx (not the Background one), as calling `cancel`
	// only affects the wrapped context
	p.ctx = ctx

	// remember this cancel func so p.Exit works (XXX requires locking?)
	p.cancelFunc = cancel

	loopers := []interface {
		Loop(ctx context.Context, cancel func()) error
	}{
		NewInput(p, p.Keymap(), p.screen.PollEvent()),
		NewView(p),
		NewFilter(p),
		sig.New(sig.SigReceivedHandlerFunc(func(sig os.Signal) {
			p.Exit(errors.New("received signal: " + sig.String()))
		})),
	}

	for _, l := range loopers {
		go l.Loop(ctx, cancel)
	}

	if pdebug.Enabled {
		pdebug.Printf("peco is now ready, go go go!")
	}

	close(p.readyCh)
	<-ctx.Done()

	return p.Err()
}

func parseCommandLine(opts *CLIOptions, args *[]string, argv []string) error {
	remaining, err := opts.parse(argv)
	if err != nil {
		return errors.Wrap(err, "failed to parse command line options")
	}

	if opts.OptHelp {
		os.Stdout.Write(opts.help())
		return makeIgnorable(errors.New("user asked to show help message"))
	}

	if opts.OptVersion {
		os.Stdout.Write([]byte("peco version " + version))
		return makeIgnorable(errors.New("user asked to show version"))
	}

	if opts.OptRcfile == "" {
		if file, err := LocateRcfile(locateRcfileIn); err == nil {
			opts.OptRcfile = file
		}
	}

	*args = remaining

	return nil
}

func (p *Peco) SetupSource() (s *Source, err error) {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.SetupSource").BindError(&err)
		defer g.End()
	}

	var in *os.File
	switch {
	case len(p.args) > 1:
		in, err = os.Open(p.args[1])
		if err != nil {
			return nil, errors.Wrap(err, "failed to open file for input")
		}
	case !util.IsTty(os.Stdin.Fd()):
		in = os.Stdin
	default:
		return nil, errors.New("you must supply something to work with via filename or stdin")
	}
	defer in.Close()

	src := NewSource(in, p.enableSep)

	// Block until we receive something from `in`
	if pdebug.Enabled {
		pdebug.Printf("Blocking until we read something in source...")
	}
	go src.Setup(p)
	<-src.Ready()

	return src, nil
}

func readConfig(cfg *Config, filename string) error {
	if filename != "" {
		if err := cfg.ReadFilename(filename); err != nil {
			return errors.Wrap(err, "failed to read config file")
		}
	}

	return nil
}

func (p *Peco) populateCommandList() error {
	for _, v := range p.config.Command {
		if len(v.Args) == 0 {
			continue
		}
		makeCommandAction(&v).Register("ExecuteCommand." + v.Name)
	}

	return nil
}

func (p *Peco) ApplyConfig() error {
	// If layoutType is not set and is set in the config, set it
	if p.layoutType == "" {
		if v := p.config.Layout; v != "" {
			p.layoutType = v
		} else {
			p.layoutType = DefaultLayoutType
		}
	}

	if err := p.populateCommandList(); err != nil {
		return errors.Wrap(err, "failed to populate command list")
	}

	if err := p.populateFilters(); err != nil {
		return errors.Wrap(err, "failed to populate filters")
	}

	if err := p.populateKeymap(); err != nil {
		return errors.Wrap(err, "failed to populate keymap")
	}

	if err := p.populateStyles(); err != nil {
		return errors.Wrap(err, "failed to populate styles")
	}

	return nil
}

func (p *Peco) populateFilters() error {
	p.filters.Add(NewIgnoreCaseFilter())
	p.filters.Add(NewCaseSensitiveFilter())
	p.filters.Add(NewSmartCaseFilter())
	p.filters.Add(NewRegexpFilter())
	return nil
}

func (p *Peco) populateKeymap() error {
	// Create a new keymap object
	k := NewKeymap(p.config.Keymap, p.config.Action)
	if err := k.ApplyKeybinding(); err != nil {
		return errors.Wrap(err, "failed to apply key bindings")
	}
	p.keymap = k
	return nil
}

func (p *Peco) populateStyles() error {
	p.styles = *(p.config.Style)
	return nil
}

func (p *Peco) CurrentLineBuffer() Buffer {
	return p.currentLineBuffer
}

func (p *Peco) SetCurrentLineBuffer(b Buffer) {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.SetCurrentLineBuffer %s", reflect.TypeOf(b).String())
		defer g.End()
	}
	p.currentLineBuffer = b
	p.Hub().SendDraw(false)
}

func (p *Peco) ResetCurrentLineBuffer() {
	p.SetCurrentLineBuffer(p.source)
}

func (p *Peco) ExecQuery() bool {
	if pdebug.Enabled {
		g := pdebug.Marker("Peco.ExecQuery")
		defer g.End()
	}

	select {
	case <-p.Ready():
	default:
		if pdebug.Enabled {
			pdebug.Printf("peco is not ready yet, ignoring.")
		}
		return false
	}

	// If this is an empty query, reset the display to show
	// the raw source buffer
	q := p.Query()
	if q.Len() <= 0 {
		if pdebug.Enabled {
			pdebug.Printf("empty query, reset buffer")
		}
		p.ResetCurrentLineBuffer()
		return true
	}

	delay := p.QueryExecDelay()
	if delay <= 0 {
		// No delay, execute immediately
		p.Hub().SendQuery(q.String())
		return true
	}

	p.queryExecMutex.Lock()
	defer p.queryExecMutex.Unlock()

	if p.queryExecTimer != nil {
		return true
	}

	// Wait $delay millisecs before sending the query
	// if a new input comes in, batch them up
	p.queryExecTimer = time.AfterFunc(delay, func() {
		p.Hub().SendQuery(q.String())

		p.queryExecMutex.Lock()
		defer p.queryExecMutex.Unlock()

		p.queryExecTimer = nil
	})
	return true
}

func (p *Peco) collectResults() {
	// In rare cases where the result channel is not setup
	// prior to call to this method, bail out
	if p.resultCh == nil {
		return
	}

	p.selection.Ascend(func(it btree.Item) bool {
		p.resultCh <- it.(Line)
		return true
	})
	close(p.resultCh)
}
<|endoftext|>


<commit_before>package render

import (
	"context"
	"net/http"
	"strings"
)

var (
	ContentTypeCtxKey = &contextKey{"ContentType"}
)

// ContentType is an enumeration of common HTTP content types.
type ContentType int

// ContentTypes handled by this package.
const (
	ContentTypeUnknown = iota
	ContentTypePlainText
	ContentTypeHTML
	ContentTypeJSON
	ContentTypeXML
	ContentTypeForm
	ContentTypeEventStream
)

func GetContentType(s string) ContentType {
	switch s {
	case "text/plain":
		return ContentTypePlainText
	case "text/html", "application/xhtml+xml":
		return ContentTypeHTML
	case "application/json", "text/javascript":
		return ContentTypeJSON
	case "text/xml", "application/xml":
		return ContentTypeXML
	case "application/x-www-form-urlencoded":
		return ContentTypeForm
	case "text/event-stream":
		return ContentTypeEventStream
	default:
		return ContentTypeUnknown
	}
}

// SetContentType is a middleware that forces response Content-Type.
func SetContentType(contentType ContentType) func(next http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		fn := func(w http.ResponseWriter, r *http.Request) {
			r = r.WithContext(context.WithValue(r.Context(), ContentTypeCtxKey, contentType))
			next.ServeHTTP(w, r)
		}
		return http.HandlerFunc(fn)
	}
}

// GetRequestContentType is a helper function that returns ContentType based on
// context or request headers.
func GetRequestContentType(r *http.Request) ContentType {
	if contentType, ok := r.Context().Value(ContentTypeCtxKey).(ContentType); ok {
		return contentType
	}
	return GetContentType(r.Header.Get("Content-Type"))
}

func GetAcceptedContentType(r *http.Request) ContentType {
	if contentType, ok := r.Context().Value(ContentTypeCtxKey).(ContentType); ok {
		return contentType
	}

	var contentType ContentType

	// Parse request Accept header.
	fields := strings.Split(r.Header.Get("Accept"), ",")
	if len(fields) > 0 {
		contentType = GetContentType(strings.TrimSpace(fields[0]))
	}

	if contentType == ContentTypeUnknown {
		contentType = ContentTypePlainText
	}
	return contentType
}
<commit_msg>Fix #185 to make best effort to parse content type<commit_after>package render

import (
	"context"
	"net/http"
	"strings"
)

var (
	ContentTypeCtxKey = &contextKey{"ContentType"}
)

// ContentType is an enumeration of common HTTP content types.
type ContentType int

// ContentTypes handled by this package.
const (
	ContentTypeUnknown = iota
	ContentTypePlainText
	ContentTypeHTML
	ContentTypeJSON
	ContentTypeXML
	ContentTypeForm
	ContentTypeEventStream
)

func GetContentType(s string) ContentType {
	s = strings.TrimSpace(strings.Split(s, ";")[0])
	switch s {
	case "text/plain":
		return ContentTypePlainText
	case "text/html", "application/xhtml+xml":
		return ContentTypeHTML
	case "application/json", "text/javascript":
		return ContentTypeJSON
	case "text/xml", "application/xml":
		return ContentTypeXML
	case "application/x-www-form-urlencoded":
		return ContentTypeForm
	case "text/event-stream":
		return ContentTypeEventStream
	default:
		return ContentTypeUnknown
	}
}

// SetContentType is a middleware that forces response Content-Type.
func SetContentType(contentType ContentType) func(next http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		fn := func(w http.ResponseWriter, r *http.Request) {
			r = r.WithContext(context.WithValue(r.Context(), ContentTypeCtxKey, contentType))
			next.ServeHTTP(w, r)
		}
		return http.HandlerFunc(fn)
	}
}

// GetRequestContentType is a helper function that returns ContentType based on
// context or request headers.
func GetRequestContentType(r *http.Request) ContentType {
	if contentType, ok := r.Context().Value(ContentTypeCtxKey).(ContentType); ok {
		return contentType
	}
	return GetContentType(r.Header.Get("Content-Type"))
}

func GetAcceptedContentType(r *http.Request) ContentType {
	if contentType, ok := r.Context().Value(ContentTypeCtxKey).(ContentType); ok {
		return contentType
	}

	var contentType ContentType

	// Parse request Accept header.
	fields := strings.Split(r.Header.Get("Accept"), ",")
	if len(fields) > 0 {
		contentType = GetContentType(strings.TrimSpace(fields[0]))
	}

	if contentType == ContentTypeUnknown {
		contentType = ContentTypePlainText
	}
	return contentType
}
<|endoftext|>


<commit_before>package demo

import (
	"bufio"
	"bytes"
	"encoding/csv"
	"fmt"
	"log"
	"net/http"
	"strings"

	"appengine"

	newappengine "google.golang.org/appengine"
)

func init() {
	http.HandleFunc("/import", handleImport)
	http.HandleFunc("/import/do", handleImportDo)
}

func handleImport(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Redirect(w, r, "/?error=noDirectAccess", http.StatusTemporaryRedirect)
		return
	}

	url, err := getProperDomainNameFromUrl(r.FormValue("url"))
	if err != nil {
		http.Redirect(w, r, "/?error=badUrl", http.StatusTemporaryRedirect)
		return
	}

	if !isUrlOnGoogleApp(w, r, url) {
		http.Redirect(w, r, "/?error=notOnGoogleApps", http.StatusTemporaryRedirect)
		return
	}

	r.ParseMultipartForm(32 << 20)
	inp_file, _, err = r.FormFile("inputfile")
	if err != nil {
		log.Print("\n returning bcoz of error 1")
		log.Print(err)
		return
	}
	defer inp_file.Close()

	config.RedirectURL = `http://www.cloudtest1.com/import/do`
	url := config.AuthCodeURL(yeah)

	ctx := appengine.NewContext(r)
	ctx.Infof("Auth: %v", url)

	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

func handleImportDo(w http.ResponseWriter, r *http.Request) {

	ctx := appengine.NewContext(r)

	state := r.FormValue("state")
	if state != yeah {
		ctx.Errorf("invalid state '%v'", state)
		return
	}

	newctx := newappengine.NewContext(r)

	tok, err := config.Exchange(newctx, r.FormValue("code"))
	if err != nil {
		ctx.Errorf("exchange error: %v", err)
		return
	}

	client := config.Client(newctx, tok)

	cr := csv.NewReader(bufio.NewReader(inp_file))
	records, err := cr.ReadAll()
	if err != nil {
		log.Print("\n CSV file error")
		ctx.Errorf("%v", err)
		return
	}

	names := records[0]
	datalen := len(records)
	log.Print("\n Loop started")

	for i := 1; i < datalen; i++ {
		rec := records[i]
		buf := new(bytes.Buffer)
		fmt.Fprintf(buf, `<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
<atom:category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact' />
<atom:content type='text'>Notes</atom:content>
`)
		numExtended, M := 0, 10
		for j, s := range names {
			if s == "Name" {
				fmt.Fprintf(buf, "<gd:name><gd:fullName>%v</gd:fullName></gd:name>\n", rec[j])
			} else if s == "E-mail Address" {
				fmt.Fprintf(buf, "<gd:email rel='http://schemas.google.com/g/2005#home' address='%v'/>", rec[j])
			} else if strings.HasPrefix(s, "E-mail ") && strings.HasSuffix(s, " Address") {
				var num uint
				fmt.Sscanf(s, "E-mail %v Address", &num)
				if numExtended < M && ((0 < num && num < 6) || s == "E-mail Address") {
					fmt.Fprintf(buf, `<gd:extendedProperty name="%v" value="%v" />`+"\n", s, rec[j])
					numExtended++
				}
			} else if numExtended < M {
				fmt.Fprintf(buf, `<gd:extendedProperty name="%v" value="%v" />`+"\n", s, rec[j])
				numExtended++
			}
		}

		fmt.Fprintf(buf, `</atom:entry>`)

		res, _ := client.Post(feedUrl, `application/atom+xml`, strings.NewReader(buf.String()))

		fmt.Fprintf(w, "Result: %v
", res.Status)
	}
}
<commit_msg>make the import process domain agnostic<commit_after>package demo

import (
	"bufio"
	"bytes"
	"encoding/csv"
	"fmt"
	"log"
	"net/http"
	"strings"

	"appengine"

	newappengine "google.golang.org/appengine"
)

func init() {
	http.HandleFunc("/import", handleImport)
	http.HandleFunc("/import/do", handleImportDo)
}

func handleImport(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Redirect(w, r, "/?error=noDirectAccess", http.StatusTemporaryRedirect)
		return
	}

	url, err := getProperDomainNameFromUrl(r.FormValue("url"))
	if err != nil {
		http.Redirect(w, r, "/?error=badUrl", http.StatusTemporaryRedirect)
		return
	}

	if !isUrlOnGoogleApp(w, r, url) {
		http.Redirect(w, r, "/?error=notOnGoogleApps", http.StatusTemporaryRedirect)
		return
	}

	r.ParseMultipartForm(32 << 20)
	inp_file, _, err = r.FormFile("inputfile")
	if err != nil {
		log.Print("\n returning bcoz of error 1")
		log.Print(err)
		return
	}
	defer inp_file.Close()

	x := AppState{url}
	ctx := appengine.NewContext(r)
	config.RedirectURL = fmt.Sprintf(`http://%s/import/do`, r.Host)

	url = config.AuthCodeURL(x.encodeState())
	ctx.Infof("Auth: %v", url)

	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

func handleImportDo(w http.ResponseWriter, r *http.Request) {
	y := r.FormValue("state")

	state := new(AppState)
	state.decodeState(y)

	ctx := appengine.NewContext(r)
	newctx := newappengine.NewContext(r)

	tok, err := config.Exchange(newctx, r.FormValue("code"))
	if err != nil {
		ctx.Errorf("exchange error: %v", err)
		return
	}

	client := config.Client(newctx, tok)

	cr := csv.NewReader(bufio.NewReader(inp_file))
	records, err := cr.ReadAll()
	if err != nil {
		log.Print("\n CSV file error")
		ctx.Errorf("%v", err)
		return
	}

	names := records[0]
	datalen := len(records)
	log.Print("\n Loop started")

	for i := 1; i < datalen; i++ {
		rec := records[i]
		buf := new(bytes.Buffer)
		fmt.Fprintf(buf, `<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
<atom:category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact' />
<atom:content type='text'>Notes</atom:content>
`)
		numExtended, M := 0, 10
		for j, s := range names {
			if s == "Name" {
				fmt.Fprintf(buf, "<gd:name><gd:fullName>%v</gd:fullName></gd:name>\n", rec[j])
			} else if s == "E-mail Address" {
				fmt.Fprintf(buf, "<gd:email rel='http://schemas.google.com/g/2005#home' address='%v'/>", rec[j])
			} else if strings.HasPrefix(s, "E-mail ") && strings.HasSuffix(s, " Address") {
				var num uint
				fmt.Sscanf(s, "E-mail %v Address", &num)
				if numExtended < M && ((0 < num && num < 6) || s == "E-mail Address") {
					fmt.Fprintf(buf, `<gd:extendedProperty name="%v" value="%v" />`+"\n", s, rec[j])
					numExtended++
				}
			} else if numExtended < M {
				fmt.Fprintf(buf, `<gd:extendedProperty name="%v" value="%v" />`+"\n", s, rec[j])
				numExtended++
			}
		}

		fmt.Fprintf(buf, `</atom:entry>`)

		res, _ := client.Post(fmt.Sprintf(feedUrl, state.Domain), `application/atom+xml`, strings.NewReader(buf.String()))

		fmt.Fprintf(w, "Result: %v
", res.Status)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
	"time"

	"github.com/zenazn/goji"
)

func ping(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "")

	referrer := r.Referer()
	if referrer == "" {
		return
	}

	url, err := url.Parse(referrer)

	if err != nil {
		http.Error(w, "Couldn't parse "+referrer+": "+err.Error(), 500)
		return
	}

	var ip string
    if res := r.Header.Get("X-Forwarded-For") {
		ip = res
		log.Println("Fetching IP from proxy: ", ip)
	} else {
		ip = r.RemoteAddr
	}

	visit := &Visit{
		IP:        ip,
		Host:      url.Host,
		Path:      url.Path,
		CreatedAt: time.Now().UTC().Format(time.RFC3339),
	}
	log.Println("Logging visit:", visit.String())

	err = visit.Save()

	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
}

func main() {
	goji.Get("/ping", ping)
	goji.Get("/ping.js", ping)
	goji.Serve()
}
<commit_msg>Fuxk environment variables.<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"time"

	"github.com/zenazn/goji"
)

func ping(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "")

	referrer := r.Referer()
	if referrer == "" {
		return
	}

	url, err := url.Parse(referrer)

	if err != nil {
		http.Error(w, "Couldn't parse "+referrer+": "+err.Error(), 500)
		return
	}

	var ip string
    if res := r.Header.Get("X-Forwarded-For"); res != "" {
		ip = res
		log.Println("Fetching IP from proxy: ", ip)
	} else {
		ip = r.RemoteAddr
	}

	visit := &Visit{
		IP:        ip,
		Host:      url.Host,
		Path:      url.Path,
		CreatedAt: time.Now().UTC().Format(time.RFC3339),
	}
	log.Println("Logging visit:", visit.String())

	err = visit.Save()

	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
}

func main() {
	goji.Get("/ping", ping)
	goji.Get("/ping.js", ping)
	goji.Serve()
}
<|endoftext|>


<commit_before>package slackapi

import (
	"encoding/json"
)

// ResponsePinsList defines the JSON-encoded output for PinsList.
type ResponsePinsList struct {
	Response
	Items []PinsListItem `json:"items"`
}

// PinsListItem defines the JSON-encoded output for one pinned message.
type PinsListItem struct {
	Channel   string      `json:"channel"`
	Created   json.Number `json:"created"`
	CreatedBy string      `json:"created_by"`
	Message   Message     `json:"message"`
	Type      string      `json:"type"`
}

// PinsAdd pins an item to a channel.
func (s *SlackAPI) PinsAdd(channel string, itemid string) Response {
	var response Response

	if len(itemid) >= 3 && itemid[0:2] == "Fc" {
		/* remove pinned file comment */
		s.GetRequest(&response, "pins.add", struct {
			Channel     string `json:"channel"`
			FileComment string `json:"file_comment"`
		}{s.ChannelsID(channel), itemid})
	} else if len(itemid) >= 2 && itemid[0] == 'F' {
		/* remove pinned file */
		s.GetRequest(&response, "pins.add", struct {
			Channel string `json:"channel"`
			File    string `json:"file"`
		}{s.ChannelsID(channel), itemid})
	} else {
		/* remove pinned message */
		s.GetRequest(&response, "pins.add", struct {
			Channel   string `json:"channel"`
			Timestamp string `json:"timestamp"`
		}{s.ChannelsID(channel), itemid})
	}

	return response
}

// PinsList lists items pinned to a channel.
func (s *SlackAPI) PinsList(channel string) ResponsePinsList {
	var response ResponsePinsList
	s.GetRequest(&response, "pins.list", struct {
		Channel string `json:"channel"`
	}{s.ChannelsID(channel)})
	return response
}

// PinsRemove lists items pinned to a channel.
func (s *SlackAPI) PinsRemove(channel string, itemid string) Response {
	var response Response

	if len(itemid) >= 3 && itemid[0:2] == "Fc" {
		/* remove pinned file comment */
		s.GetRequest(&response, "pins.remove", struct {
			Channel     string `json:"channel"`
			FileComment string `json:"file_comment"`
		}{s.ChannelsID(channel), itemid})
	} else if len(itemid) >= 2 && itemid[0] == 'F' {
		/* remove pinned file */
		s.GetRequest(&response, "pins.remove", struct {
			Channel string `json:"channel"`
			File    string `json:"file"`
		}{s.ChannelsID(channel), itemid})
	} else {
		/* remove pinned message */
		s.GetRequest(&response, "pins.remove", struct {
			Channel   string `json:"channel"`
			Timestamp string `json:"timestamp"`
		}{s.ChannelsID(channel), itemid})
	}

	return response
}
<commit_msg>Modify pins.remove http method to comply with the spec<commit_after>package slackapi

import (
	"encoding/json"
)

// ResponsePinsList defines the JSON-encoded output for PinsList.
type ResponsePinsList struct {
	Response
	Items []PinsListItem `json:"items"`
}

// PinsListItem defines the JSON-encoded output for one pinned message.
type PinsListItem struct {
	Channel   string      `json:"channel"`
	Created   json.Number `json:"created"`
	CreatedBy string      `json:"created_by"`
	Message   Message     `json:"message"`
	Type      string      `json:"type"`
}

// PinsAdd pins an item to a channel.
func (s *SlackAPI) PinsAdd(channel string, itemid string) Response {
	var response Response

	if len(itemid) >= 3 && itemid[0:2] == "Fc" {
		/* remove pinned file comment */
		s.GetRequest(&response, "pins.add", struct {
			Channel     string `json:"channel"`
			FileComment string `json:"file_comment"`
		}{s.ChannelsID(channel), itemid})
	} else if len(itemid) >= 2 && itemid[0] == 'F' {
		/* remove pinned file */
		s.GetRequest(&response, "pins.add", struct {
			Channel string `json:"channel"`
			File    string `json:"file"`
		}{s.ChannelsID(channel), itemid})
	} else {
		/* remove pinned message */
		s.GetRequest(&response, "pins.add", struct {
			Channel   string `json:"channel"`
			Timestamp string `json:"timestamp"`
		}{s.ChannelsID(channel), itemid})
	}

	return response
}

// PinsList lists items pinned to a channel.
func (s *SlackAPI) PinsList(channel string) ResponsePinsList {
	var response ResponsePinsList
	s.GetRequest(&response, "pins.list", struct {
		Channel string `json:"channel"`
	}{s.ChannelsID(channel)})
	return response
}

// PinsRemove lists items pinned to a channel.
func (s *SlackAPI) PinsRemove(channel string, itemid string) Response {
	var response Response

	if len(itemid) >= 3 && itemid[0:2] == "Fc" {
		/* remove pinned file comment */
		s.PostRequest(&response, "pins.remove", struct {
			Channel     string `json:"channel"`
			FileComment string `json:"file_comment"`
		}{s.ChannelsID(channel), itemid})
	} else if len(itemid) >= 2 && itemid[0] == 'F' {
		/* remove pinned file */
		s.PostRequest(&response, "pins.remove", struct {
			Channel string `json:"channel"`
			File    string `json:"file"`
		}{s.ChannelsID(channel), itemid})
	} else {
		/* remove pinned message */
		s.PostRequest(&response, "pins.remove", struct {
			Channel   string `json:"channel"`
			Timestamp string `json:"timestamp"`
		}{s.ChannelsID(channel), itemid})
	}

	return response
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"

)

func SendMsgResult(w *http.ResponseWriter, r *msg.Result) {
	var (
		bjson  []byte
		err    error
		k      auth.Kex
		result proto.Result
		action string
	)

	// this is central error command, proceeding to log
	if r.Error != nil {
		log.Printf(LogStrErr, r.Type, r.Action, r.Code, r.Error.Error())
	}

	switch r.Type {
	case `supervisor`:
		switch r.Action {
		case `kex_reply`:
			k = r.Super.Kex
			if bjson, err = json.Marshal(&k); err != nil {
				log.Printf(LogStrErr, r.Type, r.Action, r.Code, err.Error())
				DispatchInternalError(w, nil)
				return
			}
			goto dispatchJSON
		case `bootstrap_root`:
			fallthrough
		case `activate_user`:
			fallthrough
		case `issue_token`, `reset_user_password`, `change_user_password`:
			// for this request type, errors are masked in responses
			switch r.Code {
			case 200:
				if r.Super.Verdict == 200 {
					log.Printf(LogStrOK, r.Type, r.Action, r.Code, 200)
					goto dispatchOCTET
				}
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 401)
				DispatchUnauthorized(w, nil)
			case 400:
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 400)
				DispatchBadRequest(w, nil)
			case 404:
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 404)
				DispatchNotFound(w, r.Error)
			case 406:
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 406)
				DispatchConflict(w, r.Error)
			default:
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 401)
				DispatchUnauthorized(w, nil)
			}
			return
		case `category`:
			result = proto.NewCategoryResult()
			*result.Categories = append(*result.Categories, r.Category...)
			goto UnmaskedReply
		case `permission`:
			result = proto.NewPermissionResult()
			*result.Permissions = append(*result.Permissions, r.Permission...)
			goto UnmaskedReply
		case `right`:
			result = proto.NewGrantResult()
			*result.Grants = append(*result.Grants, r.Grant...)
			goto UnmaskedReply
		default:
			log.Printf(LogStrErr, r.Type, r.Action, 0, `Unhandled supervisor action`)
			// supervisor as auth-lord has special default to avoid
			// accidental leakage
			DispatchUnauthorized(w, nil)
			return
		} // end supervisor
	case `job`:
		result = proto.NewJobResult()
		*result.Jobs = append(*result.Jobs, r.Job...)
		goto UnmaskedReply
	case `tree`:
		result = proto.NewTreeResult()
		*result.Tree = r.Tree
		goto UnmaskedReply
	case `guidepost`, `forestcustodian`:
		result = proto.NewSystemOperationResult()
		*result.SystemOperations = append(*result.SystemOperations, r.System...)
		goto UnmaskedReply
	default:
		log.Printf(LogStrErr, r.Type, ``, 0, `Result from unhandled subsystem`)
		DispatchInternalError(w, nil)
		return
	}

UnmaskedReply:
	switch r.Type {
	case `supervisor`:
		action = fmt.Sprintf("%s/%s", r.Action, r.Super.Action)
	case `guidepost`, `forestcustodian`:
		action = fmt.Sprintf("%s/%s", r.Action, r.System[0].Request)
	default:
		action = r.Action
	}

	switch r.Code {
	case 200:
		log.Printf(LogStrOK, r.Type, action, r.Code, 200)
		if r.Error != nil {
			result.Error(r.Error)
		}
		result.OK()
	case 202:
		log.Printf(LogStrOK, r.Type, action, r.Code, 202)
		result.JobId = r.JobId
		result.Accepted()
	case 400:
		log.Printf(LogStrOK, r.Type, action, r.Code, 400)
		DispatchBadRequest(w, nil)
		return
	case 403:
		log.Printf(LogStrOK, r.Type, action, r.Code, 403)
		DispatchForbidden(w, r.Error)
		return
	case 404:
		log.Printf(LogStrOK, r.Type, action, r.Code, 200)
		result.NotFound()
	case 406:
		log.Printf(LogStrOK, r.Type, action, r.Code, 406)
		DispatchConflict(w, r.Error)
		return
	case 500:
		log.Printf(LogStrOK, r.Type, action, r.Code, 500)
		result.Error(r.Error)
	case 501:
		log.Printf(LogStrOK, r.Type, action, r.Code, 501)
		result.NotImplemented()
	default:
		log.Printf(LogStrErr, r.Type, action, r.Code, `Unhandled internal result code`)
		DispatchInternalError(w, nil)
		return
	}
	goto buildJSON

dispatchOCTET:
	DispatchOctetReply(w, &r.Super.Data)
	return

buildJSON:
	if bjson, err = json.Marshal(&result); err != nil {
		log.Printf(LogStrErr, r.Type, r.Action, r.Code, err)
		DispatchInternalError(w, nil)
		return
	}

dispatchJSON:
	DispatchJsonReply(w, &bjson)
	return
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<commit_msg>Handle 503 in unmasked http output routine<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"

)

func SendMsgResult(w *http.ResponseWriter, r *msg.Result) {
	var (
		bjson  []byte
		err    error
		k      auth.Kex
		result proto.Result
		action string
	)

	// this is central error command, proceeding to log
	if r.Error != nil {
		log.Printf(LogStrErr, r.Type, r.Action, r.Code, r.Error.Error())
	}

	switch r.Type {
	case `supervisor`:
		switch r.Action {
		case `kex_reply`:
			k = r.Super.Kex
			if bjson, err = json.Marshal(&k); err != nil {
				log.Printf(LogStrErr, r.Type, r.Action, r.Code, err.Error())
				DispatchInternalError(w, nil)
				return
			}
			goto dispatchJSON
		case `bootstrap_root`:
			fallthrough
		case `activate_user`:
			fallthrough
		case `issue_token`, `reset_user_password`, `change_user_password`:
			// for this request type, errors are masked in responses
			switch r.Code {
			case 200:
				if r.Super.Verdict == 200 {
					log.Printf(LogStrOK, r.Type, r.Action, r.Code, 200)
					goto dispatchOCTET
				}
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 401)
				DispatchUnauthorized(w, nil)
			case 400:
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 400)
				DispatchBadRequest(w, nil)
			case 404:
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 404)
				DispatchNotFound(w, r.Error)
			case 406:
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 406)
				DispatchConflict(w, r.Error)
			default:
				log.Printf(LogStrOK, r.Type, r.Action, r.Code, 401)
				DispatchUnauthorized(w, nil)
			}
			return
		case `category`:
			result = proto.NewCategoryResult()
			*result.Categories = append(*result.Categories, r.Category...)
			goto UnmaskedReply
		case `permission`:
			result = proto.NewPermissionResult()
			*result.Permissions = append(*result.Permissions, r.Permission...)
			goto UnmaskedReply
		case `right`:
			result = proto.NewGrantResult()
			*result.Grants = append(*result.Grants, r.Grant...)
			goto UnmaskedReply
		default:
			log.Printf(LogStrErr, r.Type, r.Action, 0, `Unhandled supervisor action`)
			// supervisor as auth-lord has special default to avoid
			// accidental leakage
			DispatchUnauthorized(w, nil)
			return
		} // end supervisor
	case `job`:
		result = proto.NewJobResult()
		*result.Jobs = append(*result.Jobs, r.Job...)
		goto UnmaskedReply
	case `tree`:
		result = proto.NewTreeResult()
		*result.Tree = r.Tree
		goto UnmaskedReply
	case `guidepost`, `forestcustodian`:
		result = proto.NewSystemOperationResult()
		*result.SystemOperations = append(*result.SystemOperations, r.System...)
		goto UnmaskedReply
	default:
		log.Printf(LogStrErr, r.Type, ``, 0, `Result from unhandled subsystem`)
		DispatchInternalError(w, nil)
		return
	}

UnmaskedReply:
	switch r.Type {
	case `supervisor`:
		action = fmt.Sprintf("%s/%s", r.Action, r.Super.Action)
	case `guidepost`, `forestcustodian`:
		action = fmt.Sprintf("%s/%s", r.Action, r.System[0].Request)
	default:
		action = r.Action
	}

	switch r.Code {
	case 200:
		log.Printf(LogStrOK, r.Type, action, r.Code, 200)
		if r.Error != nil {
			result.Error(r.Error)
		}
		result.OK()
	case 202:
		log.Printf(LogStrOK, r.Type, action, r.Code, 202)
		result.JobId = r.JobId
		result.Accepted()
	case 400:
		log.Printf(LogStrOK, r.Type, action, r.Code, 400)
		DispatchBadRequest(w, nil)
		return
	case 403:
		log.Printf(LogStrOK, r.Type, action, r.Code, 403)
		DispatchForbidden(w, r.Error)
		return
	case 404:
		log.Printf(LogStrOK, r.Type, action, r.Code, 200)
		result.NotFound()
	case 406:
		log.Printf(LogStrOK, r.Type, action, r.Code, 406)
		DispatchConflict(w, r.Error)
		return
	case 500:
		log.Printf(LogStrOK, r.Type, action, r.Code, 500)
		result.Error(r.Error)
	case 501:
		log.Printf(LogStrOK, r.Type, action, r.Code, 501)
		result.NotImplemented()
	case 503:
		log.Printf(LogStrOK, r.Type, action, r.Code, 503)
		result.Unavailable()
	default:
		log.Printf(LogStrErr, r.Type, action, r.Code, `Unhandled internal result code`)
		DispatchInternalError(w, nil)
		return
	}
	goto buildJSON

dispatchOCTET:
	DispatchOctetReply(w, &r.Super.Data)
	return

buildJSON:
	if bjson, err = json.Marshal(&result); err != nil {
		log.Printf(LogStrErr, r.Type, r.Action, r.Code, err)
		DispatchInternalError(w, nil)
		return
	}

dispatchJSON:
	DispatchJsonReply(w, &bjson)
	return
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<|endoftext|>


<commit_before>package ps

import (
	"errors"
	"fmt"
	"strings"

	dockeroptions "github.com/dokku/dokku/plugins/docker-options"

	"github.com/dokku/dokku/plugins/common"
)

// CommandInspect displays a sanitized version of docker inspect for an app
func CommandInspect(appName string) error {
	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	scheduler := common.GetAppScheduler(appName)
	return common.PlugnTrigger("scheduler-inspect", []string{scheduler, appName}...)
}

// CommandRebuild rebuilds an app from source
func CommandRebuild(appName string, allApps bool, parallelCount int) error {
	if allApps {
		return common.RunCommandAgainstAllApps(Rebuild, "rebuild", parallelCount)
	}

	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Rebuild(appName)
}

// CommandReport displays a ps report for one or more apps
func CommandReport(appName string, infoFlag string) error {
	if strings.HasPrefix(appName, "--") {
		infoFlag = appName
		appName = ""
	}

	if len(appName) == 0 {
		apps, err := common.DokkuApps()
		if err != nil {
			return err
		}
		for _, appName := range apps {
			if err := ReportSingleApp(appName, infoFlag); err != nil {
				return err
			}
		}
		return nil
	}

	return ReportSingleApp(appName, infoFlag)
}

// CommandRestart restarts an app
func CommandRestart(appName string, allApps bool, parallelCount int) error {
	if allApps {
		return common.RunCommandAgainstAllApps(Restart, "restart", parallelCount)
	}

	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Restart(appName)
}

// CommandRestore starts previously running apps e.g. after reboot
// TODO: implement me
func CommandRestore(appName string, allApps bool, parallelCount int) error {
	if allApps {
		if err := RestorePrep(); err != nil {
			return err
		}

		return common.RunCommandAgainstAllApps(Restore, "restore", parallelCount)
	}

	if appName == "" {
		common.LogWarn("Restore specified without app, assuming --all")

		if err := RestorePrep(); err != nil {
			return err
		}
		return common.RunCommandAgainstAllApps(Restore, "restore", parallelCount)
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Restore(appName)
}

// CommandRetire ensures old containers are retired
// TODO: implement me
func CommandRetire() error {
	return nil
}

// CommandScale gets or sets how many instances of a given process to run
func CommandScale(appName string, skipDeploy bool, processTuples []string) error {
	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	procfilePath := getProcfilePath(appName)
	if !common.FileExists(procfilePath) {
		image := common.GetAppImageRepo(appName)
		common.SuppressOutput(func() error {
			extractProcfile(appName, image, procfilePath)
			return nil
		})
	}

	if !hasScaleFile(appName) {
		err := common.SuppressOutput(func() error {
			return updateScalefile(appName, make(map[string]int))
		})
		if err != nil {
			return err
		}
	} else if common.FileExists(procfilePath) {
		if err := updateScalefile(appName, make(map[string]int)); err != nil {
			return err
		}
	}

	if len(processTuples) == 0 {
		return scaleReport(appName)
	}

	return scaleSet(appName, skipDeploy, processTuples)
}

// CommandSet sets or clears a ps property for an app
func CommandSet(appName string, property string, value string) error {
	if property == "restart-policy" {
		if !isValidRestartPolicy(value) {
			return errors.New("Invalid restart-policy specified")
		}

		common.LogInfo2Quiet(fmt.Sprintf("Setting %s to %s", property, value))
		return dockeroptions.SetDockerOptionForPhases(appName, []string{"deploy"}, "restart", value)
	}

	common.CommandPropertySet("ps", appName, property, value, DefaultProperties)
	return nil
}

// CommandStart starts an app
func CommandStart(appName string, allApps bool, parallelCount int) error {
	if allApps {
		return common.RunCommandAgainstAllApps(Start, "start", parallelCount)
	}

	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Start(appName)
}

// CommandStop stops an app
func CommandStop(appName string, allApps bool, parallelCount int) error {
	if allApps {
		return common.RunCommandAgainstAllApps(Stop, "stop", parallelCount)
	}

	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Stop(appName)
}
<commit_msg>chore: drop implemented function<commit_after>package ps

import (
	"errors"
	"fmt"
	"strings"

	dockeroptions "github.com/dokku/dokku/plugins/docker-options"

	"github.com/dokku/dokku/plugins/common"
)

// CommandInspect displays a sanitized version of docker inspect for an app
func CommandInspect(appName string) error {
	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	scheduler := common.GetAppScheduler(appName)
	return common.PlugnTrigger("scheduler-inspect", []string{scheduler, appName}...)
}

// CommandRebuild rebuilds an app from source
func CommandRebuild(appName string, allApps bool, parallelCount int) error {
	if allApps {
		return common.RunCommandAgainstAllApps(Rebuild, "rebuild", parallelCount)
	}

	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Rebuild(appName)
}

// CommandReport displays a ps report for one or more apps
func CommandReport(appName string, infoFlag string) error {
	if strings.HasPrefix(appName, "--") {
		infoFlag = appName
		appName = ""
	}

	if len(appName) == 0 {
		apps, err := common.DokkuApps()
		if err != nil {
			return err
		}
		for _, appName := range apps {
			if err := ReportSingleApp(appName, infoFlag); err != nil {
				return err
			}
		}
		return nil
	}

	return ReportSingleApp(appName, infoFlag)
}

// CommandRestart restarts an app
func CommandRestart(appName string, allApps bool, parallelCount int) error {
	if allApps {
		return common.RunCommandAgainstAllApps(Restart, "restart", parallelCount)
	}

	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Restart(appName)
}

// CommandRestore starts previously running apps e.g. after reboot
func CommandRestore(appName string, allApps bool, parallelCount int) error {
	if allApps {
		if err := RestorePrep(); err != nil {
			return err
		}

		return common.RunCommandAgainstAllApps(Restore, "restore", parallelCount)
	}

	if appName == "" {
		common.LogWarn("Restore specified without app, assuming --all")

		if err := RestorePrep(); err != nil {
			return err
		}
		return common.RunCommandAgainstAllApps(Restore, "restore", parallelCount)
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Restore(appName)
}

// CommandRetire ensures old containers are retired
// TODO: implement me
func CommandRetire() error {
	return nil
}

// CommandScale gets or sets how many instances of a given process to run
func CommandScale(appName string, skipDeploy bool, processTuples []string) error {
	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	procfilePath := getProcfilePath(appName)
	if !common.FileExists(procfilePath) {
		image := common.GetAppImageRepo(appName)
		common.SuppressOutput(func() error {
			extractProcfile(appName, image, procfilePath)
			return nil
		})
	}

	if !hasScaleFile(appName) {
		err := common.SuppressOutput(func() error {
			return updateScalefile(appName, make(map[string]int))
		})
		if err != nil {
			return err
		}
	} else if common.FileExists(procfilePath) {
		if err := updateScalefile(appName, make(map[string]int)); err != nil {
			return err
		}
	}

	if len(processTuples) == 0 {
		return scaleReport(appName)
	}

	return scaleSet(appName, skipDeploy, processTuples)
}

// CommandSet sets or clears a ps property for an app
func CommandSet(appName string, property string, value string) error {
	if property == "restart-policy" {
		if !isValidRestartPolicy(value) {
			return errors.New("Invalid restart-policy specified")
		}

		common.LogInfo2Quiet(fmt.Sprintf("Setting %s to %s", property, value))
		return dockeroptions.SetDockerOptionForPhases(appName, []string{"deploy"}, "restart", value)
	}

	common.CommandPropertySet("ps", appName, property, value, DefaultProperties)
	return nil
}

// CommandStart starts an app
func CommandStart(appName string, allApps bool, parallelCount int) error {
	if allApps {
		return common.RunCommandAgainstAllApps(Start, "start", parallelCount)
	}

	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Start(appName)
}

// CommandStop stops an app
func CommandStop(appName string, allApps bool, parallelCount int) error {
	if allApps {
		return common.RunCommandAgainstAllApps(Stop, "stop", parallelCount)
	}

	if appName == "" {
		return errors.New("Please specify an app to run the command on")
	}

	if err := common.VerifyAppName(appName); err != nil {
		return err
	}

	return Stop(appName)
}
<|endoftext|>


<commit_before>package herd

import (
	"errors"
	"github.com/Symantec/Dominator/dom/images"
	"github.com/Symantec/Dominator/lib/constants"
	filegenclient "github.com/Symantec/Dominator/lib/filegen/client"
	"github.com/Symantec/Dominator/lib/objectserver"
	"github.com/Symantec/Dominator/lib/url"
	subproto "github.com/Symantec/Dominator/proto/sub"
	"log"
	"runtime"
	"syscall"
	"time"
)

func newHerd(imageServerAddress string, objectServer objectserver.ObjectServer,
	logger *log.Logger) *Herd {
	var herd Herd
	herd.imageManager = images.New(imageServerAddress, logger)
	herd.objectServer = objectServer
	herd.computedFilesManager = filegenclient.New(objectServer, logger)
	herd.logger = logger
	herd.configurationForSubs.ScanSpeedPercent =
		constants.DefaultScanSpeedPercent
	herd.configurationForSubs.NetworkSpeedPercent =
		constants.DefaultNetworkSpeedPercent
	herd.configurationForSubs.ScanExclusionList =
		constants.ScanExcludeList
	herd.subsByName = make(map[string]*Sub)
	// Limit concurrent connection attempts so that the file descriptor limit is
	// not exceeded.
	var rlim syscall.Rlimit
	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
		panic(err)
	}
	maxConnAttempts := rlim.Cur - 50
	maxConnAttempts = (maxConnAttempts / 100)
	if maxConnAttempts < 1 {
		maxConnAttempts = 1
	} else {
		maxConnAttempts *= 100
	}
	herd.connectionSemaphore = make(chan struct{}, maxConnAttempts)
	herd.pollSemaphore = make(chan struct{}, runtime.NumCPU()*10)
	herd.pushSemaphore = make(chan struct{}, runtime.NumCPU())
	herd.computeSemaphore = make(chan struct{}, runtime.NumCPU())
	herd.currentScanStartTime = time.Now()
	return &herd
}

func (herd *Herd) clearSafetyShutoff(hostname string) error {
	herd.Lock()
	sub, ok := herd.subsByName[hostname]
	herd.Unlock()
	if !ok {
		return errors.New("unknown sub: " + hostname)
	}
	return sub.clearSafetyShutoff()
}

func (herd *Herd) configureSubs(configuration subproto.Configuration) error {
	herd.Lock()
	defer herd.Unlock()
	herd.configurationForSubs = configuration
	return nil
}

func (herd *Herd) disableUpdates(username, reason string) error {
	if reason == "" {
		return errors.New("error disabling updates: no reason given")
	}
	herd.updatesDisabledBy = username
	herd.updatesDisabledReason = reason
	herd.updatesDisabledTime = time.Now()
	return nil
}

func (herd *Herd) enableUpdates() error {
	herd.updatesDisabledReason = ""
	return nil
}

func (herd *Herd) getSubsConfiguration() subproto.Configuration {
	herd.RLock()
	defer herd.RUnlock()
	return herd.configurationForSubs
}

func (herd *Herd) pollNextSub() bool {
	if herd.nextSubToPoll >= uint(len(herd.subsByIndex)) {
		herd.nextSubToPoll = 0
		herd.previousScanDuration = time.Since(herd.currentScanStartTime)
		return true
	}
	if herd.nextSubToPoll == 0 {
		herd.currentScanStartTime = time.Now()
	}
	sub := herd.subsByIndex[herd.nextSubToPoll]
	herd.nextSubToPoll++
	if sub.busy { // Quick lockless check.
		return false
	}
	herd.connectionSemaphore <- struct{}{}
	go func() {
		defer func() { <-herd.connectionSemaphore }()
		if !sub.tryMakeBusy() {
			return
		}
		sub.connectAndPoll()
		sub.makeUnbusy()
	}()
	return false
}

func (herd *Herd) countSelectedSubs(selectFunc func(*Sub) bool) uint64 {
	herd.RLock()
	defer herd.RUnlock()
	if selectFunc == nil {
		return uint64(len(herd.subsByIndex))
	}
	count := 0
	for _, sub := range herd.subsByIndex {
		if selectFunc(sub) {
			count++
		}
	}
	return uint64(count)
}

func (herd *Herd) getSelectedSubs(selectFunc func(*Sub) bool) []*Sub {
	herd.RLock()
	defer herd.RUnlock()
	subs := make([]*Sub, 0, len(herd.subsByIndex))
	for _, sub := range herd.subsByIndex {
		if selectFunc == nil || selectFunc(sub) {
			subs = append(subs, sub)
		}
	}
	return subs
}

func (herd *Herd) getReachableSelector(parsedQuery url.ParsedQuery) (
	func(*Sub) bool, error) {
	duration, err := parsedQuery.Last()
	if err != nil {
		return nil, err
	}
	return rDuration(duration).selector, nil
}

func (herd *Herd) setDefaultImage(imageName string) error {
	if imageName == "" {
		herd.defaultImageName = ""
		return nil
	}
	img, err := herd.imageManager.Get(imageName, true)
	if err != nil {
		return err
	}
	if img == nil {
		return errors.New("unknown image: " + imageName)
	}
	if img.Filter != nil {
		return errors.New("only sparse images can be set as default")
	}
	if len(img.FileSystem.InodeTable) > 100 {
		return errors.New("cannot set default image with more than 100 inodes")
	}
	herd.defaultImageName = imageName
	return nil
}
<commit_msg>Add -pollSlotsPerCPU option to dominator. Change default from 10 to 100.<commit_after>package herd

import (
	"errors"
	"flag"
	"github.com/Symantec/Dominator/dom/images"
	"github.com/Symantec/Dominator/lib/constants"
	filegenclient "github.com/Symantec/Dominator/lib/filegen/client"
	"github.com/Symantec/Dominator/lib/objectserver"
	"github.com/Symantec/Dominator/lib/url"
	subproto "github.com/Symantec/Dominator/proto/sub"
	"log"
	"runtime"
	"syscall"
	"time"
)

var (
	pollSlotsPerCPU = flag.Uint("pollSlotsPerCPU", 100,
		"Number of poll slots per CPU")
)

func newHerd(imageServerAddress string, objectServer objectserver.ObjectServer,
	logger *log.Logger) *Herd {
	var herd Herd
	herd.imageManager = images.New(imageServerAddress, logger)
	herd.objectServer = objectServer
	herd.computedFilesManager = filegenclient.New(objectServer, logger)
	herd.logger = logger
	herd.configurationForSubs.ScanSpeedPercent =
		constants.DefaultScanSpeedPercent
	herd.configurationForSubs.NetworkSpeedPercent =
		constants.DefaultNetworkSpeedPercent
	herd.configurationForSubs.ScanExclusionList =
		constants.ScanExcludeList
	herd.subsByName = make(map[string]*Sub)
	// Limit concurrent connection attempts so that the file descriptor limit is
	// not exceeded.
	var rlim syscall.Rlimit
	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
		panic(err)
	}
	maxConnAttempts := rlim.Cur - 50
	maxConnAttempts = (maxConnAttempts / 100)
	if maxConnAttempts < 1 {
		maxConnAttempts = 1
	} else {
		maxConnAttempts *= 100
	}
	herd.connectionSemaphore = make(chan struct{}, maxConnAttempts)
	numPollSlots := uint(runtime.NumCPU()) * *pollSlotsPerCPU
	herd.pollSemaphore = make(chan struct{}, numPollSlots)
	herd.pushSemaphore = make(chan struct{}, runtime.NumCPU())
	herd.computeSemaphore = make(chan struct{}, runtime.NumCPU())
	herd.currentScanStartTime = time.Now()
	return &herd
}

func (herd *Herd) clearSafetyShutoff(hostname string) error {
	herd.Lock()
	sub, ok := herd.subsByName[hostname]
	herd.Unlock()
	if !ok {
		return errors.New("unknown sub: " + hostname)
	}
	return sub.clearSafetyShutoff()
}

func (herd *Herd) configureSubs(configuration subproto.Configuration) error {
	herd.Lock()
	defer herd.Unlock()
	herd.configurationForSubs = configuration
	return nil
}

func (herd *Herd) disableUpdates(username, reason string) error {
	if reason == "" {
		return errors.New("error disabling updates: no reason given")
	}
	herd.updatesDisabledBy = username
	herd.updatesDisabledReason = reason
	herd.updatesDisabledTime = time.Now()
	return nil
}

func (herd *Herd) enableUpdates() error {
	herd.updatesDisabledReason = ""
	return nil
}

func (herd *Herd) getSubsConfiguration() subproto.Configuration {
	herd.RLock()
	defer herd.RUnlock()
	return herd.configurationForSubs
}

func (herd *Herd) pollNextSub() bool {
	if herd.nextSubToPoll >= uint(len(herd.subsByIndex)) {
		herd.nextSubToPoll = 0
		herd.previousScanDuration = time.Since(herd.currentScanStartTime)
		return true
	}
	if herd.nextSubToPoll == 0 {
		herd.currentScanStartTime = time.Now()
	}
	sub := herd.subsByIndex[herd.nextSubToPoll]
	herd.nextSubToPoll++
	if sub.busy { // Quick lockless check.
		return false
	}
	herd.connectionSemaphore <- struct{}{}
	go func() {
		defer func() { <-herd.connectionSemaphore }()
		if !sub.tryMakeBusy() {
			return
		}
		sub.connectAndPoll()
		sub.makeUnbusy()
	}()
	return false
}

func (herd *Herd) countSelectedSubs(selectFunc func(*Sub) bool) uint64 {
	herd.RLock()
	defer herd.RUnlock()
	if selectFunc == nil {
		return uint64(len(herd.subsByIndex))
	}
	count := 0
	for _, sub := range herd.subsByIndex {
		if selectFunc(sub) {
			count++
		}
	}
	return uint64(count)
}

func (herd *Herd) getSelectedSubs(selectFunc func(*Sub) bool) []*Sub {
	herd.RLock()
	defer herd.RUnlock()
	subs := make([]*Sub, 0, len(herd.subsByIndex))
	for _, sub := range herd.subsByIndex {
		if selectFunc == nil || selectFunc(sub) {
			subs = append(subs, sub)
		}
	}
	return subs
}

func (herd *Herd) getReachableSelector(parsedQuery url.ParsedQuery) (
	func(*Sub) bool, error) {
	duration, err := parsedQuery.Last()
	if err != nil {
		return nil, err
	}
	return rDuration(duration).selector, nil
}

func (herd *Herd) setDefaultImage(imageName string) error {
	if imageName == "" {
		herd.defaultImageName = ""
		return nil
	}
	img, err := herd.imageManager.Get(imageName, true)
	if err != nil {
		return err
	}
	if img == nil {
		return errors.New("unknown image: " + imageName)
	}
	if img.Filter != nil {
		return errors.New("only sparse images can be set as default")
	}
	if len(img.FileSystem.InodeTable) > 100 {
		return errors.New("cannot set default image with more than 100 inodes")
	}
	herd.defaultImageName = imageName
	return nil
}
<|endoftext|>


<commit_before>package serial

import (
	"fmt"
	"io"
	"os"
	"sync"
	"syscall"
	"unsafe"
)

type serialPort struct {
	f  *os.File
	fd syscall.Handle
	rl sync.Mutex
	wl sync.Mutex
	ro *syscall.Overlapped
	wo *syscall.Overlapped
}

type structDCB struct {
	DCBlength, BaudRate                            uint32
	flags                                          [4]byte
	wReserved, XonLim, XoffLim                     uint16
	ByteSize, Parity, StopBits                     byte
	XonChar, XoffChar, ErrorChar, EofChar, EvtChar byte
	wReserved1                                     uint16
}

type structTimeouts struct {
	ReadIntervalTimeout         uint32
	ReadTotalTimeoutMultiplier  uint32
	ReadTotalTimeoutConstant    uint32
	WriteTotalTimeoutMultiplier uint32
	WriteTotalTimeoutConstant   uint32
}

func OpenPort(name string, baud int) (rwc io.ReadWriteCloser, err os.Error) {
	if len(name) > 0 && name[0] != '\\' {
		name = "\\\\.\\" + name
	}

	const FILE_FLAGS_OVERLAPPED = 0x40000000
	h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(name),
		syscall.GENERIC_READ|syscall.GENERIC_WRITE,
		0,
		nil,
		syscall.OPEN_EXISTING,
		syscall.FILE_ATTRIBUTE_NORMAL|FILE_FLAGS_OVERLAPPED,
		0)
	if e != 0 {
		err = &os.PathError{"open", name, os.Errno(e)}
		return
	}
	f := os.NewFile(h, name)
	defer func() {
		if err != nil {
			f.Close()
		}
	}()

	if err = setCommState(h, baud); err != nil {
		return
	}
	if err = setupComm(h, 64, 64); err != nil {
		return
	}
	if err = setCommTimeouts(h); err != nil {
		return
	}
	if err = setCommMask(h); err != nil {
		return
	}

	ro, err := newOverlapped()
	if err != nil {
		return
	}
	wo, err := newOverlapped()
	if err != nil {
		return
	}
	port := new(serialPort)
	port.f = f
	port.fd = h
	port.ro = ro
	port.wo = wo

	return port, nil
}

func (p *serialPort) Close() os.Error {
	return p.f.Close()
}

func (p *serialPort) Write(buf []byte) (int, os.Error) {
	p.wl.Lock()
	defer p.wl.Unlock()

	if err := resetEvent(p.wo.HEvent); err != nil {
		return 0, err
	}
	var n uint32
	e := syscall.WriteFile(p.fd, buf, &n, p.wo)
	if e != 0 && e != syscall.ERROR_IO_PENDING {
		return int(n), errno(uintptr(e))
	}
	return getOverlappedResult(p.fd, p.wo)
}

func (p *serialPort) Read(buf []byte) (int, os.Error) {
	if p == nil || p.f == nil {
		return 0, fmt.Errorf("Invalid port on read %v %v", p, p.f)
	}

	p.rl.Lock()
	defer p.rl.Unlock()

	if err := resetEvent(p.ro.HEvent); err != nil {
		return 0, err
	}
	var done uint32
	e := syscall.ReadFile(p.fd, buf, &done, p.ro)
	if e != 0 && e != syscall.ERROR_IO_PENDING {
		return int(done), errno(uintptr(e))
	}
	return getOverlappedResult(p.fd, p.ro)
}

var (
	nSetCommState,
	nSetCommTimeouts,
	nSetCommMask,
	nSetupComm,
	nWaitCommEvent,
	nGetOverlappedResult,
	nCreateEvent,
	nResetEvent syscall.Handle
)

func init() {
	k32, err := syscall.LoadLibrary("kernel32.dll")
	if err != 0 {
		panic("LoadLibrary " + syscall.Errstr(err))
	}
	defer syscall.FreeLibrary(k32)

	nSetCommState = getProcAddr(k32, "SetCommState")
	nSetCommTimeouts = getProcAddr(k32, "SetCommTimeouts")
	nSetCommMask = getProcAddr(k32, "SetCommMask")
	nSetupComm = getProcAddr(k32, "SetupComm")
	nWaitCommEvent = getProcAddr(k32, "WaitCommEvent")
	nGetOverlappedResult = getProcAddr(k32, "GetOverlappedResult")
	nCreateEvent = getProcAddr(k32, "CreateEventW")
	nResetEvent = getProcAddr(k32, "ResetEvent")
}

func getProcAddr(lib syscall.Handle, name string) syscall.Handle {
	addr, err := syscall.GetProcAddress(lib, name)
	if err != 0 {
		panic(name + " " + syscall.Errstr(err))
	}
	return addr
}

func errno(e uintptr) os.Error {
	if e != 0 {
		return os.Errno(e)
	}
	return os.Errno(syscall.EINVAL)
}

func setCommState(h syscall.Handle, baud int) os.Error {
	var params structDCB
	params.DCBlength = uint32(unsafe.Sizeof(params))

	params.flags[0] = 0x01  // fBinary
	params.flags[0] |= 0x10 // Assert DSR

	params.BaudRate = uint32(baud)
	params.ByteSize = 8

	r, _, e := syscall.Syscall(uintptr(nSetCommState), 2, uintptr(h), uintptr(unsafe.Pointer(&params)), 0)
	if r == 0 {
		return errno(e)
	}
	return nil
}

func setCommTimeouts(h syscall.Handle) os.Error {
	var timeouts structTimeouts
	timeouts.ReadIntervalTimeout = 1<<32 - 1
	timeouts.ReadTotalTimeoutConstant = 0
	r, _, e := syscall.Syscall(uintptr(nSetCommTimeouts), 2, uintptr(h), uintptr(unsafe.Pointer(&timeouts)), 0)
	if r == 0 {
		return errno(e)
	}
	return nil
}

func setupComm(h syscall.Handle, in, out int) os.Error {
	r, _, e := syscall.Syscall(uintptr(nSetupComm), 3, uintptr(h), uintptr(in), uintptr(out))
	if r == 0 {
		return errno(e)
	}
	return nil
}

func setCommMask(h syscall.Handle) os.Error {
	const EV_RXCHAR = 0x0001
	r, _, e := syscall.Syscall(uintptr(nSetCommMask), 2, uintptr(h), EV_RXCHAR, 0)
	if r == 0 {
		return errno(e)
	}
	return nil
}

func resetEvent(h syscall.Handle) os.Error {
	r, _, e := syscall.Syscall(uintptr(nResetEvent), 1, uintptr(h), 0, 0)
	if r == 0 {
		return errno(e)
	}
	return nil
}

func newOverlapped() (*syscall.Overlapped, os.Error) {
	var overlapped syscall.Overlapped
	r, _, e := syscall.Syscall6(uintptr(nCreateEvent), 4, 0, 1, 0, 0, 0, 0)
	if r == 0 {
		return nil, errno(e)
	}
	overlapped.HEvent = syscall.Handle(r)
	return &overlapped, nil
}

func getOverlappedResult(h syscall.Handle, overlapped *syscall.Overlapped) (int, os.Error) {
	var n int
	r, _, e := syscall.Syscall6(uintptr(nGetOverlappedResult), 4,
		uintptr(h),
		uintptr(unsafe.Pointer(overlapped)),
		uintptr(unsafe.Pointer(&n)), 1, 0, 0)
	if r == 0 {
		return n, errno(e)
	}

	return n, nil
}

func waitCommEvent(h syscall.Handle, events *uint32, overlapped *syscall.Overlapped) os.Error {
	r, _, e := syscall.Syscall(uintptr(nWaitCommEvent), 3, uintptr(h), uintptr(unsafe.Pointer(events)), uintptr(unsafe.Pointer(overlapped)))
	if r == 0 {
		return errno(e)
	}

	return nil
}
<commit_msg>Remove waitCommEvent<commit_after>package serial

import (
	"fmt"
	"io"
	"os"
	"sync"
	"syscall"
	"unsafe"
)

type serialPort struct {
	f  *os.File
	fd syscall.Handle
	rl sync.Mutex
	wl sync.Mutex
	ro *syscall.Overlapped
	wo *syscall.Overlapped
}

type structDCB struct {
	DCBlength, BaudRate                            uint32
	flags                                          [4]byte
	wReserved, XonLim, XoffLim                     uint16
	ByteSize, Parity, StopBits                     byte
	XonChar, XoffChar, ErrorChar, EofChar, EvtChar byte
	wReserved1                                     uint16
}

type structTimeouts struct {
	ReadIntervalTimeout         uint32
	ReadTotalTimeoutMultiplier  uint32
	ReadTotalTimeoutConstant    uint32
	WriteTotalTimeoutMultiplier uint32
	WriteTotalTimeoutConstant   uint32
}

func OpenPort(name string, baud int) (rwc io.ReadWriteCloser, err os.Error) {
	if len(name) > 0 && name[0] != '\\' {
		name = "\\\\.\\" + name
	}

	const FILE_FLAGS_OVERLAPPED = 0x40000000
	h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(name),
		syscall.GENERIC_READ|syscall.GENERIC_WRITE,
		0,
		nil,
		syscall.OPEN_EXISTING,
		syscall.FILE_ATTRIBUTE_NORMAL|FILE_FLAGS_OVERLAPPED,
		0)
	if e != 0 {
		err = &os.PathError{"open", name, os.Errno(e)}
		return
	}
	f := os.NewFile(h, name)
	defer func() {
		if err != nil {
			f.Close()
		}
	}()

	if err = setCommState(h, baud); err != nil {
		return
	}
	if err = setupComm(h, 64, 64); err != nil {
		return
	}
	if err = setCommTimeouts(h); err != nil {
		return
	}
	if err = setCommMask(h); err != nil {
		return
	}

	ro, err := newOverlapped()
	if err != nil {
		return
	}
	wo, err := newOverlapped()
	if err != nil {
		return
	}
	port := new(serialPort)
	port.f = f
	port.fd = h
	port.ro = ro
	port.wo = wo

	return port, nil
}

func (p *serialPort) Close() os.Error {
	return p.f.Close()
}

func (p *serialPort) Write(buf []byte) (int, os.Error) {
	p.wl.Lock()
	defer p.wl.Unlock()

	if err := resetEvent(p.wo.HEvent); err != nil {
		return 0, err
	}
	var n uint32
	e := syscall.WriteFile(p.fd, buf, &n, p.wo)
	if e != 0 && e != syscall.ERROR_IO_PENDING {
		return int(n), errno(uintptr(e))
	}
	return getOverlappedResult(p.fd, p.wo)
}

func (p *serialPort) Read(buf []byte) (int, os.Error) {
	if p == nil || p.f == nil {
		return 0, fmt.Errorf("Invalid port on read %v %v", p, p.f)
	}

	p.rl.Lock()
	defer p.rl.Unlock()

	if err := resetEvent(p.ro.HEvent); err != nil {
		return 0, err
	}
	var done uint32
	e := syscall.ReadFile(p.fd, buf, &done, p.ro)
	if e != 0 && e != syscall.ERROR_IO_PENDING {
		return int(done), errno(uintptr(e))
	}
	return getOverlappedResult(p.fd, p.ro)
}

var (
	nSetCommState,
	nSetCommTimeouts,
	nSetCommMask,
	nSetupComm,
	nGetOverlappedResult,
	nCreateEvent,
	nResetEvent syscall.Handle
)

func init() {
	k32, err := syscall.LoadLibrary("kernel32.dll")
	if err != 0 {
		panic("LoadLibrary " + syscall.Errstr(err))
	}
	defer syscall.FreeLibrary(k32)

	nSetCommState = getProcAddr(k32, "SetCommState")
	nSetCommTimeouts = getProcAddr(k32, "SetCommTimeouts")
	nSetCommMask = getProcAddr(k32, "SetCommMask")
	nSetupComm = getProcAddr(k32, "SetupComm")
	nGetOverlappedResult = getProcAddr(k32, "GetOverlappedResult")
	nCreateEvent = getProcAddr(k32, "CreateEventW")
	nResetEvent = getProcAddr(k32, "ResetEvent")
}

func getProcAddr(lib syscall.Handle, name string) syscall.Handle {
	addr, err := syscall.GetProcAddress(lib, name)
	if err != 0 {
		panic(name + " " + syscall.Errstr(err))
	}
	return addr
}

func errno(e uintptr) os.Error {
	if e != 0 {
		return os.Errno(e)
	}
	return os.Errno(syscall.EINVAL)
}

func setCommState(h syscall.Handle, baud int) os.Error {
	var params structDCB
	params.DCBlength = uint32(unsafe.Sizeof(params))

	params.flags[0] = 0x01  // fBinary
	params.flags[0] |= 0x10 // Assert DSR

	params.BaudRate = uint32(baud)
	params.ByteSize = 8

	r, _, e := syscall.Syscall(uintptr(nSetCommState), 2, uintptr(h), uintptr(unsafe.Pointer(&params)), 0)
	if r == 0 {
		return errno(e)
	}
	return nil
}

func setCommTimeouts(h syscall.Handle) os.Error {
	var timeouts structTimeouts
	timeouts.ReadIntervalTimeout = 1<<32 - 1
	timeouts.ReadTotalTimeoutConstant = 0
	r, _, e := syscall.Syscall(uintptr(nSetCommTimeouts), 2, uintptr(h), uintptr(unsafe.Pointer(&timeouts)), 0)
	if r == 0 {
		return errno(e)
	}
	return nil
}

func setupComm(h syscall.Handle, in, out int) os.Error {
	r, _, e := syscall.Syscall(uintptr(nSetupComm), 3, uintptr(h), uintptr(in), uintptr(out))
	if r == 0 {
		return errno(e)
	}
	return nil
}

func setCommMask(h syscall.Handle) os.Error {
	const EV_RXCHAR = 0x0001
	r, _, e := syscall.Syscall(uintptr(nSetCommMask), 2, uintptr(h), EV_RXCHAR, 0)
	if r == 0 {
		return errno(e)
	}
	return nil
}

func resetEvent(h syscall.Handle) os.Error {
	r, _, e := syscall.Syscall(uintptr(nResetEvent), 1, uintptr(h), 0, 0)
	if r == 0 {
		return errno(e)
	}
	return nil
}

func newOverlapped() (*syscall.Overlapped, os.Error) {
	var overlapped syscall.Overlapped
	r, _, e := syscall.Syscall6(uintptr(nCreateEvent), 4, 0, 1, 0, 0, 0, 0)
	if r == 0 {
		return nil, errno(e)
	}
	overlapped.HEvent = syscall.Handle(r)
	return &overlapped, nil
}

func getOverlappedResult(h syscall.Handle, overlapped *syscall.Overlapped) (int, os.Error) {
	var n int
	r, _, e := syscall.Syscall6(uintptr(nGetOverlappedResult), 4,
		uintptr(h),
		uintptr(unsafe.Pointer(overlapped)),
		uintptr(unsafe.Pointer(&n)), 1, 0, 0)
	if r == 0 {
		return n, errno(e)
	}

	return n, nil
}
<|endoftext|>


<commit_before>package domain

import (
	"time"

	log "github.com/Sirupsen/logrus"
)

// BackupState represents a backup state executed by backoops
type BackupState struct {
	Items []BackupItemState
}

// BackupItemState represents the state of a backup item
type BackupItemState struct {
	BackupSpec
	Checksum   string
	LastBackup *time.Time
}

type updateReport struct {
	Created   int
	Unchanged int
	Deleted   int
}

// NewBackupState returns a new BackupState.
// Use it to initialize a new backup item.
func NewBackupState(config BackupConfig) BackupState {
	backupState := BackupState{}
	backupState.Update(config)

	return backupState
}

// Update a BackupState from a config and log the report
func (b *BackupState) Update(config BackupConfig) {

	report := updateReport{}

	// this value will be decremented for each item found
	report.Deleted = len(b.Items)

	// map the checksums to each item
	itemsByChecksum := map[string]BackupItemState{}
	for i := range b.Items {
		itemsByChecksum[b.Items[i].Checksum] = b.Items[i]
	}

	items := []BackupItemState{}
	for _, backup := range config.Backups {

		checksum := backup.GetChecksum()
		var backupState BackupItemState

		// search if the item already exists
		if existingState, ok := itemsByChecksum[checksum]; ok {
			backupState = existingState

			report.Unchanged++
			report.Deleted--
		} else {
			backupState = BackupItemState{
				BackupSpec: backup,
				Checksum:   checksum,
				LastBackup: nil,
			}
			report.Created++
		}

		items = append(items, backupState)
	}

	b.Items = items

	log.WithFields(log.Fields{
		"name":      config.Name,
		"created":   report.Created,
		"unchanged": report.Unchanged,
		"deleted":   report.Deleted,
	}).Infoln("Backup successfully configured")

}
<commit_msg>Limit logs<commit_after>package domain

import (
	"time"

	log "github.com/Sirupsen/logrus"
)

// BackupState represents a backup state executed by backoops
type BackupState struct {
	Items []BackupItemState
}

// BackupItemState represents the state of a backup item
type BackupItemState struct {
	BackupSpec
	Checksum   string
	LastBackup *time.Time
}

type updateReport struct {
	Created   int
	Unchanged int
	Deleted   int
}

// NewBackupState returns a new BackupState.
// Use it to initialize a new backup item.
func NewBackupState(config BackupConfig) BackupState {
	backupState := BackupState{}
	backupState.Update(config)

	return backupState
}

// Update a BackupState from a config and log the report
func (b *BackupState) Update(config BackupConfig) {

	report := updateReport{}

	// this value will be decremented for each item found
	report.Deleted = len(b.Items)

	// map the checksums to each item
	itemsByChecksum := map[string]BackupItemState{}
	for i := range b.Items {
		itemsByChecksum[b.Items[i].Checksum] = b.Items[i]
	}

	items := []BackupItemState{}
	for _, backup := range config.Backups {

		checksum := backup.GetChecksum()
		var backupState BackupItemState

		// search if the item already exists
		if existingState, ok := itemsByChecksum[checksum]; ok {
			backupState = existingState

			report.Unchanged++
			report.Deleted--
		} else {
			backupState = BackupItemState{
				BackupSpec: backup,
				Checksum:   checksum,
				LastBackup: nil,
			}
			report.Created++
		}

		items = append(items, backupState)
	}

	b.Items = items

	// log only when a config has been updated
	if report.Created > 0 || report.Deleted > 0 {
		log.WithFields(log.Fields{
			"name":      config.Name,
			"created":   report.Created,
			"unchanged": report.Unchanged,
			"deleted":   report.Deleted,
		}).Infoln("Backup successfully configured")
	}

}
<|endoftext|>