<commit_before>package jade

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"testing"
)

var fname = []string{
	"attributes",
	"code",
	"dynamicscript",
	"each",
	"extend",
	"extend-layout",
	"form",
	"includes",
	"layout",
	"mixins",
	"pet",
	"rss",
	"text",
	"whitespace",
}

func TestJadeExamples(t *testing.T) {
	for _, name := range fname {
		fmt.Println("========= testing: " + name + ".jade")

		dat, err := ioutil.ReadFile("testdata/" + name + ".jade")
		if err != nil {
			fmt.Printf("--- FAIL: ReadFile error: %v\n", err)
			t.Fail()
			continue
		}

		tpl, err := Parse("tpl"+name, string(dat))
		if err != nil {
			fmt.Printf("--- FAIL: Parse error: %v\n", err)
			t.Fail()
			continue
		}
		tmpl := bufio.NewScanner(strings.NewReader(tpl))
		tmpl.Split(bufio.ScanLines)

		inFile, err := os.Open("testdata/" + name + ".html")
		if err != nil {
			fmt.Printf("--- FAIL: OpenFile error: %v\n", err)
			t.Fail()
			continue
		}
		file := bufio.NewScanner(inFile)
		file.Split(bufio.ScanLines)

		nilerr := true
		for tmpl.Scan() {
			file.Scan()

			a := tmpl.Text()
			b := file.Text()

			if strings.Compare(a, b) != 0 {
				fmt.Printf("%s\n%s\n___________________________\n", a, b)
				nilerr = false
				t.Fail()
			}
		}
		inFile.Close()

		if nilerr {
			fmt.Println("--- PASS")
		} else {
			fmt.Println("--- FAIL")
		}
	}
	// ioutil.WriteFile("testdata/"+name+".html", []byte(tpl), 0644)
}
<commit_msg>more readable test output<commit_after>package jade

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"testing"
)

var fname = []string{
	"attributes",
	"code",
	"dynamicscript",
	"each",
	"extend",
	"extend-layout",
	"form",
	"includes",
	"layout",
	"mixins",
	"pet",
	"rss",
	"text",
	"whitespace",
}

func TestJadeExamples(t *testing.T) {
	for _, name := range fname {
		fmt.Println("_________" + name + ".jade")

		dat, err := ioutil.ReadFile("testdata/" + name + ".jade")
		if err != nil {
			fmt.Printf("--- FAIL: ReadFile error: %v\n\n", err)
			t.Fail()
			continue
		}

		tpl, err := Parse(name+".jade", string(dat))
		if err != nil {
			fmt.Printf("--- FAIL: Parse error: %v\n\n", err)
			t.Fail()
			continue
		}
		tmpl := bufio.NewScanner(strings.NewReader(tpl))
		tmpl.Split(bufio.ScanLines)

		inFile, err := os.Open("testdata/" + name + ".html")
		if err != nil {
			fmt.Printf("--- FAIL: OpenFile error: %v\n\n", err)
			t.Fail()
			continue
		}
		file := bufio.NewScanner(inFile)
		file.Split(bufio.ScanLines)

		nilerr := 0
		line := 0
		for tmpl.Scan() {
			file.Scan()

			a := tmpl.Text()
			b := file.Text()
			line += 1

			if strings.Compare(a, b) != 0 && nilerr < 4 {
				fmt.Printf("%s\n%s\n%d^___________________________\n", a, b, line)
				nilerr += 1
				t.Fail()
			}
		}
		inFile.Close()

		if nilerr == 0 {
			fmt.Println("    PASS\n")
		} else {
			fmt.Println("--- FAIL\n")
		}
	}
	// ioutil.WriteFile("testdata/"+name+".html", []byte(tpl), 0644)
}
<|endoftext|>


<commit_before>package main

import (
	"ddtxn"
	"ddtxn/apps"
	"ddtxn/dlog"
	"ddtxn/prof"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"os"
	"runtime"
	"sync"
	"time"
)

var nprocs = flag.Int("nprocs", 2, "GOMAXPROCS default 2")
var nsec = flag.Int("nsec", 2, "Time to run in seconds")
var clientGoRoutines = flag.Int("ngo", 0, "Number of goroutines/workers generating client requests.")
var nworkers = flag.Int("nw", 0, "Number of workers")
var doValidate = flag.Bool("validate", false, "Validate")

var contention = flag.Int("contention", 30, "Amount of contention, higher is more")
var nbidders = flag.Int("nb", 1000000, "Bidders in store, default is 1M")
var readrate = flag.Int("rr", 0, "Read rate %.  Rest are bids")
var notcontended_readrate = flag.Float64("ncrr", .8, "Uncontended read rate %.  Default to .8")

var latency = flag.Bool("latency", false, "Measure latency")
var dataFile = flag.String("out", "rubis-data.out", "Filename for output")

