<commit_before>package main

// An example of shifting 8 bit data to a TLC5940 shift register.
// Implements a continuous 8-bit binary counter.

import (
	"hwio"
	"fmt"
)

func main() {
	// Get the pins we're going to use. These are on a beaglebone.
	sinPin, _ := hwio.GetPin("P9.11")
	sclkPin, _ := hwio.GetPin("P9.12")
	xlatPin, _ := hwio.GetPin("P9.13")
	gsclkPin, _ := hwio.GetPin("P9.14")
	blankPin, _ := hwio.GetPin("P9.15")

	fmt.Printf("Pins are: sin=%d, sclk=%d, xlat=%d, gsclk=%d, blank=%d", sinPin, sclkPin, xlatPin, gsclkPin, blankPin)
	// Make them all outputs
	e := hwio.PinMode(sinPin, hwio.OUTPUT)
	if e == nil {
		hwio.PinMode(sclkPin, hwio.OUTPUT)
	}
	if e == nil {
		hwio.PinMode(xlatPin, hwio.OUTPUT)
	}
	if e == nil {
		hwio.PinMode(gsclkPin, hwio.OUTPUT)
	}
	if e == nil {
		hwio.PinMode(blankPin, hwio.OUTPUT)
	}
	if e != nil {
		fmt.Printf("Could not initialise pins: %s", e)
		return
	}

	// set clocks low
	hwio.DigitalWrite(sclkPin, hwio.LOW)
	hwio.DigitalWrite(xlatPin, hwio.LOW)
	hwio.DigitalWrite(gsclkPin, hwio.LOW)

	// run GS clock in it's own space
//	go func() {
		hwio.DigitalWrite(blankPin, hwio.HIGH)
		hwio.DigitalWrite(blankPin, hwio.LOW)
		clockData(gsclkPin)
//	}();

	for b := 0; b < 4096; b++ {
		writeData(uint(b), sinPin, sclkPin, xlatPin)

		for j := 0; j < 10; j++ {
			hwio.DigitalWrite(blankPin, hwio.HIGH)
			hwio.DigitalWrite(blankPin, hwio.LOW)
			clockData(gsclkPin)
		}

//		hwio.Delay(100)
	}

//		hwio.ShiftOut(dataPin, clockPin, uint(data), hwio.MSBFIRST)
}

// val is a 12-bit int
func writeData(val uint, sinPin hwio.Pin, sclkPin hwio.Pin, xlatPin hwio.Pin) {
	fmt.Printf("writing data %d\n", val)
	bits := 0
	mask := uint(1) << 11
	for i := 0; i < 16; i++ {
		v := val
		for j := 0; j < 12; j++ {
			if (v & mask) != 0 {
				hwio.DigitalWrite(sinPin, hwio.HIGH)
			} else {
				hwio.DigitalWrite(sinPin, hwio.HIGH)
			}
			hwio.DigitalWrite(sclkPin, hwio.HIGH)
			hwio.DigitalWrite(sclkPin, hwio.LOW)

			v = v << 1
			bits++
		}
	}

	hwio.DigitalWrite(xlatPin, hwio.HIGH)
	hwio.DigitalWrite(xlatPin, hwio.LOW)
	fmt.Printf("Wrote %d bits\n", bits)
}

func clockData(gsclkPin hwio.Pin) {
	for g :=0; g < 4096; g++ {
		hwio.DigitalWrite(gsclkPin, hwio.HIGH)
		hwio.DigitalWrite(gsclkPin, hwio.LOW)
	}
}

<commit_msg>cleanup<commit_after>package main

// An example of shifting 8 bit data to a TLC5940 shift register.
// Implements a continuous 8-bit binary counter.

import (
	"hwio"
	"fmt"
)

func main() {
	// Get the pins we're going to use. These are on a beaglebone.
	sinPin, _ := hwio.GetPin("P9.11")
	sclkPin, _ := hwio.GetPin("P9.12")
	xlatPin, _ := hwio.GetPin("P9.13")
	gsclkPin, _ := hwio.GetPin("P9.14")
	blankPin, _ := hwio.GetPin("P9.15")

	fmt.Printf("Pins are: sin=%d, sclk=%d, xlat=%d, gsclk=%d, blank=%d", sinPin, sclkPin, xlatPin, gsclkPin, blankPin)
	// Make them all outputs
	e := hwio.PinMode(sinPin, hwio.OUTPUT)
	if e == nil {
		hwio.PinMode(sclkPin, hwio.OUTPUT)
	}
	if e == nil {
		hwio.PinMode(xlatPin, hwio.OUTPUT)
	}
	if e == nil {
		hwio.PinMode(gsclkPin, hwio.OUTPUT)
	}
	if e == nil {
		hwio.PinMode(blankPin, hwio.OUTPUT)
	}
	if e != nil {
		fmt.Printf("Could not initialise pins: %s", e)
		return
	}

	// set clocks low
	hwio.DigitalWrite(sclkPin, hwio.LOW)
	hwio.DigitalWrite(xlatPin, hwio.LOW)
	hwio.DigitalWrite(gsclkPin, hwio.LOW)

	// run GS clock in it's own space
	hwio.DigitalWrite(blankPin, hwio.HIGH)
	hwio.DigitalWrite(blankPin, hwio.LOW)
	clockData(gsclkPin)

	for b := 0; b < 4096; b++ {
		writeData(uint(b), sinPin, sclkPin, xlatPin)

		for j := 0; j < 10; j++ {
			hwio.DigitalWrite(blankPin, hwio.HIGH)
			hwio.DigitalWrite(blankPin, hwio.LOW)
			clockData(gsclkPin)
		}

//		hwio.Delay(100)
	}

//		hwio.ShiftOut(dataPin, clockPin, uint(data), hwio.MSBFIRST)
}

// val is a 12-bit int
func writeData(val uint, sinPin hwio.Pin, sclkPin hwio.Pin, xlatPin hwio.Pin) {
	fmt.Printf("writing data %d\n", val)
	bits := 0
	mask := uint(1) << 11
	for i := 0; i < 16; i++ {
		v := val
		for j := 0; j < 12; j++ {
			if (v & mask) != 0 {
				hwio.DigitalWrite(sinPin, hwio.HIGH)
			} else {
				hwio.DigitalWrite(sinPin, hwio.HIGH)
			}
			hwio.DigitalWrite(sclkPin, hwio.HIGH)
			hwio.DigitalWrite(sclkPin, hwio.LOW)

			v = v << 1
			bits++
		}
	}

	hwio.DigitalWrite(xlatPin, hwio.HIGH)
	hwio.DigitalWrite(xlatPin, hwio.LOW)
	fmt.Printf("Wrote %d bits\n", bits)
}

func clockData(gsclkPin hwio.Pin) {
	for g :=0; g < 4096; g++ {
		hwio.DigitalWrite(gsclkPin, hwio.HIGH)
		hwio.DigitalWrite(gsclkPin, hwio.LOW)
	}
}

<|endoftext|>


<commit_before>package rpc

import (
	"errors"
	"fmt"
	zmq "github.com/pebbe/zmq4"
	"log"
)

type Server struct {
	id            string
	address       string
	port          int
	running       bool
	remoteSocket  *zmq.Socket
	workersSocket *zmq.Socket
}

func NewServer(address string, port int) *Server {
	server := &Server{
		id:      fmt.Sprintf("%s:%d", address, port),
		address: address,
		port:    port,
	}

	return server
}

func (s *Server) Start() error {
	var err error

	log.Println("Starting the server")

	s.remoteSocket, err = zmq.NewSocket(zmq.ROUTER)
	if err != nil {
		return err
	}

	s.remoteSocket.Bind(fmt.Sprintf("tcp://%s:%d", s.address, s.port))
	if err != nil {
		return err
	}

	s.workersSocket, err = zmq.NewSocket(zmq.ROUTER)
	if err != nil {
		return err
	}

	err = s.workersSocket.Bind("inproc://" + s.id)
	if err != nil {
		return err
	}

	poller := zmq.NewPoller()
	poller.Add(s.remoteSocket, zmq.POLLIN)
	poller.Add(s.workersSocket, zmq.POLLIN)

	s.running = true

	for s.running {
		polled, err := poller.Poll(100)
		if err != nil {
			// TODO Log a warning
		}

		if len(polled) > 0 {
			s.handleSockets(polled)
		}
	}

	return nil
}

func (s *Server) Stop() error {
	log.Println("Stopping the server")

	if !s.running {
		return errors.New("Server is already stopped")
	}

	s.running = false
	return nil
}

func (s *Server) handleSockets(polled []zmq.Polled) {
	for _, p := range polled {
		switch socket := p.Socket; socket {
		case s.remoteSocket:
			s.handleRemoteSocket()
		case s.workersSocket:
			s.handleWorkersSocket()
		}
	}
}

func (s *Server) handleRemoteSocket() {
	// TODO Receive message and route it to one of available workers
}

func (s *Server) handleWorkersSocket() {
	// TODO Receive message and route it back to the remote client
}

func (s *Server) Id() string {
	return s.id
}

func (s *Server) Address() string {
	return s.address
}

func (s *Server) Port() int {
	return s.port
}
<commit_msg>Cosmetics.<commit_after>package rpc

import (
	"errors"
	"fmt"
	zmq "github.com/pebbe/zmq4"
	"log"
)

type Server struct {
	id      string
	address string
	port    int
	running bool

	remoteSocket  *zmq.Socket
	workersSocket *zmq.Socket
}

func NewServer(address string, port int) *Server {
	server := &Server{
		id:      fmt.Sprintf("%s:%d", address, port),
		address: address,
		port:    port,
	}

	return server
}

func (s *Server) Start() error {
	var err error

	log.Println("Starting the server")

	s.remoteSocket, err = zmq.NewSocket(zmq.ROUTER)
	if err != nil {
		return err
	}

	s.remoteSocket.Bind(fmt.Sprintf("tcp://%s:%d", s.address, s.port))
	if err != nil {
		return err
	}

	s.workersSocket, err = zmq.NewSocket(zmq.ROUTER)
	if err != nil {
		return err
	}

	err = s.workersSocket.Bind("inproc://" + s.id)
	if err != nil {
		return err
	}

	poller := zmq.NewPoller()
	poller.Add(s.remoteSocket, zmq.POLLIN)
	poller.Add(s.workersSocket, zmq.POLLIN)

	s.running = true

	for s.running {
		polled, err := poller.Poll(100)
		if err != nil {
			// TODO Log a warning
		}

		if len(polled) > 0 {
			s.handleSockets(polled)
		}
	}

	return nil
}

func (s *Server) Stop() error {
	log.Println("Stopping the server")

	if !s.running {
		return errors.New("Server is already stopped")
	}

	s.running = false
	return nil
}

func (s *Server) handleSockets(polled []zmq.Polled) {
	for _, p := range polled {
		switch socket := p.Socket; socket {
		case s.remoteSocket:
			s.handleRemoteSocket()
		case s.workersSocket:
			s.handleWorkersSocket()
		}
	}
}

func (s *Server) handleRemoteSocket() {
	// TODO Receive message and route it to one of available workers
}

func (s *Server) handleWorkersSocket() {
	// TODO Receive message and route it back to the remote client
}

func (s *Server) Id() string {
	return s.id
}

func (s *Server) Address() string {
	return s.address
}

func (s *Server) Port() int {
	return s.port
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"restic/errors"
	"sort"

	"github.com/spf13/cobra"

	"encoding/json"
	"restic"
)

var cmdSnapshots = &cobra.Command{
	Use:   "snapshots",
	Short: "list all snapshots",
	Long: `
The "snapshots" command lists all snapshots stored in the repository.
`,
	RunE: func(cmd *cobra.Command, args []string) error {
		return runSnapshots(snapshotOptions, globalOptions, args)
	},
}

