<commit_before>package mailck

import (
	"fmt"
	"github.com/siebenmann/smtpd"
	"github.com/stretchr/testify/assert"
	"net"
	"testing"
	"time"
)

func TestCheckSyntax(t *testing.T) {
	tests := []struct {
		mail  string
		valid bool
	}{
		{"", false},
		{"xxx", false},
		{"s.mancketarent.de", false},
		{"s.mancke@tarentde", false},
		{"s.mancke@tarent@sdc.de", false},
		{"s.mancke@tarent.de", true},
		{"s.Mancke+yzz42@tarent.de", true},
	}

	for _, test := range tests {
		t.Run(test.mail, func(t *testing.T) {
			result := CheckSyntax(test.mail)
			assert.Equal(t, test.valid, result)
		})
	}
}

func TestCheck(t *testing.T) {
	tests := []struct {
		mail   string
		result CheckResult
		msg    string
		err    error
	}{
		{"xxx", Invalid, "invalid syntax", nil},
		{"s.mancke@sdcsdcsdcsdctarent.de", Invalid, "error, no mailserver for hostname", nil},
		{"foo@example.com", Invalid, "error, no mailserver for hostname", nil},
		{"foo@mailinator.com", Disposable, "disposable email", nil},
	}

	for _, test := range tests {
		t.Run(test.mail, func(t *testing.T) {
			start := time.Now()
			result, msg, err := Check("noreply@mancke.net", test.mail)
			assert.Equal(t, test.result, result)
			assert.Equal(t, test.msg, msg)
			assert.Equal(t, test.err, err)
			fmt.Printf("check for %30v: %-15v => %-10v (%v)\n", test.mail, time.Since(start), test.result, msg)
		})
	}
}

func Test_checkMailbox(t *testing.T) {
	tests := []struct {
		stopAt      smtpd.Command
		result      CheckResult
		msg         string
		expectError bool
	}{
		{smtpd.QUIT, Valid, "Ok", false},
		{smtpd.RCPTTO, Invalid, "mailbox unavailable", false},
		{smtpd.MAILFROM, Undefined, "smtp error", true},
	}

	for _, test := range tests {
		t.Run(fmt.Sprintf("stop at: %v", test.stopAt), func(t *testing.T) {
			dummyServer := NewDummySMTPServer("localhost:2525", test.stopAt)
			defer dummyServer.Close()
			result, msg, err := checkMailbox("noreply@mancke.net", "foo@bar.de", []*net.MX{{Host: "localhost"}}, 2525)
			assert.Equal(t, test.result, result)
			assert.Equal(t, test.msg, msg)
			if test.expectError {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
			}
		})
	}
}

type DummySMTPServer struct {
	listener net.Listener
	running  bool
	rejectAt smtpd.Command
}

func NewDummySMTPServer(listen string, rejectAt smtpd.Command) *DummySMTPServer {
	ln, err := net.Listen("tcp", listen)
	if err != nil {
		panic(err)
	}
	smtpserver := &DummySMTPServer{
		listener: ln,
		running:  true,
		rejectAt: rejectAt,
	}

	go func() {
		for {
			conn, err := ln.Accept()
			if err != nil {
				return
			}
			smtpserver.handleClient(conn)
		}
	}()
	return smtpserver
}

func (smtpserver *DummySMTPServer) Close() {
	smtpserver.listener.Close()
	smtpserver.running = false
}

func (smtpserver *DummySMTPServer) handleClient(conn net.Conn) {
	cfg := smtpd.Config{
		LocalName: "testserver",
		SftName:   "testserver",
	}
	c := smtpd.NewConn(conn, cfg, nil)
	for smtpserver.running {
		event := c.Next()
		//fmt.Printf("event: %+v\n", event)
		if event.Cmd == smtpserver.rejectAt {
			c.Reject()
		} else {
			c.Accept()
		}
		if event.What == smtpd.DONE {
			return
		}
	}
}
<commit_msg>increased testcoverage<commit_after>package mailck

import (
	"fmt"
	"github.com/siebenmann/smtpd"
	"github.com/stretchr/testify/assert"
	"net"
	"testing"
	"time"
)

func TestCheckSyntax(t *testing.T) {
	tests := []struct {
		mail  string
		valid bool
	}{
		{"", false},
		{"xxx", false},
		{"s.mancketarent.de", false},
		{"s.mancke@tarentde", false},
		{"s.mancke@tarent@sdc.de", false},
		{"s.mancke@tarent.de", true},
		{"s.Mancke+yzz42@tarent.de", true},
	}

	for _, test := range tests {
		t.Run(test.mail, func(t *testing.T) {
			result := CheckSyntax(test.mail)
			assert.Equal(t, test.valid, result)
		})
	}
}

func TestCheck(t *testing.T) {
	tests := []struct {
		mail   string
		result CheckResult
		msg    string
		err    error
	}{
		{"xxx", Invalid, "invalid syntax", nil},
		{"s.mancke@sdcsdcsdcsdctarent.de", Invalid, "error, no mailserver for hostname", nil},
		{"foo@example.com", Invalid, "error, no mailserver for hostname", nil},
		{"foo@mailinator.com", Disposable, "disposable email", nil},
	}

	for _, test := range tests {
		t.Run(test.mail, func(t *testing.T) {
			start := time.Now()
			result, msg, err := Check("noreply@mancke.net", test.mail)
			assert.Equal(t, test.result, result)
			assert.Equal(t, test.msg, msg)
			assert.Equal(t, test.err, err)
			fmt.Printf("check for %30v: %-15v => %-10v (%v)\n", test.mail, time.Since(start), test.result, msg)
		})
	}
}

func Test_checkMailbox(t *testing.T) {
	tests := []struct {
		stopAt      smtpd.Command
		result      CheckResult
		msg         string
		expectError bool
	}{
		{smtpd.QUIT, Valid, "Ok", false},
		{smtpd.RCPTTO, Invalid, "mailbox unavailable", false},
		{smtpd.MAILFROM, Undefined, "smtp error", true},
		{smtpd.HELO, Undefined, "smtp error", true},
	}

	for _, test := range tests {
		t.Run(fmt.Sprintf("stop at: %v", test.stopAt), func(t *testing.T) {
			dummyServer := NewDummySMTPServer("localhost:2525", test.stopAt)
			defer dummyServer.Close()
			result, msg, err := checkMailbox("noreply@mancke.net", "foo@bar.de", []*net.MX{{Host: "localhost"}}, 2525)
			assert.Equal(t, test.result, result)
			assert.Equal(t, test.msg, msg)
			if test.expectError {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
			}
		})
	}
}

func Test_checkMailbox_NetworkError(t *testing.T) {
	result, msg, err := checkMailbox("noreply@mancke.net", "foo@bar.de", []*net.MX{{Host: "localhost"}}, 6666)
	assert.Equal(t, Undefined, result)
	assert.Equal(t, "smtp error", msg)
	assert.Error(t, err)
}

type DummySMTPServer struct {
	listener net.Listener
	running  bool
	rejectAt smtpd.Command
}

func NewDummySMTPServer(listen string, rejectAt smtpd.Command) *DummySMTPServer {
	time.Sleep(10 * time.Millisecond)
	ln, err := net.Listen("tcp", listen)
	if err != nil {
		panic(err)
	}
	smtpserver := &DummySMTPServer{
		listener: ln,
		running:  true,
		rejectAt: rejectAt,
	}

	go func() {
		for {
			conn, err := ln.Accept()
			if err != nil {
				return
			}
			smtpserver.handleClient(conn)
		}
	}()
	time.Sleep(10 * time.Millisecond)
	return smtpserver
}

func (smtpserver *DummySMTPServer) Close() {
	smtpserver.listener.Close()
	smtpserver.running = false
}

func (smtpserver *DummySMTPServer) handleClient(conn net.Conn) {
	cfg := smtpd.Config{
		LocalName: "testserver",
		SftName:   "testserver",
	}
	c := smtpd.NewConn(conn, cfg, nil)
	for smtpserver.running {
		event := c.Next()
		if event.Cmd == smtpserver.rejectAt ||
			(smtpserver.rejectAt == smtpd.HELO && event.Cmd == smtpd.EHLO) {
			c.Reject()
		} else {
			c.Accept()
		}
		if event.What == smtpd.DONE {
			return
		}
	}
}
<|endoftext|>


<commit_before>package odp

import (
	"fmt"
	"syscall"
)

const (
	DATAPATH     = iota
	VPORT        = iota
	FLOW         = iota
	PACKET       = iota
	FAMILY_COUNT = iota
)

var familyNames = [FAMILY_COUNT]string{
	"ovs_datapath",
	"ovs_vport",
	"ovs_flow",
	"ovs_packet",
}

type Dpif struct {
	sock      *NetlinkSocket
	familyIds [FAMILY_COUNT]uint16
}

func lookupFamily(sock *NetlinkSocket, name string) (uint16, error) {
	id, err := sock.LookupGenlFamily(name)
	if err == nil {
		return id, nil
	}

	if err == NetlinkError(syscall.ENOENT) {
		return 0, fmt.Errorf("Generic netlink family '%s' unavailable; the Open vSwitch kernel module is probably not loaded", name)
	}

	return 0, err
}

func NewDpif() (*Dpif, error) {
	sock, err := OpenNetlinkSocket(syscall.NETLINK_GENERIC)
	if err != nil {
		return nil, err
	}

	dpif := &Dpif{sock: sock}

	for i := 0; i < FAMILY_COUNT; i++ {
		dpif.familyIds[i], err = lookupFamily(sock, familyNames[i])
		if err != nil {
			sock.Close()
			return nil, err
		}
	}

	return dpif, nil
}

func (dpif *Dpif) Close() error {
	if dpif.sock == nil {
		return nil
	}
	err := dpif.sock.Close()
	dpif.sock = nil
	return err
}

func (nlmsg *NlMsgBuilder) putOvsHeader(ifindex int32) {
	pos := nlmsg.AlignGrow(syscall.NLMSG_ALIGNTO, SizeofOvsHeader)
	h := ovsHeaderAt(nlmsg.buf, pos)
	h.DpIfIndex = ifindex
}

func (nlmsg *NlMsgParser) takeOvsHeader() (*OvsHeader, error) {
	pos, err := nlmsg.AlignAdvance(syscall.NLMSG_ALIGNTO, SizeofOvsHeader)
	if err != nil {
		return nil, err
	}

	return ovsHeaderAt(nlmsg.data, pos), nil
}
<commit_msg>Make an error message more helpful<commit_after>package odp

import (
	"fmt"
	"syscall"
)

const (
	DATAPATH     = iota
	VPORT        = iota
	FLOW         = iota
	PACKET       = iota
	FAMILY_COUNT = iota
)