func main() {
	flag.Parse()
	runtime.GOMAXPROCS(*nprocs)

	if *clientGoRoutines == 0 {
		*clientGoRoutines = *nprocs
	}
	if *nworkers == 0 {
		*nworkers = *nprocs
	}

	if *doValidate {
		if !*ddtxn.Allocate {
			log.Fatalf("Cannot correctly validate without waiting for results; add -allocate\n")
		}
	}

	nproducts := *nbidders / *contention
	s := ddtxn.NewStore()
	coord := ddtxn.NewCoordinator(*nworkers, s)

	if *ddtxn.CountKeys {
		for i := 0; i < *nworkers; i++ {
			w := coord.Workers[i]
			w.NKeyAccesses = make([]int64, *nbidders)
		}
	}

	rubis := &apps.Rubis{}
	rubis.Init(nproducts, *nbidders, *nworkers, *readrate, *clientGoRoutines, *notcontended_readrate)
	rubis.Populate(s, coord.Workers[0].E)

	dlog.Printf("Done initializing rubis\n")

	p := prof.StartProfile()
	start := time.Now()

	var wg sync.WaitGroup
	for i := 0; i < *clientGoRoutines; i++ {
		wg.Add(1)
		go func(n int) {
			duration := time.Now().Add(time.Duration(*nsec) * time.Second)
			var local_seed uint32 = uint32(rand.Intn(1000000))
			wi := n % (*nworkers)
			w := coord.Workers[wi]
			// It's ok to reuse t because it gets copied in
			// w.One(), and if we're actually reading from t later
			// we pause and don't re-write it until it's done.
			var t ddtxn.Query
			for duration.After(time.Now()) {
				rubis.MakeOne(w.ID, &local_seed, &t)
				if *apps.Latency || *doValidate {
					t.W = make(chan struct {
						R *ddtxn.Result
						E error
					})
					txn_start := time.Now()
					_, err := w.One(t)
					if err == ddtxn.ESTASH {
						x := <-t.W
						err = x.E
					}
					txn_end := time.Since(txn_start)
					if *apps.Latency {
						rubis.Time(&t, txn_end, n)
					}
					if *doValidate {
						if err == nil {
							rubis.Add(t)
						}
					}
				} else {
					w.One(t)
				}
			}
			wg.Done()
		}(i)
	}
	wg.Wait()
	coord.Finish()
	end := time.Since(start)
	p.Stop()
	stats := make([]int64, ddtxn.LAST_STAT)
	nitr, nwait, nwait2 := ddtxn.CollectCounts(coord, stats)
	_ = nwait
	_ = nwait2

	if *doValidate {
		rubis.Validate(s, int(nitr))
	}

	out := fmt.Sprintf(" sys: %v, nworkers: %v, nbidders: %v, nitems: %v, contention: %v, done: %v, actual time: %v, epoch changes: %v, total/sec: %v, throughput: ns/txn: %v, naborts: %v, nwmoved: %v, nrmoved: %v", *ddtxn.SysType, *nworkers, *nbidders, nproducts, *contention, nitr, end, ddtxn.NextEpoch, float64(nitr)/end.Seconds(), end.Nanoseconds()/nitr, stats[ddtxn.NABORTS], ddtxn.WMoved, ddtxn.RMoved)
	fmt.Printf(out)
	fmt.Printf("\n")
	f, err := os.OpenFile(*dataFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	ddtxn.PrintStats(out, stats, f, coord, s, *nbidders)

	x, y := rubis.LatencyString()
	f.WriteString(x)
	f.WriteString(y)
	f.WriteString("\n")
}
<commit_msg>Fix rubis to run properly.<commit_after>package main

import (
	"ddtxn"
	"ddtxn/apps"
	"ddtxn/dlog"
	"ddtxn/prof"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"os"
	"runtime"
	"sync"
	"time"
)

var nprocs = flag.Int("nprocs", 2, "GOMAXPROCS default 2")
var nsec = flag.Int("nsec", 2, "Time to run in seconds")
var clientGoRoutines = flag.Int("ngo", 0, "Number of goroutines/workers generating client requests.")
var nworkers = flag.Int("nw", 0, "Number of workers")
var doValidate = flag.Bool("validate", false, "Validate")

var contention = flag.Int("contention", 30, "Amount of contention, higher is more")
var nbidders = flag.Int("nb", 1000000, "Bidders in store, default is 1M")
var readrate = flag.Int("rr", 0, "Read rate %.  Rest are bids")
var notcontended_readrate = flag.Float64("ncrr", .8, "Uncontended read rate %.  Default to .8")

var dataFile = flag.String("out", "rubis-data.out", "Filename for output")

func main() {
	flag.Parse()
	runtime.GOMAXPROCS(*nprocs)

	if *clientGoRoutines == 0 {
		*clientGoRoutines = *nprocs
	}
	if *nworkers == 0 {
		*nworkers = *nprocs
	}

	if *doValidate {
		if !*ddtxn.Allocate {
			log.Fatalf("Cannot correctly validate without waiting for results; add -allocate\n")
		}
	}

	nproducts := *nbidders / *contention
	s := ddtxn.NewStore()
	coord := ddtxn.NewCoordinator(*nworkers, s)

	if *ddtxn.CountKeys {
		for i := 0; i < *nworkers; i++ {
			w := coord.Workers[i]
			w.NKeyAccesses = make([]int64, *nbidders)
		}
	}

	rubis := &apps.Rubis{}
	rubis.Init(nproducts, *nbidders, *nworkers, *readrate, *clientGoRoutines, *notcontended_readrate)
	rubis.Populate(s, coord.Workers[0].E)

	dlog.Printf("Done initializing rubis\n")

	p := prof.StartProfile()
	start := time.Now()

	var wg sync.WaitGroup
	for i := 0; i < *clientGoRoutines; i++ {
		wg.Add(1)
		go func(n int) {
			duration := time.Now().Add(time.Duration(*nsec) * time.Second)
			var local_seed uint32 = uint32(rand.Intn(1000000))
			wi := n % (*nworkers)
			w := coord.Workers[wi]
			// It's ok to reuse t because it gets copied in
			// w.One(), and if we're actually reading from t later
			// we pause and don't re-write it until it's done.
			var t ddtxn.Query
			for duration.After(time.Now()) {
				rubis.MakeOne(w.ID, &local_seed, &t)
				if *apps.Latency || *doValidate {
					t.W = make(chan struct {
						R *ddtxn.Result
						E error
					})
					txn_start := time.Now()
					_, err := w.One(t)
					if err == ddtxn.ESTASH {
						x := <-t.W
						err = x.E
					}
					txn_end := time.Since(txn_start)
					if *apps.Latency {
						rubis.Time(&t, txn_end, n)
					}
					if *doValidate {
						if err == nil {
							rubis.Add(t)
						}
					}
				} else {
					w.One(t)
				}
			}
			wg.Done()
		}(i)
	}
	wg.Wait()
	coord.Finish()
	end := time.Since(start)
	p.Stop()
	stats := make([]int64, ddtxn.LAST_STAT)
	nitr, nwait, nwait2 := ddtxn.CollectCounts(coord, stats)
	_ = nwait
	_ = nwait2

	if *doValidate {
		rubis.Validate(s, int(nitr))
	}

	out := fmt.Sprintf(" sys: %v, nworkers: %v, nbidders: %v, nitems: %v, contention: %v, done: %v, actual time: %v, epoch changes: %v, total/sec: %v, throughput: ns/txn: %v, naborts: %v, nwmoved: %v, nrmoved: %v", *ddtxn.SysType, *nworkers, *nbidders, nproducts, *contention, nitr, end, ddtxn.NextEpoch, float64(nitr)/end.Seconds(), end.Nanoseconds()/nitr, stats[ddtxn.NABORTS], ddtxn.WMoved, ddtxn.RMoved)
	fmt.Printf(out)
	fmt.Printf("\n")
	f, err := os.OpenFile(*dataFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	ddtxn.PrintStats(out, stats, f, coord, s, *nbidders)

	x, y := rubis.LatencyString()
	f.WriteString(x)
	f.WriteString(y)
	f.WriteString("\n")
}
<|endoftext|>


<commit_before>package bogus

import (
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
)

type HitRecord struct {
	Verb  string
	Path  string
	Query url.Values
	Body  []byte
}

type Bogus struct {
	server     *httptest.Server
	hits       int
	paths      map[string]*Path
	pathsHit   chan string
	hitRecords []HitRecord
}

func New() *Bogus {
	return &Bogus{
		paths: map[string]*Path{},
	}
}

func (b *Bogus) AddPath(path string) *Path {
	if _, ok := b.paths[path]; !ok {
		b.paths[path] = &Path{}
	}

	return b.paths[path]
}

func (b *Bogus) Close() {
	b.server.Close()
}

func (b *Bogus) HandlePaths(w http.ResponseWriter, r *http.Request) {
	b.pathsHit <- r.URL.Path
	b.hits++

	bodyBytes, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()
	b.hitRecords = append(b.hitRecords, HitRecord{r.Method, r.URL.Path, r.URL.Query(), bodyBytes})

	var status int
	var payload []byte

	// if we have only registered the / path, use that
	if path, ok := b.paths["/"]; ok && len(b.paths) == 1 {
		path.hits++
		status = path.status
		payload = path.payload
	} else {
		// if we've registered the given path, let's use it.
		// else if we've not registered a path, return 404
		if path, ok := b.paths[r.URL.Path]; ok {
			path.hits++
			status = path.status
			payload = path.payload
		} else {
			status = http.StatusNotFound
			payload = []byte("Not Found")
		}
	}

	w.WriteHeader(status)
	w.Write(payload)
}

func (b *Bogus) Hits() int {
	return b.hits
}

func (b *Bogus) HitRecords() []HitRecord {
	return b.hitRecords
}

func (b *Bogus) HostPort() (string, string) {
	h, p, _ := net.SplitHostPort(b.server.URL[7:])
	return h, p
}

func (b *Bogus) PathHit() string {
	return <-b.pathsHit
}

func (b *Bogus) SetPayload(p []byte) {
	b.AddPath("/").SetPayload(p)
}

func (b *Bogus) SetStatus(s int) {
	b.AddPath("/").SetStatus(s)
}

func (b *Bogus) Start() {
	b.server = httptest.NewServer(http.HandlerFunc(b.HandlePaths))
	b.pathsHit = make(chan string, 1000)
}
<commit_msg>returning to original logic<commit_after>package bogus

import (
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
)

type HitRecord struct {
	Verb  string
	Path  string
	Query url.Values
	Body  []byte
}

type Bogus struct {
	server     *httptest.Server
	hits       int
	paths      map[string]*Path
	pathsHit   chan string
	hitRecords []HitRecord
}

func New() *Bogus {
	return &Bogus{
		paths: map[string]*Path{},
	}
}

func (b *Bogus) AddPath(path string) *Path {
	if _, ok := b.paths[path]; !ok {
		b.paths[path] = &Path{}
	}

	return b.paths[path]
}

func (b *Bogus) Close() {
	b.server.Close()
}

func (b *Bogus) HandlePaths(w http.ResponseWriter, r *http.Request) {
	b.pathsHit <- r.URL.Path
	b.hits++

	bodyBytes, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()
	b.hitRecords = append(b.hitRecords, HitRecord{r.Method, r.URL.Path, r.URL.Query(), bodyBytes})

	var path *Path
	var ok bool

	// if we have only registered the / path, use that
	// else return 404 for missing paths we've not registered
	if path, ok = b.paths[r.URL.Path]; !ok {
		if path, ok = b.paths["/"]; !ok || len(b.paths) != 1 {
			path = &Path{
				payload: []byte("Not Found"),
				status:  http.StatusNotFound,
			}
		}
	}

	path.hits++
	w.WriteHeader(path.status)
	w.Write(path.payload)
}

func (b *Bogus) Hits() int {
	return b.hits
}

func (b *Bogus) HitRecords() []HitRecord {
	return b.hitRecords
}

func (b *Bogus) HostPort() (string, string) {
	h, p, _ := net.SplitHostPort(b.server.URL[7:])
	return h, p
}

func (b *Bogus) PathHit() string {
	return <-b.pathsHit
}

func (b *Bogus) SetPayload(p []byte) {
	b.AddPath("/").SetPayload(p)
}

func (b *Bogus) SetStatus(s int) {
	b.AddPath("/").SetStatus(s)
}

func (b *Bogus) Start() {
	b.server = httptest.NewServer(http.HandlerFunc(b.HandlePaths))
	b.pathsHit = make(chan string, 1000)
}
<|endoftext|>


<commit_before>package edn

import "fmt"
import "strings"
import "unicode"

// A lot of this is based on: http://cuddle.googlecode.com/hg/talk/lex.html

type tokenType int

const (
	tEOF tokenType = 1 << iota
	tOpenParen
	tCloseParen
	tOpenBrace
	tCloseBrace
	tOpenBracket
	tCloseBracket
	tQuoteNextForm
	tString
	tSymbol
	tKeyword
	tNumber
	tWhitespace // needed?
	tComment    // needed?

	tError
)

type token struct {
	kind  tokenType
	value string
}

func (t *token) String() string {
	switch t.kind {
	case tEOF:
		return "EOF"
	case tError:
		return t.value
	default:
		return fmt.Sprintf("%q", t.value)
	}

	panic("unreachable")
}

func isWhitespace(ch rune) bool {
	return unicode.IsSpace(ch) || ch == ','
}

func lexEDN(l *lexer) {
	for {
		ch, _, err := l.read()

		if err != nil {
			return
		}

		switch ch {
		case '(':
			l.emit(tOpenParen)
		case '[':
			l.emit(tOpenBracket)
		case '{':
			l.emit(tOpenBrace)
		case ')':
			l.emit(tCloseParen)
		case ']':
			l.emit(tCloseBracket)
		case '}':
			l.emit(tCloseBrace)
		case ':': // keyword
		case '\'': l.emit(tQuoteNextForm)
		case '#': // ...
		case '"':
			for {
				// FIXME: strings with \"
				ch, _, _ := l.read()
				if ch == '"' {
					break
				}
			}

			l.emit(tString)
		case ';': // comment
		case '\t', ',', ' ': // whitespace
			for {
				ch, size, _ := l.read()
				if !isWhitespace(ch) {
					l.unread(size)
					break
				}
			}
			// l.emit(tWhitespace)
			l.start = l.position // Temporarily ignore whitespace
		default:
			switch {
				case unicode.IsNumber(ch):
					// TODO: non integer numbers...
					for {
						ch, size, _ := l.read()
						if !unicode.IsNumber(ch) {
							l.unread(size)
							break
						}
					}
					l.emit(tNumber)
			default:
				// TODO: proper error handling
				panic("Unexpected character " + fmt.Sprintf("'%c'", ch))
			}

		}
	}
}

type lexer struct {
	input    string
	reader   *strings.Reader
	start    int
	position int
	tokens   chan token
}

func (l *lexer) peek() (ch rune, size int, err error) {
	ch, size, err = l.read()
	l.unread(size)
	return
}

func (l *lexer) unread(size int) {
	l.reader.UnreadRune()
	l.position -= size
}

func (l *lexer) read() (ch rune, size int, err error) {
	ch, size, err = l.reader.ReadRune()
	l.position += size
	return
}

func (l *lexer) run() {
	lexEDN(l)
	l.emit(tEOF)
	close(l.tokens)
}

func (l *lexer) emit(tt tokenType) {
	value := l.input[l.start:l.position]
	l.start = l.position
	l.tokens <- token{kind: tt, value: value}
}

func (l *lexer) Next() (t token, more bool) {
	t, more = <-l.tokens
	return
}

func Lex(input string) *lexer {
	l := &lexer{
		input:  input,
		reader: strings.NewReader(input),
		tokens: make(chan token, 100),
	}

	go l.run()
	return l
}
<commit_msg>More tokens<commit_after>package edn

import "fmt"
import "strings"
import "unicode"

// A lot of this is based on: http://cuddle.googlecode.com/hg/talk/lex.html

type tokenType int

const (
	tEOF tokenType = 1 << iota
	tOpenParen
	tCloseParen
	tOpenBrace
	tCloseBrace
	tOpenBracket
	tCloseBracket
	tQuoteNextForm
	tOpenSet
	tString
	tSymbol
	tKeyword
	tNumber
	tMetadata
	tIgnoreNextForm
	tWhitespace // needed?
	tComment    // needed?

	tError
)

type token struct {
	kind  tokenType
	value string
}

func (t *token) String() string {
	switch t.kind {
	case tEOF:
		return "EOF"
	case tError:
		return t.value
	default:
		return fmt.Sprintf("%q", t.value)
	}

	panic("unreachable")
}

func isWhitespace(ch rune) bool {
	return unicode.IsSpace(ch) || ch == ','
}

func lexEDN(l *lexer) {
	for {
		ch, _, err := l.read()

		if err != nil {
			return
		}

		switch ch {
		case '(':
			l.emit(tOpenParen)
		case '[':
			l.emit(tOpenBracket)
		case '{':
			l.emit(tOpenBrace)
		case ')':
			l.emit(tCloseParen)
		case ']':
			l.emit(tCloseBracket)
		case '}':
			l.emit(tCloseBrace)
		case ':': // keyword
			// TODO: Read keyword value
			l.emit(tKeyword)
		case '\'': l.emit(tQuoteNextForm)
		case '^': l.emit(tMetadata)
		case '#': // ...
			ch, _, _ := l.read()

			switch ch {
				case '_':
					l.emit(tIgnoreNextForm)
				case '{':
					l.emit(tOpenSet)
				case '^':
					l.emit(tMetadata)
			}
		case '"':
			for {
				// FIXME: strings with \"
				ch, _, _ := l.read()
				if ch == '"' {
					break
				}
			}

			l.emit(tString)
		case ';': // comment
		case '\t', ',', ' ': // whitespace
			for {
				ch, size, _ := l.read()
				if !isWhitespace(ch) {
					l.unread(size)
					break
				}
			}
			// l.emit(tWhitespace)
			l.start = l.position // Temporarily ignore whitespace
		default:
			switch {
				case unicode.IsNumber(ch):
					// TODO: non integer numbers...
					for {
						ch, size, _ := l.read()
						if !unicode.IsNumber(ch) {
							l.unread(size)
							break
						}
					}
					l.emit(tNumber)
			default:
				// TODO: proper error handling
				panic("Unexpected character " + fmt.Sprintf("'%c'", ch))
			}

		}
	}
}

type lexer struct {
	input    string
	reader   *strings.Reader
	start    int
	position int
	tokens   chan token
}

func (l *lexer) peek() (ch rune, size int, err error) {
	ch, size, err = l.read()
	l.unread(size)
	return
}

func (l *lexer) unread(size int) {
	l.reader.UnreadRune()
	l.position -= size
}

func (l *lexer) read() (ch rune, size int, err error) {
	ch, size, err = l.reader.ReadRune()
	l.position += size
	return
}

func (l *lexer) run() {
	lexEDN(l)
	l.emit(tEOF)
	close(l.tokens)
}

func (l *lexer) emit(tt tokenType) {
	value := l.input[l.start:l.position]
	l.start = l.position
	l.tokens <- token{kind: tt, value: value}
}

func (l *lexer) Next() (t token, more bool) {
	t, more = <-l.tokens
	return
}

func Lex(input string) *lexer {
	l := &lexer{
		input:  input,
		reader: strings.NewReader(input),
		tokens: make(chan token, 100),
	}

	go l.run()
	return l
}
<|endoftext|>


<commit_before>package bongo

import (
	"os"

	"github.com/bongo-contrib/loaders"
	"github.com/bongo-contrib/matters"
	"github.com/bongo-contrib/models"
	"github.com/bongo-contrib/renderers"
)

type defaultApp struct {
	loaders.DefaultLoader
	*matters.Matter
	*renderers.DefaultRenderer
}

func newDefaultApp() *defaultApp {
	app := &defaultApp{}
	app.Matter = matters.NewYAML()
	app.DefaultRenderer=renderers.New()
	return app
}

//App is the main bongo application
type App struct {
	gene models.Generator
}

//New creates a new App which uses default models.Generator implementation
func New() *App {
	return NewApp(newDefaultApp())
}

//NewApp creates a new app, that uses g as the generator
func NewApp(g models.Generator) *App {
	return &App{gene: g}
}

// Run runs the app
func (g *App) Run(root string) error {
	files, err := g.gene.Load(root)
	if err != nil {
		return err
	}
	var pages models.PageList
	send := make(chan *models.Page)
	errs := make(chan error)
	for _, f := range files {
		go func(file string) {
			f, err := os.Open(file)
			if err != nil {
				errs <- err
				return
			}
			defer f.Close()
			front, body, err := g.gene.Parse(f)
			if err != nil {
				errs <- err
				return
			}
			stat, err := f.Stat()
			if err != nil {
				errs <- err
				return
			}
			send <- &models.Page{Path: file, Body: body, Data: front, ModTime: stat.ModTime()}
		}(f)
	}
	n := 0
	var fish error
END:
	for {
		select {
		case pg := <-send:
			pages = append(pages, pg)
			n++
		case perr := <-errs:
			fish = perr
			break END

		default:
			if len(files) <= n {
				break END
			}
		}

	}
	if fish != nil {
		return fish
	}

	// run before rendering
	err=g.gene.Before(root)
	if err!=nil{
		return nil
	}
	err = g.gene.Render(root, pages)
	if err != nil {
		renderers.Rollback(root) // roll back before exiting
		return err
	}

	// run after rendering
	err=g.gene.After(root)
	if err!=nil{
		return err
	}
	return nil

}
<commit_msg>preallocate the pages slice<commit_after>package bongo

import (
	"os"

	"github.com/bongo-contrib/loaders"
	"github.com/bongo-contrib/matters"
	"github.com/bongo-contrib/models"
	"github.com/bongo-contrib/renderers"
)

type defaultApp struct {
	loaders.DefaultLoader
	*matters.Matter
	*renderers.DefaultRenderer
}

func newDefaultApp() *defaultApp {
	app := &defaultApp{}
	app.Matter = matters.NewYAML()
	app.DefaultRenderer = renderers.New()
	return app
}

//App is the main bongo application
type App struct {
	gene models.Generator
}

//New creates a new App which uses default models.Generator implementation
func New() *App {
	return NewApp(newDefaultApp())
}

//NewApp creates a new app, that uses g as the generator
func NewApp(g models.Generator) *App {
	return &App{gene: g}
}

// Run runs the app
func (g *App) Run(root string) error {
	files, err := g.gene.Load(root)
	if err != nil {
		return err
	}
	pages := make(models.PageList, len(files))
	send := make(chan *models.Page)
	errs := make(chan error)
	for _, f := range files {
		go func(file string) {
			f, err := os.Open(file)
			if err != nil {
				errs <- err
				return
			}
			defer f.Close()
			front, body, err := g.gene.Parse(f)
			if err != nil {
				errs <- err
				return
			}
			stat, err := f.Stat()
			if err != nil {
				errs <- err
				return
			}
			send <- &models.Page{Path: file, Body: body, Data: front, ModTime: stat.ModTime()}
		}(f)
	}
	n := 0
	var fish error
END:
	for {
		select {
		case pg := <-send:
			pages[n] = pg
			n++
		case perr := <-errs:
			fish = perr
			break END

		default:
			if len(files) <= n {
				break END
			}
		}

	}
	if fish != nil {
		return fish
	}

	// run before rendering
	err = g.gene.Before(root)
	if err != nil {
		return nil
	}
	err = g.gene.Render(root, pages)
	if err != nil {
		renderers.Rollback(root) // roll back before exiting
		return err
	}

	// run after rendering
	err = g.gene.After(root)
	if err != nil {
		return err
	}
	return nil

}
<|endoftext|>


<commit_before>package common

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
)

// Fusion6Driver is a driver that can run VMware Fusion 5.
type Fusion6Driver struct {
	Fusion5Driver
}

func (d *Fusion6Driver) Clone(dst, src string) error {
	cmd := exec.Command(d.vmrunPath(),
		"-T", "fusion",
		"clone", src, dst,
		"full")
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	return nil
}

func (d *Fusion6Driver) Verify() error {
	if err := d.Fusion5Driver.Verify(); err != nil {
		return err
	}

	vmxpath := filepath.Join(d.AppPath, "Contents", "Library", "vmware-vmx")
	if _, err := os.Stat(vmxpath); err != nil {
		if os.IsNotExist(err) {
			return fmt.Errorf("vmware-vmx could not be found at path: %s",
				vmxpath)
		}

		return err
	}

	var stderr bytes.Buffer
	cmd := exec.Command(vmxpath, "-v")
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		return err
	}

	versionRe := regexp.MustCompile(`(?i)VMware [a-z0-9-]+ (\d+\.\d+\.\d+)\s`)
	matches := versionRe.FindStringSubmatch(stderr.String())
	if matches == nil {
		return fmt.Errorf(
			"Couldn't find VMware version in output: %s", stderr.String())
	}
	log.Printf("Detected VMware version: %s", matches[1])

	if !strings.HasPrefix(matches[1], "6.") {
		return fmt.Errorf(
			"Fusion 6 not detected. Got version: %s", matches[1])
	}

	return nil
}
<commit_msg>builder/vmware: better error if clone not supported [GH-787]<commit_after>package common

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
)

