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

package search

import (
	"math"
	"math/rand"

	"github.com/gonum/graph"
	"github.com/gonum/graph/concrete"
)

// JohnsonAllPaths returns a shortest-path tree for shortest paths in the graph g.
// If weight is nil and the graph does not implement graph.Coster, UniformCost is used.
//
// The time complexity of JohnsonAllPaths is O(|V|.|E|+|V|^2.log|V|).
func JohnsonAllPaths(g graph.Graph, weight graph.CostFunc) (paths AllShortest, ok bool) {
	jg := johnsonWeightAdjuster{
		g:      g,
		from:   g.From,
		to:     g.From,
		weight: weight,
		edgeTo: g.Edge,
	}
	switch g := g.(type) {
	case graph.Directed:
		jg.to = g.To
	}
	if jg.weight == nil {
		if g, ok := g.(graph.Coster); ok {
			jg.weight = g.Cost
		} else {
			jg.weight = UniformCost
		}
	}

	paths = newAllShortest(g.Nodes(), false)

	sign := -1
	for {
		// Choose a random node ID until we find
		// one that is not in g.
		jg.q = sign * rand.Int()
		if _, exists := paths.indexOf[jg.q]; !exists {
			break
		}
		sign *= -1
	}

	jg.bellmanFord = true
	jg.adjustBy, ok = BellmanFordFrom(johnsonGraphNode(jg.q), jg, nil)
	if !ok {
		return paths, false
	}

	jg.bellmanFord = false
	dijkstraAllPaths(jg, nil, paths)

	for i, u := range paths.nodes {
		hu := jg.adjustBy.WeightTo(u)
		for j, v := range paths.nodes {
			if i == j {
				continue
			}
			hv := jg.adjustBy.WeightTo(v)
			paths.dist.Set(i, j, paths.dist.At(i, j)-hu+hv)
		}
	}

	return paths, ok
}

type johnsonWeightAdjuster struct {
	q int
	g graph.Graph

	from, to func(graph.Node) []graph.Node
	edgeTo   func(graph.Node, graph.Node) graph.Edge
	weight   graph.CostFunc

	bellmanFord bool
	adjustBy    Shortest
}

var (
	_ graph.Directed = johnsonWeightAdjuster{}
	_ graph.Coster   = johnsonWeightAdjuster{}
)

func (g johnsonWeightAdjuster) Has(n graph.Node) bool {
	if g.bellmanFord && n.ID() == g.q {
		return true
	}
	return g.g.Has(n)

}

func (g johnsonWeightAdjuster) Nodes() []graph.Node {
	if g.bellmanFord {
		return append(g.g.Nodes(), johnsonGraphNode(g.q))
	}
	return g.g.Nodes()
}

func (g johnsonWeightAdjuster) From(n graph.Node) []graph.Node {
	if g.bellmanFord && n.ID() == g.q {
		return g.g.Nodes()
	}
	return g.from(n)
}

func (g johnsonWeightAdjuster) Edge(u, v graph.Node) graph.Edge {
	if g.bellmanFord && u.ID() == g.q && g.g.Has(v) {
		return concrete.Edge{johnsonGraphNode(g.q), v}
	}
	return g.edgeTo(u, v)
}

func (g johnsonWeightAdjuster) Cost(e graph.Edge) float64 {
	if g.bellmanFord {
		switch g.q {
		case e.From().ID():
			return 0
		case e.To().ID():
			return math.Inf(1)
		default:
			return g.weight(e)
		}
	}
	return g.weight(e) + g.adjustBy.WeightTo(e.From()) - g.adjustBy.WeightTo(e.To())
}

func (johnsonWeightAdjuster) HasEdge(_, _ graph.Node) bool {
	panic("search: unintended use of johnsonWeightAdjuster")
}
func (johnsonWeightAdjuster) EdgeFromTo(_, _ graph.Node) graph.Edge {
	panic("search: unintended use of johnsonWeightAdjuster")
}
func (johnsonWeightAdjuster) To(graph.Node) []graph.Node {
	panic("search: unintended use of johnsonWeightAdjuster")
}
<commit_msg>search: simplify JohnsonAllPaths due to interface changes<commit_after>// Copyright ©2015 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package search

import (
	"math"
	"math/rand"

	"github.com/gonum/graph"
	"github.com/gonum/graph/concrete"
)

// JohnsonAllPaths returns a shortest-path tree for shortest paths in the graph g.
// If weight is nil and the graph does not implement graph.Coster, UniformCost is used.
//
// The time complexity of JohnsonAllPaths is O(|V|.|E|+|V|^2.log|V|).
func JohnsonAllPaths(g graph.Graph, weight graph.CostFunc) (paths AllShortest, ok bool) {
	jg := johnsonWeightAdjuster{
		g:      g,
		from:   g.From,
		weight: weight,
		edgeTo: g.Edge,
	}
	if jg.weight == nil {
		if g, ok := g.(graph.Coster); ok {
			jg.weight = g.Cost
		} else {
			jg.weight = UniformCost
		}
	}

	paths = newAllShortest(g.Nodes(), false)

	sign := -1
	for {
		// Choose a random node ID until we find
		// one that is not in g.
		jg.q = sign * rand.Int()
		if _, exists := paths.indexOf[jg.q]; !exists {
			break
		}
		sign *= -1
	}

	jg.bellmanFord = true
	jg.adjustBy, ok = BellmanFordFrom(johnsonGraphNode(jg.q), jg, nil)
	if !ok {
		return paths, false
	}

	jg.bellmanFord = false
	dijkstraAllPaths(jg, nil, paths)

	for i, u := range paths.nodes {
		hu := jg.adjustBy.WeightTo(u)
		for j, v := range paths.nodes {
			if i == j {
				continue
			}
			hv := jg.adjustBy.WeightTo(v)
			paths.dist.Set(i, j, paths.dist.At(i, j)-hu+hv)
		}
	}

	return paths, ok
}

type johnsonWeightAdjuster struct {
	q int
	g graph.Graph

	from   func(graph.Node) []graph.Node
	edgeTo func(graph.Node, graph.Node) graph.Edge
	weight graph.CostFunc

	bellmanFord bool
	adjustBy    Shortest
}

var (
	// johnsonWeightAdjuster has the behaviour
	// of a directed graph, but we don't need
	// to be explicit with the type since it
	// is not exported.
	_ graph.Graph  = johnsonWeightAdjuster{}
	_ graph.Coster = johnsonWeightAdjuster{}
)

func (g johnsonWeightAdjuster) Has(n graph.Node) bool {
	if g.bellmanFord && n.ID() == g.q {
		return true
	}
	return g.g.Has(n)

}

func (g johnsonWeightAdjuster) Nodes() []graph.Node {
	if g.bellmanFord {
		return append(g.g.Nodes(), johnsonGraphNode(g.q))
	}
	return g.g.Nodes()
}

func (g johnsonWeightAdjuster) From(n graph.Node) []graph.Node {
	if g.bellmanFord && n.ID() == g.q {
		return g.g.Nodes()
	}
	return g.from(n)
}

func (g johnsonWeightAdjuster) Edge(u, v graph.Node) graph.Edge {
	if g.bellmanFord && u.ID() == g.q && g.g.Has(v) {
		return concrete.Edge{johnsonGraphNode(g.q), v}
	}
	return g.edgeTo(u, v)
}

func (g johnsonWeightAdjuster) Cost(e graph.Edge) float64 {
	if g.bellmanFord {
		switch g.q {
		case e.From().ID():
			return 0
		case e.To().ID():
			return math.Inf(1)
		default:
			return g.weight(e)
		}
	}
	return g.weight(e) + g.adjustBy.WeightTo(e.From()) - g.adjustBy.WeightTo(e.To())
}

func (johnsonWeightAdjuster) HasEdge(_, _ graph.Node) bool {
	panic("search: unintended use of johnsonWeightAdjuster")
}
<|endoftext|>


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

package main

import (
	"encoding/json"
	"github.com/blevesearch/bleve"
	bleveMappingUI "github.com/blevesearch/bleve-mapping-ui"
	bleveHttp "github.com/blevesearch/bleve/http"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"

	// import general purpose configuration
	_ "github.com/blevesearch/bleve/config"
	//"github.com/projectOpenRAP/OpenRAP/searchServer/edu"
)

var createIndexHandlerGlobal *(bleveHttp.CreateIndexHandler)

func createAndInitIndexHandler(w http.ResponseWriter, r *http.Request) {
	pathVariable := mux.Vars(r)
	indexName := pathVariable["indexName"]
	jsonDir := r.URL.Query().Get("jsonDir")
	createIndexHandlerGlobal.ServeHTTP(w, r)
	index := bleveHttp.IndexByName(indexName)
	if index == nil {
		log.Printf("no such index '%s'", indexName)
		return
	}
	if jsonDir == nil {
		log.Printf("no metadata directory for initial index creation")
		return
	}
	dirEntries, err := ioutil.ReadDir(jsonDir)
	if err != nil {
		log.Printf("cannot open directory : %s\n", jsonDir)
		return
	}
	count := 0
	startTime := time.Now()
	batch := index.NewBatch()
	batchCount := 0
	batchSize := 50
	for _, dirEntry := range dirEntries {
		filename := dirEntry.Name()
		logger.Trace.Printf("Bulk addition to Index: %s\n", filename)
		// read the bytes
		jsonBytes, err := ioutil.ReadFile(jsonDir + "/" + filename)
		if err != nil {
			log.Printf("error while reading file")
			continue
		}

		// parse bytes as json
		var jsonDoc interface{}
		err = json.Unmarshal(jsonBytes, &jsonDoc)
		if err != nil {
			log.Printf("error while unmarshal file: %s\n", filename)
			continue
		}

		batch.Index(filename, jsonDoc)
		batchCount++
		if batchCount >= batchSize {
			err = index.Batch(batch)
			if err != nil {
				log.Printf("error while adding batch to index")
				return
			}
			batch = index.NewBatch()
			batchCount = 0
		}
		count++
		if count%1000 == 0 {
			indexDuration := time.Since(startTime)
			indexDurationSeconds := float64(indexDuration) / float64(time.Second)
			timePerDoc := float64(indexDuration) / float64(count)
			logger.Trace.Printf("Indexed %d documents, in %.2fs (average %.2fms/doc)",
				count, indexDurationSeconds, timePerDoc/float64(time.Millisecond))
		}

	}
	if batchCount > 0 {
		err = index.Batch(batch)
		if err != nil {
			log.Printf("error while adding last batch to index")
			return
		}
	}
	indexDuration := time.Since(startTime)
	indexDurationSeconds := float64(indexDuration) / float64(time.Second)
	timePerDoc := float64(indexDuration) / float64(count)
	logger.Info.Printf("Indexed %d documents, in %.2fs (average %.2fms/doc)", count, indexDurationSeconds, timePerDoc/float64(time.Millisecond))
	return
}