var familyNames = [FAMILY_COUNT]string{
	"ovs_datapath",
	"ovs_vport",
	"ovs_flow",
	"ovs_packet",
}

type Dpif struct {
	sock      *NetlinkSocket
	familyIds [FAMILY_COUNT]uint16
}

func lookupFamily(sock *NetlinkSocket, name string) (uint16, error) {
	id, err := sock.LookupGenlFamily(name)
	if err == nil {
		return id, nil
	}

	if err == NetlinkError(syscall.ENOENT) {
		return 0, fmt.Errorf("Generic netlink family '%s' unavailable; the Open vSwitch kernel module is probably not loaded, try 'modprobe openvswitch'", name)
	}

	return 0, err
}

func NewDpif() (*Dpif, error) {
	sock, err := OpenNetlinkSocket(syscall.NETLINK_GENERIC)
	if err != nil {
		return nil, err
	}

	dpif := &Dpif{sock: sock}

	for i := 0; i < FAMILY_COUNT; i++ {
		dpif.familyIds[i], err = lookupFamily(sock, familyNames[i])
		if err != nil {
			sock.Close()
			return nil, err
		}
	}

	return dpif, nil
}

func (dpif *Dpif) Close() error {
	if dpif.sock == nil {
		return nil
	}
	err := dpif.sock.Close()
	dpif.sock = nil
	return err
}

func (nlmsg *NlMsgBuilder) putOvsHeader(ifindex int32) {
	pos := nlmsg.AlignGrow(syscall.NLMSG_ALIGNTO, SizeofOvsHeader)
	h := ovsHeaderAt(nlmsg.buf, pos)
	h.DpIfIndex = ifindex
}

func (nlmsg *NlMsgParser) takeOvsHeader() (*OvsHeader, error) {
	pos, err := nlmsg.AlignAdvance(syscall.NLMSG_ALIGNTO, SizeofOvsHeader)
	if err != nil {
		return nil, err
	}

	return ovsHeaderAt(nlmsg.data, pos), nil
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Damon Revoe. All rights reserved.
// Use of this source code is governed by the MIT
// license, which can be found in the LICENSE file.

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"gopkg.in/yaml.v2"
)

type packageDefinition struct {
	Name     string   `yaml:"name"`
	Type     string   `yaml:"type"`
	Requires []string `yaml:"requires"`
}

func loadPackageDefinition(pathname string) (pd packageDefinition, err error) {
	data, err := ioutil.ReadFile(pathname)

	if err != nil {
		return
	}

	err = yaml.Unmarshal(data, &pd)

	if err != nil {
		errMessage := strings.TrimPrefix(err.Error(), "yaml: ")
		err = errors.New(pathname + ": " + errMessage)
	}

	return
}

type packageIndex struct {
	packageByName   map[string]packageDefinition
	orderedPackages []packageDefinition
}

func buildPackageIndex(pkgpath string) (packageIndex, error) {
	var pi packageIndex

	if len(pkgpath) == 0 {
		pkgpath = os.Getenv(pkgPathEnvVar)

		if len(pkgpath) == 0 {
			return pi, errors.New("-pkgpath is not given and $" +
				pkgPathEnvVar + " is not defined")
		}
	}

	for _, pkgpathDir := range strings.Split(pkgpath, ":") {
		dirEntries, _ := ioutil.ReadDir(pkgpathDir)

		for _, dirEntry := range dirEntries {
			dirEntryPathname := filepath.Join(pkgpathDir,
				dirEntry.Name(), dirEntry.Name()+".yaml")

			fileInfo, err := os.Stat(dirEntryPathname)
			if err != nil || !fileInfo.Mode().IsRegular() {
				continue
			}

			pd, err := loadPackageDefinition(dirEntryPathname)

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

			pi.orderedPackages = append(pi.orderedPackages, pd)
		}
	}

	return pi, nil
}

func (index *packageIndex) printListOfPackages() {
	fmt.Println("List of packages:")

	for _, pd := range index.orderedPackages {
		fmt.Println(pd.Name)
		fmt.Println(pd.Type)
		for _, requiredPackage := range pd.Requires {
			fmt.Println("-", requiredPackage)
		}
	}
}
<commit_msg>Add "templates" to pkgpath<commit_after>// Copyright (C) 2017 Damon Revoe. All rights reserved.
// Use of this source code is governed by the MIT
// license, which can be found in the LICENSE file.

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"gopkg.in/yaml.v2"
)

type packageDefinition struct {
	Name     string   `yaml:"name"`
	Type     string   `yaml:"type"`
	Requires []string `yaml:"requires"`
}

func loadPackageDefinition(pathname string) (pd packageDefinition, err error) {
	data, err := ioutil.ReadFile(pathname)

	if err != nil {
		return
	}

	err = yaml.Unmarshal(data, &pd)

	if err != nil {
		errMessage := strings.TrimPrefix(err.Error(), "yaml: ")
		err = errors.New(pathname + ": " + errMessage)
	}

	return
}

type packageIndex struct {
	packageByName   map[string]packageDefinition
	orderedPackages []packageDefinition
}

func buildPackageIndex(pkgpath string) (packageIndex, error) {
	var pi packageIndex

	if len(pkgpath) == 0 {
		pkgpath = os.Getenv(pkgPathEnvVar)

		if len(pkgpath) == 0 {
			return pi, errors.New("-pkgpath is not given and $" +
				pkgPathEnvVar + " is not defined")
		}
	}

	pkgpathDirs := append(strings.Split(pkgpath, ":"),
		filepath.Join(filepath.Dir(os.Args[0]), "templates"))

	for _, pkgpathDir := range pkgpathDirs {
		dirEntries, _ := ioutil.ReadDir(pkgpathDir)

		for _, dirEntry := range dirEntries {
			dirEntryPathname := filepath.Join(pkgpathDir,
				dirEntry.Name(), dirEntry.Name()+".yaml")

			fileInfo, err := os.Stat(dirEntryPathname)
			if err != nil || !fileInfo.Mode().IsRegular() {
				continue
			}

			pd, err := loadPackageDefinition(dirEntryPathname)

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

			pi.orderedPackages = append(pi.orderedPackages, pd)
		}
	}

	return pi, nil
}

func (index *packageIndex) printListOfPackages() {
	fmt.Println("List of packages:")

	for _, pd := range index.orderedPackages {
		fmt.Println(pd.Name)
		fmt.Println(pd.Type)
		for _, requiredPackage := range pd.Requires {
			fmt.Println("-", requiredPackage)
		}
	}
}
<|endoftext|>


<commit_before>package state

import (
	log "github.com/Sirupsen/logrus"
	"encoding/json"
	"fmt"
)

func newFile(metadata Metadata, data []byte) (*File, error) {
	file := &File{}
	err := json.Unmarshal(data, &file)
	if err != nil {
		return file, err
	}
	file.Metadata = metadata
	switch metadata.State {
	case "absent":
	case "linked":
	case "rendered":
	default: return file, fmt.Errorf("Invalid file state: %s", metadata.State)
	}
	if file.Path == "" {
		file.Path = metadata.Name
	}
	return file, nil

}

func newPackage(metadata Metadata, data []byte) (*Package, error) {
	pkg := &Package{}
	err := json.Unmarshal(data, &pkg)
	if err != nil {
		return pkg, err
	}
	pkg.Metadata = metadata
	switch metadata.State {
	case "installed":
	case "removed":
	default:
		return pkg, fmt.Errorf("Invalid package state: %s", metadata.State)
	}
	if pkg.Name == "" {
		pkg.Name = metadata.Name
	}
	return pkg, nil
}

func newService(metadata Metadata, data []byte) (*Service, error) {
	service := &Service{}
	err := json.Unmarshal(data, &service)
	if err != nil {
		return service, err
	}
	service.Metadata = metadata
	switch metadata.State {
	case "running":
	case "stopped":
	default:
		return service, fmt.Errorf("Invalid service state: %s", metadata.State)
	}
	if service.Name == "" {
		service.Name = metadata.Name
	}
	return service, nil
}

func StateFactory(metadata Metadata, data []byte) (State, error) {
	log.Printf("Loading state %s: %s.%s", metadata.Name, metadata.Type, metadata.State)
	err := json.Unmarshal(data, &metadata) // Load requirements from each state into Metadata
	if err != nil {
		panic(err)
	}
	switch metadata.Type {
	case "file":
		return newFile(metadata, data)
	case "package":
		return newPackage(metadata, data)
	case "service":
		return newService(metadata, data)
	default:
		panic(fmt.Errorf("Unknown state keyword: %s", metadata.Type))
	}
}
<commit_msg>Return nil states<commit_after>package state

import (
	log "github.com/Sirupsen/logrus"
	"encoding/json"
	"fmt"
)

/*
Create and validate a new File State
 */
func newFile(metadata Metadata, data []byte) (*File, error) {
	file := &File{}
	err := json.Unmarshal(data, &file)
	if err != nil {
		return nil, err
	}
	file.Metadata = metadata
	switch metadata.State {
	case "absent":
	case "linked":
	case "rendered":
	default: return nil, fmt.Errorf("Invalid file state: %s", metadata.State)
	}
	if file.Path == "" {
		file.Path = metadata.Name
	}
	return file, nil

}

/*
Create and validate a new Package State
 */
func newPackage(metadata Metadata, data []byte) (*Package, error) {
	pkg := &Package{}
	err := json.Unmarshal(data, &pkg)
	if err != nil {
		return nil, err
	}
	pkg.Metadata = metadata
	switch metadata.State {
	case "installed":
	case "removed":
	default:
		return nil, fmt.Errorf("Invalid package state: %s", metadata.State)
	}
	if pkg.Name == "" {
		pkg.Name = metadata.Name
	}
	return pkg, nil
}

/*
Create and validate a new Service State
 */
func newService(metadata Metadata, data []byte) (*Service, error) {
	service := &Service{}
	err := json.Unmarshal(data, &service)
	if err != nil {
		return nil, err
	}
	service.Metadata = metadata
	switch metadata.State {
	case "running":
	case "stopped":
	default:
		return nil, fmt.Errorf("Invalid service state: %s", metadata.State)
	}
	if service.Name == "" {
		service.Name = metadata.Name
	}
	return service, nil
}

func StateFactory(metadata Metadata, data []byte) (State, error) {
	log.Printf("Loading state %s: %s.%s", metadata.Name, metadata.Type, metadata.State)
	err := json.Unmarshal(data, &metadata) // Load requirements from each state into Metadata
	if err != nil {
		panic(err)
	}
	switch metadata.Type {
	case "file":
		return newFile(metadata, data)
	case "package":
		return newPackage(metadata, data)
	case "service":
		return newService(metadata, data)
	default:
		panic(fmt.Errorf("Unknown state keyword: %s", metadata.Type))
	}
}
<|endoftext|>