// Fusion6Driver is a driver that can run VMware Fusion 5.
type Fusion6Driver struct {
	Fusion5Driver
}

func (d *Fusion6Driver) Clone(dst, src string) error {
	cmd := exec.Command(d.vmrunPath(),
		"-T", "fusion",
		"clone", src, dst,
		"full")
	if _, _, err := runAndLog(cmd); err != nil {
		if strings.Contains(err.Error(), "parameters was invalid") {
			return fmt.Errorf(
				"Clone is not supported with your version of Fusion. Packer " +
				"only works with Fusion 6 Professional. Please verify your version.")
		}

		return err
	}

	return nil
}

func (d *Fusion6Driver) Verify() error {
	if err := d.Fusion5Driver.Verify(); err != nil {
		return err
	}

	vmxpath := filepath.Join(d.AppPath, "Contents", "Library", "vmware-vmx")
	if _, err := os.Stat(vmxpath); err != nil {
		if os.IsNotExist(err) {
			return fmt.Errorf("vmware-vmx could not be found at path: %s",
				vmxpath)
		}

		return err
	}

	var stderr bytes.Buffer
	cmd := exec.Command(vmxpath, "-v")
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		return err
	}

	versionRe := regexp.MustCompile(`(?i)VMware [a-z0-9-]+ (\d+\.\d+\.\d+)\s`)
	matches := versionRe.FindStringSubmatch(stderr.String())
	if matches == nil {
		return fmt.Errorf(
			"Couldn't find VMware version in output: %s", stderr.String())
	}
	log.Printf("Detected VMware version: %s", matches[1])

	if !strings.HasPrefix(matches[1], "6.") {
		return fmt.Errorf(
			"Fusion 6 not detected. Got version: %s", matches[1])
	}

	return nil
}
<|endoftext|>


<commit_before>package client

import (
	// Stdlib
	"fmt"
	"log"
	"strings"

	// Vendor
	"github.com/pkg/errors"
)

//We check whether there is a voter on the list of those who have already voted
func (api *Client) Verify_Voter_Weight(author, permlink, voter string, weight int) bool {
	ans, err := api.Rpc.Database.GetActiveVotes(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Voter: "))
		return false
	} else {
		for _, v := range ans {
			if v.Voter == voter && v.Percent == weight {
				return true
			}
		}
		return false
	}
}

func (api *Client) Verify_Voter(author, permlink, voter string) bool {
	ans, err := api.Rpc.Database.GetActiveVotes(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Voter: "))
		return false
	} else {
		for _, v := range ans {
			if v.Voter == voter {
				return true
			}
		}
		return false
	}
}

//We check whether there are voted
func (api *Client) Verify_Votes(author, permlink string) bool {
	ans, err := api.Rpc.Database.GetActiveVotes(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Votes: "))
		return false
	} else {
		if len(ans) > 0 {
			return true
		} else {
			return false
		}
	}
}

func (api *Client) Verify_Comments(author, permlink string) bool {
	ans, err := api.Rpc.Database.GetContentReplies(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Comments: "))
		return false
	} else {
		if len(ans) > 0 {
			return true
		} else {
			return false
		}
	}
}

func (api *Client) Verify_Reblogs(author, permlink, rebloger string) bool {
	ans, err := api.Rpc.Follow.GetRebloggedBy(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Reblogs: "))
		return false
	} else {
		for _, v := range ans {
			if v == rebloger {
				return true
			}
		}
		return false
	}
}

func (api *Client) Verify_Follow(follower, following string) bool {
	ans, err := api.Rpc.Follow.GetFollowing(follower, following, "blog", 1)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Follow: "))
		return false
	} else {
		for _, v := range ans {
			if (v.Follower == follower) && (v.Following == following) {
				return true
			} else {
				return false
			}
		}
		return false
	}
}

func (api *Client) Verify_Post(author, permlink string) bool {
	ans, err := api.Rpc.Database.GetContent(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Post: "))
		return false
	} else {
		if (ans.Author == author) && (ans.Permlink == permlink) {
			return true
		} else {
			return false
		}
		return false
	}
}

func (api *Client) Verify_Delegate_Posting_Key_Sign(username string, arr []string) []string {
	var truearr []string

	acc, err := api.Rpc.Database.GetAccounts(arr)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Delegate Vote Sign: "))
		return nil
	} else {
		for _, val := range acc {
			for _, v := range val.Posting.AccountAuths {
				l := strings.Split(strings.Replace(strings.Replace(fmt.Sprintf("%v", v), "[", "", -1), "]", "", -1), " ")[0]
				if l == username {
					truearr = append(truearr, val.Name)
				}
			}
		}
	}

	return truearr
}
<commit_msg>Check vesting shares (#52)<commit_after>package client

import (
	// Stdlib
	"fmt"
	"log"
	"strings"
	"strconv"
	"math/big"

	// Vendor
	"github.com/pkg/errors"
)

//We check whether there is a voter on the list of those who have already voted
func (api *Client) Verify_Voter_Weight(author, permlink, voter string, weight int) bool {
	ans, err := api.Rpc.Database.GetActiveVotes(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Voter: "))
		return false
	} else {
		for _, v := range ans {
			if v.Voter == voter && v.Percent == weight {
				return true
			}
		}
		return false
	}
}

func (api *Client) Verify_Voter(author, permlink, voter string) bool {
	ans, err := api.Rpc.Database.GetActiveVotes(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Voter: "))
		return false
	} else {
		for _, v := range ans {
			if v.Voter == voter {
				return true
			}
		}
		return false
	}
}

//We check whether there are voted
func (api *Client) Verify_Votes(author, permlink string) bool {
	ans, err := api.Rpc.Database.GetActiveVotes(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Votes: "))
		return false
	} else {
		if len(ans) > 0 {
			return true
		} else {
			return false
		}
	}
}

func (api *Client) Verify_Comments(author, permlink string) bool {
	ans, err := api.Rpc.Database.GetContentReplies(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Comments: "))
		return false
	} else {
		if len(ans) > 0 {
			return true
		} else {
			return false
		}
	}
}

func (api *Client) Verify_Reblogs(author, permlink, rebloger string) bool {
	ans, err := api.Rpc.Follow.GetRebloggedBy(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Reblogs: "))
		return false
	} else {
		for _, v := range ans {
			if v == rebloger {
				return true
			}
		}
		return false
	}
}

func (api *Client) Verify_Follow(follower, following string) bool {
	ans, err := api.Rpc.Follow.GetFollowing(follower, following, "blog", 1)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Follow: "))
		return false
	} else {
		for _, v := range ans {
			if (v.Follower == follower) && (v.Following == following) {
				return true
			} else {
				return false
			}
		}
		return false
	}
}

func (api *Client) Verify_Post(author, permlink string) bool {
	ans, err := api.Rpc.Database.GetContent(author, permlink)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Post: "))
		return false
	} else {
		if (ans.Author == author) && (ans.Permlink == permlink) {
			return true
		} else {
			return false
		}
		return false
	}
}

func (api *Client) Verify_Delegate_Posting_Key_Sign(username string, arr []string) []string {
	var truearr []string

	props, err := api.Rpc.Database.GetDynamicGlobalProperties()
	if err != nil {
		log.Println(errors.Wrap(err, "Error Get Dynamic Global Properties"))
		return nil
	}
	totalVestingShares, err := strconv.ParseFloat(strings.Split(props.TotalVestingShares, " ")[0], 64)
	if err != nil {
		log.Println(errors.Wrap(err, "Error Parse Total Vesting Shares"))
		return nil
	}
	totalVestingSharesInt, _ := new(big.Float).SetFloat64(totalVestingShares).Int(nil)
	maxVirtualBandwidth := props.MaxVirtualBandwidth.Int

	acc, err := api.Rpc.Database.GetAccounts(arr)
	if err != nil {
		log.Println(errors.Wrapf(err, "Error Verify Delegate Vote Sign: "))
		return nil
	} else {
		for _, val := range acc {
			if !val.CanVote {
				continue
			}
			vestingShares, err := strconv.ParseFloat(strings.Split(val.VestingShares, " ")[0], 64)
			if err != nil {
				log.Println(errors.Wrap(err, "Error Parse Vesting Shares"))
				continue
			}
			if vestingShares < 0 {
				continue
			}
			vestingSharesInt, _ := new(big.Float).SetFloat64(vestingShares).Int(nil)
			firstCondition := new(big.Int).Mul(vestingSharesInt, maxVirtualBandwidth)
			secondCondition := new(big.Int).Mul(val.AverageBandwidth.Int, totalVestingSharesInt)
			log.Printf("Разность: %s", new(big.Int).Sub(firstCondition, secondCondition).String())
			if firstCondition.Cmp(secondCondition) == -1 {
				log.Printf("Аккаунт %s has exceeded maximum allowed bandwidth per vesting share", val.Name)
				continue
			}
			for _, v := range val.Posting.AccountAuths {
				l := strings.Split(strings.Replace(strings.Replace(fmt.Sprintf("%v", v), "[", "", -1), "]", "", -1), " ")[0]
				if l == username {
					truearr = append(truearr, val.Name)
				}
			}
		}
	}

	return truearr
}
<|endoftext|>


<commit_before>package glfw3