func loadIndexAndServe(indexDir, bindAddr string) {

	// walk the data dir and register index names
	dirEntries, err := ioutil.ReadDir(indexDir)
	if err != nil {
		log.Fatalf("error reading data dir: %v", err)
	}

	for _, dirInfo := range dirEntries {
		indexPath := indexDir + string(os.PathSeparator) + dirInfo.Name()

		// skip single files in data dir since a valid index is a directory that
		// contains multiple files
		if !dirInfo.IsDir() {
			log.Printf("Deleting unknown db: %s", indexPath)
			os.RemoveAll(indexPath)

			continue
		}

		i, err := bleve.Open(indexPath)
		if err != nil {
			log.Printf("error opening index %s: %v", indexPath, err)
			os.RemoveAll(indexPath)
		} else {
			log.Printf("registered index: %s", dirInfo.Name())
			bleveHttp.RegisterIndexName(dirInfo.Name(), i)
			// set correct name in stats
			i.SetName(dirInfo.Name())
		}
	}

	router := mux.NewRouter()
	router.StrictSlash(true)

	// add edu routes
	// edu.EduInit(router)

	// add the API
	bleveMappingUI.RegisterHandlers(router, "/api")

	createIndexHandler := bleveHttp.NewCreateIndexHandler(indexDir)
	createIndexHandler.IndexNameLookup = indexNameLookup
	createIndexHandlerGlobal = createIndexHandler
	//router.Handle("/api/search/v2/index/{indexName}", createIndexHandler).Methods("PUT")
	router.HandleFunc("/api/search/v2/index/{indexName}", createAndInitIndexHandler).Methods("PUT")

	getIndexHandler := bleveHttp.NewGetIndexHandler()
	getIndexHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}", getIndexHandler).Methods("GET")

	deleteIndexHandler := bleveHttp.NewDeleteIndexHandler(indexDir)
	deleteIndexHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}", deleteIndexHandler).Methods("DELETE")

	listIndexesHandler := bleveHttp.NewListIndexesHandler()
	router.Handle("/api/search/v2/index", listIndexesHandler).Methods("GET")

	docIndexHandler := bleveHttp.NewDocIndexHandler("")
	docIndexHandler.IndexNameLookup = indexNameLookup
	docIndexHandler.DocIDLookup = docIDLookup
	router.Handle("/api/search/v2/index/{indexName}/document/{docID}", docIndexHandler).Methods("PUT")

	docCountHandler := bleveHttp.NewDocCountHandler("")
	docCountHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}/_count", docCountHandler).Methods("GET")

	docGetHandler := bleveHttp.NewDocGetHandler("")
	docGetHandler.IndexNameLookup = indexNameLookup
	docGetHandler.DocIDLookup = docIDLookup
	router.Handle("/api/search/v2/index/{indexName}/document/{docID}", docGetHandler).Methods("GET")

	docDeleteHandler := bleveHttp.NewDocDeleteHandler("")
	docDeleteHandler.IndexNameLookup = indexNameLookup
	docDeleteHandler.DocIDLookup = docIDLookup
	router.Handle("/api/search/v2/index/{indexName}/document/{docID}", docDeleteHandler).Methods("DELETE")

	searchHandler := bleveHttp.NewSearchHandler("")
	searchHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}/_search", searchHandler).Methods("POST")

	listFieldsHandler := bleveHttp.NewListFieldsHandler("")
	listFieldsHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}/_fields", listFieldsHandler).Methods("GET")

	debugHandler := bleveHttp.NewDebugDocumentHandler("")
	debugHandler.IndexNameLookup = indexNameLookup
	debugHandler.DocIDLookup = docIDLookup
	router.Handle("/api/search/v2/index/{indexName}/document/{docID}/_debug", debugHandler).Methods("GET")

	aliasHandler := bleveHttp.NewAliasHandler()
	router.Handle("/api/search/v2/_aliases", aliasHandler).Methods("POST")

	// start the HTTP server
	http.Handle("/", router)
	log.Printf("Listening on %v", bindAddr)
	log.Fatal(http.ListenAndServe(bindAddr, nil))
}
<commit_msg>error fix<commit_after>//  Copyright (c) 2014 Couchbase, Inc.
//  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
//  except in compliance with the License. You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//  Unless required by applicable law or agreed to in writing, software distributed under the
//  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
//  either express or implied. See the License for the specific language governing permissions
//  and limitations under the License.

package main

import (
	"encoding/json"
	"github.com/blevesearch/bleve"
	bleveMappingUI "github.com/blevesearch/bleve-mapping-ui"
	bleveHttp "github.com/blevesearch/bleve/http"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"

	// import general purpose configuration
	_ "github.com/blevesearch/bleve/config"
	//"github.com/projectOpenRAP/OpenRAP/searchServer/edu"
)

var createIndexHandlerGlobal *(bleveHttp.CreateIndexHandler)

func createAndInitIndexHandler(w http.ResponseWriter, r *http.Request) {
	pathVariable := mux.Vars(r)
	indexName := pathVariable["indexName"]
	jsonDir := r.URL.Query().Get("jsonDir")
	createIndexHandlerGlobal.ServeHTTP(w, r)
	index := bleveHttp.IndexByName(indexName)
	if index == nil {
		log.Printf("no such index '%s'", indexName)
		return
	}
	if jsonDir == "" {
		log.Printf("no metadata directory for initial index creation")
		return
	}
	dirEntries, err := ioutil.ReadDir(jsonDir)
	if err != nil {
		log.Printf("cannot open directory : %s\n", jsonDir)
		return
	}
	count := 0
	startTime := time.Now()
	batch := index.NewBatch()
	batchCount := 0
	batchSize := 50
	for _, dirEntry := range dirEntries {
		filename := dirEntry.Name()
		logger.Trace.Printf("Bulk addition to Index: %s\n", filename)
		// read the bytes
		jsonBytes, err := ioutil.ReadFile(jsonDir + "/" + filename)
		if err != nil {
			log.Printf("error while reading file")
			continue
		}

		// parse bytes as json
		var jsonDoc interface{}
		err = json.Unmarshal(jsonBytes, &jsonDoc)
		if err != nil {
			log.Printf("error while unmarshal file: %s\n", filename)
			continue
		}

		batch.Index(filename, jsonDoc)
		batchCount++
		if batchCount >= batchSize {
			err = index.Batch(batch)
			if err != nil {
				log.Printf("error while adding batch to index")
				return
			}
			batch = index.NewBatch()
			batchCount = 0
		}
		count++
		if count%1000 == 0 {
			indexDuration := time.Since(startTime)
			indexDurationSeconds := float64(indexDuration) / float64(time.Second)
			timePerDoc := float64(indexDuration) / float64(count)
			logger.Trace.Printf("Indexed %d documents, in %.2fs (average %.2fms/doc)",
				count, indexDurationSeconds, timePerDoc/float64(time.Millisecond))
		}

	}
	if batchCount > 0 {
		err = index.Batch(batch)
		if err != nil {
			log.Printf("error while adding last batch to index")
			return
		}
	}
	indexDuration := time.Since(startTime)
	indexDurationSeconds := float64(indexDuration) / float64(time.Second)
	timePerDoc := float64(indexDuration) / float64(count)
	logger.Info.Printf("Indexed %d documents, in %.2fs (average %.2fms/doc)", count, indexDurationSeconds, timePerDoc/float64(time.Millisecond))
	return
}

func loadIndexAndServe(indexDir, bindAddr string) {

	// walk the data dir and register index names
	dirEntries, err := ioutil.ReadDir(indexDir)
	if err != nil {
		log.Fatalf("error reading data dir: %v", err)
	}

	for _, dirInfo := range dirEntries {
		indexPath := indexDir + string(os.PathSeparator) + dirInfo.Name()

		// skip single files in data dir since a valid index is a directory that
		// contains multiple files
		if !dirInfo.IsDir() {
			log.Printf("Deleting unknown db: %s", indexPath)
			os.RemoveAll(indexPath)

			continue
		}

		i, err := bleve.Open(indexPath)
		if err != nil {
			log.Printf("error opening index %s: %v", indexPath, err)
			os.RemoveAll(indexPath)
		} else {
			log.Printf("registered index: %s", dirInfo.Name())
			bleveHttp.RegisterIndexName(dirInfo.Name(), i)
			// set correct name in stats
			i.SetName(dirInfo.Name())
		}
	}

	router := mux.NewRouter()
	router.StrictSlash(true)

	// add edu routes
	// edu.EduInit(router)

	// add the API
	bleveMappingUI.RegisterHandlers(router, "/api")

	createIndexHandler := bleveHttp.NewCreateIndexHandler(indexDir)
	createIndexHandler.IndexNameLookup = indexNameLookup
	createIndexHandlerGlobal = createIndexHandler
	//router.Handle("/api/search/v2/index/{indexName}", createIndexHandler).Methods("PUT")
	router.HandleFunc("/api/search/v2/index/{indexName}", createAndInitIndexHandler).Methods("PUT")

	getIndexHandler := bleveHttp.NewGetIndexHandler()
	getIndexHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}", getIndexHandler).Methods("GET")

	deleteIndexHandler := bleveHttp.NewDeleteIndexHandler(indexDir)
	deleteIndexHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}", deleteIndexHandler).Methods("DELETE")

	listIndexesHandler := bleveHttp.NewListIndexesHandler()
	router.Handle("/api/search/v2/index", listIndexesHandler).Methods("GET")

	docIndexHandler := bleveHttp.NewDocIndexHandler("")
	docIndexHandler.IndexNameLookup = indexNameLookup
	docIndexHandler.DocIDLookup = docIDLookup
	router.Handle("/api/search/v2/index/{indexName}/document/{docID}", docIndexHandler).Methods("PUT")

	docCountHandler := bleveHttp.NewDocCountHandler("")
	docCountHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}/_count", docCountHandler).Methods("GET")

	docGetHandler := bleveHttp.NewDocGetHandler("")
	docGetHandler.IndexNameLookup = indexNameLookup
	docGetHandler.DocIDLookup = docIDLookup
	router.Handle("/api/search/v2/index/{indexName}/document/{docID}", docGetHandler).Methods("GET")

	docDeleteHandler := bleveHttp.NewDocDeleteHandler("")
	docDeleteHandler.IndexNameLookup = indexNameLookup
	docDeleteHandler.DocIDLookup = docIDLookup
	router.Handle("/api/search/v2/index/{indexName}/document/{docID}", docDeleteHandler).Methods("DELETE")

	searchHandler := bleveHttp.NewSearchHandler("")
	searchHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}/_search", searchHandler).Methods("POST")

	listFieldsHandler := bleveHttp.NewListFieldsHandler("")
	listFieldsHandler.IndexNameLookup = indexNameLookup
	router.Handle("/api/search/v2/index/{indexName}/_fields", listFieldsHandler).Methods("GET")

	debugHandler := bleveHttp.NewDebugDocumentHandler("")
	debugHandler.IndexNameLookup = indexNameLookup
	debugHandler.DocIDLookup = docIDLookup
	router.Handle("/api/search/v2/index/{indexName}/document/{docID}/_debug", debugHandler).Methods("GET")

	aliasHandler := bleveHttp.NewAliasHandler()
	router.Handle("/api/search/v2/_aliases", aliasHandler).Methods("POST")

	// start the HTTP server
	http.Handle("/", router)
	log.Printf("Listening on %v", bindAddr)
	log.Fatal(http.ListenAndServe(bindAddr, nil))
}
<|endoftext|>


<commit_before>// Package semaphore implements the semaphore resiliency pattern for Go.
package semaphore

import (
	"errors"
	"time"
)

// ErrNoTickets is the error returned by Acquire when it could not acquire
// a ticket from the semaphore within the configured timeout.
var ErrNoTickets = errors.New("could not acquire semaphore ticket")

// Semaphore implements the semaphore resiliency pattern
type Semaphore struct {
	sem     chan struct{}
	timeout time.Duration
}

// New constructs a new Semaphore with the given ticket-count
// and timeout.
func New(tickets int, timeout time.Duration) *Semaphore {
	return &Semaphore{
		sem:     make(chan struct{}, tickets),
		timeout: timeout,
	}
}

// Acquire tries to acquire a ticket from the semaphore. If it can, it returns nil.
// If it cannot after "timeout" amount of time, it returns ErrNoTickets. It is
// safe to call Acquire concurrently on a single Semaphore.
func (s *Semaphore) Acquire() error {
	select {
	case s.sem <- struct{}{}:
		return nil
	case <-time.After(s.timeout):
		return ErrNoTickets
	}
}

// Release releases an acquired ticket back to the semaphore. It is safe to call
// Release concurrently on a single Semaphore. It is an error to call Release on
// a Semaphore from which you have not first acquired a ticket.
func (s *Semaphore) Release() {
	<-s.sem
}

// IsEmpty would return true if none acquired ar that moment of time, otherwise false.
func (s *Semaphore) IsEmpty() bool {
	return len(s.sem) == 0
}
<commit_msg>Tweak docs on IsEmpty<commit_after>// Package semaphore implements the semaphore resiliency pattern for Go.
package semaphore

import (
	"errors"
	"time"
)

// ErrNoTickets is the error returned by Acquire when it could not acquire
// a ticket from the semaphore within the configured timeout.
var ErrNoTickets = errors.New("could not acquire semaphore ticket")

// Semaphore implements the semaphore resiliency pattern
type Semaphore struct {
	sem     chan struct{}
	timeout time.Duration
}

// New constructs a new Semaphore with the given ticket-count
// and timeout.
func New(tickets int, timeout time.Duration) *Semaphore {
	return &Semaphore{
		sem:     make(chan struct{}, tickets),
		timeout: timeout,
	}
}

// Acquire tries to acquire a ticket from the semaphore. If it can, it returns nil.
// If it cannot after "timeout" amount of time, it returns ErrNoTickets. It is
// safe to call Acquire concurrently on a single Semaphore.
func (s *Semaphore) Acquire() error {
	select {
	case s.sem <- struct{}{}:
		return nil
	case <-time.After(s.timeout):
		return ErrNoTickets
	}
}

// Release releases an acquired ticket back to the semaphore. It is safe to call
// Release concurrently on a single Semaphore. It is an error to call Release on
// a Semaphore from which you have not first acquired a ticket.
func (s *Semaphore) Release() {
	<-s.sem
}

// IsEmpty will return true if no tickets are being held at that instant.
// It is safe to call concurrently with Acquire and Release, though do note
// that the result may then be unpredictable.
func (s *Semaphore) IsEmpty() bool {
	return len(s.sem) == 0
}
<|endoftext|>


<commit_before>package template

// Functions available to gondola templates