<commit_before>package transport

import (
	"fmt"
	"github.com/mannkind/mysb/ota"
	"github.com/eclipse/paho.mqtt.golang"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"strings"
)

// MQTT - MQTT all the things!
type MQTT struct {
	Settings struct {
		ClientID string
		Broker   string
		SubTopic string
		PubTopic string
	}
	Control       ota.Control
	LastPublished string
}

// NewMQTT - Create a new MQTT
func NewMQTT(filename string) *MQTT {
	log.Printf("Loading configuration file: %s", filename)

	config := MQTT{}
	source, err := ioutil.ReadFile(filename)
	err = yaml.Unmarshal(source, &config)
	if err != nil {
		panic(err)
	}
	log.Println("Configuration file loaded")

	return &config
}

// Start - Connect and Subscribe
func (t *MQTT) Start() error {
	log.Print("Connecting to MQTT... ")
	opts := mqtt.NewClientOptions().
		AddBroker(t.Settings.Broker).
		SetClientID(t.Settings.ClientID).
        SetOnConnectHandler(t.onConnect).
        SetConnectionLostHandler(func(client mqtt.Client, err error) {
            log.Printf("Disconnected: %s", err)
        })

	client := mqtt.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		return token.Error()
	}

	return nil
}

func (t *MQTT) onConnect(client mqtt.Client) {
	log.Println("Connected")

    // Subscribe to topics
    subscriptions := map[string]mqtt.MessageHandler{
        fmt.Sprintf("%s/255/255/3/0/3", t.Settings.SubTopic): t.idRequest,
        fmt.Sprintf("%s/+/255/4/0/0", t.Settings.SubTopic):   t.configurationRequest,
        fmt.Sprintf("%s/+/255/4/0/2", t.Settings.SubTopic):   t.dataRequest,
        "mysensors/bootloader/+/+":                           t.bootloaderCommand,
    }

    for topic, handler := range subscriptions {
        if token := client.Subscribe(topic, 0, handler); token.Wait() && token.Error() != nil {
            log.Print(token.Error())
        }
    }
}

func (t *MQTT) idRequest(client mqtt.Client, msg mqtt.Message) {
	t.publish(client, fmt.Sprintf("%s/255/255/3/0/4", t.Settings.PubTopic), t.Control.IDRequest())
}

func (t *MQTT) configurationRequest(client mqtt.Client, msg mqtt.Message) {
	topic := msg.Topic()
	payload := string(msg.Payload())
	to := strings.Split(topic, "/")[1]

	// Attempt to run any bootloader commands
	if t.runBootloaderCommand(client, to) {
		return
	}

	t.publish(client, fmt.Sprintf("%s/%s/255/4/0/1", t.Settings.PubTopic, to), t.Control.ConfigurationRequest(to, payload))
}

// DataRequest - Handle incoming firmware requests
func (t *MQTT) dataRequest(client mqtt.Client, msg mqtt.Message) {
	topic := msg.Topic()
	payload := string(msg.Payload())
	to := strings.Split(topic, "/")[1]

	t.publish(client, fmt.Sprintf("%s/%s/255/4/0/3", t.Settings.PubTopic, to), t.Control.DataRequest(to, payload))
}

func (t *MQTT) bootloaderCommand(client mqtt.Client, msg mqtt.Message) {
	topic := msg.Topic()
	payload := string(msg.Payload())

	parts := strings.Split(topic, "/")
	to := parts[2]
	cmd := parts[3]

	t.Control.BootloaderCommand(to, cmd, payload)
}

func (t *MQTT) runBootloaderCommand(client mqtt.Client, to string) bool {
	if blcmd, ok := t.Control.Commands[to]; ok {
		outTopic := fmt.Sprintf("%s/%s/255/4/0/1", t.Settings.PubTopic, to)
		outPayload := blcmd.String()
		t.publish(client, outTopic, outPayload)

		delete(t.Control.Commands, to)
		return true
	}

	return false
}

func (t *MQTT) publish(client mqtt.Client, topic string, payload string) {
	client.Publish(topic, 0, false, payload)
	t.LastPublished = fmt.Sprintf("%s %s", topic, payload)
}
<commit_msg>Running 'go fmt'<commit_after>package transport

import (
	"fmt"
	"github.com/eclipse/paho.mqtt.golang"
	"github.com/mannkind/mysb/ota"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"strings"
)

// MQTT - MQTT all the things!
type MQTT struct {
	Settings struct {
		ClientID string
		Broker   string
		SubTopic string
		PubTopic string
	}
	Control       ota.Control
	LastPublished string
}

// NewMQTT - Create a new MQTT
func NewMQTT(filename string) *MQTT {
	log.Printf("Loading configuration file: %s", filename)

	config := MQTT{}
	source, err := ioutil.ReadFile(filename)
	err = yaml.Unmarshal(source, &config)
	if err != nil {
		panic(err)
	}
	log.Println("Configuration file loaded")

	return &config
}

// Start - Connect and Subscribe
func (t *MQTT) Start() error {
	log.Print("Connecting to MQTT... ")
	opts := mqtt.NewClientOptions().
		AddBroker(t.Settings.Broker).
		SetClientID(t.Settings.ClientID).
		SetOnConnectHandler(t.onConnect).
		SetConnectionLostHandler(func(client mqtt.Client, err error) {
			log.Printf("Disconnected: %s", err)
		})

	client := mqtt.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		return token.Error()
	}

	return nil
}

func (t *MQTT) onConnect(client mqtt.Client) {
	log.Println("Connected")

	// Subscribe to topics
	subscriptions := map[string]mqtt.MessageHandler{
		fmt.Sprintf("%s/255/255/3/0/3", t.Settings.SubTopic): t.idRequest,
		fmt.Sprintf("%s/+/255/4/0/0", t.Settings.SubTopic):   t.configurationRequest,
		fmt.Sprintf("%s/+/255/4/0/2", t.Settings.SubTopic):   t.dataRequest,
		"mysensors/bootloader/+/+":                           t.bootloaderCommand,
	}

	for topic, handler := range subscriptions {
		if token := client.Subscribe(topic, 0, handler); token.Wait() && token.Error() != nil {
			log.Print(token.Error())
		}
	}
}

func (t *MQTT) idRequest(client mqtt.Client, msg mqtt.Message) {
	t.publish(client, fmt.Sprintf("%s/255/255/3/0/4", t.Settings.PubTopic), t.Control.IDRequest())
}

func (t *MQTT) configurationRequest(client mqtt.Client, msg mqtt.Message) {
	topic := msg.Topic()
	payload := string(msg.Payload())
	to := strings.Split(topic, "/")[1]

	// Attempt to run any bootloader commands
	if t.runBootloaderCommand(client, to) {
		return
	}

	t.publish(client, fmt.Sprintf("%s/%s/255/4/0/1", t.Settings.PubTopic, to), t.Control.ConfigurationRequest(to, payload))
}

// DataRequest - Handle incoming firmware requests
func (t *MQTT) dataRequest(client mqtt.Client, msg mqtt.Message) {
	topic := msg.Topic()
	payload := string(msg.Payload())
	to := strings.Split(topic, "/")[1]

	t.publish(client, fmt.Sprintf("%s/%s/255/4/0/3", t.Settings.PubTopic, to), t.Control.DataRequest(to, payload))
}

func (t *MQTT) bootloaderCommand(client mqtt.Client, msg mqtt.Message) {
	topic := msg.Topic()
	payload := string(msg.Payload())

	parts := strings.Split(topic, "/")
	to := parts[2]
	cmd := parts[3]

	t.Control.BootloaderCommand(to, cmd, payload)
}

func (t *MQTT) runBootloaderCommand(client mqtt.Client, to string) bool {
	if blcmd, ok := t.Control.Commands[to]; ok {
		outTopic := fmt.Sprintf("%s/%s/255/4/0/1", t.Settings.PubTopic, to)
		outPayload := blcmd.String()
		t.publish(client, outTopic, outPayload)

		delete(t.Control.Commands, to)
		return true
	}

	return false
}

func (t *MQTT) publish(client mqtt.Client, topic string, payload string) {
	client.Publish(topic, 0, false, payload)
	t.LastPublished = fmt.Sprintf("%s %s", topic, payload)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/url"
	"strconv"
)

const (
	ASC  = 1
	DESC = -1
)

type Item interface {
	OrderValue(key string) string
}

type Interface interface {
	Equal(order string, i, j int) bool
	Value(order string, i int) string
	Len() int
}

type Page struct {
	items []Item
}

func (p *Page) Equal(order string, i, j int) bool {
	return p.Value(order, i) == p.Value(order, j)
}

func (p *Page) Value(order string, i int) string {
	return p.items[i].OrderValue(order)
}

func (p *Page) Len() int {
	return len(p.items)
}

type Config struct {
	count     int
	order     string
	direction int
}

type Cursor struct {
	Value     string
	Offset    int
	Count     int
	Order     string
	Direction int
}

func (c Cursor) DirectionString() string {
	if c.Direction == ASC {
		return "asc"
	} else {
		return "desc"
	}
}

func NewCursorFromQuery(query string) (Cursor, error) {
	c := Cursor{}
	m, err := url.ParseQuery(query)
	if err != nil {
		return c, err
	}

	if v, ok := m["value"]; ok {
		c.Value = v[0]
	}
	if v, ok := m["offset"]; ok {
		offset, err := strconv.Atoi(v[0])
		if err != nil {
			return c, err
		}
		c.Offset = offset
	}
	if v, ok := m["count"]; ok {
		count, err := strconv.Atoi(v[0])
		if err != nil {
			return c, err
		}
		c.Count = count
	}
	if v, ok := m["order"]; ok {
		c.Order = v[0]
	}
	if v, ok := m["direction"]; ok {
		switch {
		case v[0] == "desc":
			c.Direction = DESC
		case v[0] == "asc":
			c.Direction = ASC
		default:
			return c, fmt.Errorf("'%s' in not a supported direction, use asc or desc", v)
		}
	}
	return c, nil
}

type Pagination struct {
	Cursor
	config Config
}

func (p *Pagination) max(items Interface) int {
	if items.Len() <= p.Count {
		return items.Len() - 1
	} else {
		return p.Count
	}
}

func (p *Pagination) equalCount(items Interface, order string, max int) int {
	c := 0
	for i := 0; i < p.Count; i++ {
		if items.Equal(order, i, max) {
			c += 1
		}
	}
	return c
}