/*
// Choose OpenGL client on 386 and amd64.
#cgo 386 CFLAGS: -D_GLFW_USE_OPENGL
#cgo amd64 CFLAGS: -D_GLFW_USE_OPENGL

// Choose OpenGL ES V2 on arm.
#cgo arm CFLAGS: -D_GLFW_USE_GLESV2

// Windows Build Tags
// ----------------
// GLFW Options:
#cgo windows CFLAGS: -D_GLFW_WIN32 -D_GLFW_WGL

// Linker Options:
#cgo windows LDFLAGS: -lopengl32 -lgdi32

// Darwin Build Tags
// ----------------
// GLFW Options:
#cgo darwin CFLAGS: -D_GLFW_COCOA -D_GLFW_NSGL -D_GLFW_USE_CHDIR -D_GLFW_USE_MENUBAR -D_GLFW_USE_RETINA -Wno-deprecated-declarations

// Linker Options:
#cgo darwin LDFLAGS: -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo

// Linux Build Tags
// ----------------
// GLFW Options:
#cgo linux,!wayland CFLAGS: -D_GLFW_X11 -D_GLFW_GLX -D_GLFW_HAS_GLXGETPROCADDRESSARB -D_GLFW_HAS_DLOPEN
#cgo linux,wayland CFLAGS: -D_GLFW_WAYLAND -D_GLFW_EGL -D_GLFW_HAS_DLOPEN

// Linker Options:
#cgo linux,!wayland LDFLAGS: -lGL -lX11 -lXrandr -lXxf86vm -lXi -lXcursor -lm -lXinerama
#cgo linux,wayland LDFLAGS: -lGL -lX11 -lXrandr -lXxf86vm -lXi -lXcursor -lm -lXinerama

// FreeBSD Build Tags
// ----------------
// GLFW Options:
#cgo freebsd,!wayland CFLAGS: -D_GLFW_X11 -D_GLFW_GLX -D_GLFW_HAS_GLXGETPROCADDRESSARB -D_GLFW_HAS_DLOPEN
#cgo freebsd,wayland CFLAGS: -D_GLFW_WAYLAND -D_GLFW_EGL -D_GLFW_HAS_DLOPEN

// Linker Options:
#cgo freebsd,!wayland LDFLAGS: -lGL -lX11 -lXrandr -lXxf86vm -lXi -lXcursor -lm
#cgo freebsd,wayland LDFLAGS: -lGL -lX11 -lXrandr -lXxf86vm -lXi -lXcursor -lm
*/
import "C"
<commit_msg>Allow use of OpenGL ES 2 on Desktop platforms with -tags=gles2<commit_after>package glfw3

/*
// Standard OpenGL client is used on 386 and amd64 architectures, except when
// explicitly asked for gles2 or wayland.
#cgo 386,!gles2,!wayland CFLAGS: -D_GLFW_USE_OPENGL
#cgo amd64,!gles2,!wayland CFLAGS: -D_GLFW_USE_OPENGL

// Choose OpenGL ES V2 on arm, or when explicitly asked for gles2/wayland.
#cgo arm gles2 wayland CFLAGS: -D_GLFW_USE_GLESV2

// Windows Build Tags
// ----------------
// GLFW Options:
#cgo windows CFLAGS: -D_GLFW_WIN32 -D_GLFW_WGL

// Linker Options:
#cgo windows LDFLAGS: -lopengl32 -lgdi32

// Darwin Build Tags
// ----------------
// GLFW Options:
#cgo darwin CFLAGS: -D_GLFW_COCOA -D_GLFW_NSGL -D_GLFW_USE_CHDIR -D_GLFW_USE_MENUBAR -D_GLFW_USE_RETINA -Wno-deprecated-declarations

// Linker Options:
#cgo darwin LDFLAGS: -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo

// Linux Build Tags
// ----------------
// GLFW Options:
#cgo linux,!wayland CFLAGS: -D_GLFW_X11 -D_GLFW_GLX -D_GLFW_HAS_GLXGETPROCADDRESSARB -D_GLFW_HAS_DLOPEN
#cgo linux,wayland CFLAGS: -D_GLFW_WAYLAND -D_GLFW_EGL -D_GLFW_HAS_DLOPEN

// Linker Options:
#cgo linux,!wayland LDFLAGS: -lGL -lX11 -lXrandr -lXxf86vm -lXi -lXcursor -lm -lXinerama
#cgo linux,wayland LDFLAGS: -lGL -lX11 -lXrandr -lXxf86vm -lXi -lXcursor -lm -lXinerama

// FreeBSD Build Tags
// ----------------
// GLFW Options:
#cgo freebsd,!wayland CFLAGS: -D_GLFW_X11 -D_GLFW_GLX -D_GLFW_HAS_GLXGETPROCADDRESSARB -D_GLFW_HAS_DLOPEN
#cgo freebsd,wayland CFLAGS: -D_GLFW_WAYLAND -D_GLFW_EGL -D_GLFW_HAS_DLOPEN

// Linker Options:
#cgo freebsd,!wayland LDFLAGS: -lGL -lX11 -lXrandr -lXxf86vm -lXi -lXcursor -lm
#cgo freebsd,wayland LDFLAGS: -lGL -lX11 -lXrandr -lXxf86vm -lXi -lXcursor -lm
*/
import "C"
<|endoftext|>


<commit_before>package nameserver

import (
	"github.com/miekg/dns"
	"math"
	"net"
	"time"
)

// Portions of this code taken from github.com/armon/mdns

const (
	ipv4mdns = "224.0.0.251" // link-local multicast address
	mdnsPort = 5353          // mDNS assigned port
	// We wait this long to hear a response from other mDNS servers on
	// the network.
	mDNSTimeout = 500 * time.Millisecond
	MaxDuration = time.Duration(math.MaxInt64)
	MailboxSize = 16
)

var (
	ipv4Addr = &net.UDPAddr{
		IP:   net.ParseIP(ipv4mdns),
		Port: mdnsPort,
	}
)

type Response struct {
	Name string
	Addr net.IP
	Err  error
}

type responseInfo struct {
	timeout time.Time // if no answer by this time, give up
	ch      chan<- *Response
}

// Represents one query that we have sent for one name.
// If we, internally, get several requests for the same name while we have
// a query in flight, then we don't want to send more queries out.
// Invariant on responseInfos: they are in ascending order of timeout.
type inflightQuery struct {
	name          string
	id            uint16 // the DNS message ID
	responseInfos []*responseInfo
}

type MDNSClient struct {
	// note unorthodox use of 'Server' class in client logic - using it to
	// listen on a multicast socket and call callback whenever a message comes in.
	listener  *dns.Server
	conn      *net.UDPConn
	addr      *net.UDPAddr
	inflight  map[string]*inflightQuery
	queryChan chan<- *MDNSInteraction
}

type mDNSQueryInfo struct {
	name       string
	querytype  uint16
	responseCh chan<- *Response
}

func NewMDNSClient() (*MDNSClient, error) {
	if conn, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0}); err != nil {
		return nil, err
	} else {
		return &MDNSClient{
			conn:     conn,
			addr:     ipv4Addr,
			inflight: make(map[string]*inflightQuery)}, nil
	}
}

func (c *MDNSClient) Start(ifi *net.Interface) error {
	multicast, err := LinkLocalMulticastListener(ifi)
	if err != nil {
		return err
	}

	handleMDNS := func(w dns.ResponseWriter, r *dns.Msg) {
		// Don't want to handle queries here, so filter anything out that isn't a response
		if len(r.Answer) > 0 {
			c.ResponseCallback(r)
		}
	}

	c.listener = &dns.Server{Unsafe: true, PacketConn: multicast, Handler: dns.HandlerFunc(handleMDNS)}
	go c.listener.ActivateAndServe()

	queryChan := make(chan *MDNSInteraction, MailboxSize)
	c.queryChan = queryChan
	go c.queryLoop(queryChan)

	return nil
}

func LinkLocalMulticastListener(ifi *net.Interface) (net.PacketConn, error) {
	return net.ListenMulticastUDP("udp", ifi, ipv4Addr)
}

// ACTOR client API

const (
	CSendQuery = iota
	CShutdown
	CMessageReceived
)

type MDNSInteraction struct {
	code       int
	resultChan chan<- interface{}
	payload    interface{}
}

// Async
func (c *MDNSClient) Shutdown() {
	c.queryChan <- &MDNSInteraction{code: CShutdown}
}

// Async
func (c *MDNSClient) SendQuery(name string, querytype uint16, responseCh chan<- *Response) {
	c.queryChan <- &MDNSInteraction{
		code:    CSendQuery,
		payload: mDNSQueryInfo{name, querytype, responseCh},
	}
}

// Async - called from dns library multiplexer
func (c *MDNSClient) ResponseCallback(r *dns.Msg) {
	c.queryChan <- &MDNSInteraction{code: CMessageReceived, payload: r}
}

// ACTOR server

// Check all in-flight queries, close all that have already timed out,
// and return the duration until the next timeout
func (c *MDNSClient) checkInFlightQueries() time.Duration {
	now := time.Now()
	after := MaxDuration
	for name, query := range c.inflight {
		// Invariant on responseInfos: they are in ascending order of timeout.
		numClosed := 0
		for _, item := range query.responseInfos {
			duration := item.timeout.Sub(now)
			if duration <= 0 { // timed out
				close(item.ch)
				numClosed++
			} else {
				if duration < after {
					after = duration
				}
				break // don't need to look at any more for this query
			}
		}
		// Remove timed-out items from the slice
		query.responseInfos = query.responseInfos[numClosed:]
		if len(query.responseInfos) == 0 {
			delete(c.inflight, name)
		}
	}
	return after
}

func (c *MDNSClient) queryLoop(queryChan <-chan *MDNSInteraction) {
	timer := time.NewTimer(MaxDuration)
	run := func() { timer.Reset(c.checkInFlightQueries()) }
	terminate := false
	for !terminate {
		select {
		case query, ok := <-queryChan:
			if !ok {
				break
			}
			switch query.code {
			case CShutdown:
				c.listener.Shutdown()
				terminate = true
			case CSendQuery:
				c.handleSendQuery(query.payload.(mDNSQueryInfo))
				run()
			case CMessageReceived:
				c.handleResponse(query.payload.(*dns.Msg))
				run()
			}
		case <-timer.C:
			run()
		}
	}

	// Close all response channels at termination
	for _, query := range c.inflight {
		for _, item := range query.responseInfos {
			close(item.ch)
		}
	}
}

func (c *MDNSClient) handleSendQuery(q mDNSQueryInfo) {
	query, found := c.inflight[q.name]
	if !found {
		m := new(dns.Msg)
		m.SetQuestion(q.name, q.querytype)
		m.RecursionDesired = false
		buf, err := m.Pack()
		if err != nil {
			q.responseCh <- &Response{Err: err}
			close(q.responseCh)
			return
		}
		query = &inflightQuery{
			name: q.name,
			id:   m.Id,
		}
		if _, err = c.conn.WriteTo(buf, c.addr); err != nil {
			q.responseCh <- &Response{Err: err}
			close(q.responseCh)
			return
		}
		c.inflight[q.name] = query
	}
	info := &responseInfo{
		ch:      q.responseCh,
		timeout: time.Now().Add(mDNSTimeout),
	}
	// Invariant on responseInfos: they are in ascending order of timeout.
	// Since we use a fixed interval from Now(), this must be after all existing timeouts.
	query.responseInfos = append(query.responseInfos, info)
}

func (c *MDNSClient) handleResponse(r *dns.Msg) {
	for _, answer := range r.Answer {
		var name string
		var res *Response

		switch rr := answer.(type) {
		case *dns.A:
			name = rr.Hdr.Name
			res = &Response{Addr: rr.A}
		case *dns.PTR:
			name = rr.Hdr.Name
			res = &Response{Name: rr.Ptr}
		default:
			return
		}

		if query, found := c.inflight[name]; found {
			for _, resp := range query.responseInfos {
				resp.ch <- res
				close(resp.ch)
			}
			delete(c.inflight, name)
		} else {
			// We've received a response that didn't match a query
			// Do we want to cache it?
		}
	}
}
<commit_msg>convert MDNSClient actor to use closures for methods We use a 'nil' closure to indicate shutdown.<commit_after>package nameserver

import (
	"github.com/miekg/dns"
	"math"
	"net"
	"time"
)

// Portions of this code taken from github.com/armon/mdns

const (
	ipv4mdns = "224.0.0.251" // link-local multicast address
	mdnsPort = 5353          // mDNS assigned port
	// We wait this long to hear a response from other mDNS servers on
	// the network.
	mDNSTimeout = 500 * time.Millisecond
	MaxDuration = time.Duration(math.MaxInt64)
	MailboxSize = 16
)

var (
	ipv4Addr = &net.UDPAddr{
		IP:   net.ParseIP(ipv4mdns),
		Port: mdnsPort,
	}
)

type Response struct {
	Name string
	Addr net.IP
	Err  error
}

type responseInfo struct {
	timeout time.Time // if no answer by this time, give up
	ch      chan<- *Response
}

// Represents one query that we have sent for one name.
// If we, internally, get several requests for the same name while we have
// a query in flight, then we don't want to send more queries out.
// Invariant on responseInfos: they are in ascending order of timeout.
type inflightQuery struct {
	name          string
	id            uint16 // the DNS message ID
	responseInfos []*responseInfo
}

type MDNSClient struct {
	// note unorthodox use of 'Server' class in client logic - using it to
	// listen on a multicast socket and call callback whenever a message comes in.
	listener   *dns.Server
	conn       *net.UDPConn
	addr       *net.UDPAddr
	inflight   map[string]*inflightQuery
	actionChan chan<- MDNSAction
}

type mDNSQueryInfo struct {
	name       string
	querytype  uint16
	responseCh chan<- *Response
}

func NewMDNSClient() (*MDNSClient, error) {
	if conn, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0}); err != nil {
		return nil, err
	} else {
		return &MDNSClient{
			conn:     conn,
			addr:     ipv4Addr,
			inflight: make(map[string]*inflightQuery)}, nil
	}
}

func (c *MDNSClient) Start(ifi *net.Interface) error {
	multicast, err := LinkLocalMulticastListener(ifi)
	if err != nil {
		return err
	}

	handleMDNS := func(w dns.ResponseWriter, r *dns.Msg) {
		// Don't want to handle queries here, so filter anything out that isn't a response
		if len(r.Answer) > 0 {
			c.ResponseCallback(r)
		}
	}

	c.listener = &dns.Server{Unsafe: true, PacketConn: multicast, Handler: dns.HandlerFunc(handleMDNS)}
	go c.listener.ActivateAndServe()

	actionChan := make(chan MDNSAction, MailboxSize)
	c.actionChan = actionChan
	go c.actorLoop(actionChan)

	return nil
}