import (
	"bytes"
	"encoding/json"
	"fmt"
	"gnd.la/mux/serialize"
	"gnd.la/template/assets"
	"gnd.la/types"
	"html/template"
	"reflect"
	"strconv"
	"strings"
	"time"
)

func eq(args ...interface{}) bool {
	if len(args) == 0 {
		return false
	}
	x := args[0]
	switch x := x.(type) {
	case string, int, int64, byte, float32, float64:
		for _, y := range args[1:] {
			if x == y {
				return true
			}
		}
		return false
	}

	for _, y := range args[1:] {
		if reflect.DeepEqual(x, y) {
			return true
		}
	}
	return false
}

func neq(args ...interface{}) bool {
	return !eq(args...)
}

func lt(arg1, arg2 interface{}) (bool, error) {
	v1 := reflect.ValueOf(arg1)
	v2 := reflect.ValueOf(arg2)
	t1 := v1.Type()
	t2 := v2.Type()
	switch {
	case types.IsInt(t1) && types.IsInt(t2):
		return v1.Int() < v2.Int(), nil
	case types.IsUint(t1) && types.IsUint(t2):
		return v1.Uint() < v2.Uint(), nil
	case types.IsFloat(t1) && types.IsFloat(t2):
		return v1.Float() < v2.Float(), nil
	}
	return false, fmt.Errorf("can't compare %T with %T", arg1, arg2)
}

func lte(arg1, arg2 interface{}) (bool, error) {
	lessThan, err := lt(arg1, arg2)
	if lessThan || err != nil {
		return lessThan, err
	}
	return eq(arg1, arg2), nil
}

func gt(arg1, arg2 interface{}) (bool, error) {
	v1 := reflect.ValueOf(arg1)
	v2 := reflect.ValueOf(arg2)
	t1 := v1.Type()
	t2 := v2.Type()
	switch {
	case types.IsInt(t1) && types.IsInt(t2):
		return v1.Int() > v2.Int(), nil
	case types.IsUint(t1) && types.IsUint(t2):
		return v1.Uint() > v2.Uint(), nil
	case types.IsFloat(t1) && types.IsFloat(t2):
		return v1.Float() > v2.Float(), nil
	}
	return false, fmt.Errorf("can't compare %T with %T", arg1, arg2)
}

func gte(arg1, arg2 interface{}) (bool, error) {
	greaterThan, err := gt(arg1, arg2)
	if greaterThan || err != nil {
		return greaterThan, err
	}
	return eq(arg1, arg2), nil
}

func jsons(arg interface{}) (string, error) {
	if jw, ok := arg.(serialize.JSONWriter); ok {
		var buf bytes.Buffer
		_, err := jw.WriteJSON(&buf)
		return buf.String(), err
	}
	b, err := json.Marshal(arg)
	return string(b), err
}

func _json(arg interface{}) (template.JS, error) {
	s, err := jsons(arg)
	return template.JS(s), err
}

func nz(x interface{}) bool {
	switch x := x.(type) {
	case int, uint, int64, uint64, byte, float32, float64:
		return x != 0
	case string:
		return len(x) > 0
	}
	return false
}

func lower(x string) string {
	return strings.ToLower(x)
}

func join(x []string, sep string) string {
	return strings.Join(x, sep)
}

func _map(args ...interface{}) (map[string]interface{}, error) {
	var key string
	m := make(map[string]interface{})
	for ii, v := range args {
		if ii%2 == 0 {
			if s, ok := v.(string); ok {
				key = s
			} else {
				return nil, fmt.Errorf("Invalid argument to map at index %d, %t instead of string", ii, v)
			}
		} else {
			m[key] = v
		}
	}
	return m, nil
}

// this returns *[]interface{} so append works on
// slices declared in templates
func _slice(args ...interface{}) *[]interface{} {
	return &args
}

func _append(items interface{}, args ...interface{}) (string, error) {
	val := reflect.ValueOf(items)
	if !val.IsValid() || val.Kind() != reflect.Ptr || val.Elem().Kind() != reflect.Slice {
		return "", fmt.Errorf("first argument to append must be pointer to slice, it's %T", items)
	}
	sl := val.Elem()
	for _, v := range args {
		vval := reflect.ValueOf(v)
		if !vval.Type().AssignableTo(sl.Type().Elem()) {
			return "", fmt.Errorf("can't append %s to %s", vval.Type(), sl.Type())
		}
		sl = reflect.Append(sl, vval)
	}
	val.Elem().Set(sl)
	return "", nil
}

func mult(args ...interface{}) (float64, error) {
	val := 1.0
	for ii, v := range args {
		value := reflect.ValueOf(v)
		switch value.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			val *= float64(value.Int())
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			val *= float64(value.Uint())
		case reflect.Float32, reflect.Float64:
			val *= value.Float()
		case reflect.String:
			v, err := strconv.ParseFloat(value.String(), 64)
			if err != nil {
				return 0, fmt.Errorf("Error parsing string passed to mult at index %d: %s", ii, err)
			}
			val *= v
		default:
			return 0, fmt.Errorf("Invalid argument of type %T passed to mult at index %d", v, ii)
		}
	}
	return val, nil

}

func add(args ...interface{}) (float64, error) {
	val := 0.0
	for ii, v := range args {
		value := reflect.ValueOf(v)
		switch value.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			val += float64(value.Int())
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			val += float64(value.Uint())
		case reflect.Float32, reflect.Float64:
			val += value.Float()
		case reflect.String:
			v, err := strconv.ParseFloat(value.String(), 64)
			if err != nil {
				return 0, fmt.Errorf("error parsing string passed to add() at index %d: %s", ii, err)
			}
			val += v
		default:
			return 0, fmt.Errorf("invalid argument of type %T passed to add() at index %d", v, ii)
		}
	}
	return val, nil

}

func concat(args ...interface{}) string {
	s := make([]string, len(args))
	for ii, v := range args {
		s[ii] = types.ToString(v)
	}
	return strings.Join(s, "")
}

func and(args ...interface{}) bool {
	for _, v := range args {
		t, _ := types.IsTrue(v)
		if !t {
			return false
		}
	}
	return true
}

func or(args ...interface{}) interface{} {
	for _, v := range args {
		t, _ := types.IsTrue(v)
		if t {
			return v
		}
	}
	return nil
}

func not(arg interface{}) bool {
	t, _ := types.IsTrue(arg)
	return !t
}

func divisible(n interface{}, d interface{}) (bool, error) {
	ni, err := types.ToInt(n)
	if err != nil {
		return false, fmt.Errorf("divisible() invalid number %v: %s", n, err)
	}
	di, err := types.ToInt(d)
	if err != nil {
		return false, fmt.Errorf("divisible() invalid divisor %v: %s", d, err)
	}
	return ni%di == 0, nil
}

func even(arg interface{}) (bool, error) {
	return divisible(arg, 2)
}

func odd(arg interface{}) (bool, error) {
	res, err := divisible(arg, 2)
	if err != nil {
		return false, err
	}
	return !res, nil
}

func now() time.Time {
	return time.Now()
}

var templateFuncs template.FuncMap = template.FuncMap{
	"eq":        eq,
	"neq":       neq,
	"lt":        lt,
	"lte":       lte,
	"gt":        lt,
	"gte":       lte,
	"json":      _json,
	"jsons":     jsons,
	"nz":        nz,
	"lower":     lower,
	"join":      join,
	"map":       _map,
	"slice":     _slice,
	"append":    _append,
	"mult":      mult,
	"divisible": divisible,
	"add":       add,
	"even":      even,
	"odd":       odd,
	"render":    assets.Render,
	"concat":    concat,
	"and":       and,
	"or":        or,
	"not":       not,
	"now":       now,

	// Go builtins
	"call":     call,
	"html":     template.HTMLEscaper,
	"index":    index,
	"js":       template.JSEscaper,
	"len":      length,
	"print":    fmt.Sprint,
	"printf":   fmt.Sprintf,
	"println":  fmt.Sprintln,
	"urlquery": template.URLQueryEscaper,
}
<commit_msg>Add to_lower, to_upper and to_title to template functions<commit_after>package template

// Functions available to gondola templates

import (
	"bytes"
	"encoding/json"
	"fmt"
	"gnd.la/mux/serialize"
	"gnd.la/template/assets"
	"gnd.la/types"
	"html/template"
	"reflect"
	"strconv"
	"strings"
	"time"
)

func eq(args ...interface{}) bool {
	if len(args) == 0 {
		return false
	}
	x := args[0]
	switch x := x.(type) {
	case string, int, int64, byte, float32, float64:
		for _, y := range args[1:] {
			if x == y {
				return true
			}
		}
		return false
	}

	for _, y := range args[1:] {
		if reflect.DeepEqual(x, y) {
			return true
		}
	}
	return false
}

func neq(args ...interface{}) bool {
	return !eq(args...)
}

func lt(arg1, arg2 interface{}) (bool, error) {
	v1 := reflect.ValueOf(arg1)
	v2 := reflect.ValueOf(arg2)
	t1 := v1.Type()
	t2 := v2.Type()
	switch {
	case types.IsInt(t1) && types.IsInt(t2):
		return v1.Int() < v2.Int(), nil
	case types.IsUint(t1) && types.IsUint(t2):
		return v1.Uint() < v2.Uint(), nil
	case types.IsFloat(t1) && types.IsFloat(t2):
		return v1.Float() < v2.Float(), nil
	}
	return false, fmt.Errorf("can't compare %T with %T", arg1, arg2)
}

func lte(arg1, arg2 interface{}) (bool, error) {
	lessThan, err := lt(arg1, arg2)
	if lessThan || err != nil {
		return lessThan, err
	}
	return eq(arg1, arg2), nil
}

func gt(arg1, arg2 interface{}) (bool, error) {
	v1 := reflect.ValueOf(arg1)
	v2 := reflect.ValueOf(arg2)
	t1 := v1.Type()
	t2 := v2.Type()
	switch {
	case types.IsInt(t1) && types.IsInt(t2):
		return v1.Int() > v2.Int(), nil
	case types.IsUint(t1) && types.IsUint(t2):
		return v1.Uint() > v2.Uint(), nil
	case types.IsFloat(t1) && types.IsFloat(t2):
		return v1.Float() > v2.Float(), nil
	}
	return false, fmt.Errorf("can't compare %T with %T", arg1, arg2)
}

func gte(arg1, arg2 interface{}) (bool, error) {
	greaterThan, err := gt(arg1, arg2)
	if greaterThan || err != nil {
		return greaterThan, err
	}
	return eq(arg1, arg2), nil
}

func jsons(arg interface{}) (string, error) {
	if jw, ok := arg.(serialize.JSONWriter); ok {
		var buf bytes.Buffer
		_, err := jw.WriteJSON(&buf)
		return buf.String(), err
	}
	b, err := json.Marshal(arg)
	return string(b), err
}

func _json(arg interface{}) (template.JS, error) {
	s, err := jsons(arg)
	return template.JS(s), err
}

func nz(x interface{}) bool {
	switch x := x.(type) {
	case int, uint, int64, uint64, byte, float32, float64:
		return x != 0
	case string:
		return len(x) > 0
	}
	return false
}

func lower(x string) string {
	return strings.ToLower(x)
}

func join(x []string, sep string) string {
	return strings.Join(x, sep)
}

func _map(args ...interface{}) (map[string]interface{}, error) {
	var key string
	m := make(map[string]interface{})
	for ii, v := range args {
		if ii%2 == 0 {
			if s, ok := v.(string); ok {
				key = s
			} else {
				return nil, fmt.Errorf("Invalid argument to map at index %d, %t instead of string", ii, v)
			}
		} else {
			m[key] = v
		}
	}
	return m, nil
}

// this returns *[]interface{} so append works on
// slices declared in templates
func _slice(args ...interface{}) *[]interface{} {
	return &args
}

func _append(items interface{}, args ...interface{}) (string, error) {
	val := reflect.ValueOf(items)
	if !val.IsValid() || val.Kind() != reflect.Ptr || val.Elem().Kind() != reflect.Slice {
		return "", fmt.Errorf("first argument to append must be pointer to slice, it's %T", items)
	}
	sl := val.Elem()
	for _, v := range args {
		vval := reflect.ValueOf(v)
		if !vval.Type().AssignableTo(sl.Type().Elem()) {
			return "", fmt.Errorf("can't append %s to %s", vval.Type(), sl.Type())
		}
		sl = reflect.Append(sl, vval)
	}
	val.Elem().Set(sl)
	return "", nil
}

func mult(args ...interface{}) (float64, error) {
	val := 1.0
	for ii, v := range args {
		value := reflect.ValueOf(v)
		switch value.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			val *= float64(value.Int())
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			val *= float64(value.Uint())
		case reflect.Float32, reflect.Float64:
			val *= value.Float()
		case reflect.String:
			v, err := strconv.ParseFloat(value.String(), 64)
			if err != nil {
				return 0, fmt.Errorf("Error parsing string passed to mult at index %d: %s", ii, err)
			}
			val *= v
		default:
			return 0, fmt.Errorf("Invalid argument of type %T passed to mult at index %d", v, ii)
		}
	}
	return val, nil

}