func NewPagination(cursor Cursor, config Config) *Pagination {
	if cursor.Count == 0 {
		cursor.Count = config.count
	}
	if cursor.Order == "" {
		cursor.Order = config.order
	}
	if cursor.Direction == 0 {
		cursor.Direction = config.direction
	}
	return &Pagination{cursor, config}
}

func (p *Pagination) after(items Interface, last, direction int) *Pagination {
	if items.Len() == 0 {
		return nil
	}
	value := items.Value(p.Order, last)
	offset := p.equalCount(items, p.Order, last)
	if offset == p.Count && value == p.Value {
		offset += p.Offset
	}
	cursor := Cursor{value, offset, p.Count, p.Order, direction}
	return &Pagination{cursor, p.config}
}

func (p *Pagination) prev(items Interface) *Pagination {
	min := 0
	return p.after(items, min, p.Direction*-1)
}

func (p *Pagination) next(items Interface, next_page_prefetched bool) *Pagination {
	if next_page_prefetched && items.Len() <= p.Count {
		return nil
	}
	max := p.max(items)
	return p.after(items, max, p.Direction)
}

func (p *Pagination) toUrl(baseurl *url.URL) (*url.URL, error) {
	query, err := url.ParseQuery(baseurl.RawQuery)
	if err != nil {
		return nil, err
	}
	query.Set("value", p.Value)
	query.Set("offset", strconv.Itoa(p.Offset))
	query.Set("count", strconv.Itoa(p.Count))
	query.Set("order", p.Order)
	query.Set("direction", p.DirectionString())
	newurl, err := url.Parse(baseurl.String())
	if err != nil {
		return nil, err
	}
	newurl.RawQuery = query.Encode()
	return newurl, nil
}

type Comment struct {
	text       string
	created_at int
	updated_at int
}

func (c *Comment) OrderValue(order string) string {
	switch {
	case order == "created_at":
		return strconv.Itoa(c.created_at)
	case order == "updated_at":
		return strconv.Itoa(c.updated_at)
	default:
		return ""
	}
}

func main() {
	items := &Page{[]Item{
		&Comment{"e", 3, 5},
		&Comment{"d", 3, 5},
		&Comment{"c", 2, 5},
		&Comment{"b", 1, 4},
		&Comment{"a", 0, 4},
	}}

	cursor := Cursor{Order: "created_at"}
	config := Config{count: 2, order: "updated_at", direction: DESC}
	pagination := NewPagination(cursor, config)
	next := pagination.next(items, true)
	prev := pagination.prev(items)

	fmt.Printf("next value: %i, offset: %i, direction: %i\n", next.Value, next.Offset, next.Direction)
	fmt.Printf("prev value: %i, offset: %i, direction: %i\n", prev.Value, prev.Offset, prev.Direction)

	u, _ := url.Parse("http://kajic.com?order=updated_at&direction=desc&value=5&offset=0&count=4")
	cursor, _ = NewCursorFromQuery(u.RawQuery)
	pagination = NewPagination(cursor, config)
	next = pagination.next(items, true)
	prev = pagination.prev(items)

	nexturl, _ := next.toUrl(u)
	prevurl, _ := prev.toUrl(u)
	fmt.Println("nexturl", nexturl)
	fmt.Println("prevurl", prevurl)
	fmt.Println("origurl", u)
}
<commit_msg>Rename key to order<commit_after>package main

import (
	"fmt"
	"net/url"
	"strconv"
)

const (
	ASC  = 1
	DESC = -1
)

type Item interface {
	OrderValue(order string) string
}

type Interface interface {
	Equal(order string, i, j int) bool
	Value(order string, i int) string
	Len() int
}

type Page struct {
	items []Item
}

func (p *Page) Equal(order string, i, j int) bool {
	return p.Value(order, i) == p.Value(order, j)
}

func (p *Page) Value(order string, i int) string {
	return p.items[i].OrderValue(order)
}

func (p *Page) Len() int {
	return len(p.items)
}

type Config struct {
	count     int
	order     string
	direction int
}

type Cursor struct {
	Value     string
	Offset    int
	Count     int
	Order     string
	Direction int
}

func (c Cursor) DirectionString() string {
	if c.Direction == ASC {
		return "asc"
	} else {
		return "desc"
	}
}

func NewCursorFromQuery(query string) (Cursor, error) {
	c := Cursor{}
	m, err := url.ParseQuery(query)
	if err != nil {
		return c, err
	}

	if v, ok := m["value"]; ok {
		c.Value = v[0]
	}
	if v, ok := m["offset"]; ok {
		offset, err := strconv.Atoi(v[0])
		if err != nil {
			return c, err
		}
		c.Offset = offset
	}
	if v, ok := m["count"]; ok {
		count, err := strconv.Atoi(v[0])
		if err != nil {
			return c, err
		}
		c.Count = count
	}
	if v, ok := m["order"]; ok {
		c.Order = v[0]
	}
	if v, ok := m["direction"]; ok {
		switch {
		case v[0] == "desc":
			c.Direction = DESC
		case v[0] == "asc":
			c.Direction = ASC
		default:
			return c, fmt.Errorf("'%s' in not a supported direction, use asc or desc", v)
		}
	}
	return c, nil
}

type Pagination struct {
	Cursor
	config Config
}

func (p *Pagination) max(items Interface) int {
	if items.Len() <= p.Count {
		return items.Len() - 1
	} else {
		return p.Count
	}
}

func (p *Pagination) equalCount(items Interface, order string, max int) int {
	c := 0
	for i := 0; i < p.Count; i++ {
		if items.Equal(order, i, max) {
			c += 1
		}
	}
	return c
}

func NewPagination(cursor Cursor, config Config) *Pagination {
	if cursor.Count == 0 {
		cursor.Count = config.count
	}
	if cursor.Order == "" {
		cursor.Order = config.order
	}
	if cursor.Direction == 0 {
		cursor.Direction = config.direction
	}
	return &Pagination{cursor, config}
}

func (p *Pagination) after(items Interface, last, direction int) *Pagination {
	if items.Len() == 0 {
		return nil
	}
	value := items.Value(p.Order, last)
	offset := p.equalCount(items, p.Order, last)
	if offset == p.Count && value == p.Value {
		offset += p.Offset
	}
	cursor := Cursor{value, offset, p.Count, p.Order, direction}
	return &Pagination{cursor, p.config}
}

func (p *Pagination) prev(items Interface) *Pagination {
	min := 0
	return p.after(items, min, p.Direction*-1)
}

func (p *Pagination) next(items Interface, next_page_prefetched bool) *Pagination {
	if next_page_prefetched && items.Len() <= p.Count {
		return nil
	}
	max := p.max(items)
	return p.after(items, max, p.Direction)
}

func (p *Pagination) toUrl(baseurl *url.URL) (*url.URL, error) {
	query, err := url.ParseQuery(baseurl.RawQuery)
	if err != nil {
		return nil, err
	}
	query.Set("value", p.Value)
	query.Set("offset", strconv.Itoa(p.Offset))
	query.Set("count", strconv.Itoa(p.Count))
	query.Set("order", p.Order)
	query.Set("direction", p.DirectionString())
	newurl, err := url.Parse(baseurl.String())
	if err != nil {
		return nil, err
	}
	newurl.RawQuery = query.Encode()
	return newurl, nil
}

type Comment struct {
	text       string
	created_at int
	updated_at int
}

func (c *Comment) OrderValue(order string) string {
	switch {
	case order == "created_at":
		return strconv.Itoa(c.created_at)
	case order == "updated_at":
		return strconv.Itoa(c.updated_at)
	default:
		return ""
	}
}

func main() {
	items := &Page{[]Item{
		&Comment{"e", 3, 5},
		&Comment{"d", 3, 5},
		&Comment{"c", 2, 5},
		&Comment{"b", 1, 4},
		&Comment{"a", 0, 4},
	}}

	cursor := Cursor{Order: "created_at"}
	config := Config{count: 2, order: "updated_at", direction: DESC}
	pagination := NewPagination(cursor, config)
	next := pagination.next(items, true)
	prev := pagination.prev(items)

	fmt.Printf("next value: %i, offset: %i, direction: %i\n", next.Value, next.Offset, next.Direction)
	fmt.Printf("prev value: %i, offset: %i, direction: %i\n", prev.Value, prev.Offset, prev.Direction)

	u, _ := url.Parse("http://kajic.com?order=updated_at&direction=desc&value=5&offset=0&count=4")
	cursor, _ = NewCursorFromQuery(u.RawQuery)
	pagination = NewPagination(cursor, config)
	next = pagination.next(items, true)
	prev = pagination.prev(items)

	nexturl, _ := next.toUrl(u)
	prevurl, _ := prev.toUrl(u)
	fmt.Println("nexturl", nexturl)
	fmt.Println("prevurl", prevurl)
	fmt.Println("origurl", u)
}
<|endoftext|>


<commit_before>package paginate

import (
	"net/url"
	"strconv"
)

const (
	DESC = 0
	ASC  = 1

	DEFAULT_COUNT = 10
)

type Cursor struct {
	Value     string
	Offset    int
	Count     int
	Order     string
	Direction int
	Url       *url.URL
}

func NewCursorFromDefaults(c *Cursor) *Cursor {
	if c == nil {
		c = &Cursor{}
	}
	if c.Count == 0 {
		c.Count = DEFAULT_COUNT
	}
	return c
}

type Item interface {
	PaginationValue(c *Cursor) string
}

type Response struct {
	Next *string `json:"next"`
}

func NewCursorFromUrl(u *url.URL, defaults *Cursor) *Cursor {
	c := NewCursorFromDefaults(defaults)
	c.Url = u

	values := u.Query()
	if v, ok := values["value"]; ok {
		c.Value = v[0]
	}
	if v, ok := values["offset"]; ok {
		offset, err := strconv.Atoi(v[0])
		if err != nil {
			c.Offset = offset
		}
	}
	if v, ok := values["count"]; ok {
		count, err := strconv.Atoi(v[0])
		if err == nil {
			c.Count = count
		}
	}
	if v, ok := values["order"]; ok {
		c.Order = v[0]
	}
	if v, ok := values["direction"]; ok {
		direction, err := strconv.Atoi(v[0])
		if err == nil && (direction == ASC || direction == DESC) {
			c.Direction = direction
		}
	}
	return c
}

func (c *Cursor) lastItemIndex(items []Item) int {
	if len(items) <= c.Count {
		return len(items) - 1
	} else {
		// This is the index of the first item on the next page.
		return c.Count
	}
}

func (c *Cursor) equalCount(items []Item, lastItemIndex int) int {
	count := 0
	for i := 0; i < c.Count; i++ {
		if items[i].PaginationValue(c) == items[lastItemIndex].PaginationValue(c) {
			count += 1
		}
	}
	return count
}