func LinkLocalMulticastListener(ifi *net.Interface) (net.PacketConn, error) {
	return net.ListenMulticastUDP("udp", ifi, ipv4Addr)
}

// ACTOR client API

type MDNSAction func()

// Async
func (c *MDNSClient) Shutdown() {
	c.actionChan <- nil
}

// Async
func (c *MDNSClient) SendQuery(name string, querytype uint16, responseCh chan<- *Response) {
	c.actionChan <- func() {
		query, found := c.inflight[name]
		if !found {
			m := new(dns.Msg)
			m.SetQuestion(name, querytype)
			m.RecursionDesired = false
			buf, err := m.Pack()
			if err != nil {
				responseCh <- &Response{Err: err}
				close(responseCh)
				return
			}
			query = &inflightQuery{
				name: name,
				id:   m.Id,
			}
			if _, err = c.conn.WriteTo(buf, c.addr); err != nil {
				responseCh <- &Response{Err: err}
				close(responseCh)
				return
			}
			c.inflight[name] = query
		}
		info := &responseInfo{
			ch:      responseCh,
			timeout: time.Now().Add(mDNSTimeout),
		}
		// Invariant on responseInfos: they are in ascending order of
		// timeout.  Since we use a fixed interval from Now(), this
		// must be after all existing timeouts.
		query.responseInfos = append(query.responseInfos, info)
	}
}

// Async - called from dns library multiplexer
func (c *MDNSClient) ResponseCallback(r *dns.Msg) {
	c.actionChan <- func() {
		for _, answer := range r.Answer {
			var name string
			var res *Response

			switch rr := answer.(type) {
			case *dns.A:
				name = rr.Hdr.Name
				res = &Response{Addr: rr.A}
			case *dns.PTR:
				name = rr.Hdr.Name
				res = &Response{Name: rr.Ptr}
			default:
				return
			}

			if query, found := c.inflight[name]; found {
				for _, resp := range query.responseInfos {
					resp.ch <- res
					close(resp.ch)
				}
				delete(c.inflight, name)
			} else {
				// We've received a response that didn't match a query
				// Do we want to cache it?
			}
		}
	}
}

// ACTOR server

// Check all in-flight queries, close all that have already timed out,
// and return the duration until the next timeout
func (c *MDNSClient) checkInFlightQueries() time.Duration {
	now := time.Now()
	after := MaxDuration
	for name, query := range c.inflight {
		// Invariant on responseInfos: they are in ascending order of timeout.
		numClosed := 0
		for _, item := range query.responseInfos {
			duration := item.timeout.Sub(now)
			if duration <= 0 { // timed out
				close(item.ch)
				numClosed++
			} else {
				if duration < after {
					after = duration
				}
				break // don't need to look at any more for this query
			}
		}
		// Remove timed-out items from the slice
		query.responseInfos = query.responseInfos[numClosed:]
		if len(query.responseInfos) == 0 {
			delete(c.inflight, name)
		}
	}
	return after
}

func (c *MDNSClient) actorLoop(actionChan <-chan MDNSAction) {
	timer := time.NewTimer(MaxDuration)
	run := func() { timer.Reset(c.checkInFlightQueries()) }
	terminate := false
	for !terminate {
		select {
		case action := <-actionChan:
			if action == nil {
				c.listener.Shutdown()
				terminate = true
			} else {
				action()
				run()
			}
		case <-timer.C:
			run()
		}
	}

	// Close all response channels at termination
	for _, query := range c.inflight {
		for _, item := range query.responseInfos {
			close(item.ch)
		}
	}
}
<|endoftext|>


<commit_before>package httpbackend

import (
	"net/http"

	"github.com/khades/servbot/repos"
	"github.com/kidstuff/mongostore"

	goji "goji.io"

	"goji.io/pat"
)

var sessionStore = mongostore.NewMongoStore(repos.Db.C("sessions"), 86400*7, true, []byte("something-very-secret"))

// Start We are starting server here
func Start() {
	mux := goji.NewMux()
	mux.HandleFunc(pat.Get("/api/channel/:channel"), withSessionAndChannel(channel))
	mux.HandleFunc(pat.Get("/api/channel/:channel/logs"), withMod(logsUsers))
	mux.HandleFunc(pat.Get("/api/channel/:channel/logs/username/:user"), withMod(logsByUsername))
	mux.HandleFunc(pat.Get("/api/channel/:channel/logs/userid/:userID"), withMod(logsByUserID))

	mux.HandleFunc(pat.Get("/api/channel/:channel/subs"), withMod(subscriptions))
	mux.HandleFunc(pat.Get("/api/channel/:channel/subs/limit/:limit"), withMod(subscriptionsWithLimit))

	mux.HandleFunc(pat.Get("/api/channel/:channel/subs/events"), withMod(subscriptionEvents))
	mux.HandleFunc(pat.Get("/api/user"), withAuth(user))
	mux.HandleFunc(pat.Get("/api/user/index"), withAuth(userIndex))
	mux.HandleFunc(pat.Get("/api/channel/:channel/templates"), withMod(templates))

	mux.HandleFunc(pat.Get("/api/channel/:channel/templates/:commandName"), withMod(template))
	mux.HandleFunc(pat.Post("/api/channel/:channel/templates/:commandName"), withMod(putTemplate))
	mux.HandleFunc(pat.Options("/api/channel/:channel/templates/:commandName"), corsEnabled(options))

	mux.HandleFunc(pat.Post("/api/channel/:channel/templates/:commandName/setAliasTo"), withMod(aliasTemplate))
	mux.HandleFunc(pat.Options("/api/channel/:channel/templates/:commandName/setAliasTo"), corsEnabled(options))

	mux.HandleFunc(pat.Get("/api/channel/:channel/subalert"), withMod(subAlert))
	mux.HandleFunc(pat.Post("/api/channel/:channel/subalert"), withMod(setSubAlert))
	mux.HandleFunc(pat.Options("/api/channel/:channel/subalert"), corsEnabled(options))

	mux.HandleFunc(pat.Get("/api/channel/:channel/automessages"), withMod(autoMessageList))
	mux.HandleFunc(pat.Options("/api/channel/:channel/automessages"), corsEnabled(options))

	mux.HandleFunc(pat.Get("/api/channel/:channel/automessages/:messageID"), withMod(autoMessageGet))
	mux.HandleFunc(pat.Options("/api/channel/:channel/automessages/:id"), corsEnabled(options))

	mux.HandleFunc(pat.Post("/api/channel/:channel/automessages"), withMod(autoMessageCreate))
	mux.HandleFunc(pat.Post("/api/channel/:channel/automessages/:id"), withMod(autoMessageUpdate))

	//mux.HandleFunc(pat.Get("/api/channel/:channel/songrequest/events"), songrequestEvents)
	// mux.HandleFunc(pat.Get("/isMod/:channel"), withSession(mod(func(w http.ResponseWriter, r *http.Request, session *models.HTTPSession) {
	// 	fmt.Fprintf(w, "Hello, %s, you're moderator of that channel!", session.Username)
	// })))
	// mux.HandleFunc(pat.Get("/isSub/:channel"), withSession(sub(func(w http.ResponseWriter, r *http.Request, session *models.HTTPSession) {
	// 	fmt.Fprintf(w, "Hello, %s, you're moderator of that channel!", session.Username)
	// })))
	mux.HandleFunc(pat.Get("/oauth"), oauth)
	mux.HandleFunc(pat.Get("/oauth/initiate"), withSession(oauthInitiate))

	mux.HandleFunc(pat.Get("/api/time"), corsEnabled(getTime))
	mux.HandleFunc(pat.Get("/api/timeticker"), corsEnabled(timeTicker))
	http.ListenAndServe("localhost:8000", mux)
}
<commit_msg>Fix: changed http session TTL to a day<commit_after>package httpbackend

import (
	"net/http"

	"github.com/khades/servbot/repos"
	"github.com/kidstuff/mongostore"

	goji "goji.io"

	"goji.io/pat"
)

var sessionStore = mongostore.NewMongoStore(repos.Db.C("sessions"), 3600*24, true, []byte("something-very-secret"))

// Start We are starting server here
func Start() {
	mux := goji.NewMux()
	mux.HandleFunc(pat.Get("/api/channel/:channel"), withSessionAndChannel(channel))
	mux.HandleFunc(pat.Get("/api/channel/:channel/logs"), withMod(logsUsers))
	mux.HandleFunc(pat.Get("/api/channel/:channel/logs/username/:user"), withMod(logsByUsername))
	mux.HandleFunc(pat.Get("/api/channel/:channel/logs/userid/:userID"), withMod(logsByUserID))

	mux.HandleFunc(pat.Get("/api/channel/:channel/subs"), withMod(subscriptions))
	mux.HandleFunc(pat.Get("/api/channel/:channel/subs/limit/:limit"), withMod(subscriptionsWithLimit))

	mux.HandleFunc(pat.Get("/api/channel/:channel/subs/events"), withMod(subscriptionEvents))
	mux.HandleFunc(pat.Get("/api/user"), withAuth(user))
	mux.HandleFunc(pat.Get("/api/user/index"), withAuth(userIndex))
	mux.HandleFunc(pat.Get("/api/channel/:channel/templates"), withMod(templates))

	mux.HandleFunc(pat.Get("/api/channel/:channel/templates/:commandName"), withMod(template))
	mux.HandleFunc(pat.Post("/api/channel/:channel/templates/:commandName"), withMod(putTemplate))
	mux.HandleFunc(pat.Options("/api/channel/:channel/templates/:commandName"), corsEnabled(options))

	mux.HandleFunc(pat.Post("/api/channel/:channel/templates/:commandName/setAliasTo"), withMod(aliasTemplate))
	mux.HandleFunc(pat.Options("/api/channel/:channel/templates/:commandName/setAliasTo"), corsEnabled(options))

	mux.HandleFunc(pat.Get("/api/channel/:channel/subalert"), withMod(subAlert))
	mux.HandleFunc(pat.Post("/api/channel/:channel/subalert"), withMod(setSubAlert))
	mux.HandleFunc(pat.Options("/api/channel/:channel/subalert"), corsEnabled(options))

	mux.HandleFunc(pat.Get("/api/channel/:channel/automessages"), withMod(autoMessageList))
	mux.HandleFunc(pat.Options("/api/channel/:channel/automessages"), corsEnabled(options))

	mux.HandleFunc(pat.Get("/api/channel/:channel/automessages/:messageID"), withMod(autoMessageGet))
	mux.HandleFunc(pat.Options("/api/channel/:channel/automessages/:id"), corsEnabled(options))

	mux.HandleFunc(pat.Post("/api/channel/:channel/automessages"), withMod(autoMessageCreate))
	mux.HandleFunc(pat.Post("/api/channel/:channel/automessages/:id"), withMod(autoMessageUpdate))

	//mux.HandleFunc(pat.Get("/api/channel/:channel/songrequest/events"), songrequestEvents)
	// mux.HandleFunc(pat.Get("/isMod/:channel"), withSession(mod(func(w http.ResponseWriter, r *http.Request, session *models.HTTPSession) {
	// 	fmt.Fprintf(w, "Hello, %s, you're moderator of that channel!", session.Username)
	// })))
	// mux.HandleFunc(pat.Get("/isSub/:channel"), withSession(sub(func(w http.ResponseWriter, r *http.Request, session *models.HTTPSession) {
	// 	fmt.Fprintf(w, "Hello, %s, you're moderator of that channel!", session.Username)
	// })))
	mux.HandleFunc(pat.Get("/oauth"), oauth)
	mux.HandleFunc(pat.Get("/oauth/initiate"), withSession(oauthInitiate))

	mux.HandleFunc(pat.Get("/api/time"), corsEnabled(getTime))
	mux.HandleFunc(pat.Get("/api/timeticker"), corsEnabled(timeTicker))
	http.ListenAndServe("localhost:8000", mux)
}
<|endoftext|>


<commit_before>package schema

import (
	"errors"
	"regexp"
	"sync"

	"github.com/lestrrat/go-jsref"
)

const (
	SchemaURL      = `http://json-schema.org/draft-04/schema`
	HyperSchemaURL = `http://json-schema.org/draft-03/hyper-schema`
	MIMEType       = "application/schema+json"
)

var ErrExpectedArrayOfString = errors.New("invalid value: expected array of string")
var ErrInvalidStringArray = ErrExpectedArrayOfString

type PrimitiveType int
type PrimitiveTypes []PrimitiveType
type Format string

const (
	FormatDateTime Format = "date-time"
	FormatEmail    Format = "email"
	FormatHostname Format = "hostname"
	FormatIPv4     Format = "ipv4"
	FormatIPv6     Format = "ipv6"
	FormatURI      Format = "uri"
)

type Number struct {
	Val         float64
	Initialized bool
}

type Integer struct {
	Val         int
	Initialized bool
}

type Bool struct {
	Val         bool
	Default     bool
	Initialized bool
}

const (
	UnspecifiedType PrimitiveType = iota
	NullType
	IntegerType
	StringType
	ObjectType
	ArrayType
	BooleanType
	NumberType
)