// SnapshotOptions bundle all options for the snapshots command.
type SnapshotOptions struct {
	Host  string
	Paths []string
}

var snapshotOptions SnapshotOptions

func init() {
	cmdRoot.AddCommand(cmdSnapshots)

	f := cmdSnapshots.Flags()
	f.StringVar(&snapshotOptions.Host, "host", "", "only print snapshots for this host")
	f.StringSliceVar(&snapshotOptions.Paths, "path", []string{}, "only print snapshots for this `path` (can be specified multiple times)")
}

func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) error {
	if len(args) != 0 {
		return errors.Fatal("wrong number of arguments")
	}

	repo, err := OpenRepository(gopts)
	if err != nil {
		return err
	}

	if !gopts.NoLock {
		lock, err := lockRepo(repo)
		defer unlockRepo(lock)
		if err != nil {
			return err
		}
	}

	done := make(chan struct{})
	defer close(done)

	list := []*restic.Snapshot{}
	for id := range repo.List(restic.SnapshotFile, done) {
		sn, err := restic.LoadSnapshot(repo, id)
		if err != nil {
			Warnf("error loading snapshot %s: %v\n", id, err)
			continue
		}

		if restic.SamePaths(sn.Paths, opts.Paths) && (opts.Host == "" || opts.Host == sn.Hostname) {
			pos := sort.Search(len(list), func(i int) bool {
				return list[i].Time.After(sn.Time)
			})

			if pos < len(list) {
				list = append(list, nil)
				copy(list[pos+1:], list[pos:])
				list[pos] = sn
			} else {
				list = append(list, sn)
			}
		}

	}

	if gopts.JSON {
		err := printSnapshotsJSON(gopts.stdout, list)
		if err != nil {
			Warnf("error printing snapshot: %v\n", err)
		}
		return nil
	}
	printSnapshotsReadable(gopts.stdout, list)

	return nil
}

// printSnapshotsReadable prints a text table of the snapshots in list to stdout.
func printSnapshotsReadable(stdout io.Writer, list []*restic.Snapshot) {

	// Determine the max widths for host and tag.
	maxHost, maxTag := 10, 6
	for _, sn := range list {
		if len(sn.Hostname) > maxHost {
			maxHost = len(sn.Hostname)
		}
		for _, tag := range sn.Tags {
			if len(tag) > maxTag {
				maxTag = len(tag)
			}
		}
	}

	tab := NewTable()
	tab.Header = fmt.Sprintf("%-8s  %-19s  %-*s  %-*s  %-3s %s", "ID", "Date", -maxHost, "Host", -maxTag, "Tags", "", "Directory")
	tab.RowFormat = fmt.Sprintf("%%-8s  %%-19s  %%%ds  %%%ds  %%-3s %%s", -maxHost, -maxTag)

	for _, sn := range list {
		if len(sn.Paths) == 0 {
			continue
		}

		firstTag := ""
		if len(sn.Tags) > 0 {
			firstTag = sn.Tags[0]
		}

		rows := len(sn.Paths)

		treeElement := "   "
		if rows != 1 {
			treeElement = "┌──"
		}

		tab.Rows = append(tab.Rows, []interface{}{sn.ID().Str(), sn.Time.Format(TimeFormat), sn.Hostname, firstTag, treeElement, sn.Paths[0]})

		if len(sn.Tags) > rows {
			rows = len(sn.Tags)
		}

		for i := 1; i < rows; i++ {
			path := ""
			if len(sn.Paths) > i {
				path = sn.Paths[i]
			}

			tag := ""
			if len(sn.Tags) > i {
				tag = sn.Tags[i]
			}

			treeElement := "│"
			if i == (rows - 1) {
				treeElement = "└──"
			}

			tab.Rows = append(tab.Rows, []interface{}{"", "", "", tag, treeElement, path})
		}
	}

	tab.Write(stdout)
}

// Snapshot helps to print Snaphots as JSON
type Snapshot struct {
	*restic.Snapshot

	ID *restic.ID `json:"id"`
}

// printSnapshotsJSON writes the JSON representation of list to stdout.
func printSnapshotsJSON(stdout io.Writer, list []*restic.Snapshot) error {

	var snapshots []Snapshot

	for _, sn := range list {

		k := Snapshot{
			Snapshot: sn,
			ID:       sn.ID(),
		}
		snapshots = append(snapshots, k)
	}

	return json.NewEncoder(stdout).Encode(snapshots)

}
<commit_msg>Fix layout issue in cmd_snapshot "ascii art"<commit_after>package main

import (
	"fmt"
	"io"
	"restic/errors"
	"sort"

	"github.com/spf13/cobra"

	"encoding/json"
	"restic"
)

var cmdSnapshots = &cobra.Command{
	Use:   "snapshots",
	Short: "list all snapshots",
	Long: `
The "snapshots" command lists all snapshots stored in the repository.
`,
	RunE: func(cmd *cobra.Command, args []string) error {
		return runSnapshots(snapshotOptions, globalOptions, args)
	},
}

// SnapshotOptions bundle all options for the snapshots command.
type SnapshotOptions struct {
	Host  string
	Paths []string
}

var snapshotOptions SnapshotOptions

func init() {
	cmdRoot.AddCommand(cmdSnapshots)

	f := cmdSnapshots.Flags()
	f.StringVar(&snapshotOptions.Host, "host", "", "only print snapshots for this host")
	f.StringSliceVar(&snapshotOptions.Paths, "path", []string{}, "only print snapshots for this `path` (can be specified multiple times)")
}

func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) error {
	if len(args) != 0 {
		return errors.Fatal("wrong number of arguments")
	}

	repo, err := OpenRepository(gopts)
	if err != nil {
		return err
	}

	if !gopts.NoLock {
		lock, err := lockRepo(repo)
		defer unlockRepo(lock)
		if err != nil {
			return err
		}
	}

	done := make(chan struct{})
	defer close(done)

	list := []*restic.Snapshot{}
	for id := range repo.List(restic.SnapshotFile, done) {
		sn, err := restic.LoadSnapshot(repo, id)
		if err != nil {
			Warnf("error loading snapshot %s: %v\n", id, err)
			continue
		}

		if restic.SamePaths(sn.Paths, opts.Paths) && (opts.Host == "" || opts.Host == sn.Hostname) {
			pos := sort.Search(len(list), func(i int) bool {
				return list[i].Time.After(sn.Time)
			})

			if pos < len(list) {
				list = append(list, nil)
				copy(list[pos+1:], list[pos:])
				list[pos] = sn
			} else {
				list = append(list, sn)
			}
		}

	}

	if gopts.JSON {
		err := printSnapshotsJSON(gopts.stdout, list)
		if err != nil {
			Warnf("error printing snapshot: %v\n", err)
		}
		return nil
	}
	printSnapshotsReadable(gopts.stdout, list)

	return nil
}

// printSnapshotsReadable prints a text table of the snapshots in list to stdout.
func printSnapshotsReadable(stdout io.Writer, list []*restic.Snapshot) {

	// Determine the max widths for host and tag.
	maxHost, maxTag := 10, 6
	for _, sn := range list {
		if len(sn.Hostname) > maxHost {
			maxHost = len(sn.Hostname)
		}
		for _, tag := range sn.Tags {
			if len(tag) > maxTag {
				maxTag = len(tag)
			}
		}
	}

	tab := NewTable()
	tab.Header = fmt.Sprintf("%-8s  %-19s  %-*s  %-*s  %-3s %s", "ID", "Date", -maxHost, "Host", -maxTag, "Tags", "", "Directory")
	tab.RowFormat = fmt.Sprintf("%%-8s  %%-19s  %%%ds  %%%ds  %%-3s %%s", -maxHost, -maxTag)

	for _, sn := range list {
		if len(sn.Paths) == 0 {
			continue
		}

		firstTag := ""
		if len(sn.Tags) > 0 {
			firstTag = sn.Tags[0]
		}

		rows := len(sn.Paths)
		if rows < len(sn.Tags) {
			rows = len(sn.Tags)
		}

		treeElement := "   "
		if rows != 1 {
			treeElement = "┌──"
		}

		tab.Rows = append(tab.Rows, []interface{}{sn.ID().Str(), sn.Time.Format(TimeFormat), sn.Hostname, firstTag, treeElement, sn.Paths[0]})

		if len(sn.Tags) > rows {
			rows = len(sn.Tags)
		}

		for i := 1; i < rows; i++ {
			path := ""
			if len(sn.Paths) > i {
				path = sn.Paths[i]
			}

			tag := ""
			if len(sn.Tags) > i {
				tag = sn.Tags[i]
			}

			treeElement := "│"
			if i == (rows - 1) {
				treeElement = "└──"
			}

			tab.Rows = append(tab.Rows, []interface{}{"", "", "", tag, treeElement, path})
		}
	}

	tab.Write(stdout)
}

// Snapshot helps to print Snaphots as JSON
type Snapshot struct {
	*restic.Snapshot

	ID *restic.ID `json:"id"`
}

// printSnapshotsJSON writes the JSON representation of list to stdout.
func printSnapshotsJSON(stdout io.Writer, list []*restic.Snapshot) error {

	var snapshots []Snapshot

	for _, sn := range list {

		k := Snapshot{
			Snapshot: sn,
			ID:       sn.ID(),
		}
		snapshots = append(snapshots, k)
	}

	return json.NewEncoder(stdout).Encode(snapshots)

}
<|endoftext|>


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

package save

import (
	"errors"
	"testing"

	"golang.org/x/net/context"

	"github.com/jacobsa/comeback/internal/state"
	. "github.com/jacobsa/ogletest"
	"github.com/jacobsa/timeutil"
)

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

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

type scoreMapTest struct {
	ctx      context.Context
	scoreMap state.ScoreMap
	clock    timeutil.Clock

	node fsNode
}

var _ SetUpInterface = &scoreMapTest{}