func (c *Cursor) after(items []Item, last, direction int) *Cursor {
	if len(items) == 0 {
		return nil
	}
	value := items[last].PaginationValue(c)
	offset := c.equalCount(items, last)
	if offset == c.Count && value == c.Value {
		offset += c.Offset
	}
	return &Cursor{value, offset, c.Count, c.Order, direction, c.Url}
}

func (c *Cursor) Prev(items []Item) *Cursor {
	lastItemIndex := 0
	var newDirection int
	if c.Direction == ASC {
		newDirection = DESC
	} else {
		newDirection = ASC
	}
	return c.after(items, lastItemIndex, newDirection)
}

func (c *Cursor) Next(items []Item, nextPagePrefetched bool) *Cursor {
	if nextPagePrefetched && len(items) <= c.Count {
		return nil
	}
	return c.after(items, c.lastItemIndex(items), c.Direction)
}

func (c *Cursor) ToUrl() *url.URL {
	newUrl := *c.Url
	values := newUrl.Query()
	values.Set("value", c.Value)
	values.Set("offset", strconv.Itoa(c.Offset))
	values.Set("count", strconv.Itoa(c.Count))
	values.Set("order", c.Order)
	values.Set("direction", strconv.Itoa(c.Direction))
	newUrl.RawQuery = values.Encode()
	return &newUrl
}

func (c *Cursor) ToResponse(items []Item, nextPagePrefetched bool) *Response {
	response := &Response{}
	next := c.Next(items, nextPagePrefetched)
	if next != nil {
		nextUrlString := next.ToUrl().String()
		response.Next = &nextUrlString
	}
	return response
}
<commit_msg>Fix bug	that occurs when there are few items<commit_after>package paginate

import (
	"net/url"
	"strconv"
)

const (
	DESC = 0
	ASC  = 1

	DEFAULT_COUNT = 10
)

type Cursor struct {
	Value     string
	Offset    int
	Count     int
	Order     string
	Direction int
	Url       *url.URL
}

func NewCursorFromDefaults(c *Cursor) *Cursor {
	if c == nil {
		c = &Cursor{}
	}
	if c.Count == 0 {
		c.Count = DEFAULT_COUNT
	}
	return c
}

type Item interface {
	PaginationValue(c *Cursor) string
}

type Response struct {
	Next *string `json:"next"`
}

func NewCursorFromUrl(u *url.URL, defaults *Cursor) *Cursor {
	c := NewCursorFromDefaults(defaults)
	c.Url = u

	values := u.Query()
	if v, ok := values["value"]; ok {
		c.Value = v[0]
	}
	if v, ok := values["offset"]; ok {
		offset, err := strconv.Atoi(v[0])
		if err != nil {
			c.Offset = offset
		}
	}
	if v, ok := values["count"]; ok {
		count, err := strconv.Atoi(v[0])
		if err == nil {
			c.Count = count
		}
	}
	if v, ok := values["order"]; ok {
		c.Order = v[0]
	}
	if v, ok := values["direction"]; ok {
		direction, err := strconv.Atoi(v[0])
		if err == nil && (direction == ASC || direction == DESC) {
			c.Direction = direction
		}
	}
	return c
}

func (c *Cursor) lastItemIndex(items []Item) int {
	if len(items) <= c.Count {
		return len(items) - 1
	} else {
		// This is the index of the first item on the next page.
		return c.Count
	}
}

func (c *Cursor) equalCount(items []Item, lastItemIndex int) int {
	count := 0
	for i := 0; i < len(items) && i < c.Count; i++ {
		if items[i].PaginationValue(c) == items[lastItemIndex].PaginationValue(c) {
			count += 1
		}
	}
	return count
}

func (c *Cursor) after(items []Item, last, direction int) *Cursor {
	if len(items) == 0 {
		return nil
	}
	value := items[last].PaginationValue(c)
	offset := c.equalCount(items, last)
	if offset == c.Count && value == c.Value {
		offset += c.Offset
	}
	return &Cursor{value, offset, c.Count, c.Order, direction, c.Url}
}

func (c *Cursor) Prev(items []Item) *Cursor {
	lastItemIndex := 0
	var newDirection int
	if c.Direction == ASC {
		newDirection = DESC
	} else {
		newDirection = ASC
	}
	return c.after(items, lastItemIndex, newDirection)
}

func (c *Cursor) Next(items []Item, nextPagePrefetched bool) *Cursor {
	if nextPagePrefetched && len(items) <= c.Count {
		return nil
	}
	return c.after(items, c.lastItemIndex(items), c.Direction)
}

func (c *Cursor) ToUrl() *url.URL {
	newUrl := *c.Url
	values := newUrl.Query()
	values.Set("value", c.Value)
	values.Set("offset", strconv.Itoa(c.Offset))
	values.Set("count", strconv.Itoa(c.Count))
	values.Set("order", c.Order)
	values.Set("direction", strconv.Itoa(c.Direction))
	newUrl.RawQuery = values.Encode()
	return &newUrl
}

func (c *Cursor) ToResponse(items []Item, nextPagePrefetched bool) *Response {
	response := &Response{}
	next := c.Next(items, nextPagePrefetched)
	if next != nil {
		nextUrlString := next.ToUrl().String()
		response.Next = &nextUrlString
	}
	return response
}
<|endoftext|>


<commit_before>package main

func match(p Program, q Program) bool {
	if len(p) != len(q) {
		return false
	}
	for i := range p {
		if p[i].Op != q[i].Op {
			return false
		}
		if q[i].Arg != 0 && p[i].Arg != q[i].Arg {
			return false
		}
	}
	return true
}

func loops(p Program) Program {
	for i, cmd := range p {
		if cmd.Op != BNZ {
			continue
		}
		switch b := cmd.Branch; {
		// [-] or [+]
		case match(b, Program{
			Command{Op: Add}}):
			p[i] = Command{Op: Clear}
		// [>] or [<]
		case match(b, Program{
			Command{Op: Move}}):
			p[i] = Command{Op: Search, Arg: b[0].Arg}
		// [->+<]
		case len(b) == 4 && match(b, Program{
			Command{Op: Add, Arg: -1},
			Command{Op: Move},
			Command{Op: Add},
			Command{Op: Move, Arg: -b[1].Arg}}):
			p[i] = Command{
				Op:  Mult,
				Off: b[1].Arg,
				Arg: b[2].Arg,
			}
		// [>+<-]
		case len(b) == 4 && match(b, Program{
			Command{Op: Move},
			Command{Op: Add},
			Command{Op: Move, Arg: -b[0].Arg},
			Command{Op: Add, Arg: -1}}):
			p[i] = Command{
				Op:  Mult,
				Off: b[0].Arg,
				Arg: b[1].Arg,
			}
		// todo: [->+>+<<]
		// todo: [>+>+<<-]
		default:
			p[i].Branch = loops(b)
		}
	}
	return p
}

func scan(p Program) (Command, int) {
	n := 1
	c := p[0]
	for _, cmd := range p[1:] {
		if cmd.Op == c.Op {
			c.Arg += cmd.Arg
			n++
		} else {
			break
		}
	}
	return c, n
}

func contract(p Program) Program {
	var o Program
	for i := 0; i < len(p); i++ {
		cmd := p[i]
		switch cmd.Op {
		case BNZ:
			cmd.Branch = contract(cmd.Branch)
		case Add, Move:
			var n int
			cmd, n = scan(p[i:])
			i += n - 1
		}
		o = append(o, cmd)
	}
	return o
}

func Optimize(p Program) Program {
	o := contract(p)
	return loops(o)
}
<commit_msg>Prepare for futher optimizations<commit_after>package main

func match(p Program, q Program) bool {
	if len(p) != len(q) {
		return false
	}
	for i := range p {
		if p[i].Op != q[i].Op {
			return false
		}
		if q[i].Arg != 0 && p[i].Arg != q[i].Arg {
			return false
		}
	}
	return true
}

func loops(p Program) Program {
	var o Program
	for _, cmd := range p {
		switch cmd.Op {
		case BNZ:
			switch b := cmd.Branch; {
			// [-] or [+]
			case match(b, Program{Command{Op: Add}}):
				o = append(o, Command{Op: Clear})
			// [>] or [<]
			case match(b, Program{Command{Op: Move}}):
				o = append(o, Command{Op: Search, Arg: b[0].Arg})
			// [->+<]
			case len(b) == 4 && match(b, Program{
				Command{Op: Add, Arg: -1},
				Command{Op: Move},
				Command{Op: Add},
				Command{Op: Move, Arg: -b[1].Arg}}):
				o = append(o, Command{
					Op:  Mult,
					Off: b[1].Arg,
					Arg: b[2].Arg,
				})
			// [>+<-]
			case len(b) == 4 && match(b, Program{
				Command{Op: Move},
				Command{Op: Add},
				Command{Op: Move, Arg: -b[0].Arg},
				Command{Op: Add, Arg: -1}}):
				o = append(o, Command{
					Op:  Mult,
					Off: b[0].Arg,
					Arg: b[1].Arg,
				})
			// todo: [->+>+<<]
			// todo: [>+>+<<-]
			default:
				o = append(o, Command{Op: BNZ, Branch: loops(b)})
			}
		default:
			// passthrough
			o = append(o, cmd)
		}
	}
	return o
}

func scan(p Program) (Command, int) {
	n := 1
	c := p[0]
	for _, cmd := range p[1:] {
		if cmd.Op == c.Op {
			c.Arg += cmd.Arg
			n++
		} else {
			break
		}
	}
	return c, n
}

func contract(p Program) Program {
	var o Program
	for i := 0; i < len(p); i++ {
		cmd := p[i]
		switch cmd.Op {
		case BNZ:
			cmd.Branch = contract(cmd.Branch)
		case Add, Move:
			var n int
			cmd, n = scan(p[i:])
			i += n - 1
		}
		o = append(o, cmd)
	}
	return o
}

func Optimize(p Program) Program {
	o := contract(p)
	return loops(o)
}
<|endoftext|>


<commit_before>package pipe

import (
	"sync"
)

type parItem struct {
	index int
	value string
}

// ParallelMap calls fn(x) for every item x in a pool of n
// goroutines and yields the outputs of the fn calls. The output order
// matches the input order.
func ParallelMap(n int, fn func(string) string) Filter {
	return func(arg Arg) {
		// Attach a sequence number to each item.
		source := make(chan parItem, 10000)
		go func() {
			i := 0
			for s := range arg.In {
				source <- parItem{i, s}
				i++
			}
			close(source)
		}()

		// We keep track of outputs in a map indexed by the
		// sequence number of the item.  These items are
		// yielded in order.
		var mu sync.Mutex
		buffered := make(map[int]string)
		next := 0
		nextItemReady := func() bool {
			_, ok := buffered[next]
			return ok
		}

		// Process the items in n go routines.
		var wg sync.WaitGroup
		wg.Add(n)
		for i := 0; i < n; i++ {
			go func() {
				for item := range source {
					s := fn(item.value)
					mu.Lock()
					buffered[item.index] = s
					for nextItemReady() {
						arg.Out <- buffered[next]
						delete(buffered, next)
						next++
					}
					mu.Unlock()
				}
				wg.Done()
			}()
		}
		wg.Wait()
	}
}
<commit_msg>checkpoint<commit_after>package pipe