type SchemaList []*Schema
type Schema struct {
	parent          *Schema
	resolveLock     sync.Mutex
	resolvedSchemas map[string]interface{}
	resolver        *jsref.Resolver
	ID              string             `json:"id,omitempty"`
	Title           string             `json:"title,omitempty"`
	Description     string             `json:"description,omitempty"`
	Default         interface{}        `json:"default,omitempty"`
	Type            PrimitiveTypes     `json:"type,omitempty"`
	SchemaRef       string             `json:"$schema,omitempty"`
	Definitions     map[string]*Schema `json:"definitions,omitempty"`
	Reference       string             `json:"$ref,omitempty"`
	Format          Format             `json:"format,omitempty"`

	// NumericValidations
	MultipleOf       Number `json:"multipleOf,omitempty"`
	Minimum          Number `json:"minimum,omitempty"`
	Maximum          Number `json:"maximum,omitempty"`
	ExclusiveMinimum Bool   `json:"exclusiveMinimum,omitempty"`
	ExclusiveMaximum Bool   `json:"exclusiveMaximum,omitempty"`

	// StringValidation
	MaxLength Integer        `json:"maxLength,omitempty"`
	MinLength Integer        `json:"minLength,omitempty"`
	Pattern   *regexp.Regexp `json:"pattern,omitempty"`

	// ArrayValidations
	AdditionalItems *AdditionalItems
	Items           *ItemSpec
	MinItems        Integer
	MaxItems        Integer
	UniqueItems     Bool

	// ObjectValidations
	MaxProperties        Integer                    `json:"maxProperties,omitempty"`
	MinProperties        Integer                    `json:"minProperties,omitempty"`
	Required             []string                   `json:"required,omitempty"`
	Dependencies         DependencyMap              `json:"dependencies,omitempty"`
	Properties           map[string]*Schema         `json:"properties,omitempty"`
	AdditionalProperties *AdditionalProperties      `json:"additionalProperties,omitempty"`
	PatternProperties    map[*regexp.Regexp]*Schema `json:"patternProperties,omitempty"`

	Enum   []interface{}          `json:"enum,omitempty"`
	AllOf  SchemaList             `json:"allOf,omitempty"`
	AnyOf  SchemaList             `json:"anyOf,omitempty"`
	OneOf  SchemaList             `json:"oneOf,omitempty"`
	Not    *Schema                `json:"not,omitempty"`
	Extras map[string]interface{} `json:"-"`
}

type AdditionalItems struct {
	*Schema
}

type AdditionalProperties struct {
	*Schema
}

// DependencyMap contains the dependencies defined within this schema.
// for a given dependency name, you can have either a schema or a
// list of property names
type DependencyMap struct {
	Names   map[string][]string
	Schemas map[string]*Schema
}

type ItemSpec struct {
	TupleMode bool // If this is true, the positions mean something. if false, len(Schemas) should be 1, and we should apply the same schema validation to all elements
	Schemas   SchemaList
}
<commit_msg>golint<commit_after>package schema

import (
	"errors"
	"regexp"
	"sync"

	"github.com/lestrrat/go-jsref"
)

const (
	// SchemaURL contains the JSON Schema URL
	SchemaURL = `http://json-schema.org/draft-04/schema`
	// HyperSchemaURL contains the JSON Hyper Schema URL
	HyperSchemaURL = `http://json-schema.org/draft-03/hyper-schema`
	// MIMEType contains the MIME used for a JSON Schema
	MIMEType = "application/schema+json"
)

// ErrExpectedArrayOfString is returned when we encounter
// something other than array of strings
var ErrExpectedArrayOfString = errors.New("invalid value: expected array of string")
// ErrInvalidStringArray is the same as ErrExpectedArrayOfString.
// This is here only for backwards compatibility
var ErrInvalidStringArray = ErrExpectedArrayOfString

// PrimitiveType represents a JSON Schema primitive type such as
// "string", "integer", etc.
type PrimitiveType int

// PrimitiveTypes is a list of PrimitiveType
type PrimitiveTypes []PrimitiveType

// Format represents one of the pre-defined JSON Schema formats
type Format string

// The list of pre-defined JSON Schema formats
const (
	FormatDateTime Format = "date-time"
	FormatEmail    Format = "email"
	FormatHostname Format = "hostname"
	FormatIPv4     Format = "ipv4"
	FormatIPv6     Format = "ipv6"
	FormatURI      Format = "uri"
)

// Number represents a "number" value in a JSON Schema, such as
// "minimum", "maximum", etc.
type Number struct {
	Val         float64
	Initialized bool
}

// Integer represents a "integer" value in a JSON Schema, such as
// "minLength", "maxLength", etc.
type Integer struct {
	Val         int
	Initialized bool
}

// Bool represents a "boolean" value in a JSON Schema, such as
// "exclusiveMinimum", "exclusiveMaximum", etc.
type Bool struct {
	Val         bool
	Default     bool
	Initialized bool
}

// The list of primitive types
const (
	UnspecifiedType PrimitiveType = iota
	NullType
	IntegerType
	StringType
	ObjectType
	ArrayType
	BooleanType
	NumberType
)

// SchemaList is a list of Schemas
type SchemaList []*Schema

// Schema represents a JSON Schema object
type Schema struct {
	parent          *Schema
	resolveLock     sync.Mutex
	resolvedSchemas map[string]interface{}
	resolver        *jsref.Resolver
	ID              string             `json:"id,omitempty"`
	Title           string             `json:"title,omitempty"`
	Description     string             `json:"description,omitempty"`
	Default         interface{}        `json:"default,omitempty"`
	Type            PrimitiveTypes     `json:"type,omitempty"`
	SchemaRef       string             `json:"$schema,omitempty"`
	Definitions     map[string]*Schema `json:"definitions,omitempty"`
	Reference       string             `json:"$ref,omitempty"`
	Format          Format             `json:"format,omitempty"`

	// NumericValidations
	MultipleOf       Number `json:"multipleOf,omitempty"`
	Minimum          Number `json:"minimum,omitempty"`
	Maximum          Number `json:"maximum,omitempty"`
	ExclusiveMinimum Bool   `json:"exclusiveMinimum,omitempty"`
	ExclusiveMaximum Bool   `json:"exclusiveMaximum,omitempty"`

	// StringValidation
	MaxLength Integer        `json:"maxLength,omitempty"`
	MinLength Integer        `json:"minLength,omitempty"`
	Pattern   *regexp.Regexp `json:"pattern,omitempty"`

	// ArrayValidations
	AdditionalItems *AdditionalItems
	Items           *ItemSpec
	MinItems        Integer
	MaxItems        Integer
	UniqueItems     Bool

	// ObjectValidations
	MaxProperties        Integer                    `json:"maxProperties,omitempty"`
	MinProperties        Integer                    `json:"minProperties,omitempty"`
	Required             []string                   `json:"required,omitempty"`
	Dependencies         DependencyMap              `json:"dependencies,omitempty"`
	Properties           map[string]*Schema         `json:"properties,omitempty"`
	AdditionalProperties *AdditionalProperties      `json:"additionalProperties,omitempty"`
	PatternProperties    map[*regexp.Regexp]*Schema `json:"patternProperties,omitempty"`

	Enum   []interface{}          `json:"enum,omitempty"`
	AllOf  SchemaList             `json:"allOf,omitempty"`
	AnyOf  SchemaList             `json:"anyOf,omitempty"`
	OneOf  SchemaList             `json:"oneOf,omitempty"`
	Not    *Schema                `json:"not,omitempty"`
	Extras map[string]interface{} `json:"-"`
}

// AdditionalItems represents schema for additonalItems
type AdditionalItems struct {
	*Schema
}

// AdditionalProperties represents schema for additonalProperties
type AdditionalProperties struct {
	*Schema
}

// DependencyMap contains the dependencies defined within this schema.
// for a given dependency name, you can have either a schema or a
// list of property names
type DependencyMap struct {
	Names   map[string][]string
	Schemas map[string]*Schema
}

// ItemSpec represents a specification for `item` field
type ItemSpec struct {
	TupleMode bool // If this is true, the positions mean something. if false, len(Schemas) should be 1, and we should apply the same schema validation to all elements
	Schemas   SchemaList
}
<|endoftext|>


<commit_before>package pixel

import "image/color"

// Target is something that can be drawn onto, such as a window, a canvas, and so on.
//
// You can notice, that there are no "drawing" methods in a Target. That's because all drawing
// happens indirectly through Triangles and Picture instances generated via MakeTriangles and
// MakePicture method.
type Target interface {
	// MakeTriangles generates a specialized copy of the provided Triangles.
	//
	// When calling Draw method on the returned TargetTriangles, the TargetTriangles will be
	// drawn onto the Target that generated them.
	//
	// Note, that not every Target has to recognize all possible types of Triangles. Some may
	// only recognize TrianglesPosition and TrianglesColor and ignore all other properties (if
	// present) when making new TargetTriangles. This varies from Target to Target.
	MakeTriangles(Triangles) TargetTriangles

	// MakePicture generates a specialized copy of the provided Picture.
	//
	// When calling Draw method on the returned TargetPicture, the TargetPicture will be drawn
	// onto the Target that generated it together with the TargetTriangles supplied to the Draw
	// method.
	MakePicture(Picture) TargetPicture
}

// BasicTarget is a Target with additional basic adjustment methods.
type BasicTarget interface {
	Target

	// SetMatrix sets a Matrix that every point will be projected by.
	SetMatrix(Matrix)

	// SetColorMask sets a color that will be multiplied with the TrianglesColor property of all
	// Triangles.
	SetColorMask(color.Color)
}

// Triangles represents a list of vertices, where each three vertices form a triangle. (First,
// second and third is the first triangle, fourth, fifth and sixth is the second triangle, etc.)
type Triangles interface {
	// Len returns the number of vertices. The number of triangles is the number of vertices
	// divided by 3.
	Len() int

	// SetLen resizes Triangles to len vertices. If Triangles B were obtained by calling Slice
	// method on Triangles A, the relationship between A and B is undefined after calling SetLen
	// on either one of them.
	SetLen(len int)

	// Slice returns a sub-Triangles of this Triangles, covering vertices in range [i, j).
	//
	// If Triangles B were obtained by calling Slice(4, 9) on Triangles A, then A and B must
	// share the same underlying data. Modifying B must change the contents of A in range
	// [4, 9). The vertex with index 0 at B is the vertex with index 4 in A, and so on.
	//
	// Returned Triangles must have the same underlying type.
	Slice(i, j int) Triangles

	// Update copies vertex properties from the supplied Triangles into this Triangles.
	//
	// Properies not supported by these Triangles should be ignored. Properties not supported by
	// the supplied Triangles should be left untouched.
	//
	// The two Triangles must have the same Len.
	Update(Triangles)

	// Copy creates an exact independent copy of this Triangles (with the same underlying type).
	Copy() Triangles
}

// TargetTriangles are Triangles generated by a Target with MakeTriangles method. They can be drawn
// onto that (no other) Target.
type TargetTriangles interface {
	Triangles

	// Draw draws Triangles onto an associated Target.
	Draw()
}

// TrianglesPosition specifies Triangles with Position property.
type TrianglesPosition interface {
	Triangles
	Position(i int) Vec
}

// TrianglesColor specifies Triangles with Color property.
type TrianglesColor interface {
	Triangles
	Color(i int) RGBA
}

// TrianglesPicture specifies Triangles with Picture propery.
//
// The first value returned from Picture method is Picture coordinates. The second one specifies the
// weight of the Picture. Value of 0 means, that Picture should be completely ignored, 1 means that
// is should be fully included and anything in between means anything in between.
type TrianglesPicture interface {
	Triangles
	Picture(i int) (pic Vec, intensity float64)
}

// Picture represents a rectangular area of raster data, such as a color. It has Bounds which
// specify the rectangle where data is located.
type Picture interface {
	// Bounds returns the rectangle of the Picture. All data is located witih this rectangle.
	// Querying properties outside the rectangle should return default value of that property.
	Bounds() Rect
}

// TargetPicture is a Picture generated by a Target using MakePicture method. This Picture can be drawn onto
// that (no other) Target together with a TargetTriangles generated by the same Target.
//
// The TargetTriangles specify where, shape and how the Picture should be drawn.
type TargetPicture interface {
	Picture

	// Draw draws the supplied TargetTriangles (which must be generated by the same Target as
	// this TargetPicture) with this TargetPicture. The TargetTriangles should utilize the data
	// from this TargetPicture in some way.
	Draw(TargetTriangles)
}

// PictureColor specifies Picture with Color property, so that every position inside the Picture's
// Bounds has a color.
//
// Positions outside the Picture's Bounds must return full transparent (RGBA{R: 0, G: 0, B: 0, A: 0}).
type PictureColor interface {
	Picture
	Color(at Vec) RGBA
}
<commit_msg>add ComposeTarget interface<commit_after>package pixel

import "image/color"

// Target is something that can be drawn onto, such as a window, a canvas, and so on.
//
// You can notice, that there are no "drawing" methods in a Target. That's because all drawing
// happens indirectly through Triangles and Picture instances generated via MakeTriangles and
// MakePicture method.
type Target interface {
	// MakeTriangles generates a specialized copy of the provided Triangles.
	//
	// When calling Draw method on the returned TargetTriangles, the TargetTriangles will be
	// drawn onto the Target that generated them.
	//
	// Note, that not every Target has to recognize all possible types of Triangles. Some may
	// only recognize TrianglesPosition and TrianglesColor and ignore all other properties (if
	// present) when making new TargetTriangles. This varies from Target to Target.
	MakeTriangles(Triangles) TargetTriangles

	// MakePicture generates a specialized copy of the provided Picture.
	//
	// When calling Draw method on the returned TargetPicture, the TargetPicture will be drawn
	// onto the Target that generated it together with the TargetTriangles supplied to the Draw
	// method.
	MakePicture(Picture) TargetPicture
}