func add(args ...interface{}) (float64, error) {
	val := 0.0
	for ii, v := range args {
		value := reflect.ValueOf(v)
		switch value.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			val += float64(value.Int())
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			val += float64(value.Uint())
		case reflect.Float32, reflect.Float64:
			val += value.Float()
		case reflect.String:
			v, err := strconv.ParseFloat(value.String(), 64)
			if err != nil {
				return 0, fmt.Errorf("error parsing string passed to add() at index %d: %s", ii, err)
			}
			val += v
		default:
			return 0, fmt.Errorf("invalid argument of type %T passed to add() at index %d", v, ii)
		}
	}
	return val, nil

}

func concat(args ...interface{}) string {
	s := make([]string, len(args))
	for ii, v := range args {
		s[ii] = types.ToString(v)
	}
	return strings.Join(s, "")
}

func and(args ...interface{}) bool {
	for _, v := range args {
		t, _ := types.IsTrue(v)
		if !t {
			return false
		}
	}
	return true
}

func or(args ...interface{}) interface{} {
	for _, v := range args {
		t, _ := types.IsTrue(v)
		if t {
			return v
		}
	}
	return nil
}

func not(arg interface{}) bool {
	t, _ := types.IsTrue(arg)
	return !t
}

func divisible(n interface{}, d interface{}) (bool, error) {
	ni, err := types.ToInt(n)
	if err != nil {
		return false, fmt.Errorf("divisible() invalid number %v: %s", n, err)
	}
	di, err := types.ToInt(d)
	if err != nil {
		return false, fmt.Errorf("divisible() invalid divisor %v: %s", d, err)
	}
	return ni%di == 0, nil
}

func even(arg interface{}) (bool, error) {
	return divisible(arg, 2)
}

func odd(arg interface{}) (bool, error) {
	res, err := divisible(arg, 2)
	if err != nil {
		return false, err
	}
	return !res, nil
}

func now() time.Time {
	return time.Now()
}