import (
	"sync"
)

type parItem struct {
	index int
	value string
}

// ParallelMap calls fn(x) for every item x in a pool of n
// goroutines and yields the outputs of the fn calls. The output order
// matches the input order.
func ParallelMap(n int, fn func(string) string) Filter {
	return func(arg Arg) {
		// Attach a sequence number to each item.
		source := make(chan parItem, 10000)
		go func() {
			i := 0
			for s := range arg.In {
				source <- parItem{i, s}
				i++
			}
			close(source)
		}()

		// We keep track of outputs in a map indexed by the item number.
		// These items are yielded in order.
		var mu sync.Mutex
		buffered := make(map[int]string)
		next := 0
		processReadyItem := func() bool {
			x, ok := buffered[next]
			if ok {
				arg.Out <- x
				delete(buffered, next)
				next++
			}
			return ok
		}

		// Process the items in n go routines.
		var wg sync.WaitGroup
		wg.Add(n)
		for i := 0; i < n; i++ {
			go func() {
				for item := range source {
					s := fn(item.value)
					mu.Lock()
					buffered[item.index] = s
					for processReadyItem() {
					}
					mu.Unlock()
				}
				wg.Done()
			}()
		}
		wg.Wait()
	}
}
<|endoftext|>


<commit_before>package cache

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"

	"github.com/Masterminds/glide/msg"
	gpath "github.com/Masterminds/glide/path"
)

var isStarted bool

// SystemLock starts a system rather than application lock. This way multiple
// app instances don't cause race conditions when working in the cache.
func SystemLock() error {
	if isStarted {
		return nil
	}
	err := waitOnLock()
	if err != nil {
		return err
	}
	err = startLock()
	isStarted = true
	return err
}

// SystemUnlock removes the system wide Glide cache lock.
func SystemUnlock() {
	lockdone <- struct{}{}
	os.Remove(lockFileName)
}

var lockdone = make(chan struct{}, 1)

type lockdata struct {
	Comment string `json:"comment"`
	Pid     int    `json:"pid"`
	Time    string `json:"time"`
}

var lockFileName = filepath.Join(gpath.Home(), "lock.json")

// Write a lock for now.
func writeLock() error {
	ld := &lockdata{
		Comment: "File managed by Glide (https://glide.sh)",
		Pid:     os.Getpid(),
		Time:    time.Now().Format(time.RFC3339Nano),
	}

	out, err := json.Marshal(ld)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(lockFileName, out, 0755)
	return err
}

func startLock() error {
	err := writeLock()
	if err != nil {
		return err
	}

	go func() {
		for {
			select {
			case <-lockdone:
				return
			default:
				time.Sleep(10 * time.Second)
				err := writeLock()
				if err != nil {
					msg.Die("Error using Glide lock: %s", err)
				}
			}
		}
	}()

	return nil
}

func waitOnLock() error {
	var announced bool
	for {
		fi, err := os.Stat(lockFileName)
		if err != nil && os.IsNotExist(err) {
			return nil
		} else if err != nil {
			return err
		}

		diff := time.Now().Sub(fi.ModTime())
		if diff.Seconds() > 15 {
			return nil
		}

		if !announced {
			announced = true
			msg.Info("Waiting on Glide global cache access")
		}

		// Check on the lock file every 15 seconds.
		// TODO(mattfarina): should this be a different length?
		time.Sleep(time.Second)
	}
}
<commit_msg>Fixed #590: When exit signal recieved remove global lock<commit_after>package cache

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"os/signal"
	"path/filepath"
	"time"

	"github.com/Masterminds/glide/msg"
	gpath "github.com/Masterminds/glide/path"
)

var isStarted bool

// SystemLock starts a system rather than application lock. This way multiple
// app instances don't cause race conditions when working in the cache.
func SystemLock() error {
	if isStarted {
		return nil
	}
	err := waitOnLock()
	if err != nil {
		return err
	}
	err = startLock()
	isStarted = true
	return err
}

// SystemUnlock removes the system wide Glide cache lock.
func SystemUnlock() {
	lockdone <- struct{}{}
	os.Remove(lockFileName)
}

var lockdone = make(chan struct{}, 1)

type lockdata struct {
	Comment string `json:"comment"`
	Pid     int    `json:"pid"`
	Time    string `json:"time"`
}

var lockFileName = filepath.Join(gpath.Home(), "lock.json")

// Write a lock for now.
func writeLock() error {
	ld := &lockdata{
		Comment: "File managed by Glide (https://glide.sh)",
		Pid:     os.Getpid(),
		Time:    time.Now().Format(time.RFC3339Nano),
	}

	out, err := json.Marshal(ld)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(lockFileName, out, 0755)
	return err
}

func startLock() error {
	err := writeLock()
	if err != nil {
		return err
	}

	go func() {
		for {
			select {
			case <-lockdone:
				return
			default:
				time.Sleep(10 * time.Second)
				err := writeLock()
				if err != nil {
					msg.Die("Error using Glide lock: %s", err)
				}
			}
		}
	}()

	// Capture ctrl-c or other interruptions then clean up the global lock.
	ch := make(chan os.Signal)
	signal.Notify(ch, os.Interrupt, os.Kill)
	go func(cc <-chan os.Signal) {
		s := <-cc
		SystemUnlock()

		// Exiting with the expected exit codes when we can.
		if s == os.Interrupt {
			os.Exit(130)
		} else if s == os.Kill {
			os.Exit(137)
		} else {
			os.Exit(1)
		}
	}(ch)

	return nil
}

func waitOnLock() error {
	var announced bool
	for {
		fi, err := os.Stat(lockFileName)
		if err != nil && os.IsNotExist(err) {
			return nil
		} else if err != nil {
			return err
		}

		diff := time.Now().Sub(fi.ModTime())
		if diff.Seconds() > 15 {
			return nil
		}

		if !announced {
			announced = true
			msg.Info("Waiting on Glide global cache access")
		}

		// Check on the lock file every second.
		time.Sleep(time.Second)
	}
}
<|endoftext|>


<commit_before>package vision

import "regexp"

// Basic rules and regular expressions for validating strings
const (
	Email        string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
	CreditCard   string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$"
	UUID3        string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
	UUID4        string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
	UUID5        string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
	UUID         string = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
	Alpha        string = "^[a-zA-Z]+$"
	Alphanumeric string = "^[a-zA-Z0-9]+$"
	Numeric      string = "^[-+]?[0-9]+$"
	IntNumber    string = "^(?:[-+]?(?:0|[1-9][0-9]*))$"
	FloatNumber  string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$"
	HexColor     string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
	RGBColor     string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$"
	Base64       string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
	DataURI      string = "^data:.+\\/(.+);base64$"
	Latitude     string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
	Longitude    string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
	URL          string = `^((ftp|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`
	Semver       string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
	Trim         string = "[]-+;:{}!@#$%^&*()<>?,./|~`'\"\\ "
	tagName      string = "valid"
)

// Regex checks for validating strings
var (
	regexEmail        = regexp.MustCompile(Email)
	regexCreditCard   = regexp.MustCompile(CreditCard)
	regexUUID3        = regexp.MustCompile(UUID3)
	regexUUID4        = regexp.MustCompile(UUID4)
	regexUUID5        = regexp.MustCompile(UUID5)
	regexUUID         = regexp.MustCompile(UUID)
	regexAlpha        = regexp.MustCompile(Alpha)
	regexAlphanumeric = regexp.MustCompile(Alphanumeric)
	regexNumeric      = regexp.MustCompile(Numeric)
	regexInt          = regexp.MustCompile(IntNumber)
	regexFloat        = regexp.MustCompile(FloatNumber)
	regexHexColor     = regexp.MustCompile(HexColor)
	regexRGBColor     = regexp.MustCompile(RGBColor)
	regexBase64       = regexp.MustCompile(Base64)
	regexDataURI      = regexp.MustCompile(DataURI)
	regexLatitude     = regexp.MustCompile(Latitude)
	regexLongitude    = regexp.MustCompile(Longitude)
	regexURL          = regexp.MustCompile(URL)
	regexSemver       = regexp.MustCompile(Semver)
)
<commit_msg>add us based phone number regex<commit_after>package vision

import "regexp"

// Basic rules and regular expressions for validating strings
const (
	Email         string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
	CreditCard    string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$"
	UUID3         string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
	UUID4         string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
	UUID5         string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
	UUID          string = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
	Alpha         string = "^[a-zA-Z]+$"
	Alphanumeric  string = "^[a-zA-Z0-9]+$"
	Numeric       string = "^[-+]?[0-9]+$"
	IntNumber     string = "^(?:[-+]?(?:0|[1-9][0-9]*))$"
	FloatNumber   string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$"
	USPhoneNumber string = "^(?:(?:\\+?1\\s*(?:[.-]\\s*)?)?(?:\\(\\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\\s*\\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\\s*(?:[.-]\\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\\s*(?:[.-]\\s*)?([0-9]{4})(?:\\s*(?:#|x\\.?|ext\\.?|extension)\\s*(\\d+))?$"
	HexColor      string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
	RGBColor      string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$"
	Base64        string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
	DataURI       string = "^data:.+\\/(.+);base64$"
	Latitude      string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
	Longitude     string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
	URL           string = `^((ftp|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`
	Semver        string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
	Trim          string = "[]-+;:{}!@#$%^&*()<>?,./|~`'\"\\ "
	tagName       string = "valid"
)

// Regex checks for validating strings
var (
	regexEmail         = regexp.MustCompile(Email)
	regexCreditCard    = regexp.MustCompile(CreditCard)
	regexUUID3         = regexp.MustCompile(UUID3)
	regexUUID4         = regexp.MustCompile(UUID4)
	regexUUID5         = regexp.MustCompile(UUID5)
	regexUUID          = regexp.MustCompile(UUID)
	regexAlpha         = regexp.MustCompile(Alpha)
	regexAlphanumeric  = regexp.MustCompile(Alphanumeric)
	regexNumeric       = regexp.MustCompile(Numeric)
	regexInt           = regexp.MustCompile(IntNumber)
	regexFloat         = regexp.MustCompile(FloatNumber)
	regexUSPhoneNumber = regexp.MustCompile(USPhoneNumber)
	regexHexColor      = regexp.MustCompile(HexColor)
	regexRGBColor      = regexp.MustCompile(RGBColor)
	regexBase64        = regexp.MustCompile(Base64)
	regexDataURI       = regexp.MustCompile(DataURI)
	regexLatitude      = regexp.MustCompile(Latitude)
	regexLongitude     = regexp.MustCompile(Longitude)
	regexURL           = regexp.MustCompile(URL)
	regexSemver        = regexp.MustCompile(Semver)
)
<|endoftext|>