// BasicTarget is a Target with additional basic adjustment methods.
type BasicTarget interface {
	Target

	// SetMatrix sets a Matrix that every point will be projected by.
	SetMatrix(Matrix)

	// SetColorMask sets a color that will be multiplied with the TrianglesColor property of all
	// Triangles.
	SetColorMask(color.Color)
}

// ComposeTarget is a BasicTarget capable of Porter-Duff composition.
type ComposeTarget interface {
	BasicTarget

	// SetComposeMethod sets a Porter-Duff composition method to be used.
	SetComposeMethod(ComposeMethod)
}

// ComposeMethod is a Porter-Duff composition method.
type ComposeMethod int

// Here's the list of all available Porter-Duff composition methods. User ComposeOver for the basic
// alpha blending.
const (
	ComposeOver ComposeMethod = iota
	ComposeIn
	ComposeOut
	ComposeAtop
	ComposeDstIn
	ComposeDstOut
	ComposeDstAtop
	ComposeXor
)

// Triangles represents a list of vertices, where each three vertices form a triangle. (First,
// second and third is the first triangle, fourth, fifth and sixth is the second triangle, etc.)
type Triangles interface {
	// Len returns the number of vertices. The number of triangles is the number of vertices
	// divided by 3.
	Len() int

	// SetLen resizes Triangles to len vertices. If Triangles B were obtained by calling Slice
	// method on Triangles A, the relationship between A and B is undefined after calling SetLen
	// on either one of them.
	SetLen(len int)

	// Slice returns a sub-Triangles of this Triangles, covering vertices in range [i, j).
	//
	// If Triangles B were obtained by calling Slice(4, 9) on Triangles A, then A and B must
	// share the same underlying data. Modifying B must change the contents of A in range
	// [4, 9). The vertex with index 0 at B is the vertex with index 4 in A, and so on.
	//
	// Returned Triangles must have the same underlying type.
	Slice(i, j int) Triangles

	// Update copies vertex properties from the supplied Triangles into this Triangles.
	//
	// Properies not supported by these Triangles should be ignored. Properties not supported by
	// the supplied Triangles should be left untouched.
	//
	// The two Triangles must have the same Len.
	Update(Triangles)

	// Copy creates an exact independent copy of this Triangles (with the same underlying type).
	Copy() Triangles
}

// TargetTriangles are Triangles generated by a Target with MakeTriangles method. They can be drawn
// onto that (no other) Target.
type TargetTriangles interface {
	Triangles

	// Draw draws Triangles onto an associated Target.
	Draw()
}

// TrianglesPosition specifies Triangles with Position property.
type TrianglesPosition interface {
	Triangles
	Position(i int) Vec
}

// TrianglesColor specifies Triangles with Color property.
type TrianglesColor interface {
	Triangles
	Color(i int) RGBA
}

// TrianglesPicture specifies Triangles with Picture propery.
//
// The first value returned from Picture method is Picture coordinates. The second one specifies the
// weight of the Picture. Value of 0 means, that Picture should be completely ignored, 1 means that
// is should be fully included and anything in between means anything in between.
type TrianglesPicture interface {
	Triangles
	Picture(i int) (pic Vec, intensity float64)
}

// Picture represents a rectangular area of raster data, such as a color. It has Bounds which
// specify the rectangle where data is located.
type Picture interface {
	// Bounds returns the rectangle of the Picture. All data is located witih this rectangle.
	// Querying properties outside the rectangle should return default value of that property.
	Bounds() Rect
}

// TargetPicture is a Picture generated by a Target using MakePicture method. This Picture can be drawn onto
// that (no other) Target together with a TargetTriangles generated by the same Target.
//
// The TargetTriangles specify where, shape and how the Picture should be drawn.
type TargetPicture interface {
	Picture

	// Draw draws the supplied TargetTriangles (which must be generated by the same Target as
	// this TargetPicture) with this TargetPicture. The TargetTriangles should utilize the data
	// from this TargetPicture in some way.
	Draw(TargetTriangles)
}

// PictureColor specifies Picture with Color property, so that every position inside the Picture's
// Bounds has a color.
//
// Positions outside the Picture's Bounds must return full transparent (RGBA{R: 0, G: 0, B: 0, A: 0}).
type PictureColor interface {
	Picture
	Color(at Vec) RGBA
}
<|endoftext|>


<commit_before>package termbox

import (
	"os"
	"syscall"
)

// public API

// Initializes termbox library. This function should be called before any other functions.
// After successful initialization, the library must be finalized using 'Close' function.
//
// Example usage:
//      err := termbox.Init()
//      if err != nil {
//              panic(err)
//      }
//      defer termbox.Close()
func Init() error {
	var err error

	in, err = syscall.GetStdHandle(syscall.STD_INPUT_HANDLE)
	if err != nil {
		return err
	}
	out, err = syscall.GetStdHandle(syscall.STD_OUTPUT_HANDLE)
	if err != nil {
		return err
	}

	err = get_console_mode(in, &orig_mode)
	if err != nil {
		return err
	}

	if fin, err := os.Open("CONIN$"); err == nil {
		if in == syscall.Handle(fin.Fd()) {
			err = set_console_mode(in, enable_window_input)
			if err != nil {
				return err
			}
		}
	}

	orig_screen = out
	out, err = create_console_screen_buffer()
	if err != nil {
		return err
	}
	w, h := get_win_size(out)

	err = set_console_screen_buffer_size(out, coord{short(w), short(h)})
	if err != nil {
		return err
	}

	err = set_console_active_screen_buffer(out)
	if err != nil {
		return err
	}

	show_cursor(false)
	termw, termh = get_term_size(out)
	back_buffer.init(termw, termh)
	front_buffer.init(termw, termh)
	back_buffer.clear()
	front_buffer.clear()
	clear()

	attrsbuf = make([]word, 0, termw*termh)
	charsbuf = make([]wchar, 0, termw*termh)
	diffbuf = make([]diff_msg, 0, 32)

	go input_event_producer()

	return nil
}

// Finalizes termbox library, should be called after successful initialization
// when termbox's functionality isn't required anymore.
func Close() {
	// we ignore errors here, because we can't really do anything about them
	set_console_mode(in, orig_mode)
	set_console_active_screen_buffer(orig_screen)
	syscall.Close(out)
}

// Synchronizes the internal back buffer with the terminal.
func Flush() error {
	update_size_maybe()
	prepare_diff_messages()
	for _, msg := range diffbuf {
		write_console_output_attribute(out, msg.attrs, msg.pos)
		write_console_output_character(out, msg.chars, msg.pos)
	}
	if !is_cursor_hidden(cursor_x, cursor_y) {
		move_cursor(cursor_x, cursor_y)
	}
	return nil
}

// Sets the position of the cursor. See also HideCursor().
func SetCursor(x, y int) {
	if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
		show_cursor(true)
	}

	if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
		show_cursor(false)
	}

	cursor_x, cursor_y = x, y
	if !is_cursor_hidden(cursor_x, cursor_y) {
		move_cursor(cursor_x, cursor_y)
	}
}

// The shortcut for SetCursor(-1, -1).
func HideCursor() {
	SetCursor(cursor_hidden, cursor_hidden)
}

// Changes cell's parameters in the internal back buffer at the specified
// position.
func SetCell(x, y int, ch rune, fg, bg Attribute) {
	if x < 0 || x >= back_buffer.width {
		return
	}
	if y < 0 || y >= back_buffer.height {
		return
	}

	back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
}

// Returns a slice into the termbox's back buffer. You can get its dimensions
// using 'Size' function. The slice remains valid as long as no 'Clear' or
// 'Flush' function calls were made after call to this function.
func CellBuffer() []Cell {
	return back_buffer.cells
}

// Wait for an event and return it. This is a blocking function call.
func PollEvent() Event {
	return <-input_comm
}

// Returns the size of the internal back buffer (which is the same as
// terminal's window size in characters).
func Size() (int, int) {
	return termw, termh
}

// Clears the internal back buffer.
func Clear(fg, bg Attribute) error {
	foreground, background = fg, bg
	update_size_maybe()
	back_buffer.clear()
	return nil
}

// Sets termbox input mode. Termbox has two input modes:
//
// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC means KeyEsc. This is the default input mode.
//
// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
//
// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
// enable mouse button click events.
//
// If 'mode' is InputCurrent, returns the current input mode. See also Input*
// constants.
func SetInputMode(mode InputMode) InputMode {
	if mode == InputCurrent {
		return input_mode
	}
	if mode&InputMouse != 0 {
		err := set_console_mode(in, enable_window_input|enable_mouse_input)
		if err != nil {
			panic(err)
		}
	} else {
		err := set_console_mode(in, enable_window_input)
		if err != nil {
			panic(err)
		}
	}

	input_mode = mode
	return input_mode
}

// Sync comes handy when something causes desync between termbox's understanding
// of a terminal buffer and the reality. Such as a third party process. Sync
// forces a complete resync between the termbox and a terminal, it may not be
// visually pretty though. At the moment on Windows it does nothing.
func Sync() error {
	return nil
}
<commit_msg>Fix SetInputMode on windows. it can't set InputAlt without setting enable_window_input<commit_after>package termbox

import (
	"os"
	"syscall"
)

// public API

// Initializes termbox library. This function should be called before any other functions.
// After successful initialization, the library must be finalized using 'Close' function.
//
// Example usage:
//      err := termbox.Init()
//      if err != nil {
//              panic(err)
//      }
//      defer termbox.Close()
func Init() error {
	var err error

	in, err = syscall.GetStdHandle(syscall.STD_INPUT_HANDLE)
	if err != nil {
		return err
	}
	out, err = syscall.GetStdHandle(syscall.STD_OUTPUT_HANDLE)
	if err != nil {
		return err
	}

	err = get_console_mode(in, &orig_mode)
	if err != nil {
		return err
	}

	if fin, err := os.Open("CONIN$"); err == nil {
		if in == syscall.Handle(fin.Fd()) {
			err = set_console_mode(in, enable_window_input)
			if err != nil {
				return err
			}
		}
	}

	orig_screen = out
	out, err = create_console_screen_buffer()
	if err != nil {
		return err
	}
	w, h := get_win_size(out)

	err = set_console_screen_buffer_size(out, coord{short(w), short(h)})
	if err != nil {
		return err
	}

	err = set_console_active_screen_buffer(out)
	if err != nil {
		return err
	}

	show_cursor(false)
	termw, termh = get_term_size(out)
	back_buffer.init(termw, termh)
	front_buffer.init(termw, termh)
	back_buffer.clear()
	front_buffer.clear()
	clear()

	attrsbuf = make([]word, 0, termw*termh)
	charsbuf = make([]wchar, 0, termw*termh)
	diffbuf = make([]diff_msg, 0, 32)

	go input_event_producer()

	return nil
}

// Finalizes termbox library, should be called after successful initialization
// when termbox's functionality isn't required anymore.
func Close() {
	// we ignore errors here, because we can't really do anything about them
	set_console_mode(in, orig_mode)
	set_console_active_screen_buffer(orig_screen)
	syscall.Close(out)
}

// Synchronizes the internal back buffer with the terminal.
func Flush() error {
	update_size_maybe()
	prepare_diff_messages()
	for _, msg := range diffbuf {
		write_console_output_attribute(out, msg.attrs, msg.pos)
		write_console_output_character(out, msg.chars, msg.pos)
	}
	if !is_cursor_hidden(cursor_x, cursor_y) {
		move_cursor(cursor_x, cursor_y)
	}
	return nil
}

// Sets the position of the cursor. See also HideCursor().
func SetCursor(x, y int) {
	if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
		show_cursor(true)
	}

	if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
		show_cursor(false)
	}

	cursor_x, cursor_y = x, y
	if !is_cursor_hidden(cursor_x, cursor_y) {
		move_cursor(cursor_x, cursor_y)
	}
}

// The shortcut for SetCursor(-1, -1).
func HideCursor() {
	SetCursor(cursor_hidden, cursor_hidden)
}

// Changes cell's parameters in the internal back buffer at the specified
// position.
func SetCell(x, y int, ch rune, fg, bg Attribute) {
	if x < 0 || x >= back_buffer.width {
		return
	}
	if y < 0 || y >= back_buffer.height {
		return
	}

	back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
}

// Returns a slice into the termbox's back buffer. You can get its dimensions
// using 'Size' function. The slice remains valid as long as no 'Clear' or
// 'Flush' function calls were made after call to this function.
func CellBuffer() []Cell {
	return back_buffer.cells
}

// Wait for an event and return it. This is a blocking function call.
func PollEvent() Event {
	return <-input_comm
}

// Returns the size of the internal back buffer (which is the same as
// terminal's window size in characters).
func Size() (int, int) {
	return termw, termh
}

// Clears the internal back buffer.
func Clear(fg, bg Attribute) error {
	foreground, background = fg, bg
	update_size_maybe()
	back_buffer.clear()
	return nil
}

// Sets termbox input mode. Termbox has two input modes:
//
// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC means KeyEsc. This is the default input mode.
//
// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
//
// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
// enable mouse button click events.
//
// If 'mode' is InputCurrent, returns the current input mode. See also Input*
// constants.
func SetInputMode(mode InputMode) InputMode {
	if mode == InputCurrent {
		return input_mode
	}
	if mode&InputMouse != 0 {
		err := set_console_mode(in, enable_window_input|enable_mouse_input)
		if err != nil {
			panic(err)
		}
	} else if mode&InputAlt == 0 {
		err := set_console_mode(in, enable_window_input)
		if err != nil {
			panic(err)
		}
	}

	input_mode = mode
	return input_mode
}