var templateFuncs template.FuncMap = template.FuncMap{
	"eq":        eq,
	"neq":       neq,
	"lt":        lt,
	"lte":       lte,
	"gt":        lt,
	"gte":       lte,
	"json":      _json,
	"jsons":     jsons,
	"nz":        nz,
	"lower":     lower,
	"join":      join,
	"map":       _map,
	"slice":     _slice,
	"append":    _append,
	"mult":      mult,
	"divisible": divisible,
	"add":       add,
	"even":      even,
	"odd":       odd,
	"render":    assets.Render,
	"concat":    concat,
	"and":       and,
	"or":        or,
	"not":       not,
	"now":       now,
	"to_lower":  strings.ToLower,
	"to_title":  strings.ToTitle,
	"to_upper":  strings.ToUpper,

	// Go builtins
	"call":     call,
	"html":     template.HTMLEscaper,
	"index":    index,
	"js":       template.JSEscaper,
	"len":      length,
	"print":    fmt.Sprint,
	"printf":   fmt.Sprintf,
	"println":  fmt.Sprintln,
	"urlquery": template.URLQueryEscaper,
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package fdroidcl

import (
	"encoding/hex"
	"encoding/xml"
	"fmt"
	"io"
	"sort"
	"strings"
	"time"
)

type Index struct {
	Repo struct {
		Name        string `xml:"name,attr"`
		PubKey      string `xml:"pubkey,attr"`
		Timestamp   int    `xml:"timestamp,attr"`
		URL         string `xml:"url,attr"`
		Version     int    `xml:"version,attr"`
		MaxAge      int    `xml:"maxage,attr"`
		Description string `xml:"description"`
	} `xml:"repo"`
	Apps []App `xml:"application"`
}

type CommaList []string

func (cl *CommaList) FromString(s string) {
	*cl = strings.Split(s, ",")
}

func (cl *CommaList) String() string {
	return strings.Join(*cl, ",")
}

func (cl *CommaList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var content string
	if err := d.DecodeElement(&content, &start); err != nil {
		return err
	}
	cl.FromString(content)
	return nil
}

func (cl *CommaList) UnmarshalText(text []byte) (err error) {
	cl.FromString(string(text))
	return nil
}

type HexVal []byte

func (hv *HexVal) FromString(s string) error {
	b, err := hex.DecodeString(s)
	if err != nil {
		return err
	}
	*hv = b
	return nil
}

func (hv *HexVal) String() string {
	return hex.EncodeToString(*hv)
}

func (hv *HexVal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var content string
	if err := d.DecodeElement(&content, &start); err != nil {
		return err
	}
	return hv.FromString(content)
}

func (hv *HexVal) UnmarshalText(text []byte) (err error) {
	return hv.FromString(string(text))
}

// App is an Android application
type App struct {
	ID        string    `xml:"id"`
	Name      string    `xml:"name"`
	Summary   string    `xml:"summary"`
	Desc      string    `xml:"desc"`
	License   string    `xml:"license"`
	Categs    CommaList `xml:"categories"`
	Website   string    `xml:"web"`
	Source    string    `xml:"source"`
	Tracker   string    `xml:"tracker"`
	Changelog string    `xml:"changelog"`
	Donate    string    `xml:"donate"`
	Bitcoin   string    `xml:"bitcoin"`
	Litecoin  string    `xml:"litecoin"`
	Dogecoin  string    `xml:"dogecoin"`
	FlattrID  string    `xml:"flattr"`
	Apks      []Apk     `xml:"package"`
	CVName    string    `xml:"marketversion"`
	CVCode    int       `xml:"marketvercode"`
	CurApk    *Apk
}

type HexHash struct {
	Type string `xml:"type,attr"`
	Data HexVal `xml:",chardata"`
}

type DateVal struct {
	time.Time
}

func (dv *DateVal) FromString(s string) error {
	t, err := time.Parse("2006-01-02", s)
	if err != nil {
		return err
	}
	*dv = DateVal{t}
	return nil
}

func (dv *DateVal) String() string {
	return dv.Format("2006-01-02")
}

func (dv *DateVal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var content string
	if err := d.DecodeElement(&content, &start); err != nil {
		return err
	}
	return dv.FromString(content)
}

func (dv *DateVal) UnmarshalText(text []byte) (err error) {
	return dv.FromString(string(text))
}

// Apk is an Android package
type Apk struct {
	VName   string    `xml:"version"`
	VCode   int       `xml:"versioncode"`
	Size    int64     `xml:"size"`
	MinSdk  int       `xml:"sdkver"`
	MaxSdk  int       `xml:"maxsdkver"`
	ABIs    CommaList `xml:"nativecode"`
	ApkName string    `xml:"apkname"`
	SrcName string    `xml:"srcname"`
	Sig     HexVal    `xml:"sig"`
	Added   DateVal   `xml:"added"`
	Perms   CommaList `xml:"permissions"`
	Feats   CommaList `xml:"features"`
	Hash    HexHash   `xml:"hash"`
}

func (app *App) TextDesc(w io.Writer) {
	reader := strings.NewReader(app.Desc)
	decoder := xml.NewDecoder(reader)
	firstParagraph := true
	linePrefix := ""
	colsUsed := 0
	var links []string
	linked := false
	for {
		token, err := decoder.Token()
		if err == io.EOF || token == nil {
			break
		}
		switch t := token.(type) {
		case xml.StartElement:
			switch t.Name.Local {
			case "p":
				if firstParagraph {
					firstParagraph = false
				} else {
					fmt.Fprintln(w)
				}
				linePrefix = ""
				colsUsed = 0
			case "li":
				fmt.Fprint(w, "\n *")
				linePrefix = "   "
				colsUsed = 0
			case "a":
				for _, attr := range t.Attr {
					if attr.Name.Local == "href" {
						links = append(links, attr.Value)
						linked = true
						break
					}
				}
			}
		case xml.EndElement:
			switch t.Name.Local {
			case "p":
				fmt.Fprintln(w)
			case "ul":
				fmt.Fprintln(w)
			case "ol":
				fmt.Fprintln(w)
			}
		case xml.CharData:
			left := string(t)
			if linked {
				left += fmt.Sprintf("[%d]", len(links)-1)
				linked = false
			}
			limit := 80 - len(linePrefix) - colsUsed
			firstLine := true
			for len(left) > limit {
				last := 0
				for i, c := range left {
					if i >= limit {
						break
					}
					if c == ' ' {
						last = i
					}
				}
				if firstLine {
					firstLine = false
					limit += colsUsed
				} else {
					fmt.Fprint(w, linePrefix)
				}
				fmt.Fprintln(w, left[:last])
				left = left[last+1:]
				colsUsed = 0
			}
			if firstLine {
				firstLine = false
			} else {
				fmt.Fprint(w, linePrefix)
			}
			fmt.Fprint(w, left)
			colsUsed += len(left)
		}
	}
	if len(links) > 0 {
		fmt.Fprintln(w)
		for i, link := range links {
			fmt.Fprintf(w, "[%d] %s\n", i, link)
		}
	}
}

type appList []App

func (al appList) Len() int           { return len(al) }
func (al appList) Swap(i, j int)      { al[i], al[j] = al[j], al[i] }
func (al appList) Less(i, j int) bool { return al[i].ID < al[j].ID }

type apkList []Apk

func (al apkList) Len() int           { return len(al) }
func (al apkList) Swap(i, j int)      { al[i], al[j] = al[j], al[i] }
func (al apkList) Less(i, j int) bool { return al[i].VCode > al[j].VCode }

func LoadIndexXml(r io.Reader) (*Index, error) {
	var index Index
	decoder := xml.NewDecoder(r)
	if err := decoder.Decode(&index); err != nil {
		return nil, err
	}

	sort.Sort(appList(index.Apps))

	for i := range index.Apps {
		app := &index.Apps[i]
		sort.Sort(apkList(app.Apks))
		app.calcCurApk()
	}
	return &index, nil
}

func (app *App) calcCurApk() {
	for _, apk := range app.Apks {
		app.CurApk = &apk
		if app.CVCode >= apk.VCode {
			break
		}
	}
}
<commit_msg>Separate repo struct<commit_after>// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package fdroidcl

import (
	"encoding/hex"
	"encoding/xml"
	"fmt"
	"io"
	"sort"
	"strings"
	"time"
)

type Index struct {
	Repo Repo  `xml:"repo"`
	Apps []App `xml:"application"`
}

type Repo struct {
	Name        string `xml:"name,attr"`
	PubKey      string `xml:"pubkey,attr"`
	Timestamp   int    `xml:"timestamp,attr"`
	URL         string `xml:"url,attr"`
	Version     int    `xml:"version,attr"`
	MaxAge      int    `xml:"maxage,attr"`
	Description string `xml:"description"`
}

type CommaList []string

func (cl *CommaList) FromString(s string) {
	*cl = strings.Split(s, ",")
}

func (cl *CommaList) String() string {
	return strings.Join(*cl, ",")
}

func (cl *CommaList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var content string
	if err := d.DecodeElement(&content, &start); err != nil {
		return err
	}
	cl.FromString(content)
	return nil
}

func (cl *CommaList) UnmarshalText(text []byte) (err error) {
	cl.FromString(string(text))
	return nil
}

type HexVal []byte

func (hv *HexVal) FromString(s string) error {
	b, err := hex.DecodeString(s)
	if err != nil {
		return err
	}
	*hv = b
	return nil
}

func (hv *HexVal) String() string {
	return hex.EncodeToString(*hv)
}

func (hv *HexVal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var content string
	if err := d.DecodeElement(&content, &start); err != nil {
		return err
	}
	return hv.FromString(content)
}

func (hv *HexVal) UnmarshalText(text []byte) (err error) {
	return hv.FromString(string(text))
}

// App is an Android application
type App struct {
	ID        string    `xml:"id"`
	Name      string    `xml:"name"`
	Summary   string    `xml:"summary"`
	Desc      string    `xml:"desc"`
	License   string    `xml:"license"`
	Categs    CommaList `xml:"categories"`
	Website   string    `xml:"web"`
	Source    string    `xml:"source"`
	Tracker   string    `xml:"tracker"`
	Changelog string    `xml:"changelog"`
	Donate    string    `xml:"donate"`
	Bitcoin   string    `xml:"bitcoin"`
	Litecoin  string    `xml:"litecoin"`
	Dogecoin  string    `xml:"dogecoin"`
	FlattrID  string    `xml:"flattr"`
	Apks      []Apk     `xml:"package"`
	CVName    string    `xml:"marketversion"`
	CVCode    int       `xml:"marketvercode"`
	CurApk    *Apk
}

type HexHash struct {
	Type string `xml:"type,attr"`
	Data HexVal `xml:",chardata"`
}

type DateVal struct {
	time.Time
}

func (dv *DateVal) FromString(s string) error {
	t, err := time.Parse("2006-01-02", s)
	if err != nil {
		return err
	}
	*dv = DateVal{t}
	return nil
}

func (dv *DateVal) String() string {
	return dv.Format("2006-01-02")
}

func (dv *DateVal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var content string
	if err := d.DecodeElement(&content, &start); err != nil {
		return err
	}
	return dv.FromString(content)
}

func (dv *DateVal) UnmarshalText(text []byte) (err error) {
	return dv.FromString(string(text))
}

// Apk is an Android package
type Apk struct {
	VName   string    `xml:"version"`
	VCode   int       `xml:"versioncode"`
	Size    int64     `xml:"size"`
	MinSdk  int       `xml:"sdkver"`
	MaxSdk  int       `xml:"maxsdkver"`
	ABIs    CommaList `xml:"nativecode"`
	ApkName string    `xml:"apkname"`
	SrcName string    `xml:"srcname"`
	Sig     HexVal    `xml:"sig"`
	Added   DateVal   `xml:"added"`
	Perms   CommaList `xml:"permissions"`
	Feats   CommaList `xml:"features"`
	Hash    HexHash   `xml:"hash"`
}

func (app *App) TextDesc(w io.Writer) {
	reader := strings.NewReader(app.Desc)
	decoder := xml.NewDecoder(reader)
	firstParagraph := true
	linePrefix := ""
	colsUsed := 0
	var links []string
	linked := false
	for {
		token, err := decoder.Token()
		if err == io.EOF || token == nil {
			break
		}
		switch t := token.(type) {
		case xml.StartElement:
			switch t.Name.Local {
			case "p":
				if firstParagraph {
					firstParagraph = false
				} else {
					fmt.Fprintln(w)
				}
				linePrefix = ""
				colsUsed = 0
			case "li":
				fmt.Fprint(w, "\n *")
				linePrefix = "   "
				colsUsed = 0
			case "a":
				for _, attr := range t.Attr {
					if attr.Name.Local == "href" {
						links = append(links, attr.Value)
						linked = true
						break
					}
				}
			}
		case xml.EndElement:
			switch t.Name.Local {
			case "p":
				fmt.Fprintln(w)
			case "ul":
				fmt.Fprintln(w)
			case "ol":
				fmt.Fprintln(w)
			}
		case xml.CharData:
			left := string(t)
			if linked {
				left += fmt.Sprintf("[%d]", len(links)-1)
				linked = false
			}
			limit := 80 - len(linePrefix) - colsUsed
			firstLine := true
			for len(left) > limit {
				last := 0
				for i, c := range left {
					if i >= limit {
						break
					}
					if c == ' ' {
						last = i
					}
				}
				if firstLine {
					firstLine = false
					limit += colsUsed
				} else {
					fmt.Fprint(w, linePrefix)
				}
				fmt.Fprintln(w, left[:last])
				left = left[last+1:]
				colsUsed = 0
			}
			if firstLine {
				firstLine = false
			} else {
				fmt.Fprint(w, linePrefix)
			}
			fmt.Fprint(w, left)
			colsUsed += len(left)
		}
	}
	if len(links) > 0 {
		fmt.Fprintln(w)
		for i, link := range links {
			fmt.Fprintf(w, "[%d] %s\n", i, link)
		}
	}
}

type appList []App

func (al appList) Len() int           { return len(al) }
func (al appList) Swap(i, j int)      { al[i], al[j] = al[j], al[i] }
func (al appList) Less(i, j int) bool { return al[i].ID < al[j].ID }

type apkList []Apk

func (al apkList) Len() int           { return len(al) }
func (al apkList) Swap(i, j int)      { al[i], al[j] = al[j], al[i] }
func (al apkList) Less(i, j int) bool { return al[i].VCode > al[j].VCode }

func LoadIndexXml(r io.Reader) (*Index, error) {
	var index Index
	decoder := xml.NewDecoder(r)
	if err := decoder.Decode(&index); err != nil {
		return nil, err
	}

	sort.Sort(appList(index.Apps))

	for i := range index.Apps {
		app := &index.Apps[i]
		sort.Sort(apkList(app.Apks))
		app.calcCurApk()
	}
	return &index, nil
}

func (app *App) calcCurApk() {
	for _, apk := range app.Apks {
		app.CurApk = &apk
		if app.CVCode >= apk.VCode {
			break
		}
	}
}
<|endoftext|>


<commit_before>package rest

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

// Possible improvements:
// If AllowedMethods["*"] then Access-Control-Allow-Methods is set to the requested methods
// If AllowedHeaderss["*"] then Access-Control-Allow-Headers is set to the requested headers
// Put some presets in AllowedHeaders
// Put some presets in AccessControlExposeHeaders

// CorsMiddleware provides a configurable CORS implementation.
type CorsMiddleware struct {
	allowedMethods map[string]bool
	allowedHeaders map[string]bool

	// Reject non CORS requests if true. See CorsInfo.IsCors.
	RejectNonCorsRequests bool

	// Function excecuted for every CORS requests to validate the Origin. (Required)
	// Must return true if valid, false if invalid.
	// For instance: simple equality, regexp, DB lookup, ...
	OriginValidator func(origin string, request *Request) bool

	// List of allowed HTTP methods. Note that the comparison will be made in uppercase
	// to avoid common mistakes. And that the Access-Control-Allow-Methods response header
	// also uses uppercase.
	// (see CorsInfo.AccessControlRequestMethod)
	AllowedMethods []string

	// List of allowed HTTP Headers. Note that the comparison will be made with
	// noarmalized names (http.CanonicalHeaderKey). And that the response header
	// also uses normalized names.
	// (see CorsInfo.AccessControlRequestHeaders)
	AllowedHeaders []string

	// List of headers used to set the Access-Control-Expose-Headers header.
	AccessControlExposeHeaders []string

	// User to se the Access-Control-Allow-Credentials response header.
	AccessControlAllowCredentials bool

	// Used to set the Access-Control-Max-Age response header, in seconds.
	AccessControlMaxAge int
}

// MiddlewareFunc makes CorsMiddleware implement the Middleware interface.
func (mw *CorsMiddleware) MiddlewareFunc(handler HandlerFunc) HandlerFunc {

	// precompute as much as possible at init time

	mw.allowedMethods = map[string]bool{}
	for _, allowedMethod := range mw.AllowedMethods {
		mw.allowedMethods[strings.ToUpper(allowedMethod)] = true
	}

	mw.allowedHeaders = map[string]bool{}
	for _, allowedHeader := range mw.AllowedHeaders {
		mw.allowedHeaders[http.CanonicalHeaderKey(allowedHeader)] = true
	}

	return func(writer ResponseWriter, request *Request) {

		corsInfo := request.GetCorsInfo()

		// non CORS requests
		if !corsInfo.IsCors {
			if mw.RejectNonCorsRequests {
				Error(writer, "Non CORS request", http.StatusForbidden)
				return
			}
			// continue, execute the wrapped middleware
			handler(writer, request)
			return
		}

		// Validate the Origin
		if mw.OriginValidator(corsInfo.Origin, request) == false {
			Error(writer, "Invalid Origin", http.StatusForbidden)
			return
		}

		if corsInfo.IsPreflight {

			// check the request methods
			if mw.allowedMethods[corsInfo.AccessControlRequestMethod] == false {
				Error(writer, "Invalid Preflight Request", http.StatusForbidden)
				return
			}

			// check the request headers
			for _, requestedHeader := range corsInfo.AccessControlRequestHeaders {
				if mw.allowedHeaders[requestedHeader] == false {
					Error(writer, "Invalid Preflight Request", http.StatusForbidden)
					return
				}
			}

			for allowedMethod := range mw.allowedMethods {
				writer.Header().Add("Access-Control-Allow-Methods", allowedMethod)
			}
			for allowedHeader := range mw.allowedHeaders {
				writer.Header().Add("Access-Control-Allow-Headers", allowedHeader)
			}
			writer.Header().Set("Access-Control-Allow-Origin", corsInfo.Origin)
			if mw.AccessControlAllowCredentials == true {
				writer.Header().Set("Access-Control-Allow-Credentials", "true")
			}
			writer.Header().Set("Access-Control-Max-Age", strconv.Itoa(mw.AccessControlMaxAge))
			writer.WriteHeader(http.StatusOK)
			return
		}

		// Non-preflight requests
		for _, exposed := range mw.AccessControlExposeHeaders {
			writer.Header().Add("Access-Control-Expose-Headers", exposed)
		}
		writer.Header().Set("Access-Control-Allow-Origin", corsInfo.Origin)
		if mw.AccessControlAllowCredentials == true {
			writer.Header().Set("Access-Control-Allow-Credentials", "true")
		}
		// continure, execute the wrapped middleware
		handler(writer, request)
		return
	}
}
<commit_msg>Use comma separated values for CORS response headers<commit_after>package rest

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

// Possible improvements:
// If AllowedMethods["*"] then Access-Control-Allow-Methods is set to the requested methods
// If AllowedHeaderss["*"] then Access-Control-Allow-Headers is set to the requested headers
// Put some presets in AllowedHeaders
// Put some presets in AccessControlExposeHeaders

// CorsMiddleware provides a configurable CORS implementation.
type CorsMiddleware struct {
	allowedMethods    map[string]bool
	allowedMethodsCsv string
	allowedHeaders    map[string]bool
	allowedHeadersCsv string

	// Reject non CORS requests if true. See CorsInfo.IsCors.
	RejectNonCorsRequests bool

	// Function excecuted for every CORS requests to validate the Origin. (Required)
	// Must return true if valid, false if invalid.
	// For instance: simple equality, regexp, DB lookup, ...
	OriginValidator func(origin string, request *Request) bool

	// List of allowed HTTP methods. Note that the comparison will be made in uppercase
	// to avoid common mistakes. And that the Access-Control-Allow-Methods response header
	// also uses uppercase.
	// (see CorsInfo.AccessControlRequestMethod)
	AllowedMethods []string

	// List of allowed HTTP Headers. Note that the comparison will be made with
	// noarmalized names (http.CanonicalHeaderKey). And that the response header
	// also uses normalized names.
	// (see CorsInfo.AccessControlRequestHeaders)
	AllowedHeaders []string

	// List of headers used to set the Access-Control-Expose-Headers header.
	AccessControlExposeHeaders []string

	// User to se the Access-Control-Allow-Credentials response header.
	AccessControlAllowCredentials bool

	// Used to set the Access-Control-Max-Age response header, in seconds.
	AccessControlMaxAge int
}

// MiddlewareFunc makes CorsMiddleware implement the Middleware interface.
func (mw *CorsMiddleware) MiddlewareFunc(handler HandlerFunc) HandlerFunc {

	// precompute as much as possible at init time

	mw.allowedMethods = map[string]bool{}
	normedMethods := []string{}
	for _, allowedMethod := range mw.AllowedMethods {
		normed := strings.ToUpper(allowedMethod)
		mw.allowedMethods[normed] = true
		normedMethods = append(normedMethods, normed)
	}
	mw.allowedMethodsCsv = strings.Join(normedMethods, ",")

	mw.allowedHeaders = map[string]bool{}
	normedHeaders := []string{}
	for _, allowedHeader := range mw.AllowedHeaders {
		normed := http.CanonicalHeaderKey(allowedHeader)
		mw.allowedHeaders[normed] = true
		normedHeaders = append(normedHeaders, normed)
	}
	mw.allowedHeadersCsv = strings.Join(normedHeaders, ",")

	return func(writer ResponseWriter, request *Request) {

		corsInfo := request.GetCorsInfo()

		// non CORS requests
		if !corsInfo.IsCors {
			if mw.RejectNonCorsRequests {
				Error(writer, "Non CORS request", http.StatusForbidden)
				return
			}
			// continue, execute the wrapped middleware
			handler(writer, request)
			return
		}

		// Validate the Origin
		if mw.OriginValidator(corsInfo.Origin, request) == false {
			Error(writer, "Invalid Origin", http.StatusForbidden)
			return
		}

		if corsInfo.IsPreflight {

			// check the request methods
			if mw.allowedMethods[corsInfo.AccessControlRequestMethod] == false {
				Error(writer, "Invalid Preflight Request", http.StatusForbidden)
				return
			}

			// check the request headers
			for _, requestedHeader := range corsInfo.AccessControlRequestHeaders {
				if mw.allowedHeaders[requestedHeader] == false {
					Error(writer, "Invalid Preflight Request", http.StatusForbidden)
					return
				}
			}

			writer.Header().Set("Access-Control-Allow-Methods", mw.allowedMethodsCsv)
			writer.Header().Set("Access-Control-Allow-Headers", mw.allowedHeadersCsv)
			writer.Header().Set("Access-Control-Allow-Origin", corsInfo.Origin)
			if mw.AccessControlAllowCredentials == true {
				writer.Header().Set("Access-Control-Allow-Credentials", "true")
			}
			writer.Header().Set("Access-Control-Max-Age", strconv.Itoa(mw.AccessControlMaxAge))
			writer.WriteHeader(http.StatusOK)
			return
		}

		// Non-preflight requests
		for _, exposed := range mw.AccessControlExposeHeaders {
			writer.Header().Add("Access-Control-Expose-Headers", exposed)
		}
		writer.Header().Set("Access-Control-Allow-Origin", corsInfo.Origin)
		if mw.AccessControlAllowCredentials == true {
			writer.Header().Set("Access-Control-Allow-Credentials", "true")
		}
		// continure, execute the wrapped middleware
		handler(writer, request)
		return
	}
}
<|endoftext|>


<commit_before>package terraform

import (
	"bytes"
	"encoding/gob"
	"errors"
	"fmt"
	"io"
	"sync"

	"github.com/hashicorp/terraform/config"
)

func init() {
	gob.Register(make([]interface{}, 0))
	gob.Register(make([]map[string]interface{}, 0))
}

// PlanOpts are the options used to generate an execution plan for
// Terraform.
type PlanOpts struct {
	// If set to true, then the generated plan will destroy all resources
	// that are created. Otherwise, it will move towards the desired state
	// specified in the configuration.
	Destroy bool

	Config *config.Config
	State  *State
	Vars   map[string]string
}

// Plan represents a single Terraform execution plan, which contains
// all the information necessary to make an infrastructure change.
type Plan struct {
	Config *config.Config
	Diff   *Diff
	State  *State
	Vars   map[string]string

	once sync.Once
}

func (p *Plan) String() string {
	buf := new(bytes.Buffer)
	buf.WriteString("DIFF:\n\n")
	buf.WriteString(p.Diff.String())
	buf.WriteString("\nSTATE:\n\n")
	buf.WriteString(p.State.String())
	return buf.String()
}

func (p *Plan) init() {
	p.once.Do(func() {
		if p.Config == nil {
			p.Config = new(config.Config)
		}

		if p.Diff == nil {
			p.Diff = new(Diff)
			p.Diff.init()
		}

		if p.State == nil {
			p.State = new(State)
			p.State.init()
		}

		if p.Vars == nil {
			p.Vars = make(map[string]string)
		}
	})
}

// The format byte is prefixed into the plan file format so that we have
// the ability in the future to change the file format if we want for any
// reason.
const planFormatByte byte = 1

// ReadPlan reads a plan structure out of a reader in the format that
// was written by WritePlan.
func ReadPlan(src io.Reader) (*Plan, error) {
	var result *Plan

	var formatByte [1]byte
	n, err := src.Read(formatByte[:])
	if err != nil {
		return nil, err
	}
	if n != len(formatByte) {
		return nil, errors.New("failed to read plan version byte")
	}

	if formatByte[0] != planFormatByte {
		return nil, fmt.Errorf("unknown plan file version: %d", formatByte[0])
	}

	dec := gob.NewDecoder(src)
	if err := dec.Decode(&result); err != nil {
		return nil, err
	}

	return result, nil
}

// WritePlan writes a plan somewhere in a binary format.
func WritePlan(d *Plan, dst io.Writer) error {
	n, err := dst.Write([]byte{planFormatByte})
	if err != nil {
		return err
	}
	if n != 1 {
		return errors.New("failed to write plan version byte")
	}

	return gob.NewEncoder(dst).Encode(d)
}
<commit_msg>terraform: Plan.Context<commit_after>package terraform

import (
	"bytes"
	"encoding/gob"
	"errors"
	"fmt"
	"io"
	"sync"

	"github.com/hashicorp/terraform/config"
)

func init() {
	gob.Register(make([]interface{}, 0))
	gob.Register(make([]map[string]interface{}, 0))
}

// PlanOpts are the options used to generate an execution plan for
// Terraform.
type PlanOpts struct {
	// If set to true, then the generated plan will destroy all resources
	// that are created. Otherwise, it will move towards the desired state
	// specified in the configuration.
	Destroy bool

	Config *config.Config
	State  *State
	Vars   map[string]string
}

// Plan represents a single Terraform execution plan, which contains
// all the information necessary to make an infrastructure change.
type Plan struct {
	Config *config.Config
	Diff   *Diff
	State  *State
	Vars   map[string]string

	once sync.Once
}

// Context returns a Context with the data encapsulated in this plan.
//
// The following fields in opts are overridden by the plan: Config,
// Diff, State, Variables.
func (p *Plan) Context(opts *ContextOpts) *Context {
	opts.Config = p.Config
	opts.Diff = p.Diff
	opts.State = p.State
	opts.Variables = p.Vars
	return NewContext(opts)
}

func (p *Plan) String() string {
	buf := new(bytes.Buffer)
	buf.WriteString("DIFF:\n\n")
	buf.WriteString(p.Diff.String())
	buf.WriteString("\nSTATE:\n\n")
	buf.WriteString(p.State.String())
	return buf.String()
}

func (p *Plan) init() {
	p.once.Do(func() {
		if p.Config == nil {
			p.Config = new(config.Config)
		}

		if p.Diff == nil {
			p.Diff = new(Diff)
			p.Diff.init()
		}

		if p.State == nil {
			p.State = new(State)
			p.State.init()
		}

		if p.Vars == nil {
			p.Vars = make(map[string]string)
		}
	})
}

// The format byte is prefixed into the plan file format so that we have
// the ability in the future to change the file format if we want for any
// reason.
const planFormatByte byte = 1

// ReadPlan reads a plan structure out of a reader in the format that
// was written by WritePlan.
func ReadPlan(src io.Reader) (*Plan, error) {
	var result *Plan

	var formatByte [1]byte
	n, err := src.Read(formatByte[:])
	if err != nil {
		return nil, err
	}
	if n != len(formatByte) {
		return nil, errors.New("failed to read plan version byte")
	}

	if formatByte[0] != planFormatByte {
		return nil, fmt.Errorf("unknown plan file version: %d", formatByte[0])
	}

	dec := gob.NewDecoder(src)
	if err := dec.Decode(&result); err != nil {
		return nil, err
	}

	return result, nil
}

// WritePlan writes a plan somewhere in a binary format.
func WritePlan(d *Plan, dst io.Writer) error {
	n, err := dst.Write([]byte{planFormatByte})
	if err != nil {
		return err
	}
	if n != 1 {
		return errors.New("failed to write plan version byte")
	}

	return gob.NewEncoder(dst).Encode(d)
}
<|endoftext|>


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

// This is a bot and a service. The bot runs in the specified intervals and
// collects data about the list of government bonds available at Bovespa.
//
// There's also a webserver that serves it directly from the memory, in JSON
// format.
package main

import (
	"encoding/json"
	"flag"
	"io/ioutil"
	"launchpad.net/xmlpath"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"
)

const URL = "http://www.bmfbovespa.com.br/pt-br/mercados/outros-titulos/tesouro-direto/tesouro-direto.aspx?idioma=pt-br"

type Titulo struct {
	Titulo      string
	Vencimento  time.Time
	PrecoCompra float64
	PrecoVenda  float64
	TaxaCompra  string
	TaxaVenda   string
}

var (
	titulos      []Titulo
	listen       string
	interval     time.Duration
	pathTD       = xmlpath.MustCompile(`//table[@summary="Taxas"]/tbody/tr/td[1]`)
	pathSiblings = xmlpath.MustCompile(`./following-sibling::*`)
)

func init() {
	flag.DurationVar(&interval, "interval", time.Minute*60, "Interval")
	flag.StringVar(&listen, "http", ":7575", "Address to listen")
}

func collectTitulos() {
	resp, err := http.Get(URL)
	if err != nil {
		log.Printf("ERROR: %s", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("ERROR: %s", err)
		return
	}
	strBody := strings.Replace(string(body), " < ", " < ", -1)
	strBody = strings.Replace(strBody, " > ", " > ", -1)
	reader := strings.NewReader(strBody)
	root, err := xmlpath.ParseHTML(reader)
	if err != nil {
		log.Printf("ERROR: %s", err)
		return
	}
	titulos = make([]Titulo, 0, 10)
	tds := pathTD.Iter(root)
	for tds.Next() {
		var titulo Titulo
		titulo.Titulo = tds.Node().String()
		siblings := pathSiblings.Iter(tds.Node())
		for i := 0; siblings.Next(); i++ {
			node := siblings.Node()
			switch i {
			case 0:
				original := node.String()
				vencimento, err := time.Parse("02/01/2006", original)
				if err != nil {
					log.Printf("[ERROR] Failed to parse vencimento: %s", err)
					break
				}
				titulo.Vencimento = vencimento
				titulo.Titulo += " " + vencimento.Format("020106")
			case 2:
				titulo.TaxaCompra = node.String()
			case 3:
				titulo.TaxaVenda = node.String()
			case 4:
				original := strings.Replace(node.String(), ",", ".", -1)
				if original == "-" {
					break
				}
				precoCompra, err := strconv.ParseFloat(original, 64)
				if err != nil {
					log.Printf("[ERROR] Failed to parse precoCompra: %s", err)
					break
				}
				titulo.PrecoCompra = precoCompra
			case 5:
				original := strings.Replace(node.String(), ",", ".", -1)
				if original == "-" {
					break
				}
				precoVenda, err := strconv.ParseFloat(original, 64)
				if err != nil {
					log.Printf("[ERROR] Failed to parse precoVenda: %s", err)
					break
				}
				titulo.PrecoVenda = precoVenda
			}
		}
		titulos = append(titulos, titulo)
	}
}

func tesouroDireto(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Content-Type", "application/json")
	json.NewEncoder(w).Encode(titulos)

}

func collectLoop() {
	for _ = range time.Tick(interval) {
		collectTitulos()
	}
}

func main() {
	flag.Parse()
	collectTitulos()
	go collectLoop()
	http.Handle("/", http.HandlerFunc(tesouroDireto))
	log.Printf("Starting server at %s...\n", listen)
	err := http.ListenAndServe(listen, nil)
	if err != nil {
		log.Printf("ERROR: %s\n", err)
	}
}
<commit_msg>tesouro_direto: remove useless blank line<commit_after>// Copyright 2015 Francisco Souza. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This is a bot and a service. The bot runs in the specified intervals and
// collects data about the list of government bonds available at Bovespa.
//
// There's also a webserver that serves it directly from the memory, in JSON
// format.
package main

import (
	"encoding/json"
	"flag"
	"io/ioutil"
	"launchpad.net/xmlpath"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"
)

const URL = "http://www.bmfbovespa.com.br/pt-br/mercados/outros-titulos/tesouro-direto/tesouro-direto.aspx?idioma=pt-br"

type Titulo struct {
	Titulo      string
	Vencimento  time.Time
	PrecoCompra float64
	PrecoVenda  float64
	TaxaCompra  string
	TaxaVenda   string
}

var (
	titulos      []Titulo
	listen       string
	interval     time.Duration
	pathTD       = xmlpath.MustCompile(`//table[@summary="Taxas"]/tbody/tr/td[1]`)
	pathSiblings = xmlpath.MustCompile(`./following-sibling::*`)
)

func init() {
	flag.DurationVar(&interval, "interval", time.Minute*60, "Interval")
	flag.StringVar(&listen, "http", ":7575", "Address to listen")
}

func collectTitulos() {
	resp, err := http.Get(URL)
	if err != nil {
		log.Printf("ERROR: %s", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("ERROR: %s", err)
		return
	}
	strBody := strings.Replace(string(body), " < ", " < ", -1)
	strBody = strings.Replace(strBody, " > ", " > ", -1)
	reader := strings.NewReader(strBody)
	root, err := xmlpath.ParseHTML(reader)
	if err != nil {
		log.Printf("ERROR: %s", err)
		return
	}
	titulos = make([]Titulo, 0, 10)
	tds := pathTD.Iter(root)
	for tds.Next() {
		var titulo Titulo
		titulo.Titulo = tds.Node().String()
		siblings := pathSiblings.Iter(tds.Node())
		for i := 0; siblings.Next(); i++ {
			node := siblings.Node()
			switch i {
			case 0:
				original := node.String()
				vencimento, err := time.Parse("02/01/2006", original)
				if err != nil {
					log.Printf("[ERROR] Failed to parse vencimento: %s", err)
					break
				}
				titulo.Vencimento = vencimento
				titulo.Titulo += " " + vencimento.Format("020106")
			case 2:
				titulo.TaxaCompra = node.String()
			case 3:
				titulo.TaxaVenda = node.String()
			case 4:
				original := strings.Replace(node.String(), ",", ".", -1)
				if original == "-" {
					break
				}
				precoCompra, err := strconv.ParseFloat(original, 64)
				if err != nil {
					log.Printf("[ERROR] Failed to parse precoCompra: %s", err)
					break
				}
				titulo.PrecoCompra = precoCompra
			case 5:
				original := strings.Replace(node.String(), ",", ".", -1)
				if original == "-" {
					break
				}
				precoVenda, err := strconv.ParseFloat(original, 64)
				if err != nil {
					log.Printf("[ERROR] Failed to parse precoVenda: %s", err)
					break
				}
				titulo.PrecoVenda = precoVenda
			}
		}
		titulos = append(titulos, titulo)
	}
}

func tesouroDireto(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Content-Type", "application/json")
	json.NewEncoder(w).Encode(titulos)
}

func collectLoop() {
	for range time.Tick(interval) {
		collectTitulos()
	}
}

func main() {
	flag.Parse()
	collectTitulos()
	go collectLoop()
	http.Handle("/", http.HandlerFunc(tesouroDireto))
	log.Printf("Starting server at %s...\n", listen)
	err := http.ListenAndServe(listen, nil)
	if err != nil {
		log.Printf("ERROR: %s\n", err)
	}
}
<|endoftext|>


<commit_before>// Package md decodes md and smd files.

package md

import (
	"bytes"
	"github.com/sselph/scraper/rom"
	"io"
	"io/ioutil"
)

func init() {
	rom.RegisterFormat(".smd", decodeSMD)
	rom.RegisterFormat(".mgd", decodeMGD)
	rom.RegisterFormat(".gen", rom.Noop)
	rom.RegisterFormat(".md", rom.Noop)
	rom.RegisterFormat(".32x", rom.Noop)
	rom.RegisterFormat(".gg", rom.Noop)
}

func DeInterleave(p []byte) []byte {
	l := len(p)
	m := l / 2
	b := make([]byte, l)
	for i, x := range p {
		if i < m {
			b[i*2+1] = x
		} else {
			b[i*2-l] = x
		}
	}
	return b
}

type SMDReader struct {
	f io.ReadCloser
	b []byte
	r *int
}

func (r SMDReader) Read(p []byte) (int, error) {
	ll := len(p)
	rl := ll - *r.r
	l := rl + 16384 - 1 - (rl-1)%16384
	copy(p, r.b[:*r.r])
	if rl <= 0 {
		*r.r = *r.r - ll
		copy(r.b, r.b[ll:])
		return ll, nil
	}
	n := *r.r
	for i := 0; i < l/16384; i++ {
		b := make([]byte, 16384)
		x, err := io.ReadFull(r.f, b)
		if x == 0 || err != nil {
			return n, err
		}
		b = DeInterleave(b)
		if ll < n+x {
			copy(p[n:ll], b)
			copy(r.b, b[ll-n:])
			*r.r = n + x - ll
			return ll, nil
		} else {
			copy(p[n:n+16384], b)
		}
		n += x
	}
	return ll, nil
}

func (r SMDReader) Close() error {
	return r.f.Close()
}

func decodeSMD(f io.ReadCloser, s int64) (io.ReadCloser, error) {
	tmp := make([]byte, 512)
	_, err := io.ReadFull(f, tmp)
	if err != nil {
		return nil, err
	}
	i := 0
	return SMDReader{f, make([]byte, 16384), &i}, nil
}

type MGDReader struct {
	r io.Reader
}

func (r MGDReader) Read(p []byte) (int, error) {
	n, err := r.r.Read(p)
	return n, err
}

func (r MGDReader) Close() error {
	return nil
}

func decodeMGD(f io.ReadCloser, s int64) (io.ReadCloser, error) {
	b, err := ioutil.ReadAll(f)
	f.Close()
	b = DeInterleave(b)
	if err != nil {
		return nil, err
	}
	return MGDReader{bytes.NewReader(b)}, nil
}
<commit_msg>Simplify MD processing. Read contents to determine file type.<commit_after>// Package md decodes md and smd files.

package md

import (
	"bytes"
	"fmt"
	"github.com/sselph/scraper/rom"
	"io"
	"io/ioutil"
)

func init() {
	rom.RegisterFormat(".smd", decodeMD)
	rom.RegisterFormat(".mgd", decodeMD)
	rom.RegisterFormat(".gen", decodeMD)
	rom.RegisterFormat(".md", decodeMD)
	rom.RegisterFormat(".32x", rom.Noop)
	rom.RegisterFormat(".gg", rom.Noop)
}

func DeInterleave(p []byte) []byte {
	l := len(p)
	m := l / 2
	b := make([]byte, l)
	for i, x := range p {
		if i < m {
			b[i*2+1] = x
		} else {
			b[i*2-l] = x
		}
	}
	return b
}

func decodeMD(f io.ReadCloser, s int64) (io.ReadCloser, error) {
	if s%16384 == 512 {
		tmp := make([]byte, 512)
		_, err := io.ReadFull(f, tmp)
		if err != nil {
			return nil, err
		}
		s -= 512
	}
	if s%16384 != 0 {
		return nil, fmt.Errorf("Invalid MD size")
	}
	b, err := ioutil.ReadAll(f)
	f.Close()
	if err != nil {
		return nil, err
	}
	if bytes.Equal(b[256:260], []byte("SEGA")) {
		return MDReader{bytes.NewReader(b)}, nil
	}
	x := DeInterleave(b[0:16384])
	if bytes.Equal(x[256:260], []byte("SEGA")) {
		for i := 0; int64(i) < (s / int64(16384)); i++ {
			x := i * 16384
			copy(b[x:x+16384], DeInterleave(b[x:x+16384]))
		}
		return MDReader{bytes.NewReader(b)}, nil
	}
	b = DeInterleave(b)
	return MDReader{bytes.NewReader(b)}, nil
}

type MDReader struct {
	r io.Reader
}

func (r MDReader) Read(p []byte) (int, error) {
	n, err := r.r.Read(p)
	return n, err
}

func (r MDReader) Close() error {
	return nil
}
<|endoftext|>


<commit_before>package lxd

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"sync"

	"github.com/gorilla/websocket"

	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/logger"
)

// ProtocolLXD represents a LXD API server
type ProtocolLXD struct {
	server *api.Server

	eventListeners     []*EventListener
	eventListenersLock sync.Mutex

	http            *http.Client
	httpHost        string
	httpUserAgent   string
	httpCertificate string
}

// RawQuery allows directly querying the LXD API
//
// This should only be used by internal LXD tools.
func (r *ProtocolLXD) RawQuery(method string, path string, data interface{}, ETag string) (*api.Response, string, error) {
	// Generate the URL
	url := fmt.Sprintf("%s%s", r.httpHost, path)

	return r.rawQuery(method, url, data, ETag)
}

// RawWebsocket allows directly connection to LXD API websockets
//
// This should only be used by internal LXD tools.
func (r *ProtocolLXD) RawWebsocket(path string) (*websocket.Conn, error) {
	// Generate the URL
	url := fmt.Sprintf("%s%s", r.httpHost, path)

	return r.rawWebsocket(url)
}

// Internal functions
func (r *ProtocolLXD) rawQuery(method string, url string, data interface{}, ETag string) (*api.Response, string, error) {
	var req *http.Request
	var err error

	// Log the request
	logger.Info("Sending request to LXD",
		"method", method,
		"url", url,
		"etag", ETag,
	)

	// Get a new HTTP request setup
	if data != nil {
		// Encode the provided data
		buf := bytes.Buffer{}
		err := json.NewEncoder(&buf).Encode(data)
		if err != nil {
			return nil, "", err
		}

		// Some data to be sent along with the request
		req, err = http.NewRequest(method, url, &buf)
		if err != nil {
			return nil, "", err
		}

		// Set the encoding accordingly
		req.Header.Set("Content-Type", "application/json")

		// Log the data
		logger.Debugf(logger.Pretty(data))
	} else {
		// No data to be sent along with the request
		req, err = http.NewRequest(method, url, nil)
		if err != nil {
			return nil, "", err
		}
	}

	// Set the user agent
	if r.httpUserAgent != "" {
		req.Header.Set("User-Agent", r.httpUserAgent)
	}

	// Set the ETag
	if ETag != "" {
		req.Header.Set("If-Match", ETag)
	}

	// Send the request
	resp, err := r.http.Do(req)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()

	// Get the ETag
	etag := resp.Header.Get("ETag")

	// Decode the response
	decoder := json.NewDecoder(resp.Body)
	response := api.Response{}

	err = decoder.Decode(&response)
	if err != nil {
		// Check the return value for a cleaner error
		if resp.StatusCode != http.StatusOK {
			return nil, "", fmt.Errorf("Failed to fetch %s: %s", url, resp.Status)
		}

		return nil, "", err
	}

	// Handle errors
	if response.Type == api.ErrorResponse {
		return nil, "", fmt.Errorf(response.Error)
	}

	return &response, etag, nil
}

func (r *ProtocolLXD) query(method string, path string, data interface{}, ETag string) (*api.Response, string, error) {
	// Generate the URL
	url := fmt.Sprintf("%s/1.0%s", r.httpHost, path)

	return r.rawQuery(method, url, data, ETag)
}

func (r *ProtocolLXD) queryStruct(method string, path string, data interface{}, ETag string, target interface{}) (string, error) {
	resp, etag, err := r.query(method, path, data, ETag)
	if err != nil {
		return "", err
	}

	err = resp.MetadataAsStruct(&target)
	if err != nil {
		return "", err
	}

	// Log the data
	logger.Debugf("Got response struct from LXD")
	logger.Debugf(logger.Pretty(target))

	return etag, nil
}

func (r *ProtocolLXD) queryOperation(method string, path string, data interface{}, ETag string) (*Operation, string, error) {
	// Send the query
	resp, etag, err := r.query(method, path, data, ETag)
	if err != nil {
		return nil, "", err
	}

	// Get to the operation
	respOperation, err := resp.MetadataAsOperation()
	if err != nil {
		return nil, "", err
	}

	// Setup an Operation wrapper
	op := Operation{
		Operation: *respOperation,
		r:         r,
		chActive:  make(chan bool),
	}

	// Log the data
	logger.Debugf("Got operation from LXD")
	logger.Debugf(logger.Pretty(op.Operation))

	return &op, etag, nil
}

func (r *ProtocolLXD) rawWebsocket(url string) (*websocket.Conn, error) {
	// Grab the http transport handler
	httpTransport := r.http.Transport.(*http.Transport)

	// Setup a new websocket dialer based on it
	dialer := websocket.Dialer{
		NetDial:         httpTransport.Dial,
		TLSClientConfig: httpTransport.TLSClientConfig,
		Proxy:           httpTransport.Proxy,
	}

	// Set the user agent
	headers := http.Header{}
	if r.httpUserAgent != "" {
		headers.Set("User-Agent", r.httpUserAgent)
	}

	// Establish the connection
	conn, _, err := dialer.Dial(url, headers)
	if err != nil {
		return nil, err
	}

	// Log the data
	logger.Debugf("Connected to the websocket")

	return conn, err
}

func (r *ProtocolLXD) websocket(path string) (*websocket.Conn, error) {
	// Generate the URL
	var url string
	if strings.HasPrefix(r.httpHost, "https://") {
		url = fmt.Sprintf("wss://%s/1.0%s", strings.TrimPrefix(r.httpHost, "https://"), path)
	} else {
		url = fmt.Sprintf("ws://%s/1.0%s", strings.TrimPrefix(r.httpHost, "http://"), path)
	}

	return r.rawWebsocket(url)
}
<commit_msg>Fix for older gorilla websocket package<commit_after>package lxd

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"sync"

	"github.com/gorilla/websocket"

	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/logger"
)

// ProtocolLXD represents a LXD API server
type ProtocolLXD struct {
	server *api.Server

	eventListeners     []*EventListener
	eventListenersLock sync.Mutex

	http            *http.Client
	httpHost        string
	httpUserAgent   string
	httpCertificate string
}

// RawQuery allows directly querying the LXD API
//
// This should only be used by internal LXD tools.
func (r *ProtocolLXD) RawQuery(method string, path string, data interface{}, ETag string) (*api.Response, string, error) {
	// Generate the URL
	url := fmt.Sprintf("%s%s", r.httpHost, path)

	return r.rawQuery(method, url, data, ETag)
}

// RawWebsocket allows directly connection to LXD API websockets
//
// This should only be used by internal LXD tools.
func (r *ProtocolLXD) RawWebsocket(path string) (*websocket.Conn, error) {
	// Generate the URL
	url := fmt.Sprintf("%s%s", r.httpHost, path)

	return r.rawWebsocket(url)
}

// Internal functions
func (r *ProtocolLXD) rawQuery(method string, url string, data interface{}, ETag string) (*api.Response, string, error) {
	var req *http.Request
	var err error

	// Log the request
	logger.Info("Sending request to LXD",
		"method", method,
		"url", url,
		"etag", ETag,
	)

	// Get a new HTTP request setup
	if data != nil {
		// Encode the provided data
		buf := bytes.Buffer{}
		err := json.NewEncoder(&buf).Encode(data)
		if err != nil {
			return nil, "", err
		}

		// Some data to be sent along with the request
		req, err = http.NewRequest(method, url, &buf)
		if err != nil {
			return nil, "", err
		}

		// Set the encoding accordingly
		req.Header.Set("Content-Type", "application/json")

		// Log the data
		logger.Debugf(logger.Pretty(data))
	} else {
		// No data to be sent along with the request
		req, err = http.NewRequest(method, url, nil)
		if err != nil {
			return nil, "", err
		}
	}

	// Set the user agent
	if r.httpUserAgent != "" {
		req.Header.Set("User-Agent", r.httpUserAgent)
	}

	// Set the ETag
	if ETag != "" {
		req.Header.Set("If-Match", ETag)
	}

	// Send the request
	resp, err := r.http.Do(req)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()

	// Get the ETag
	etag := resp.Header.Get("ETag")

	// Decode the response
	decoder := json.NewDecoder(resp.Body)
	response := api.Response{}

	err = decoder.Decode(&response)
	if err != nil {
		// Check the return value for a cleaner error
		if resp.StatusCode != http.StatusOK {
			return nil, "", fmt.Errorf("Failed to fetch %s: %s", url, resp.Status)
		}

		return nil, "", err
	}

	// Handle errors
	if response.Type == api.ErrorResponse {
		return nil, "", fmt.Errorf(response.Error)
	}

	return &response, etag, nil
}

func (r *ProtocolLXD) query(method string, path string, data interface{}, ETag string) (*api.Response, string, error) {
	// Generate the URL
	url := fmt.Sprintf("%s/1.0%s", r.httpHost, path)

	return r.rawQuery(method, url, data, ETag)
}

func (r *ProtocolLXD) queryStruct(method string, path string, data interface{}, ETag string, target interface{}) (string, error) {
	resp, etag, err := r.query(method, path, data, ETag)
	if err != nil {
		return "", err
	}

	err = resp.MetadataAsStruct(&target)
	if err != nil {
		return "", err
	}

	// Log the data
	logger.Debugf("Got response struct from LXD")
	logger.Debugf(logger.Pretty(target))

	return etag, nil
}

func (r *ProtocolLXD) queryOperation(method string, path string, data interface{}, ETag string) (*Operation, string, error) {
	// Send the query
	resp, etag, err := r.query(method, path, data, ETag)
	if err != nil {
		return nil, "", err
	}

	// Get to the operation
	respOperation, err := resp.MetadataAsOperation()
	if err != nil {
		return nil, "", err
	}

	// Setup an Operation wrapper
	op := Operation{
		Operation: *respOperation,
		r:         r,
		chActive:  make(chan bool),
	}

	// Log the data
	logger.Debugf("Got operation from LXD")
	logger.Debugf(logger.Pretty(op.Operation))

	return &op, etag, nil
}

func (r *ProtocolLXD) rawWebsocket(url string) (*websocket.Conn, error) {
	// Grab the http transport handler
	httpTransport := r.http.Transport.(*http.Transport)

	// Setup a new websocket dialer based on it
	dialer := websocket.Dialer{
		NetDial:         httpTransport.Dial,
		TLSClientConfig: httpTransport.TLSClientConfig,
	}

	// Set the user agent
	headers := http.Header{}
	if r.httpUserAgent != "" {
		headers.Set("User-Agent", r.httpUserAgent)
	}

	// Establish the connection
	conn, _, err := dialer.Dial(url, headers)
	if err != nil {
		return nil, err
	}

	// Log the data
	logger.Debugf("Connected to the websocket")

	return conn, err
}

func (r *ProtocolLXD) websocket(path string) (*websocket.Conn, error) {
	// Generate the URL
	var url string
	if strings.HasPrefix(r.httpHost, "https://") {
		url = fmt.Sprintf("wss://%s/1.0%s", strings.TrimPrefix(r.httpHost, "https://"), path)
	} else {
		url = fmt.Sprintf("ws://%s/1.0%s", strings.TrimPrefix(r.httpHost, "http://"), path)
	}

	return r.rawWebsocket(url)
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"time"

	"github.com/codegangsta/cli"
	"github.com/exercism/cli/api"
	"github.com/exercism/cli/config"
)

// Submit posts an iteration to the API.
func Submit(ctx *cli.Context) {
	if len(ctx.Args()) == 0 {
		log.Fatal("Please enter a file name")
	}

	c, err := config.New(ctx.GlobalString("config"))
	if err != nil {
		log.Fatal(err)
	}

	if ctx.GlobalBool("verbose") {
		log.Printf("Exercises dir: %s", c.Dir)
		dir, err := os.Getwd()
		if err != nil {
			log.Printf("Unable to get current working directory - %s", err)
		} else {
			log.Printf("Current dir: %s", dir)
		}
	}

	if !c.IsAuthenticated() {
		log.Fatal(msgPleaseAuthenticate)
	}

	dir, err := filepath.EvalSymlinks(c.Dir)
	if err != nil {
		log.Fatal(err)
	}

	if ctx.GlobalBool("verbose") {
		log.Printf("eval symlinks (dir): %s", dir)
	}

	files := []string{}
	for _, filename := range ctx.Args() {
		if ctx.GlobalBool("verbose") {
			log.Printf("file name: %s", filename)
		}

		if isTest(filename) && !ctx.Bool("test") {
			log.Fatal("You're trying to submit a test file. If this is really what " +
				"you want, please pass the --test flag to exercism submit.")
		}

		file, err := filepath.Abs(filename)
		if err != nil {
			log.Fatal(err)
		}

		if ctx.GlobalBool("verbose") {
			log.Printf("absolute path: %s", file)
		}

		file, err = filepath.EvalSymlinks(file)
		if err != nil {
			log.Fatal(err)
		}

		if ctx.GlobalBool("verbose") {
			log.Printf("eval symlinks (file): %s", file)
		}

		files = append(files, file)
	}

	iteration, err := api.NewIteration(dir, files)
	if err != nil {
		log.Fatalf("Unable to submit - %s", err)
	}
	iteration.Key = c.APIKey

	client := api.NewClient(c)
	submission, err := client.Submit(iteration)
	if err != nil {
		log.Fatal(err)
	}

	msg := `
Submitted %s in %s.
Your submission can be found online at %s
`

	if submission.Iteration == 1 {
		msg += `
To get the next exercise, run "exercism fetch" again.
`
		rand.Seed(time.Now().UTC().UnixNano())
		phrases := []string{
			"For bonus points",
			"Don't stop now: The fun's just begun",
			"Some tips to continue",
		}
		msg += fmt.Sprintf("\n## %s\n", phrases[rand.Intn(len(phrases))])
		msg += tips
	}

	fmt.Printf(msg, submission.Name, submission.Language, submission.URL)
}

const tips = `
Did you get the tests passing and the code clean? If you want to, these are some
additional things you could try:

* Remove as much duplication as you possibly can.
* Optimize for readability, even if it means introducing duplication.
* If you've removed all the duplication, do you have a lot of conditionals? Try
  finding ways to reduce or remove them. How does this affect your code's
  readability? It's performance?

Then please share your thoughts in a comment on the submission. Did this
experiment make the code better? Worse? Did you learn anything from it?
`
<commit_msg>Fix grammar in post-submit message<commit_after>package cmd

import (
	"fmt"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"time"

	"github.com/codegangsta/cli"
	"github.com/exercism/cli/api"
	"github.com/exercism/cli/config"
)

// Submit posts an iteration to the API.
func Submit(ctx *cli.Context) {
	if len(ctx.Args()) == 0 {
		log.Fatal("Please enter a file name")
	}

	c, err := config.New(ctx.GlobalString("config"))
	if err != nil {
		log.Fatal(err)
	}

	if ctx.GlobalBool("verbose") {
		log.Printf("Exercises dir: %s", c.Dir)
		dir, err := os.Getwd()
		if err != nil {
			log.Printf("Unable to get current working directory - %s", err)
		} else {
			log.Printf("Current dir: %s", dir)
		}
	}

	if !c.IsAuthenticated() {
		log.Fatal(msgPleaseAuthenticate)
	}

	dir, err := filepath.EvalSymlinks(c.Dir)
	if err != nil {
		log.Fatal(err)
	}

	if ctx.GlobalBool("verbose") {
		log.Printf("eval symlinks (dir): %s", dir)
	}

	files := []string{}
	for _, filename := range ctx.Args() {
		if ctx.GlobalBool("verbose") {
			log.Printf("file name: %s", filename)
		}

		if isTest(filename) && !ctx.Bool("test") {
			log.Fatal("You're trying to submit a test file. If this is really what " +
				"you want, please pass the --test flag to exercism submit.")
		}

		file, err := filepath.Abs(filename)
		if err != nil {
			log.Fatal(err)
		}

		if ctx.GlobalBool("verbose") {
			log.Printf("absolute path: %s", file)
		}

		file, err = filepath.EvalSymlinks(file)
		if err != nil {
			log.Fatal(err)
		}

		if ctx.GlobalBool("verbose") {
			log.Printf("eval symlinks (file): %s", file)
		}

		files = append(files, file)
	}

	iteration, err := api.NewIteration(dir, files)
	if err != nil {
		log.Fatalf("Unable to submit - %s", err)
	}
	iteration.Key = c.APIKey

	client := api.NewClient(c)
	submission, err := client.Submit(iteration)
	if err != nil {
		log.Fatal(err)
	}

	msg := `
Submitted %s in %s.
Your submission can be found online at %s
`

	if submission.Iteration == 1 {
		msg += `
To get the next exercise, run "exercism fetch" again.
`
		rand.Seed(time.Now().UTC().UnixNano())
		phrases := []string{
			"For bonus points",
			"Don't stop now: The fun's just begun",
			"Some tips to continue",
		}
		msg += fmt.Sprintf("\n## %s\n", phrases[rand.Intn(len(phrases))])
		msg += tips
	}

	fmt.Printf(msg, submission.Name, submission.Language, submission.URL)
}

const tips = `
Did you get the tests passing and the code clean? If you want to, these are some
additional things you could try:

* Remove as much duplication as you possibly can.
* Optimize for readability, even if it means introducing duplication.
* If you've removed all the duplication, do you have a lot of conditionals? Try
  finding ways to reduce or remove them. How does this affect your code's
  readability? Its performance?

Then please share your thoughts in a comment on the submission. Did this
experiment make the code better? Worse? Did you learn anything from it?
`
<|endoftext|>


<commit_before>package db

import (
	"database/sql"
	"fmt"

	"github.com/rafaeljusto/cctldstats/config"
)

// Connection database connection.
var Connection *sql.DB

// Connect performs the database connection. Today the following databases are supported: mysql and postgres
func Connect() (err error) {
	var connParams string
	switch config.CCTLDStats.Database.Kind {
	case "mysql":
		connParams = fmt.Sprintf("%s:%s@tcp(%s)/%s",
			config.CCTLDStats.Database.Username,
			config.CCTLDStats.Database.Password,
			config.CCTLDStats.Database.Host,
			config.CCTLDStats.Database.Name,
		)
	case "postgres":
		connParams = fmt.Sprintf("postgres://%s:%s@%s/%s",
			config.CCTLDStats.Database.Username,
			config.CCTLDStats.Database.Password,
			config.CCTLDStats.Database.Host,
			config.CCTLDStats.Database.Name,
		)
	}

	Connection, err = sql.Open(config.CCTLDStats.Database.Kind, connParams)
	return
}
<commit_msg>Disable SSL in database connection for now<commit_after>package db

import (
	"database/sql"
	"fmt"

	"github.com/rafaeljusto/cctldstats/config"
)

// Connection database connection.
var Connection *sql.DB

// Connect performs the database connection. Today the following databases are supported: mysql and postgres
func Connect() (err error) {
	var connParams string
	switch config.CCTLDStats.Database.Kind {
	case "mysql":
		connParams = fmt.Sprintf("%s:%s@tcp(%s)/%s",
			config.CCTLDStats.Database.Username,
			config.CCTLDStats.Database.Password,
			config.CCTLDStats.Database.Host,
			config.CCTLDStats.Database.Name,
		)
	case "postgres":
		connParams = fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=disable",
			config.CCTLDStats.Database.Username,
			config.CCTLDStats.Database.Password,
			config.CCTLDStats.Database.Host,
			config.CCTLDStats.Database.Name,
		)
	}

	Connection, err = sql.Open(config.CCTLDStats.Database.Kind, connParams)
	return
}
<|endoftext|>