<commit_before>/**
 * pecolify: peco works your program
 *
 * @package pecolify
 * @author Yoshiaki Sugimoto
 * @license MIT
 */
package pecolify

import (
	"bufio"
	"context"
	"github.com/peco/peco"
	"io/ioutil"
	"os"
	"strings"
)

//
// Runner struct
//
// stack some temporary data
//
type Runner struct {
	tmpFile    *os.File
	pipeReader *os.File
	pipeWriter *os.File

	oldStdout     *os.File
	oldArgs       []string
	captureBuffer string
}

//
// Create Runner
//
// @public
// @returns *Runner
//
func New() *Runner {
	return &Runner{
		oldStdout: os.Stdout,
		oldArgs:   os.Args,
	}
}

//
// Data pass to peco and get selected line
//
// @public
// @param data []string
// returns string, error
//
func (r *Runner) Transform(data []string) (string, error) {
	var e error

	// create tmpfile
	r.tmpFile, _ = ioutil.TempFile(os.TempDir(), "peconize")
	defer os.Remove(r.tmpFile.Name())

	// swap stdout
	r.pipeReader, r.pipeWriter, e = os.Pipe()
	os.Stdout = r.pipeWriter

	if e = r.runPeco(data); e != nil {
		r.pipeWriter.Close()
		if e != peco.ErrUserCanceled {
			return "", e
		} else {
			return "", nil
		}
	}

	// create blocking channel
	blocker := make(chan struct{}, 1)

	go r.captureOutput(blocker)

	r.pipeWriter.Close()
	<-blocker

	return r.captureBuffer, nil
}

//
// Capture peco's output
//
// @private
// @param blocker chan int
// returns void
//
func (r *Runner) captureOutput(blocker chan int) {
	var lines string

	defer r.pipeReader.Close()

	scanner := bufio.NewScanner(r.pipeReader)
	for scanner.Scan() {
		lines += scanner.Text()
	}

	r.captureBuffer = lines
	blocker <- struct{}{}
}

//
// Run the peco
//
// @private
// @param data []string
// returns error
//
func (r *Runner) runPeco(data []string) error {
	buffer := strings.Join(data, "\n")
	ioutil.WriteFile(r.tmpFile.Name(), []byte(buffer), 0644)

	// Make dummy arguments.
	// Peco will process from tempfile...
	os.Args = []string{"peconize", r.tmpFile.Name()}

	// restore
	defer func() {
		os.Stdout = r.oldStdout
		os.Args = r.oldArgs
	}()

	p := peco.New()
	p.Run(context.Background())
	p.PrintResults()

	return nil
}
<commit_msg>handle user canceled error<commit_after>/**
 * pecolify: peco works your program
 *
 * @package pecolify
 * @author Yoshiaki Sugimoto
 * @license MIT
 */
package pecolify

import (
	"bufio"
	"context"
	"github.com/peco/peco"
	"io/ioutil"
	"os"
	"strings"
)

//
// Runner struct
//
// stack some temporary data
//
type Runner struct {
	tmpFile    *os.File
	pipeReader *os.File
	pipeWriter *os.File

	oldStdout     *os.File
	oldArgs       []string
	captureBuffer string
}

//
// Create Runner
//
// @public
// @returns *Runner
//
func New() *Runner {
	return &Runner{
		oldStdout: os.Stdout,
		oldArgs:   os.Args,
	}
}

//
// Data pass to peco and get selected line
//
// @public
// @param data []string
// returns string, error
//
func (r *Runner) Transform(data []string) (string, error) {
	var e error

	// create tmpfile
	r.tmpFile, _ = ioutil.TempFile(os.TempDir(), "peconize")
	defer os.Remove(r.tmpFile.Name())

	// swap stdout
	r.pipeReader, r.pipeWriter, e = os.Pipe()
	os.Stdout = r.pipeWriter

	if e = r.runPeco(data); e != nil {
		return "", e
	}

	// create blocking channel
	blocker := make(chan struct{}, 1)

	go r.captureOutput(blocker)

	r.pipeWriter.Close()
	<-blocker

	return r.captureBuffer, nil
}

//
// Capture peco's output
//
// @private
// @param blocker chan int
// returns void
//
func (r *Runner) captureOutput(blocker chan int) {
	var lines string

	defer r.pipeReader.Close()

	scanner := bufio.NewScanner(r.pipeReader)
	for scanner.Scan() {
		lines += scanner.Text()
	}

	r.captureBuffer = lines
	blocker <- struct{}{}
}

//
// Run the peco
//
// @private
// @param data []string
// returns error
//
func (r *Runner) runPeco(data []string) error {
	buffer := strings.Join(data, "\n")
	ioutil.WriteFile(r.tmpFile.Name(), []byte(buffer), 0644)

	// Make dummy arguments.
	// Peco will process from tempfile...
	os.Args = []string{"peconize", r.tmpFile.Name()}

	// restore
	defer func() {
		os.Stdout = r.oldStdout
		os.Args = r.oldArgs
	}()

	p := peco.New()
	if err := p.Run(context.Background()); err != nil {
		if err.Error() == "user canceled" {
			return err
		}
	}
	p.PrintResults()

	return nil
}
<|endoftext|>


<commit_before>package search_test

import (
	"github.com/gonum/graph/concrete"
	"github.com/gonum/graph/search"
	"math"
	"testing"
)

func TestFloydWarshall(t *testing.T) {
	dg := concrete.NewDenseGraph(5, false)
	// Adds two paths from 0->2 of equal length
	dg.SetEdgeCost(concrete.GonumNode(0), concrete.GonumNode(2), 2.0, true)
	dg.SetEdgeCost(concrete.GonumNode(0), concrete.GonumNode(1), 1.0, true)
	dg.SetEdgeCost(concrete.GonumNode(1), concrete.GonumNode(2), 1.0, true)

	aPaths, sPath := search.FloydWarshall(dg, nil)
	path, cost, err := sPath(concrete.GonumNode(0), concrete.GonumNode(2))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-2.0) > .00001 {
		t.Errorf("Path has incorrect cost, %f", cost)
	}

	if len(path) == 2 && path[0].ID() == 0 && path[1].ID() == 2 {
		t.Logf("Got correct path: %v", path)
	} else if len(path) == 3 && path[0].ID() == 0 && path[1].ID() == 1 && path[2].ID() == 2 {
		t.Logf("Got correct path %v", path)
	} else {
		t.Errorf("Got wrong path %v", path)
	}

	paths, cost, err := aPaths(concrete.GonumNode(0), concrete.GonumNode(2))

	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-2.0) > .00001 {
		t.Errorf("All paths function gets incorrect cost, %f", cost)
	}

	if len(paths) != 2 {
		t.Fatalf("Didn't get all shortest paths %v", paths)
	}

	for _, path := range paths {
		if len(path) == 2 && path[0].ID() == 0 && path[1].ID() == 2 {
			t.Logf("Got correct path for all paths: %v", path)
		} else if len(path) == 3 && path[0].ID() == 0 && path[1].ID() == 1 && path[2].ID() == 2 {
			t.Logf("Got correct path for all paths %v", path)
		} else {
			t.Errorf("Got wrong path for all paths %v", path)
		}
	}
}
<commit_msg>Added very simple FW test<commit_after>package search_test

import (
	"github.com/gonum/graph/concrete"
	"github.com/gonum/graph/search"
	"math"
	"testing"
)

func TestFWOneEdge(t *testing.T) {
	dg := concrete.NewDenseGraph(2, true)
	aPaths, sPath := search.FloydWarshall(dg, nil)

	path, cost, err := sPath(concrete.GonumNode(0), concrete.GonumNode(1))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-1.0) > .000001 {
		t.Errorf("FW got wrong cost %f", cost)
	}

	if len(path) != 2 || path[0].ID() != 0 && path[1].ID() != 1 {
		t.Errorf("Wrong path in FW %v", path)
	}

	paths, cost, err := aPaths(concrete.GonumNode(0), concrete.GonumNode(1))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-1.0) > .000001 {
		t.Errorf("FW got wrong cost %f", cost)
	}

	if len(paths) != 1 {
		t.Errorf("Didn't get right paths in FW %v", paths)
	}

	path = paths[0]
	if len(path) != 2 || path[0].ID() != 0 && path[1].ID() != 1 {
		t.Errorf("Wrong path in FW allpaths %v", path)
	}
}

func TestFWTwoPaths(t *testing.T) {
	dg := concrete.NewDenseGraph(5, false)
	// Adds two paths from 0->2 of equal length
	dg.SetEdgeCost(concrete.GonumNode(0), concrete.GonumNode(2), 2.0, true)
	dg.SetEdgeCost(concrete.GonumNode(0), concrete.GonumNode(1), 1.0, true)
	dg.SetEdgeCost(concrete.GonumNode(1), concrete.GonumNode(2), 1.0, true)

	aPaths, sPath := search.FloydWarshall(dg, nil)
	path, cost, err := sPath(concrete.GonumNode(0), concrete.GonumNode(2))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-2.0) > .00001 {
		t.Errorf("Path has incorrect cost, %f", cost)
	}

	if len(path) == 2 && path[0].ID() == 0 && path[1].ID() == 2 {
		t.Logf("Got correct path: %v", path)
	} else if len(path) == 3 && path[0].ID() == 0 && path[1].ID() == 1 && path[2].ID() == 2 {
		t.Logf("Got correct path %v", path)
	} else {
		t.Errorf("Got wrong path %v", path)
	}

	paths, cost, err := aPaths(concrete.GonumNode(0), concrete.GonumNode(2))

	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-2.0) > .00001 {
		t.Errorf("All paths function gets incorrect cost, %f", cost)
	}

	if len(paths) != 2 {
		t.Fatalf("Didn't get all shortest paths %v", paths)
	}

	for _, path := range paths {
		if len(path) == 2 && path[0].ID() == 0 && path[1].ID() == 2 {
			t.Logf("Got correct path for all paths: %v", path)
		} else if len(path) == 3 && path[0].ID() == 0 && path[1].ID() == 1 && path[2].ID() == 2 {
			t.Logf("Got correct path for all paths %v", path)
		} else {
			t.Errorf("Got wrong path for all paths %v", path)
		}
	}
}
<|endoftext|>