// Sync comes handy when something causes desync between termbox's understanding
// of a terminal buffer and the reality. Such as a third party process. Sync
// forces a complete resync between the termbox and a terminal, it may not be
// visually pretty though. At the moment on Windows it does nothing.
func Sync() error {
	return nil
}
<|endoftext|>


<commit_before>type Object struct {
	Value interface{}
}

var DEFAULTS = map[string]Object{
	"city": Object{Value:"Default City"},
	"maxAttendees": Object{Value:0},
	"seatsAvailable": Object{Value:0},
	"topics": Object{Value:[2]string{"Default", "Topic"}},
}

func copyConferenceToForm(conf *Conference, keyStr string, displayName string) (*ConferenceForm, error) {
	//Copy relevant fields from Conference to ConferenceForm.
	cf := &ConferenceForm{
		Name: conf.Name,
		Description: conf.Description,
		OrganizerUserId: conf.OrganizerUserId,
		Topics: conf.Topics,
		City: conf.City,
		StartDate: conf.StartDate.String(),
		Month: conf.Month,
		MaxAttendees: conf.MaxAttendees,
		SeatsAvailable: conf.SeatsAvailable,
		EndDate: conf.EndDate.String(),
		WebsafeKey: html.EscapeString(keyStr),
	}
	if displayName != "" {
		cf.OrganizerDisplayName = displayName
	}
	return cf, nil
}

func createConferenceObject(r *http.Request, cf *ConferenceForm) (*ConferenceForm, error) {
	//Create or update Conference object, returning ConferenceForm.
	//preload necessary data items
	c := endpoints.NewContext(r)
	user, err := endpoints.CurrentUser(c, []string{endpoints.EmailScope},
		[]string{WEB_CLIENT_ID, endpoints.APIExplorerClientID}, []string{WEB_CLIENT_ID, endpoints.APIExplorerClientID})
	if err != nil {
		return nil, err
	}
	if user == nil {
		return nil, endpoints.UnauthorizedError
	}
	userId := getUserId(user, "")

	if cf.Name == "" {
		return nil, endpoints.BadRequestError
	}

	cf.WebsafeKey = ""
	cf.OrganizerDisplayName = ""

	//add default values for those missing
	if cf.City == "" {
		cf.City = DEFAULTS["city"].Value.(string)
	}
	if cf.MaxAttendees == 0 {
		cf.MaxAttendees = DEFAULTS["maxAttendees"].Value.(int)
	}
	if cf.SeatsAvailable == 0 {
		cf.SeatsAvailable = DEFAULTS["seatsAvailable"].Value.(int)
	}
	if cf.Topics == nil {
		cf.Topics = DEFAULTS["topics"].Value.([]string)
	}

	//convert dates from strings to Date objects; set month based on start_date
	var startDate time.Time
	var endDate time.Time
	if cf.StartDate != "" {
		startDate, _ = time.Parse(time.RFC3339, cf.StartDate)
		cf.Month = int(startDate.Month())
	} else {
		cf.Month = 0
	}
	if cf.EndDate != "" {
		endDate, _ = time.Parse(time.RFC3339, cf.EndDate)
	}

	//set seatsAvailable to be same as maxAttendees on creation
	//both for data model & outbound Message
	if cf.MaxAttendees > 0 {
		cf.SeatsAvailable = cf.MaxAttendees
	}

	//make Profile Key from user ID
	appCtx := appengine.NewContext(r)
	parentKey := datastore.NewKey(appCtx, "Profile", userId, 0, nil)
	//allocate new Conference ID with Profile key as parent
	_, high, err := datastore.AllocateIDs(appCtx, "Conference", parentKey, 1)
	if err != nil {
		return nil, err
	}
	//make Conference key from ID
	confKey := datastore.NewKey(appCtx, "Conference", "", high, parentKey)
	cf.OrganizerUserId = userId

	//create Conference & return (modified) ConferenceForm
	conf := &Conference{
		Name: cf.Name,
		Description: cf.Description,
		OrganizerUserId: cf.OrganizerUserId,
		Topics: cf.Topics,
		City: cf.City,
		StartDate: startDate,
		Month: cf.Month,
		EndDate: endDate,
		MaxAttendees: cf.MaxAttendees,
		SeatsAvailable: cf.SeatsAvailable,
	}
	_, err = datastore.Put(appCtx, confKey, conf)
	if err != nil {
		return nil, err
	}

	return cf, nil
}

func (h *ConferenceApi) CreateConference(r *http.Request, cf *ConferenceForm) (*ConferenceForm, error) {
	//Create new conference.
	return createConferenceObject(r, cf)
}<commit_msg>added 2 blank lines at end of file to keep file line numbers synced with lab instructions<commit_after>type Object struct {
	Value interface{}
}

var DEFAULTS = map[string]Object{
	"city": Object{Value:"Default City"},
	"maxAttendees": Object{Value:0},
	"seatsAvailable": Object{Value:0},
	"topics": Object{Value:[2]string{"Default", "Topic"}},
}

func copyConferenceToForm(conf *Conference, keyStr string, displayName string) (*ConferenceForm, error) {
	//Copy relevant fields from Conference to ConferenceForm.
	cf := &ConferenceForm{
		Name: conf.Name,
		Description: conf.Description,
		OrganizerUserId: conf.OrganizerUserId,
		Topics: conf.Topics,
		City: conf.City,
		StartDate: conf.StartDate.String(),
		Month: conf.Month,
		MaxAttendees: conf.MaxAttendees,
		SeatsAvailable: conf.SeatsAvailable,
		EndDate: conf.EndDate.String(),
		WebsafeKey: html.EscapeString(keyStr),
	}
	if displayName != "" {
		cf.OrganizerDisplayName = displayName
	}
	return cf, nil
}

func createConferenceObject(r *http.Request, cf *ConferenceForm) (*ConferenceForm, error) {
	//Create or update Conference object, returning ConferenceForm.
	//preload necessary data items
	c := endpoints.NewContext(r)
	user, err := endpoints.CurrentUser(c, []string{endpoints.EmailScope},
		[]string{WEB_CLIENT_ID, endpoints.APIExplorerClientID}, []string{WEB_CLIENT_ID, endpoints.APIExplorerClientID})
	if err != nil {
		return nil, err
	}
	if user == nil {
		return nil, endpoints.UnauthorizedError
	}
	userId := getUserId(user, "")

	if cf.Name == "" {
		return nil, endpoints.BadRequestError
	}

	cf.WebsafeKey = ""
	cf.OrganizerDisplayName = ""

	//add default values for those missing
	if cf.City == "" {
		cf.City = DEFAULTS["city"].Value.(string)
	}
	if cf.MaxAttendees == 0 {
		cf.MaxAttendees = DEFAULTS["maxAttendees"].Value.(int)
	}
	if cf.SeatsAvailable == 0 {
		cf.SeatsAvailable = DEFAULTS["seatsAvailable"].Value.(int)
	}
	if cf.Topics == nil {
		cf.Topics = DEFAULTS["topics"].Value.([]string)
	}

	//convert dates from strings to Date objects; set month based on start_date
	var startDate time.Time
	var endDate time.Time
	if cf.StartDate != "" {
		startDate, _ = time.Parse(time.RFC3339, cf.StartDate)
		cf.Month = int(startDate.Month())
	} else {
		cf.Month = 0
	}
	if cf.EndDate != "" {
		endDate, _ = time.Parse(time.RFC3339, cf.EndDate)
	}

	//set seatsAvailable to be same as maxAttendees on creation
	//both for data model & outbound Message
	if cf.MaxAttendees > 0 {
		cf.SeatsAvailable = cf.MaxAttendees
	}

	//make Profile Key from user ID
	appCtx := appengine.NewContext(r)
	parentKey := datastore.NewKey(appCtx, "Profile", userId, 0, nil)
	//allocate new Conference ID with Profile key as parent
	_, high, err := datastore.AllocateIDs(appCtx, "Conference", parentKey, 1)
	if err != nil {
		return nil, err
	}
	//make Conference key from ID
	confKey := datastore.NewKey(appCtx, "Conference", "", high, parentKey)
	cf.OrganizerUserId = userId

	//create Conference & return (modified) ConferenceForm
	conf := &Conference{
		Name: cf.Name,
		Description: cf.Description,
		OrganizerUserId: cf.OrganizerUserId,
		Topics: cf.Topics,
		City: cf.City,
		StartDate: startDate,
		Month: cf.Month,
		EndDate: endDate,
		MaxAttendees: cf.MaxAttendees,
		SeatsAvailable: cf.SeatsAvailable,
	}
	_, err = datastore.Put(appCtx, confKey, conf)
	if err != nil {
		return nil, err
	}

	return cf, nil
}

func (h *ConferenceApi) CreateConference(r *http.Request, cf *ConferenceForm) (*ConferenceForm, error) {
	//Create new conference.
	return createConferenceObject(r, cf)
}

<|endoftext|>


<commit_before>package main

import (
	"github.com/hanwen/termite/termite"
	"io"
	"log"
	"net"
	"os"
	"path/filepath"
	"rpc"
)

const _SOCKET = ".termite-socket"

const _TEST_CONNECTION = "test-termite-connection"

func main() {
	path := os.Getenv("PATH")

	args := os.Args
	_, base := filepath.Split(args[0])
	binary := ""
	for _, c := range filepath.SplitList(path) {
		_, dirBase := filepath.Split(c)
		if dirBase == "termite" {
			continue
		}

		try := filepath.Join(c, base)
		_, err := os.Stat(try)
		if err == nil {
			binary = try
		}
	}
	if binary == "" && binary != _TEST_CONNECTION {
		log.Fatal("could not find", base)
	}

	wd, err := os.Getwd()
	if err != nil {
		log.Fatal("Getwd", err)
	}

	socket := os.Getenv("TERMITE_SOCKET")
	if socket == "" {
		socketPath := wd
		for socketPath != "/" {
			cand := filepath.Join(socketPath, _SOCKET)
			fi, _ := os.Lstat(cand)
			if fi != nil && fi.IsSocket() {
				socket = cand
				break
			}
			socketPath = filepath.Clean(filepath.Join(socketPath, ".."))
		}
	}

	if binary == _TEST_CONNECTION {
		conn, err := net.Dial("unix", socket)

		exit := 0
		if err != nil {
			exit = 1
		} else {
			conn.Close()
		}
		os.Exit(exit)
	}

	conn := termite.OpenSocketConnection(socket, termite.RPC_CHANNEL)
	args[0] = binary
	req := termite.WorkRequest{
		StdinId: termite.ConnectionId(),
		Binary:  binary,
		Argv:    args,
		Env:     os.Environ(),
		Dir:     wd,
		Debug:   os.Getenv("TERMITE_DEBUG") != "",
	}

	stdinConn := termite.OpenSocketConnection(socket, req.StdinId)
	go func() {
		io.Copy(stdinConn, os.Stdin)
		stdinConn.Close()
	}()
	client := rpc.NewClient(conn)

	rep := termite.WorkReply{}
	err = client.Call("LocalMaster.Run", &req, &rep)
	if err != nil {
		log.Fatal("LocalMaster.Run: ", err)
	}

	os.Stdout.Write([]byte(rep.Stdout))
	os.Stderr.Write([]byte(rep.Stderr))
	// TODO -something with signals.
	os.Exit(rep.Exit.ExitStatus())
}
<commit_msg>Now that the master auto-removes sockets, remove the _TEST_CONNECTION functionality from wrapper.<commit_after>package main

import (
	"github.com/hanwen/termite/termite"
	"io"
	"log"
	"os"
	"path/filepath"
	"rpc"
)

const _SOCKET = ".termite-socket"

func main() {
	path := os.Getenv("PATH")

	args := os.Args
	_, base := filepath.Split(args[0])
	binary := ""
	for _, c := range filepath.SplitList(path) {
		_, dirBase := filepath.Split(c)
		if dirBase == "termite" {
			continue
		}

		try := filepath.Join(c, base)
		_, err := os.Stat(try)
		if err == nil {
			binary = try
		}
	}
	if binary == "" {
		log.Fatal("could not find", base)
	}

	wd, err := os.Getwd()
	if err != nil {
		log.Fatal("Getwd", err)
	}

	socket := os.Getenv("TERMITE_SOCKET")
	if socket == "" {
		socketPath := wd
		for socketPath != "/" {
			cand := filepath.Join(socketPath, _SOCKET)
			fi, _ := os.Lstat(cand)
			if fi != nil && fi.IsSocket() {
				socket = cand
				break
			}
			socketPath = filepath.Clean(filepath.Join(socketPath, ".."))
		}
	}

	conn := termite.OpenSocketConnection(socket, termite.RPC_CHANNEL)
	args[0] = binary
	req := termite.WorkRequest{
		StdinId: termite.ConnectionId(),
		Binary:  binary,
		Argv:    args,
		Env:     os.Environ(),
		Dir:     wd,
		Debug:   os.Getenv("TERMITE_DEBUG") != "",
	}

	stdinConn := termite.OpenSocketConnection(socket, req.StdinId)
	go func() {
		io.Copy(stdinConn, os.Stdin)
		stdinConn.Close()
	}()
	client := rpc.NewClient(conn)

	rep := termite.WorkReply{}
	err = client.Call("LocalMaster.Run", &req, &rep)
	if err != nil {
		log.Fatal("LocalMaster.Run: ", err)
	}

	os.Stdout.Write([]byte(rep.Stdout))
	os.Stderr.Write([]byte(rep.Stderr))
	// TODO -something with signals.
	os.Exit(rep.Exit.ExitStatus())
}
<|endoftext|>