func (t *scoreMapTest) SetUp(ti *TestInfo) {
	t.ctx = ti.Ctx
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// makeScoreMapKey
////////////////////////////////////////////////////////////////////////

type MakeScoreMapKeyTest struct {
	scoreMapTest
}

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

func (t *MakeScoreMapKeyTest) Directory() {
	AssertTrue(false, "TODO")
}

func (t *MakeScoreMapKeyTest) Symlink() {
	AssertTrue(false, "TODO")
}

func (t *MakeScoreMapKeyTest) RecentlyModified() {
	AssertTrue(false, "TODO")
}

func (t *MakeScoreMapKeyTest) ModifiedInFuture() {
	AssertTrue(false, "TODO")
}

func (t *MakeScoreMapKeyTest) Valid() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// consultScoreMap
////////////////////////////////////////////////////////////////////////

type ConsultScoreMapTest struct {
	scoreMapTest
}

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

func (t *ConsultScoreMapTest) call() (err error) {
	err = errors.New("TODO")
	return
}

func (t *ConsultScoreMapTest) DoesFoo() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// updateScoreMap
////////////////////////////////////////////////////////////////////////

type UpdateScoreMapTest struct {
	scoreMapTest
}

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

func (t *UpdateScoreMapTest) call() (err error) {
	err = errors.New("TODO")
	return
}

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

package save

import (
	"errors"
	"testing"

	"golang.org/x/net/context"

	"github.com/jacobsa/comeback/internal/state"
	. "github.com/jacobsa/ogletest"
	"github.com/jacobsa/timeutil"
)

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

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

type scoreMapTest struct {
	ctx      context.Context
	scoreMap state.ScoreMap
	clock    timeutil.Clock

	node fsNode
}

var _ SetUpInterface = &scoreMapTest{}

func (t *scoreMapTest) SetUp(ti *TestInfo) {
	t.ctx = ti.Ctx
	t.scoreMap = state.NewScoreMap()
	t.clock = timeutil.RealClock()
}

////////////////////////////////////////////////////////////////////////
// makeScoreMapKey
////////////////////////////////////////////////////////////////////////

type MakeScoreMapKeyTest struct {
	scoreMapTest
}

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

func (t *MakeScoreMapKeyTest) Directory() {
	AssertTrue(false, "TODO")
}

func (t *MakeScoreMapKeyTest) Symlink() {
	AssertTrue(false, "TODO")
}

func (t *MakeScoreMapKeyTest) RecentlyModified() {
	AssertTrue(false, "TODO")
}

func (t *MakeScoreMapKeyTest) ModifiedInFuture() {
	AssertTrue(false, "TODO")
}

func (t *MakeScoreMapKeyTest) Valid() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// consultScoreMap
////////////////////////////////////////////////////////////////////////

type ConsultScoreMapTest struct {
	scoreMapTest
}

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

func (t *ConsultScoreMapTest) call() (err error) {
	err = errors.New("TODO")
	return
}

func (t *ConsultScoreMapTest) DoesFoo() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// updateScoreMap
////////////////////////////////////////////////////////////////////////

type UpdateScoreMapTest struct {
	scoreMapTest
}

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

func (t *UpdateScoreMapTest) call() (err error) {
	err = errors.New("TODO")
	return
}

func (t *UpdateScoreMapTest) DoesFoo() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


<commit_before>package testutil

import (
	"v.io/x/devtools/internal/collect"
	"v.io/x/devtools/internal/tool"
)

// vanadiumPostsubmitPoll polls for new changes in all projects' master branches,
// and starts the corresponding Jenkins targets based on the changes.
func vanadiumPostsubmitPoll(ctx *tool.Context, testName string, _ ...TestOpt) (_ *TestResult, e error) {
	// Initialize the test.
	cleanup, err := initTest(ctx, testName, nil)
	if err != nil {
		return nil, internalTestError{err, "Init"}
	}
	defer collect.Error(func() error { return cleanup() }, &e)

	// Run the "postsubmit poll" command.
	args := []string{}
	if ctx.Verbose() {
		args = append(args, "-v")
	}
	args = append(args,
		"-host", jenkinsHost,
		"poll",
		"-manifest", "public-mirror",
	)
	if err := ctx.Run().Command("postsubmit", args...); err != nil {
		return nil, err
	}

	return &TestResult{Status: TestPassed}, nil
}
<commit_msg>TBR: postsubmit: fix manifest.<commit_after>package testutil

import (
	"v.io/x/devtools/internal/collect"
	"v.io/x/devtools/internal/tool"
)

// vanadiumPostsubmitPoll polls for new changes in all projects' master branches,
// and starts the corresponding Jenkins targets based on the changes.
func vanadiumPostsubmitPoll(ctx *tool.Context, testName string, _ ...TestOpt) (_ *TestResult, e error) {
	// Initialize the test.
	cleanup, err := initTest(ctx, testName, nil)
	if err != nil {
		return nil, internalTestError{err, "Init"}
	}
	defer collect.Error(func() error { return cleanup() }, &e)

	// Run the "postsubmit poll" command.
	args := []string{}
	if ctx.Verbose() {
		args = append(args, "-v")
	}
	args = append(args,
		"-host", jenkinsHost,
		"poll",
		"-manifest", "mirror/public",
	)
	if err := ctx.Run().Command("postsubmit", args...); err != nil {
		return nil, err
	}

	return &TestResult{Status: TestPassed}, nil
}
<|endoftext|>


<commit_before>package types

import (
	. "github.com/101loops/bdd"

	ae "appengine"
	ds "appengine/datastore"
)

var _ = Describe("Iterator", func() {

	var (
		qry *Query
	)

	BeforeEach(func() {
		qry = NewQuery("my-kind")
	})

	It("should create a new iterator", func() {
		it := NewIterator(ctx, qry)
		Check(it.inner, NotNil)
	})

	It("should return a cursor", func() {
		cursor, err := NewIterator(ctx, qry).Cursor()

		Check(err, IsNil)
		Check(cursor, IsZero)
	})

	It("should return next entity", func() {
		_, err := NewIterator(ctx, qry).Next(func(_ ae.Context) ds.PropertyLoadSaver {
			return nil
		})
		Check(err, Equals, ds.Done)
	})
})
<commit_msg>test error case as well<commit_after>package types

import (
	. "github.com/101loops/bdd"

	ae "appengine"
	ds "appengine/datastore"
)

var _ = Describe("Iterator", func() {

	var (
		qry *Query
	)

	BeforeEach(func() {
		qry = NewQuery("my-kind")
	})

	It("should create a new iterator", func() {
		it := NewIterator(ctx, qry)
		Check(it.inner, NotNil)
	})

	It("should return next entity", func() {
		_, err := NewIterator(ctx, qry).Next(func(_ ae.Context) ds.PropertyLoadSaver {
			return nil
		})
		Check(err, Equals, ds.Done)
	})

	Context("cursor", func() {

		It("should return a cursor", func() {
			cursor, err := NewIterator(ctx, qry).Cursor()

			Check(err, IsNil)
			Check(cursor, IsZero)
		})

		It("should return an error for invalid query", func() {
			qry.Filter = []Filter{Filter{"age !=", 18}}
			cursor, err := NewIterator(ctx, qry).Cursor()

			Check(cursor, IsZero)
			Check(err, HasOccurred).And(Contains, "invalid operator")
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"context"
	"log"
	"net"
	"strconv"
	ip_capnp "zenhack.net/go/sandstorm/capnp/ip"
	"zenhack.net/go/sandstorm/ip"
)

func ipNetworkProxy(
	ctx context.Context,
	netCaps <-chan *ip_capnp.IpNetwork,
	configs <-chan *ServerConfig,
) {

	var (
		config *ServerConfig
		cap    *ip_capnp.IpNetwork
	)

	for config == nil || cap == nil {
		select {
		case config = <-configs:
			cap = <-netCaps
		case cap = <-netCaps:
			config = <-configs
		}
	}

	conns := make(chan net.Conn)
	go ipNetworkListener(conns)

	for {
		log.Printf("Config: %v, Cap: %v", config, cap)
		select {
		case config = <-configs:
		case cap = <-netCaps:
		case zncConn := <-conns:
			log.Printf("Got connection from znc")
			dialer := &ip.IpNetworkDialer{
				Ctx:       ctx,
				IpNetwork: *cap,
			}
			serverConn, err := dialer.Dial(
				"tcp",
				net.JoinHostPort(
					config.Host,
					strconv.Itoa(int(config.Port)),
				),
			)
			if err != nil {
				log.Printf("error connecting to irc server: %v", err)
				zncConn.Close()
				continue
			}
			go copyClose(serverConn, zncConn)
		}
	}
}

func ipNetworkListener(conns chan<- net.Conn) {
	l, err := net.Listen("tcp", ipNetworkAddr)
	chkfatal(err)
	for {
		conn, err := l.Accept()
		if err != nil {
			log.Printf("Error in Accept(): %v")
		}
		conns <- conn
	}
}
<commit_msg>Start ipnetwork proxy right away.<commit_after>package main

import (
	"context"
	"log"
	"net"
	"strconv"
	ip_capnp "zenhack.net/go/sandstorm/capnp/ip"
	"zenhack.net/go/sandstorm/ip"
)

func ipNetworkProxy(
	ctx context.Context,
	netCaps <-chan *ip_capnp.IpNetwork,
	configs <-chan *ServerConfig,
) {

	var (
		config *ServerConfig
		cap    *ip_capnp.IpNetwork
	)

	conns := make(chan net.Conn)
	go ipNetworkListener(conns)

	for {
		log.Printf("Config: %v, Cap: %v", config, cap)
		select {
		case config = <-configs:
		case cap = <-netCaps:
		case zncConn := <-conns:
			if config == nil {
				log.Print("IpNetwork Proxy got a connection " +
					"from ZNC, but we don't have our config yet.")
				zncConn.Close()
				continue
			}
			if cap == nil {
				log.Print("IpNetwork Proxy got a connection " +
					"from ZNC, but we don't have internet access yet.")
				zncConn.Close()
			}
			log.Printf("Got connection from znc")
			dialer := &ip.IpNetworkDialer{
				Ctx:       ctx,
				IpNetwork: *cap,
			}
			serverConn, err := dialer.Dial(
				"tcp",
				net.JoinHostPort(
					config.Host,
					strconv.Itoa(int(config.Port)),
				),
			)
			if err != nil {
				log.Printf("error connecting to irc server: %v", err)
				zncConn.Close()
				continue
			}
			go copyClose(serverConn, zncConn)
		}
	}
}

func ipNetworkListener(conns chan<- net.Conn) {
	l, err := net.Listen("tcp", ipNetworkAddr)
	chkfatal(err)
	for {
		conn, err := l.Accept()
		if err != nil {
			log.Printf("Error in Accept(): %v")
		}
		conns <- conn
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os/exec"
	"io"
	"os"
	"io/ioutil"
	"strings"
	"syscall"
	"fmt"

	"github.com/flynn/go-discover/discover"
)

func main() {
	root := "/var/lib/demo/apps"
	hostname := shell("curl -s icanhazip.com")

	client, err := discover.NewClient()
	if err != nil {
		panic(err)
	}
	set, _ := client.Services("shelf")
	addrs := set.OnlineAddrs()
	if len(addrs) < 1 {
		panic("Shelf is not discoverable")
	}
	shelfHost := addrs[0]

	app := os.Args[2]
	os.MkdirAll(root + "/" + app, 0755)

	fmt.Printf("-----> Building %s on %s ...\n", app, hostname)

	cmd := exec.Command("docker", "run", "-i", "-a=stdin", "-a=stdout", "flynn/slugbuilder", "http://"+shelfHost+"/"+app+".tgz")
	errCh := attachCmd(cmd, os.Stdout, os.Stderr, os.Stdin)
	err = cmd.Start()
	if err != nil {
		panic(err)
	}
	exitCh := exitStatusCh(cmd)
	if err = <-errCh; err != nil {
		panic(err)
	}
	<-exitCh

	fmt.Printf("-----> Deploying %s ...\n", app)
	if _, err := os.Stat(root + "/" + app + "/CONTAINER"); err == nil {
    	oldid := readFile(root + "/" + app + "/CONTAINER")
    	shell("docker kill " + oldid)
	}

	id := shell("docker run -d -p 5000 -e PORT=5000 -e SLUG_URL=http://"+shelfHost+"/"+app+".tgz flynn/slugrunner start web")
	writeFile(root + "/" + app + "/CONTAINER", id)
	port := shell("docker port "+id+" 5000 | sed 's/0.0.0.0://'")
	writeFile(root + "/" + app + "/PORT", port)
	writeFile(root + "/" + app + "/URL", "http://"+hostname+":"+port)

	fmt.Printf("=====> Application deployed:\n")
	fmt.Printf("       %s\n", readFile(root + "/" + app + "/URL"))
	fmt.Println("")

}

func readFile(filename string) string {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	return string(data)
}

func writeFile(filename, data string) {
	err := ioutil.WriteFile(filename, []byte(data), 0644)
	if err != nil {
		panic(err)
	}
}

func shell(cmdline string) string {
	out, err := exec.Command("bash", "-c", cmdline).Output()
	if err != nil {
		panic(err)
	}
	return strings.Trim(string(out), " \n")
}

func attachCmd(cmd *exec.Cmd, stdout, stderr io.Writer, stdin io.Reader) chan error {
	errCh := make(chan error)

	stdinIn, err := cmd.StdinPipe()
	if err != nil {
		panic(err)
	}
	stdoutOut, err := cmd.StdoutPipe()
	if err != nil {
		panic(err)
	}
	stderrOut, err := cmd.StderrPipe()
	if err != nil {
		panic(err)
	}

	go func() {
		_, e := io.Copy(stdinIn, stdin)
		errCh <- e
	}()
	go func() {
		_, e := io.Copy(stdout, stdoutOut)
		errCh <- e
	}()
	go func() {
		_, e := io.Copy(stderr, stderrOut)
		errCh <- e
	}()

	return errCh
}

func exitStatusCh(cmd *exec.Cmd) chan uint {
	exitCh := make(chan uint)
	go func() {
		err := cmd.Wait()
		if err != nil {
			if exiterr, ok := err.(*exec.ExitError); ok {
				// There is no plattform independent way to retrieve
				// the exit code, but the following will work on Unix
				if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
					exitCh <- uint(status.ExitStatus())
				}
			} else {
				panic(err)
			}
			return
		}
		exitCh <- uint(0)
	}()
	return exitCh
}<commit_msg>maybe it will work?<commit_after>package main

import (
	"os/exec"
	"io"
	"os"
	"io/ioutil"
	"strings"
	"syscall"
	"fmt"
	"bytes"
    "crypto/rand"
    "encoding/base64"
    "encoding/gob"
    "log"
    "net"

	"github.com/flynn/go-discover/discover"
    "github.com/flynn/lorne/types"
    "github.com/flynn/sampi/client"
    "github.com/flynn/sampi/types"
    "github.com/titanous/go-dockerclient"
)

func main() {
	root := "/var/lib/demo/apps"
	hostname := shell("curl -s icanhazip.com")

	client, err := discover.NewClient()
	if err != nil {
		panic(err)
	}
	set, _ := client.Services("shelf")
	addrs := set.OnlineAddrs()
	if len(addrs) < 1 {
		panic("Shelf is not discoverable")
	}
	shelfHost := addrs[0]

	app := os.Args[2]
	os.MkdirAll(root + "/" + app, 0755)

	fmt.Printf("-----> Building %s on %s ...\n", app, hostname)

	scheduleAndAttach(docker.Config{
        Image:        "flynn/slugbuilder",
        Cmd:          []string{"http://"+shelfHost+"/"+app+".tgz",},
        Tty:          false,
        AttachStdin:  true,
        AttachStdout: true,
        AttachStderr: true,
        OpenStdin:    true,
        StdinOnce:    true,
	})

	/*fmt.Printf("-----> Deploying %s ...\n", app)
	if _, err := os.Stat(root + "/" + app + "/CONTAINER"); err == nil {
    	oldid := readFile(root + "/" + app + "/CONTAINER")
    	shell("docker kill " + oldid)
	}

	id := shell("docker run -d -p 5000 -e PORT=5000 -e SLUG_URL=http://"+shelfHost+"/"+app+".tgz flynn/slugrunner start web")
	writeFile(root + "/" + app + "/CONTAINER", id)
	port := shell("docker port "+id+" 5000 | sed 's/0.0.0.0://'")
	writeFile(root + "/" + app + "/PORT", port)
	writeFile(root + "/" + app + "/URL", "http://"+hostname+":"+port)

	fmt.Printf("=====> Application deployed:\n")
	fmt.Printf("       %s\n", readFile(root + "/" + app + "/URL"))*/
	fmt.Println("")

}

func readFile(filename string) string {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	return string(data)
}

func writeFile(filename, data string) {
	err := ioutil.WriteFile(filename, []byte(data), 0644)
	if err != nil {
		panic(err)
	}
}

func shell(cmdline string) string {
	out, err := exec.Command("bash", "-c", cmdline).Output()
	if err != nil {
		panic(err)
	}
	return strings.Trim(string(out), " \n")
}

func attachCmd(cmd *exec.Cmd, stdout, stderr io.Writer, stdin io.Reader) chan error {
	errCh := make(chan error)

	stdinIn, err := cmd.StdinPipe()
	if err != nil {
		panic(err)
	}
	stdoutOut, err := cmd.StdoutPipe()
	if err != nil {
		panic(err)
	}
	stderrOut, err := cmd.StderrPipe()
	if err != nil {
		panic(err)
	}

	go func() {
		_, e := io.Copy(stdinIn, stdin)
		errCh <- e
	}()
	go func() {
		_, e := io.Copy(stdout, stdoutOut)
		errCh <- e
	}()
	go func() {
		_, e := io.Copy(stderr, stderrOut)
		errCh <- e
	}()

	return errCh
}

func exitStatusCh(cmd *exec.Cmd) chan uint {
	exitCh := make(chan uint)
	go func() {
		err := cmd.Wait()
		if err != nil {
			if exiterr, ok := err.(*exec.ExitError); ok {
				// There is no plattform independent way to retrieve
				// the exit code, but the following will work on Unix
				if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
					exitCh <- uint(status.ExitStatus())
				}
			} else {
				panic(err)
			}
			return
		}
		exitCh <- uint(0)
	}()
	return exitCh
}

func scheduleAndAttach(config docker.Config) {
        disc, err := discover.NewClient()
        if err != nil {
                log.Fatal(err)
        }

        scheduler, err := client.New()
        if err != nil {
                log.Fatal(err)
        }

        state, err := scheduler.State()
        if err != nil {
                log.Fatal(err)
        }

        var firstHost string
        for k := range state {
                firstHost = k
                break
        }
        if firstHost == "" {
                log.Fatal("no hosts")
        }

        id := randomID()

        services, err := disc.Services("flynn-lorne-attach." + firstHost)
        if err != nil {
                log.Fatal(err)
        }
        conn, err := net.Dial("tcp", services.OnlineAddrs()[0])
        if err != nil {
                log.Fatal(err)
        }
        err = gob.NewEncoder(conn).Encode(&lorne.AttachReq{
                JobID:  id,
                Flags:  lorne.AttachFlagStdout | lorne.AttachFlagStderr | lorne.AttachFlagStdin | lorne.AttachFlagStream,
        })
        if err != nil {
                log.Fatal(err)
        }
        attachState := make([]byte, 1)
        if _, err := conn.Read(attachState); err != nil {
                log.Fatal(err)
        }
        switch attachState[0] {
        case lorne.AttachError:
                log.Fatal("attach error")
        }

        schedReq := &sampi.ScheduleReq{
                Incremental: true,
                HostJobs: map[string][]*sampi.Job{firstHost: {{ID: id, Config: &config}}},
        }
        if _, err := scheduler.Schedule(schedReq); err != nil {
                log.Fatal(err)
        }

        if _, err := conn.Read(attachState); err != nil {
                log.Fatal(err)
        }

        go io.Copy(conn, os.Stdin)
        if _, err := io.Copy(os.Stdout, conn); err != nil {
                log.Fatal(err)
        }
}

func randomID() string {
        b := make([]byte, 16)
        enc := make([]byte, 24)
        _, err := io.ReadFull(rand.Reader, b)
        if err != nil {
                panic(err) // This shouldn't ever happen, right?
        }
        base64.URLEncoding.Encode(enc, b)
        return string(bytes.TrimRight(enc, "="))
}
<|endoftext|>


<commit_before>package main

import (
	"os/exec"
	"strings"
	"encoding/gob"
	"fmt"
	"bufio"
	"io"
	"log"
	"net"
	"time"
	"os"

	"github.com/flynn/go-discover/discover"
	"github.com/flynn/lorne/types"
	"github.com/titanous/go-dockerclient"
	"github.com/flynn/sampi/types"
	sc "github.com/flynn/sampi/client"
	lc "github.com/flynn/lorne/client"
)

// WARNING: assumes one host at the moment (firstHost will always be the same)

var sd *discover.Client
var sched *sc.Client
var host *lc.Client
var hostid string

func init() {
	var err error
	sd, err = discover.NewClient()
	if err != nil {
		log.Fatal(err)
	}

	sched, err = sc.New()
	if err != nil {
		log.Fatal(err)
	}

	hostid = findHost()
	host, err = lc.New(hostid)
	if err != nil {
		log.Fatal(err)
	}
}

func main() {
	root := "/var/lib/demo/apps"
	hostname := shell("curl -s icanhazip.com")

	set, _ := sd.Services("shelf")
	addrs := set.OnlineAddrs()
	if len(addrs) < 1 {
		panic("Shelf is not discoverable")
	}
	shelfHost := addrs[0]

	app := os.Args[2]
	os.MkdirAll(root+"/"+app, 0755)

	fmt.Printf("-----> Building %s on %s ...\n", app, hostname)

	scheduleAndAttach(app + ".build", docker.Config{
		Image:        "flynn/slugbuilder",
		Cmd:          []string{"http://" + shelfHost + "/" + app + ".tgz"},
		Tty:          false,
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		OpenStdin:    true,
		StdinOnce:    true,
	})

	fmt.Printf("-----> Deploying %s ...\n", app)

	jobid := app + ".web"

	stopIfExists(jobid)
	scheduleWithTcpPort(jobid, docker.Config{
		Image:        "flynn/slugrunner",
		Cmd:          []string{"start", "web"},
		Tty:          false,
		AttachStdin:  false,
		AttachStdout: false,
		AttachStderr: false,
		OpenStdin:    false,
		StdinOnce:    false,
		Env: []string{
			"SLUG_URL=http://" + shelfHost + "/" + app + ".tgz",
		},
	})

	time.Sleep(1 * time.Second)
	fmt.Printf("=====> Application deployed:\n")
	fmt.Printf("       http://%s:%s\n", hostname, getPort(jobid))
	fmt.Println("")

}

func shell(cmdline string) string {
        out, err := exec.Command("bash", "-c", cmdline).Output()
        if err != nil {
                panic(err)
        }
        return strings.Trim(string(out), " \n")
}

func stopIfExists(jobid string) {
	_, err := host.GetJob(jobid)
	if err != nil {
		return
	}
	if err := host.StopJob(jobid); err != nil {
		return
	}
}

func scheduleWithTcpPort(jobid string, config docker.Config) {

	schedReq := &sampi.ScheduleReq{
		Incremental: true,
		HostJobs:    map[string][]*sampi.Job{hostid: {{ID: jobid, Config: &config, TCPPorts: 1}}},
	}
	if _, err := sched.Schedule(schedReq); err != nil {
		log.Fatal(err)
	}
}

func getPort(jobid string) string {
	job, err := host.GetJob(jobid)
	if err != nil {
		log.Fatal(err)
	}
	for portspec := range job.Job.Config.ExposedPorts {
		return strings.Split(portspec, "/", 1)[0]
	}
}

func findHost() string {
	state, err := sched.State()
	if err != nil {
		log.Fatal(err)
	}

	var firstHost string
	for k := range state {
		firstHost = k
		break
	}
	if firstHost == "" {
		log.Fatal("no hosts")
	}
	return firstHost
}

func scheduleAndAttach(jobid string, config docker.Config) {

	services, err := sd.Services("flynn-lorne-attach." + hostid)
	if err != nil {
		log.Fatal(err)
	}
	conn, err := net.Dial("tcp", services.OnlineAddrs()[0])
	if err != nil {
		log.Fatal(err)
	}
	err = gob.NewEncoder(conn).Encode(&lorne.AttachReq{
		JobID: jobid,
		Flags: lorne.AttachFlagStdout | lorne.AttachFlagStderr | lorne.AttachFlagStdin | lorne.AttachFlagStream,
	})
	if err != nil {
		log.Fatal(err)
	}
	attachState := make([]byte, 1)
	if _, err := conn.Read(attachState); err != nil {
		log.Fatal(err)
	}
	switch attachState[0] {
	case lorne.AttachError:
		log.Fatal("attach error")
	}

	schedReq := &sampi.ScheduleReq{
		Incremental: true,
		HostJobs:    map[string][]*sampi.Job{hostid: {{ID: jobid, Config: &config}}},
	}
	if _, err := sched.Schedule(schedReq); err != nil {
		log.Fatal(err)
	}

	if _, err := conn.Read(attachState); err != nil {
		log.Fatal(err)
	}

	go func() {
		io.Copy(conn, os.Stdin)
		conn.(*net.TCPConn).CloseWrite()
	}()
	scanner := bufio.NewScanner(conn)
	for scanner.Scan() {
		fmt.Fprintln(os.Stdout, scanner.Text()[8:])
	}
	conn.Close()
}
<commit_msg>wrong args<commit_after>package main

import (
	"os/exec"
	"strings"
	"encoding/gob"
	"fmt"
	"bufio"
	"io"
	"log"
	"net"
	"time"
	"os"

	"github.com/flynn/go-discover/discover"
	"github.com/flynn/lorne/types"
	"github.com/titanous/go-dockerclient"
	"github.com/flynn/sampi/types"
	sc "github.com/flynn/sampi/client"
	lc "github.com/flynn/lorne/client"
)

// WARNING: assumes one host at the moment (firstHost will always be the same)

var sd *discover.Client
var sched *sc.Client
var host *lc.Client
var hostid string

func init() {
	var err error
	sd, err = discover.NewClient()
	if err != nil {
		log.Fatal(err)
	}

	sched, err = sc.New()
	if err != nil {
		log.Fatal(err)
	}

	hostid = findHost()
	host, err = lc.New(hostid)
	if err != nil {
		log.Fatal(err)
	}
}

func main() {
	root := "/var/lib/demo/apps"
	hostname := shell("curl -s icanhazip.com")

	set, _ := sd.Services("shelf")
	addrs := set.OnlineAddrs()
	if len(addrs) < 1 {
		panic("Shelf is not discoverable")
	}
	shelfHost := addrs[0]

	app := os.Args[2]
	os.MkdirAll(root+"/"+app, 0755)

	fmt.Printf("-----> Building %s on %s ...\n", app, hostname)

	scheduleAndAttach(app + ".build", docker.Config{
		Image:        "flynn/slugbuilder",
		Cmd:          []string{"http://" + shelfHost + "/" + app + ".tgz"},
		Tty:          false,
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		OpenStdin:    true,
		StdinOnce:    true,
	})

	fmt.Printf("-----> Deploying %s ...\n", app)

	jobid := app + ".web"

	stopIfExists(jobid)
	scheduleWithTcpPort(jobid, docker.Config{
		Image:        "flynn/slugrunner",
		Cmd:          []string{"start", "web"},
		Tty:          false,
		AttachStdin:  false,
		AttachStdout: false,
		AttachStderr: false,
		OpenStdin:    false,
		StdinOnce:    false,
		Env: []string{
			"SLUG_URL=http://" + shelfHost + "/" + app + ".tgz",
		},
	})

	time.Sleep(1 * time.Second)
	fmt.Printf("=====> Application deployed:\n")
	fmt.Printf("       http://%s:%s\n", hostname, getPort(jobid))
	fmt.Println("")

}

func shell(cmdline string) string {
        out, err := exec.Command("bash", "-c", cmdline).Output()
        if err != nil {
                panic(err)
        }
        return strings.Trim(string(out), " \n")
}

func stopIfExists(jobid string) {
	_, err := host.GetJob(jobid)
	if err != nil {
		return
	}
	if err := host.StopJob(jobid); err != nil {
		return
	}
}

func scheduleWithTcpPort(jobid string, config docker.Config) {

	schedReq := &sampi.ScheduleReq{
		Incremental: true,
		HostJobs:    map[string][]*sampi.Job{hostid: {{ID: jobid, Config: &config, TCPPorts: 1}}},
	}
	if _, err := sched.Schedule(schedReq); err != nil {
		log.Fatal(err)
	}
}

func getPort(jobid string) string {
	job, err := host.GetJob(jobid)
	if err != nil {
		log.Fatal(err)
	}
	for portspec := range job.Job.Config.ExposedPorts {
		return strings.Split(portspec, "/")[0]
	}
}

func findHost() string {
	state, err := sched.State()
	if err != nil {
		log.Fatal(err)
	}

	var firstHost string
	for k := range state {
		firstHost = k
		break
	}
	if firstHost == "" {
		log.Fatal("no hosts")
	}
	return firstHost
}

func scheduleAndAttach(jobid string, config docker.Config) {

	services, err := sd.Services("flynn-lorne-attach." + hostid)
	if err != nil {
		log.Fatal(err)
	}
	conn, err := net.Dial("tcp", services.OnlineAddrs()[0])
	if err != nil {
		log.Fatal(err)
	}
	err = gob.NewEncoder(conn).Encode(&lorne.AttachReq{
		JobID: jobid,
		Flags: lorne.AttachFlagStdout | lorne.AttachFlagStderr | lorne.AttachFlagStdin | lorne.AttachFlagStream,
	})
	if err != nil {
		log.Fatal(err)
	}
	attachState := make([]byte, 1)
	if _, err := conn.Read(attachState); err != nil {
		log.Fatal(err)
	}
	switch attachState[0] {
	case lorne.AttachError:
		log.Fatal("attach error")
	}

	schedReq := &sampi.ScheduleReq{
		Incremental: true,
		HostJobs:    map[string][]*sampi.Job{hostid: {{ID: jobid, Config: &config}}},
	}
	if _, err := sched.Schedule(schedReq); err != nil {
		log.Fatal(err)
	}

	if _, err := conn.Read(attachState); err != nil {
		log.Fatal(err)
	}

	go func() {
		io.Copy(conn, os.Stdin)
		conn.(*net.TCPConn).CloseWrite()
	}()
	scanner := bufio.NewScanner(conn)
	for scanner.Scan() {
		fmt.Fprintln(os.Stdout, scanner.Text()[8:])
	}
	conn.Close()
}
<|endoftext|>


<commit_before>// This package contains utility methos for testing
package test

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

func getTestCasePath() string {
	//TODO: Right now the command is hardcoded. We should decide how to fix this.
	dirPath, err := filepath.Abs("../test/tools")

	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	return filepath.Join(dirPath, "test")
}

func PrintSoftErrors(softerrors []error) {
	for _, err := range softerrors {
		fmt.Fprintln(os.Stderr, err.Error())
	}
}

// this method redirects the process's stdout to the test stdout
func LaunchTestCase() (*exec.Cmd, error) {
	cmd := exec.Command(getTestCasePath())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Start()
	return cmd, err
}

func LaunchTestCaseAndWaitForInitialization() (*exec.Cmd, error) {
	return launchProcessAndWaitInitialization(getTestCasePath())
}

// starts a process and waits until it writes everythin to stdout: that way we know it has been initialized.
// the process launched should close stdout once it has been fully initialized.
// this method redirects the process's stdout to the test stdout
func launchProcessAndWaitInitialization(file string) (*exec.Cmd, error) {
	cmd := exec.Command(file)

	childout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	defer childout.Close()

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	io.Copy(os.Stdout, childout)

	return cmd, nil
}
<commit_msg>[test] Expose a private method for new tests<commit_after>// This package contains utility methos for testing
package test

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

func GetTestCasePath() string {
	//TODO: Right now the command is hardcoded. We should decide how to fix this.
	dirPath, err := filepath.Abs("../test/tools")

	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	return filepath.Join(dirPath, "test")
}

func PrintSoftErrors(softerrors []error) {
	for _, err := range softerrors {
		fmt.Fprintln(os.Stderr, err.Error())
	}
}

// this method redirects the process's stdout to the test stdout
func LaunchTestCase() (*exec.Cmd, error) {
	cmd := exec.Command(GetTestCasePath())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Start()
	return cmd, err
}

func LaunchTestCaseAndWaitForInitialization() (*exec.Cmd, error) {
	return launchProcessAndWaitInitialization(GetTestCasePath())
}

// starts a process and waits until it writes everythin to stdout: that way we know it has been initialized.
// the process launched should close stdout once it has been fully initialized.
// this method redirects the process's stdout to the test stdout
func launchProcessAndWaitInitialization(file string) (*exec.Cmd, error) {
	cmd := exec.Command(file)

	childout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	defer childout.Close()

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	io.Copy(os.Stdout, childout)

	return cmd, nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"regexp"
	"strings"

	"github.com/flynn/flynn-controller/client"
	ct "github.com/flynn/flynn-controller/types"
	"github.com/flynn/go-discoverd"
	"github.com/flynn/go-flynn/cluster"
	"github.com/flynn/go-flynn/exec"
)

var clusterc *cluster.Client

func init() {
	log.SetFlags(0)

	var err error
	clusterc, err = cluster.NewClient()
	if err != nil {
		log.Fatalln("Error connecting to cluster leader:", err)
	}
}

var typesPattern = regexp.MustCompile("types.* -> (.+)\n")

func main() {
	client, err := controller.NewClient("", os.Getenv("CONTROLLER_AUTH_KEY"))
	if err != nil {
		log.Fatalln("Unable to connect to controller:", err)
	}
	// TODO: use discoverd http dialer here?
	services, err := discoverd.Services("shelf", discoverd.DefaultTimeout)
	if err != nil || len(services) < 1 {
		log.Fatalf("Unable to discover shelf %q", err)
	}
	shelfHost := services[0].Addr

	app := os.Args[1]
	commit := os.Args[2]

	_, err = client.GetApp(app)
	if err == controller.ErrNotFound {
		log.Fatalf("Unknown app %q", app)
	} else if err != nil {
		log.Fatalln("Error retrieving app:", err)
	}
	prevRelease, err := client.GetAppRelease(app)
	if err == controller.ErrNotFound {
		prevRelease = &ct.Release{}
	} else if err != nil {
		log.Fatalln("Error creating getting current app release:", err)
	}

	fmt.Printf("-----> Building %s...\n", app)

	var output bytes.Buffer
	slugURL := fmt.Sprintf("http://%s/%s.tgz", shelfHost, commit)
	cmd := exec.Command("flynn/slugbuilder", slugURL)
	cmd.Stdout = io.MultiWriter(os.Stdout, &output)
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	cmd.Env = prevRelease.Env

	if err := cmd.Run(); err != nil {
		log.Fatalln("Build failed:", err)
	}

	var types []string
	if match := typesPattern.FindSubmatch(output.Bytes()); match != nil {
		types = strings.Split(string(match[1]), ", ")
	}

	fmt.Printf("-----> Creating release...\n")

	artifact := &ct.Artifact{URI: "docker://flynn/slugrunner"}
	if err := client.CreateArtifact(artifact); err != nil {
		log.Fatalln("Error creating artifact:", err)
	}

	release := &ct.Release{
		ArtifactID: artifact.ID,
		Env:        prevRelease.Env,
	}
	procs := make(map[string]ct.ProcessType)
	for _, t := range types {
		proc := prevRelease.Processes[t]
		proc.Cmd = []string{"start", t}
		if t == "web" {
			proc.Ports.TCP = 1
			if proc.Env == nil {
				proc.Env = make(map[string]string)
			}
			proc.Env["SD_NAME"] = app + "-web"
		}
		procs[t] = proc
	}
	release.Processes = procs
	if release.Env == nil {
		release.Env = make(map[string]string)
	}
	release.Env["SLUG_URL"] = slugURL

	if err := client.CreateRelease(release); err != nil {
		log.Fatalln("Error creating release:", err)
	}
	if err := client.SetAppRelease(app, release.ID); err != nil {
		log.Fatalln("Error setting app release:", err)
	}

	fmt.Println("=====> Application deployed")
}
<commit_msg>Only send BUILDPACK_URL env var to slugbuilder<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"regexp"
	"strings"

	"github.com/flynn/flynn-controller/client"
	ct "github.com/flynn/flynn-controller/types"
	"github.com/flynn/go-discoverd"
	"github.com/flynn/go-flynn/cluster"
	"github.com/flynn/go-flynn/exec"
)

var clusterc *cluster.Client

func init() {
	log.SetFlags(0)

	var err error
	clusterc, err = cluster.NewClient()
	if err != nil {
		log.Fatalln("Error connecting to cluster leader:", err)
	}
}

var typesPattern = regexp.MustCompile("types.* -> (.+)\n")

func main() {
	client, err := controller.NewClient("", os.Getenv("CONTROLLER_AUTH_KEY"))
	if err != nil {
		log.Fatalln("Unable to connect to controller:", err)
	}
	// TODO: use discoverd http dialer here?
	services, err := discoverd.Services("shelf", discoverd.DefaultTimeout)
	if err != nil || len(services) < 1 {
		log.Fatalf("Unable to discover shelf %q", err)
	}
	shelfHost := services[0].Addr

	app := os.Args[1]
	commit := os.Args[2]

	_, err = client.GetApp(app)
	if err == controller.ErrNotFound {
		log.Fatalf("Unknown app %q", app)
	} else if err != nil {
		log.Fatalln("Error retrieving app:", err)
	}
	prevRelease, err := client.GetAppRelease(app)
	if err == controller.ErrNotFound {
		prevRelease = &ct.Release{}
	} else if err != nil {
		log.Fatalln("Error creating getting current app release:", err)
	}

	fmt.Printf("-----> Building %s...\n", app)

	var output bytes.Buffer
	slugURL := fmt.Sprintf("http://%s/%s.tgz", shelfHost, commit)
	cmd := exec.Command("flynn/slugbuilder", slugURL)
	cmd.Stdout = io.MultiWriter(os.Stdout, &output)
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	if buildpackURL, ok := prevRelease.Env["BUILDPACK_URL"]; ok {
		cmd.Env = map[string]string{"BUILDPACK_URL": buildpackURL}
	}

	if err := cmd.Run(); err != nil {
		log.Fatalln("Build failed:", err)
	}

	var types []string
	if match := typesPattern.FindSubmatch(output.Bytes()); match != nil {
		types = strings.Split(string(match[1]), ", ")
	}

	fmt.Printf("-----> Creating release...\n")

	artifact := &ct.Artifact{URI: "docker://flynn/slugrunner"}
	if err := client.CreateArtifact(artifact); err != nil {
		log.Fatalln("Error creating artifact:", err)
	}

	release := &ct.Release{
		ArtifactID: artifact.ID,
		Env:        prevRelease.Env,
	}
	procs := make(map[string]ct.ProcessType)
	for _, t := range types {
		proc := prevRelease.Processes[t]
		proc.Cmd = []string{"start", t}
		if t == "web" {
			proc.Ports.TCP = 1
			if proc.Env == nil {
				proc.Env = make(map[string]string)
			}
			proc.Env["SD_NAME"] = app + "-web"
		}
		procs[t] = proc
	}
	release.Processes = procs
	if release.Env == nil {
		release.Env = make(map[string]string)
	}
	release.Env["SLUG_URL"] = slugURL

	if err := client.CreateRelease(release); err != nil {
		log.Fatalln("Error creating release:", err)
	}
	if err := client.SetAppRelease(app, release.ID); err != nil {
		log.Fatalln("Error setting app release:", err)
	}

	fmt.Println("=====> Application deployed")
}
<|endoftext|>


<commit_before>package test

import (
	"encoding/xml"
	"github.com/masci/flick-rsync/flickr"
	flickErr "github.com/masci/flick-rsync/flickr/error"
	"io/ioutil"
)

type LoginResponse struct {
	flickr.FlickrResponse
	User struct {
		XMLName  xml.Name `xml:"user"`
		ID       string   `xml:"id,attr"`
		Username string   `xml:"username"`
	}
}

type EchoResponse struct {
	flickr.FlickrResponse
	Method string `xml:"method"`
	ApiKey string `xml:"api_key"`
	Format string `xml:"format"`
}

func Login(client *flickr.FlickrClient) (*LoginResponse, error) {
	client.EndpointUrl = flickr.API_ENDPOINT // TODO move to SetDefaultArgs

	client.SetDefaultArgs()
	client.Args.Set("method", "flickr.test.login")
	client.Args.Set("oauth_token", client.OAuthToken)
	client.Args.Set("oauth_consumer_key", client.ApiKey)

	client.Sign(client.OAuthTokenSecret)

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	loginResponse := LoginResponse{}
	err = xml.Unmarshal([]byte(body), &loginResponse)
	if err != nil {
		return nil, err
	}

	if loginResponse.HasErrors() {
		return &loginResponse, flickErr.NewError(10)
	}

	return &loginResponse, nil
}

func Null(client *flickr.FlickrClient) (*flickr.FlickrResponse, error) {
	client.EndpointUrl = flickr.API_ENDPOINT
	client.SetDefaultArgs()
	client.Args.Set("method", "flickr.test.null")
	client.Args.Set("oauth_token", client.OAuthToken)
	client.Args.Set("oauth_consumer_key", client.ApiKey)

	client.Sign(client.OAuthTokenSecret)

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	response := flickr.FlickrResponse{}

	err = xml.Unmarshal([]byte(body), &response)
	if err != nil {
		return nil, err
	}

	if response.HasErrors() {
		return &response, flickErr.NewError(10)
	}

	return &response, nil
}

func Echo(client *flickr.FlickrClient) (*EchoResponse, error) {
	client.EndpointUrl = flickr.API_ENDPOINT
	client.Args.Set("method", "flickr.test.echo")
	client.Args.Set("oauth_consumer_key", client.ApiKey)

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	response := EchoResponse{}

	err = xml.Unmarshal([]byte(body), &response)
	if err != nil {
		return nil, err
	}

	if response.HasErrors() {
		return &response, flickErr.NewError(10)
	}

	return &response, nil
}
<commit_msg>added docs<commit_after>// flickr.test API methods
package test

import (
	"encoding/xml"
	"github.com/masci/flick-rsync/flickr"
	flickErr "github.com/masci/flick-rsync/flickr/error"
	"io/ioutil"
)

// Response type used by Login function
type LoginResponse struct {
	flickr.FlickrResponse
	// the user who provided authentication infos
	User struct {
		XMLName xml.Name `xml:"user"`
		// Flickr ID
		ID string `xml:"id,attr"`
		// Flickr Username
		Username string `xml:"username"`
	}
}

// Response type used by Echo function
type EchoResponse struct {
	flickr.FlickrResponse
	// API method name, dotted notation
	Method string `xml:"method"`
	// API Key provided
	ApiKey string `xml:"api_key"`
	// API data exchange format (ex. rest)
	Format string `xml:"format"`
}

// A testing method which checks if the caller is logged in then returns their username.
// This method does not require authentication.
func Login(client *flickr.FlickrClient) (*LoginResponse, error) {
	client.EndpointUrl = flickr.API_ENDPOINT // TODO move to SetDefaultArgs

	client.SetDefaultArgs()
	client.Args.Set("method", "flickr.test.login")
	client.Args.Set("oauth_token", client.OAuthToken)
	client.Args.Set("oauth_consumer_key", client.ApiKey)

	client.Sign(client.OAuthTokenSecret)

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	loginResponse := LoginResponse{}
	err = xml.Unmarshal([]byte(body), &loginResponse)
	if err != nil {
		return nil, err
	}

	if loginResponse.HasErrors() {
		return &loginResponse, flickErr.NewError(10)
	}

	return &loginResponse, nil
}

// Noop method
// This method requires authentication with 'read' permission.
func Null(client *flickr.FlickrClient) (*flickr.FlickrResponse, error) {
	client.EndpointUrl = flickr.API_ENDPOINT
	client.SetDefaultArgs()
	client.Args.Set("method", "flickr.test.null")
	client.Args.Set("oauth_token", client.OAuthToken)
	client.Args.Set("oauth_consumer_key", client.ApiKey)

	client.Sign(client.OAuthTokenSecret)

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	response := flickr.FlickrResponse{}

	err = xml.Unmarshal([]byte(body), &response)
	if err != nil {
		return nil, err
	}

	if response.HasErrors() {
		return &response, flickErr.NewError(10)
	}

	return &response, nil
}

// A testing method which echo's all parameters back in the response.
// This method does not require authentication.
func Echo(client *flickr.FlickrClient) (*EchoResponse, error) {
	client.EndpointUrl = flickr.API_ENDPOINT
	client.Args.Set("method", "flickr.test.echo")
	client.Args.Set("oauth_consumer_key", client.ApiKey)

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	response := EchoResponse{}

	err = xml.Unmarshal([]byte(body), &response)
	if err != nil {
		return nil, err
	}

	if response.HasErrors() {
		return &response, flickErr.NewError(10)
	}

	return &response, nil
}
<|endoftext|>


<commit_before>package irc

import (
	"bytes"
	"github.com/Lukasa/GoBot/struc"
)

// DispatchMessages loops infinitely, accepting parsed versions of received IRC messages and dispatching them to botscripts.
// These botscripts return any messages they want to send on the 'out' channel.
// This can be viewed as the 'main' loop in GoBot.
func DispatchMessages(in, out chan *struc.IRCMessage, scripts []Botscript) {
	// Before we begin looping, set the botscripts running. Each one has its own dedicated input channel.
	chans := make([]chan *struc.IRCMessage, 0)

	for _, script := range scripts {
		newChan := make(chan *struc.IRCMessage)
		go script(newChan, out)
		chans = append(chans, newChan)
	}

	// Pull messages off the input channel and dispatch them to each botscript.
	for {
		msg, ok := <-in
		if !ok {
			break
		}

		for _, channel := range chans {
			channel <- msg
		}
	}
}

// ParsingLoop provides a tight loop that pops values off the input channel and dispatches goroutines to parse them. This loop
// is very small to attempt to avoid bottlenecking.
func ParsingLoop(in chan []byte, out chan *struc.IRCMessage) {
	for {
		unparsed, ok := <-in
		if !ok {
			break
		}

		messages := bytes.Split(unparsed, []byte{'\r', '\n'})

		for _, message := range messages {
			if len(message) > 0 {
				go ParseIRCMessage(message, out)
			}
		}
	}
}

// UnParsingLoop provides a tight loop that pops values off the input channel and dispatches goroutines to unparse them. This
// loop is very small to avoid bottlenecking, as it will get quite a lot of traffic.
func UnParsingLoop(in chan *struc.IRCMessage, out chan []byte) {
	for {
		parsed, ok := <-in
		if !ok {
			break
		}

		go UnparseIRCMessage(parsed, out)
	}
}
<commit_msg>A slightly more useful comment.<commit_after>package irc

import (
	"bytes"
	"github.com/Lukasa/GoBot/struc"
)

// DispatchMessages loops infinitely, accepting parsed versions of received IRC messages and dispatching them to botscripts.
// These botscripts return any messages they want to send on the 'out' channel.
// This can be viewed as the 'main' loop in GoBot.
func DispatchMessages(in, out chan *struc.IRCMessage, scripts []Botscript) {
	// Before we begin looping, set the botscripts running. Each one has its own dedicated input channel.
	chans := make([]chan *struc.IRCMessage, 0)

	for _, script := range scripts {
		newChan := make(chan *struc.IRCMessage)
		go script(newChan, out)
		chans = append(chans, newChan)
	}

	// Pull messages off the input channel and dispatch them to each botscript.
	for {
		msg, ok := <-in
		if !ok {
			break
		}

		for _, channel := range chans {
			channel <- msg
		}
	}
}

// ParsingLoop provides a tight loop that pops values off the input channel and dispatches goroutines to parse them. This loop
// is very small to attempt to avoid bottlenecking.
func ParsingLoop(in chan []byte, out chan *struc.IRCMessage) {
	for {
		unparsed, ok := <-in
		if !ok {
			break
		}

		// We can get multiple messages in each packet.
		messages := bytes.Split(unparsed, []byte{'\r', '\n'})

		for _, message := range messages {
			if len(message) > 0 {
				go ParseIRCMessage(message, out)
			}
		}
	}
}

// UnParsingLoop provides a tight loop that pops values off the input channel and dispatches goroutines to unparse them. This
// loop is very small to avoid bottlenecking, as it will get quite a lot of traffic.
func UnParsingLoop(in chan *struc.IRCMessage, out chan []byte) {
	for {
		parsed, ok := <-in
		if !ok {
			break
		}

		go UnparseIRCMessage(parsed, out)
	}
}
<|endoftext|>


<commit_before>package frank

import (
	"code.google.com/p/go.net/html"
	"code.google.com/p/go.net/html/atom"
	"errors"
	frankconf "github.com/breunigs/frank/config"
	irc "github.com/fluffle/goirc/client"
	"io"
	"log"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// how many URLs can the cache store
const cacheSize = 500

// how many hours an entry should be considered valid
const cacheValidHours = 24

// how many kilo bytes should be considered when looking for the title
// tag.
const httpReadKByte = 100

// don’t repost the same title within this period
const noRepostWithinSeconds = 30

// matches all whitespace and zero bytes. Additionally, all Unicode
// characters of class Cf (format chars, e.g. right-to-left) and Cc
// (control chars) are matched.
var whitespaceRegex = regexp.MustCompile(`[\s\0\p{Cf}\p{Cc}]+`)

var ignoreDomainsRegex = regexp.MustCompile(`^http://p\.nnev\.de`)

var twitterDomainRegex = regexp.MustCompile(`(?i)^https?://(?:[a-z0-9]\.)?twitter.com`)
var twitterPicsRegex = regexp.MustCompile(`(?i)(?:\b|^)pic\.twitter\.com/[a-z0-9]+(?:\b|$)`)

var noSpoilerRegex = regexp.MustCompile(`(?i)(don't|no|kein|nicht) spoiler`)

func UriFind(conn *irc.Conn, line *irc.Line) {
	defer func() {
		if r := recover(); r != nil {
			log.Printf("MEGA-WTF:pkg: %v", r)
		}
	}()

	msg := line.Args[1]

	if noSpoilerRegex.MatchString(msg) {
		log.Printf("not spoilering this line: %s", msg)
		return
	}

	urls := extract(msg)

	for _, url := range urls {
		if url == "" {
			continue
		}

		if cp := cacheGetByUrl(url); cp != nil {
			log.Printf("using cache for URL: %s", cp.url)
			ago := cacheGetTimeAgo(cp)
			postTitle(conn, line, cp.title, "cached "+ago+" ago")
			// Hack: add title to the cache again so we can correctly check
			// for reposts, even if the original link has been cached quite
			// some time ago. Since the repost check searches by title, but
			// here we search by URL wie get the correct time when it was
			// cached while still preventing people from using frank to
			// multiply their spamming.
			cacheAdd("", cp.title)
			continue
		}

		go func(url string) {
			if ignoreDomainsRegex.MatchString(url) {
				log.Printf("ignoring this URL: %s", url)
				return
			}

			log.Printf("testing URL: %s", url)
			title, _, err := TitleGet(url)
			if err != nil {
				//postTitle(conn, line, err.Error(), "Error")
			} else if title != "" {
				postTitle(conn, line, title, "")
				cacheAdd(url, title)
			}
		}(url)
	}
}

// regexing ////////////////////////////////////////////////////////////

func extract(msg string) []string {
	results := make([]string, 0)
	for idx := strings.Index(msg, "http"); idx > -1; idx = strings.Index(msg, "http") {
		url := msg[idx:]
		if !strings.HasPrefix(url, "http://") &&
			!strings.HasPrefix(url, "https://") {
			msg = msg[idx+len("http"):]
			continue
		}

		// End on commas, but only if they are followed by a space.
		// spiegel.de URLs have commas in them, that would be a
		// false positive otherwise.
		if end := strings.Index(url, ", "); end > -1 {
			url = url[:end]
		}

		// use special handling if the URL contains closing parens
		closingParen := strings.Index(url, ")")
		if closingParen > -1 {
			absPos := idx + closingParen + 1
			if len(msg) > absPos && msg[absPos] == ')' {
				// if an URL ends with double closing parens, assume that the
				// former one belongs to the URL
				url = url[:closingParen+1]
			} else if idx > 0 && msg[idx-1] == '(' {
				// if it ends on a single closing parens (follow by other chars)
				// only remove that closing parens if the URL is directly
				// preceded by one
				url = url[:closingParen]
			}
		}

		// Whitespace always ends a URL.
		if end := strings.IndexAny(url, " \t"); end > -1 {
			url = url[:end]
		}

		results = append(results, url)
		msg = msg[idx+len(url):]
	}
	return results
}

// http/html stuff /////////////////////////////////////////////////////

func TitleGet(url string) (string, string, error) {
	c := HttpClientWithTimeout()

	r, err := c.Get(url)
	if err != nil {
		log.Printf("WTF: could not resolve %s: %s\n", url, err)
		return "", url, err
	}
	defer r.Body.Close()

	lastUrl := r.Request.URL.String()

	// TODO: r.Body → utf8?
	title, tweet := titleParseHtml(io.LimitReader(r.Body, 1024*httpReadKByte))

	if r.StatusCode != 200 {
		return "", lastUrl, errors.New("[" + strconv.Itoa(r.StatusCode) + "] " + title)
	}

	if tweet != "" && twitterDomainRegex.MatchString(lastUrl) {
		title = tweet
	}

	log.Printf("Title for URL %s: %s\n", url, title)

	return title, lastUrl, nil
}

// parses the incoming HTML fragment and tries to extract text from
// suitable tags. Currently this is the page’s title tag and tweets
// when the HTML-code is similar enough to twitter.com. Returns
// title and tweet.
func titleParseHtml(r io.Reader) (string, string) {
	doc, err := html.Parse(r)
	if err != nil {
		log.Printf("WTF: html parser blew up: %s\n", err)
		return "", ""
	}

	title := ""
	tweetText := ""
	tweetUserName := ""
	tweetUserScreenName := ""
	tweetPicUrl := ""

	var f func(*html.Node)
	f = func(n *html.Node) {
		if title == "" && n.Type == html.ElementNode && n.DataAtom == atom.Title {
			title = extractText(n)
			return
		}

		if hasClass(n, "permalink-tweet") {
			tweetUserName = getAttr(n, "data-name")
			tweetUserScreenName = getAttr(n, "data-screen-name")
			// find next child “tweet-text”
			for c := n.FirstChild; c != nil; c = c.NextSibling {
				if hasClass(c, "tweet-text") {
					tweetText = extractText(c)
					break
				}
			}
		}

		isMedia := hasClass(n, "media") || hasClass(n, "media-thumbnail")
		if tweetPicUrl == "" && isMedia && !hasClass(n, "profile-picture") {
			attrVal := getAttr(n, "data-url")
			if attrVal != "" {
				tweetPicUrl = attrVal
				return
			}
		}

		// recurse down
		for c := n.FirstChild; c != nil; c = c.NextSibling {
			f(c)
		}

	}
	f(doc)

	// cleanup
	tweet := ""
	tweetUser := ""
	if tweetText != "" {
		tweetText = twitterPicsRegex.ReplaceAllString(tweetText, "")
		tweetUser = tweetUserName + " (@" + tweetUserScreenName + "): "
		tweet = tweetUser + tweetText + " " + tweetPicUrl
		tweet = clean(tweet)
	}

	return strings.TrimSpace(title), strings.TrimSpace(tweet)
}

func extractText(n *html.Node) string {
	text := ""
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		if c.Type == html.TextNode {
			text += c.Data
		} else {
			text += extractText(c)
		}
	}
	return clean(text)
}

func hasClass(n *html.Node, class string) bool {
	if n.Type != html.ElementNode {
		return false
	}

	class = " " + strings.TrimSpace(class) + " "
	attr := strings.Replace(getAttr(n, "class"), "\n", " ", -1)
	if strings.Contains(" "+attr+" ", class) {
		return true
	}
	return false
}

func getAttr(n *html.Node, findAttr string) string {
	for _, attr := range n.Attr {
		if attr.Key == findAttr {
			return attr.Val
		}
	}
	return ""
}

// Cache ///////////////////////////////////////////////////////////////
type Cache struct {
	url   string
	title string
	date  time.Time
}

var cache = [cacheSize]Cache{}
var cacheIndex = 0

func cacheAdd(url string, title string) {
	if len(cache) == cacheIndex {
		cacheIndex = 0
	}
	cache[cacheIndex] = Cache{url, title, time.Now()}
	cacheIndex += 1
}

func cacheGetByUrl(url string) *Cache {
	for _, cc := range cache {
		if cc.url == url && time.Since(cc.date).Hours() <= cacheValidHours {
			return &cc
		}
	}
	return nil
}

func cacheGetTimeAgo(cc *Cache) string {
	ago := time.Since(cc.date).Minutes()
	if ago < 60 {
		return strconv.Itoa(int(ago)) + "m"
	} else {
		hours := strconv.Itoa(int(ago/60.0 + 0.5))
		return hours + "h"
	}
}

func cacheGetSecondsToLastPost(title string) int {
	var secondsAgo = int(^uint(0) >> 1)
	for _, cc := range cache {
		var a = int(time.Since(cc.date).Seconds())
		if cc.title == title && a < secondsAgo {
			secondsAgo = a
		}
	}
	return secondsAgo
}

// util ////////////////////////////////////////////////////////////////

func postTitle(conn *irc.Conn, line *irc.Line, title string, prefix string) {
	tgt := line.Args[0]

	secondsAgo := cacheGetSecondsToLastPost(title)
	if secondsAgo <= noRepostWithinSeconds {
		log.Printf("Skipping, because posted %d seconds ago (“%s”)", secondsAgo, title)
		return
	}

	if frankconf.Debug {
		log.Printf("Title was last posted: %#v (“%s”)", secondsAgo, title)
	}

	log.Printf("nick=%s, target=%s, title=%s", line.Nick, tgt, title)
	// if target is our current nick, it was a private message.
	// Answer the users in this case.
	if tgt == conn.Me().Nick {
		tgt = line.Nick
	}
	if prefix == "" {
		prefix = "Link Info"
	} else {
		prefix = clean(prefix)
	}
	title = clean(title)
	// the IRC spec states that notice should be used instead of msg
	// and that bots should not react to notice at all. However, no
	// real world bot adheres to this. Furthermore, people who can’t
	// configure their client to not highlight them on notices will
	// complain.
	conn.Privmsg(tgt, "["+prefix+"] "+title)
}

func clean(text string) string {
	text = whitespaceRegex.ReplaceAllString(text, " ")
	return strings.TrimSpace(text)
}
<commit_msg>manually import sha512 so https sites using certificates that require sha512 resolve fine<commit_after>package frank

import (
	"code.google.com/p/go.net/html"
	"code.google.com/p/go.net/html/atom"
	_ "crypto/sha512"
	"errors"
	frankconf "github.com/breunigs/frank/config"
	irc "github.com/fluffle/goirc/client"
	"io"
	"log"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// how many URLs can the cache store
const cacheSize = 500

// how many hours an entry should be considered valid
const cacheValidHours = 24

// how many kilo bytes should be considered when looking for the title
// tag.
const httpReadKByte = 100

// don’t repost the same title within this period
const noRepostWithinSeconds = 30

// matches all whitespace and zero bytes. Additionally, all Unicode
// characters of class Cf (format chars, e.g. right-to-left) and Cc
// (control chars) are matched.
var whitespaceRegex = regexp.MustCompile(`[\s\0\p{Cf}\p{Cc}]+`)

var ignoreDomainsRegex = regexp.MustCompile(`^http://p\.nnev\.de`)

var twitterDomainRegex = regexp.MustCompile(`(?i)^https?://(?:[a-z0-9]\.)?twitter.com`)
var twitterPicsRegex = regexp.MustCompile(`(?i)(?:\b|^)pic\.twitter\.com/[a-z0-9]+(?:\b|$)`)

var noSpoilerRegex = regexp.MustCompile(`(?i)(don't|no|kein|nicht) spoiler`)

func UriFind(conn *irc.Conn, line *irc.Line) {
	defer func() {
		if r := recover(); r != nil {
			log.Printf("MEGA-WTF:pkg: %v", r)
		}
	}()

	msg := line.Args[1]

	if noSpoilerRegex.MatchString(msg) {
		log.Printf("not spoilering this line: %s", msg)
		return
	}

	urls := extract(msg)

	for _, url := range urls {
		if url == "" {
			continue
		}

		if cp := cacheGetByUrl(url); cp != nil {
			log.Printf("using cache for URL: %s", cp.url)
			ago := cacheGetTimeAgo(cp)
			postTitle(conn, line, cp.title, "cached "+ago+" ago")
			// Hack: add title to the cache again so we can correctly check
			// for reposts, even if the original link has been cached quite
			// some time ago. Since the repost check searches by title, but
			// here we search by URL wie get the correct time when it was
			// cached while still preventing people from using frank to
			// multiply their spamming.
			cacheAdd("", cp.title)
			continue
		}

		go func(url string) {
			if ignoreDomainsRegex.MatchString(url) {
				log.Printf("ignoring this URL: %s", url)
				return
			}

			log.Printf("testing URL: %s", url)
			title, _, err := TitleGet(url)
			if err != nil {
				//postTitle(conn, line, err.Error(), "Error")
			} else if title != "" {
				postTitle(conn, line, title, "")
				cacheAdd(url, title)
			}
		}(url)
	}
}

// regexing ////////////////////////////////////////////////////////////

func extract(msg string) []string {
	results := make([]string, 0)
	for idx := strings.Index(msg, "http"); idx > -1; idx = strings.Index(msg, "http") {
		url := msg[idx:]
		if !strings.HasPrefix(url, "http://") &&
			!strings.HasPrefix(url, "https://") {
			msg = msg[idx+len("http"):]
			continue
		}

		// End on commas, but only if they are followed by a space.
		// spiegel.de URLs have commas in them, that would be a
		// false positive otherwise.
		if end := strings.Index(url, ", "); end > -1 {
			url = url[:end]
		}

		// use special handling if the URL contains closing parens
		closingParen := strings.Index(url, ")")
		if closingParen > -1 {
			absPos := idx + closingParen + 1
			if len(msg) > absPos && msg[absPos] == ')' {
				// if an URL ends with double closing parens, assume that the
				// former one belongs to the URL
				url = url[:closingParen+1]
			} else if idx > 0 && msg[idx-1] == '(' {
				// if it ends on a single closing parens (follow by other chars)
				// only remove that closing parens if the URL is directly
				// preceded by one
				url = url[:closingParen]
			}
		}

		// Whitespace always ends a URL.
		if end := strings.IndexAny(url, " \t"); end > -1 {
			url = url[:end]
		}

		results = append(results, url)
		msg = msg[idx+len(url):]
	}
	return results
}

// http/html stuff /////////////////////////////////////////////////////

func TitleGet(url string) (string, string, error) {
	c := HttpClientWithTimeout()

	r, err := c.Get(url)
	if err != nil {
		log.Printf("WTF: could not resolve %s: %s\n", url, err)
		return "", url, err
	}
	defer r.Body.Close()

	lastUrl := r.Request.URL.String()

	// TODO: r.Body → utf8?
	title, tweet := titleParseHtml(io.LimitReader(r.Body, 1024*httpReadKByte))

	if r.StatusCode != 200 {
		return "", lastUrl, errors.New("[" + strconv.Itoa(r.StatusCode) + "] " + title)
	}

	if tweet != "" && twitterDomainRegex.MatchString(lastUrl) {
		title = tweet
	}

	log.Printf("Title for URL %s: %s\n", url, title)

	return title, lastUrl, nil
}

// parses the incoming HTML fragment and tries to extract text from
// suitable tags. Currently this is the page’s title tag and tweets
// when the HTML-code is similar enough to twitter.com. Returns
// title and tweet.
func titleParseHtml(r io.Reader) (string, string) {
	doc, err := html.Parse(r)
	if err != nil {
		log.Printf("WTF: html parser blew up: %s\n", err)
		return "", ""
	}

	title := ""
	tweetText := ""
	tweetUserName := ""
	tweetUserScreenName := ""
	tweetPicUrl := ""

	var f func(*html.Node)
	f = func(n *html.Node) {
		if title == "" && n.Type == html.ElementNode && n.DataAtom == atom.Title {
			title = extractText(n)
			return
		}

		if hasClass(n, "permalink-tweet") {
			tweetUserName = getAttr(n, "data-name")
			tweetUserScreenName = getAttr(n, "data-screen-name")
			// find next child “tweet-text”
			for c := n.FirstChild; c != nil; c = c.NextSibling {
				if hasClass(c, "tweet-text") {
					tweetText = extractText(c)
					break
				}
			}
		}

		isMedia := hasClass(n, "media") || hasClass(n, "media-thumbnail")
		if tweetPicUrl == "" && isMedia && !hasClass(n, "profile-picture") {
			attrVal := getAttr(n, "data-url")
			if attrVal != "" {
				tweetPicUrl = attrVal
				return
			}
		}

		// recurse down
		for c := n.FirstChild; c != nil; c = c.NextSibling {
			f(c)
		}

	}
	f(doc)

	// cleanup
	tweet := ""
	tweetUser := ""
	if tweetText != "" {
		tweetText = twitterPicsRegex.ReplaceAllString(tweetText, "")
		tweetUser = tweetUserName + " (@" + tweetUserScreenName + "): "
		tweet = tweetUser + tweetText + " " + tweetPicUrl
		tweet = clean(tweet)
	}

	return strings.TrimSpace(title), strings.TrimSpace(tweet)
}

func extractText(n *html.Node) string {
	text := ""
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		if c.Type == html.TextNode {
			text += c.Data
		} else {
			text += extractText(c)
		}
	}
	return clean(text)
}

func hasClass(n *html.Node, class string) bool {
	if n.Type != html.ElementNode {
		return false
	}

	class = " " + strings.TrimSpace(class) + " "
	attr := strings.Replace(getAttr(n, "class"), "\n", " ", -1)
	if strings.Contains(" "+attr+" ", class) {
		return true
	}
	return false
}

func getAttr(n *html.Node, findAttr string) string {
	for _, attr := range n.Attr {
		if attr.Key == findAttr {
			return attr.Val
		}
	}
	return ""
}

// Cache ///////////////////////////////////////////////////////////////
type Cache struct {
	url   string
	title string
	date  time.Time
}

var cache = [cacheSize]Cache{}
var cacheIndex = 0

func cacheAdd(url string, title string) {
	if len(cache) == cacheIndex {
		cacheIndex = 0
	}
	cache[cacheIndex] = Cache{url, title, time.Now()}
	cacheIndex += 1
}

func cacheGetByUrl(url string) *Cache {
	for _, cc := range cache {
		if cc.url == url && time.Since(cc.date).Hours() <= cacheValidHours {
			return &cc
		}
	}
	return nil
}

func cacheGetTimeAgo(cc *Cache) string {
	ago := time.Since(cc.date).Minutes()
	if ago < 60 {
		return strconv.Itoa(int(ago)) + "m"
	} else {
		hours := strconv.Itoa(int(ago/60.0 + 0.5))
		return hours + "h"
	}
}

func cacheGetSecondsToLastPost(title string) int {
	var secondsAgo = int(^uint(0) >> 1)
	for _, cc := range cache {
		var a = int(time.Since(cc.date).Seconds())
		if cc.title == title && a < secondsAgo {
			secondsAgo = a
		}
	}
	return secondsAgo
}

// util ////////////////////////////////////////////////////////////////

func postTitle(conn *irc.Conn, line *irc.Line, title string, prefix string) {
	tgt := line.Args[0]

	secondsAgo := cacheGetSecondsToLastPost(title)
	if secondsAgo <= noRepostWithinSeconds {
		log.Printf("Skipping, because posted %d seconds ago (“%s”)", secondsAgo, title)
		return
	}

	if frankconf.Debug {
		log.Printf("Title was last posted: %#v (“%s”)", secondsAgo, title)
	}

	log.Printf("nick=%s, target=%s, title=%s", line.Nick, tgt, title)
	// if target is our current nick, it was a private message.
	// Answer the users in this case.
	if tgt == conn.Me().Nick {
		tgt = line.Nick
	}
	if prefix == "" {
		prefix = "Link Info"
	} else {
		prefix = clean(prefix)
	}
	title = clean(title)
	// the IRC spec states that notice should be used instead of msg
	// and that bots should not react to notice at all. However, no
	// real world bot adheres to this. Furthermore, people who can’t
	// configure their client to not highlight them on notices will
	// complain.
	conn.Privmsg(tgt, "["+prefix+"] "+title)
}

func clean(text string) string {
	text = whitespaceRegex.ReplaceAllString(text, " ")
	return strings.TrimSpace(text)
}
<|endoftext|>


<commit_before>package dht

import (
	inet "github.com/jbenet/go-ipfs/p2p/net"
)

// netNotifiee defines methods to be used with the IpfsDHT
type netNotifiee IpfsDHT

func (nn *netNotifiee) DHT() *IpfsDHT {
	return (*IpfsDHT)(nn)
}

func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) {
	dht := nn.DHT()
	select {
	case <-dht.Closing():
		return
	}
	dht.Update(dht.Context(), v.RemotePeer())
}

func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) {
	dht := nn.DHT()
	select {
	case <-dht.Closing():
		return
	}
	dht.routingTable.Remove(v.RemotePeer())
}

func (nn *netNotifiee) OpenedStream(n inet.Network, v inet.Stream) {}
func (nn *netNotifiee) ClosedStream(n inet.Network, v inet.Stream) {}
<commit_msg>p2p/net: notify on listens<commit_after>package dht

import (
	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"

	inet "github.com/jbenet/go-ipfs/p2p/net"
)

// netNotifiee defines methods to be used with the IpfsDHT
type netNotifiee IpfsDHT

func (nn *netNotifiee) DHT() *IpfsDHT {
	return (*IpfsDHT)(nn)
}

func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) {
	dht := nn.DHT()
	select {
	case <-dht.Closing():
		return
	}
	dht.Update(dht.Context(), v.RemotePeer())
}

func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) {
	dht := nn.DHT()
	select {
	case <-dht.Closing():
		return
	}
	dht.routingTable.Remove(v.RemotePeer())
}

func (nn *netNotifiee) OpenedStream(n inet.Network, v inet.Stream) {}
func (nn *netNotifiee) ClosedStream(n inet.Network, v inet.Stream) {}
func (nn *netNotifiee) Listen(n inet.Network, a ma.Multiaddr)      {}
func (nn *netNotifiee) ListenClose(n inet.Network, a ma.Multiaddr) {}
<|endoftext|>