<commit_before>package handler

import (
	"fmt"
	"net/http"
	"strconv"

	"github.com/mattbostock/leavediary/model"
	"github.com/soh335/ical"
)

func ExportICS(w http.ResponseWriter, r *http.Request) {
	secret := r.URL.Query().Get(":secret")
	job, err := model.FindJobFromExportSecret(secret)
	if err != nil {
		internalError(w, err)
		return
	}

	if job.ID == 0 {
		http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
		return
	}

	user, err := model.FindUser(job.UserID)
	if err != nil {
		internalError(w, err)
		return
	}

	requests, err := job.RequestsLastYearAndFuture()
	if err != nil {
		internalError(w, err)
		return
	}

	cal := ical.NewBasicVCalendar()
	// PRODID must comply with RFC5545
	cal.PRODID = fmt.Sprintf("Lucky Llama Ltd: LeaveDiary v%s", version)
	cal.X_WR_TIMEZONE = user.TZLocation().String()
	cal.X_WR_CALNAME = fmt.Sprintf("Time off for %s", user.Name)

	for _, e := range requests {
		v := &ical.VEvent{
			UID:     "LeaveDiary-" + strconv.FormatUint(e.ID, 10),
			DTSTAMP: e.UpdatedAt,
			DTSTART: e.StartTime,
			DTEND:   e.EndTime,
			SUMMARY: user.Name + " annual leave: " + e.Description,
			TZID:    e.StartTime.Location().String(),

			AllDay: true, // FIXME Once part-day leave is supported
		}
		cal.VComponent = append(cal.VComponent, v)
	}

	w.Header().Set("Content-Disposition", "attachment; filename=\"leavediary.ics\"")
	w.Header().Set("Content-Type", "text/calendar")
	cal.Encode(w)
}
<commit_msg>Add one day to all-day events when exporting ICS<commit_after>package handler

import (
	"fmt"
	"net/http"
	"strconv"

	"github.com/mattbostock/leavediary/model"
	"github.com/soh335/ical"
)

func ExportICS(w http.ResponseWriter, r *http.Request) {
	secret := r.URL.Query().Get(":secret")
	job, err := model.FindJobFromExportSecret(secret)
	if err != nil {
		internalError(w, err)
		return
	}

	if job.ID == 0 {
		http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
		return
	}

	user, err := model.FindUser(job.UserID)
	if err != nil {
		internalError(w, err)
		return
	}

	requests, err := job.RequestsLastYearAndFuture()
	if err != nil {
		internalError(w, err)
		return
	}

	cal := ical.NewBasicVCalendar()
	// PRODID must comply with RFC5545
	cal.PRODID = fmt.Sprintf("Lucky Llama Ltd: LeaveDiary v%s", version)
	cal.X_WR_TIMEZONE = user.TZLocation().String()
	cal.X_WR_CALNAME = fmt.Sprintf("Time off for %s", user.Name)

	for _, e := range requests {
		endTime := e.EndTime

		// Add a day if end time is midnight
		// so that calendering applications will include last
		// day of holiday when rendering all-day events
		//
		// FIXME: Revisit this when adding support for part-day leave
		if e.EndTime.Format("15:04:00") == "00:00:00" {
			endTime = e.EndTime.AddDate(0, 0, 1)
		}

		v := &ical.VEvent{
			UID:     "LeaveDiary-" + strconv.FormatUint(e.ID, 10),
			DTSTAMP: e.UpdatedAt,
			DTSTART: e.StartTime,
			DTEND:   endTime,
			SUMMARY: user.Name + " annual leave: " + e.Description,
			TZID:    e.StartTime.Location().String(),

			AllDay: true, // FIXME Once part-day leave is supported
		}
		cal.VComponent = append(cal.VComponent, v)
	}

	w.Header().Set("Content-Disposition", "attachment; filename=\"leavediary.ics\"")
	w.Header().Set("Content-Type", "text/calendar")
	cal.Encode(w)
}
<|endoftext|>


<commit_before>package handlers

import (
	"io/ioutil"
	"net/http"
	"unicode/utf8"

	"github.com/qa-dev/universe/subscribe"
)

type SubscribeHandler struct {
	subscribeService *subscribe.SubscribeService
}

func NewSubscribeHandler(subscribeService *subscribe.SubscribeService) *SubscribeHandler {
	return &SubscribeHandler{subscribeService}
}

func (h *SubscribeHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	pluginName := req.RequestURI[utf8.RuneCountInString("/subscribe/"):]
	if len(pluginName) == 0 {
		resp.Write([]byte("FAIL: BLANK PLUGIN NAME"))
		return
	}
	input, err := ioutil.ReadAll(req.Body)
	if err != nil {
		resp.Write([]byte("FAIL: BAD REQUEST"))
		return
	}
	defer req.Body.Close()

	err = h.subscribeService.ProcessSubscribe(pluginName, input)
	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		resp.Write([]byte(`{"error": "` + err.Error() + `"}"`))
		return
	}

	resp.WriteHeader(http.StatusOK)
	resp.Write([]byte(`{"status": "ok"}`))

}
<commit_msg>typo fix<commit_after>package handlers

import (
	"io/ioutil"
	"net/http"
	"unicode/utf8"

	"github.com/qa-dev/universe/subscribe"
)

type SubscribeHandler struct {
	subscribeService *subscribe.SubscribeService
}

func NewSubscribeHandler(subscribeService *subscribe.SubscribeService) *SubscribeHandler {
	return &SubscribeHandler{subscribeService}
}

func (h *SubscribeHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	pluginName := req.RequestURI[utf8.RuneCountInString("/subscribe/"):]
	if len(pluginName) == 0 {
		resp.Write([]byte("FAIL: BLANK PLUGIN NAME"))
		return
	}
	input, err := ioutil.ReadAll(req.Body)
	if err != nil {
		resp.Write([]byte("FAIL: BAD REQUEST"))
		return
	}
	defer req.Body.Close()

	err = h.subscribeService.ProcessSubscribe(pluginName, input)
	if err != nil {
		resp.WriteHeader(http.StatusInternalServerError)
		resp.Write([]byte(`{"error": "` + err.Error() + `"}`))
		return
	}

	resp.WriteHeader(http.StatusOK)
	resp.Write([]byte(`{"status": "ok"}`))

}
<|endoftext|>


<commit_before>package config

import (
	"testing"
	"os"
	. "github.com/smartystreets/goconvey/convey"
)

func TestConfig(t *testing.T) {
	err := os.Setenv("PILOSA_CONFIG", "test.yaml")
	if err != nil {
		t.Fatal("Error setting PILOSA_CONFIG")
	}
	Convey("config.Get()", t, func() {
		So(Get("port_tcp").(int), ShouldEqual, 12000)
		So(Get("port_http").(int), ShouldEqual, 15000)
		So(Get("temp").(string), ShouldEqual, "/tmp")
		So(Get("notfound"), ShouldEqual, nil)
	})
	Convey("config.GetSafe()", t, func() {
		val, ok := GetSafe("port_tcp")
		So(ok, ShouldEqual, true)
		So(val.(int), ShouldEqual, 12000)
		val, ok = GetSafe("derp")
		So(ok, ShouldEqual, false)
		So(val, ShouldEqual, nil)
	})
	Convey("config.GetInt()", t, func() {
		So(GetInt("port_tcp"), ShouldEqual, 12000)
		So(GetInt("port_http"), ShouldEqual, 15000)
		So(GetInt("notfound"), ShouldEqual, 0)
	})
	Convey("config.GetString()", t, func() {
		So(GetString("temp"), ShouldEqual, "/tmp")
	})
}
<commit_msg>Better convey usage.<commit_after>package config

import (
	"testing"
	"os"
	. "github.com/smartystreets/goconvey/convey"
)

func TestConfig(t *testing.T) {
	err := os.Setenv("PILOSA_CONFIG", "test.yaml")
	if err != nil {
		t.Fatal("Error setting PILOSA_CONFIG")
	}
	Convey("config.Get()", t, func() {
		So(Get("port_tcp").(int), ShouldEqual, 12000)
		So(Get("port_http").(int), ShouldEqual, 15000)
		So(Get("temp").(string), ShouldEqual, "/tmp")
		So(Get("notfound"), ShouldBeNil)
	})
	Convey("config.GetSafe()", t, func() {
		val, ok := GetSafe("port_tcp")
		So(ok, ShouldBeTrue)
		So(val.(int), ShouldEqual, 12000)
		val, ok = GetSafe("derp")
		So(ok, ShouldBeFalse)
		So(val, ShouldBeNil)
	})
	Convey("config.GetInt()", t, func() {
		So(GetInt("port_tcp"), ShouldEqual, 12000)
		So(GetInt("port_http"), ShouldEqual, 15000)
		So(GetInt("notfound"), ShouldEqual, 0)
	})
	Convey("config.GetString()", t, func() {
		So(GetString("temp"), ShouldEqual, "/tmp")
	})
}
<|endoftext|>


<commit_before>package security

import (
	"fmt"
	"net/http"

	"github.com/WeisswurstSystems/WWM-BB/user/store"
)

func DefAuth(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if checkBasicAuth(r) {
			next(w, r)
			return
		}

		w.Header().Set("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, "Please login to see all users."))
		w.WriteHeader(401)
		w.Write([]byte("401 Unauthorized\n"))
	}
}

//func MeetingAuthenticationHandler(next http.HandlerFunc), meetingid)

//func OrderAuthenticationHandler(next http.HandlerFunc, meetingid, order)

func checkBasicAuth(r *http.Request) bool {
	usermail, password, ok := r.BasicAuth()
	if !ok {
		return false
	}

	findByUserMail, err := store.FindByMail(usermail)

	if err != nil {
		return false
	}

	return password == findByUserMail.Password
}
<commit_msg>change default message<commit_after>package security

import (
	"fmt"
	"net/http"

	"github.com/WeisswurstSystems/WWM-BB/user/store"
)

func DefAuth(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if checkBasicAuth(r) {
			next(w, r)
			return
		}

		w.Header().Set("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, "Your are not authenticated. Please sign in!"))
		w.WriteHeader(401)
		w.Write([]byte("401 Unauthorized\n"))
	}
}

//func MeetingAuthenticationHandler(next http.HandlerFunc), meetingid)

//func OrderAuthenticationHandler(next http.HandlerFunc, meetingid, order)

func checkBasicAuth(r *http.Request) bool {
	usermail, password, ok := r.BasicAuth()
	if !ok {
		return false
	}

	findByUserMail, err := store.FindByMail(usermail)

	if err != nil {
		return false
	}

	return password == findByUserMail.Password
}
<|endoftext|>