<commit_before>package cuid

import (
	cryptoRand "crypto/rand"
	"errors"
	"fmt"
	"io"
	"math"
	"math/big"
	"math/rand"
	"os"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"
)

const (
	blockSize = 4
	base      = 36
)

var (
	mutex          sync.Mutex
	counter        Counter
	random         *rand.Rand
	discreteValues = int32(math.Pow(base, blockSize))
	padding        = strings.Repeat("0", blockSize)
	fingerprint    = ""
	format         = regexp.MustCompile(fmt.Sprintf("c[0-9a-z]{%d}", 6*blockSize))
)

func init() {
	SetRandomSource(rand.NewSource(time.Now().Unix()))
	SetCounter(&DefaultCounter{})

	hostname, err := os.Hostname()
	if err != nil {
		hostname = "dummy-host"
	}

	acc := len(hostname) + base
	for i := range hostname {
		acc = acc + int(hostname[i])
	}

	hostID := pad(strconv.FormatInt(int64(os.Getpid()), base), 2)
	host := pad(strconv.FormatInt(int64(acc), 10), 2)
	fingerprint = hostID + host
}

func SetRandomSource(src rand.Source) {
	SetRandom(rand.New(src))
}

func SetRandom(rnd *rand.Rand) {
	mutex.Lock()
	random = rnd
	mutex.Unlock()
}

func SetCounter(cnt Counter) {
	mutex.Lock()
	counter = cnt
	mutex.Unlock()
}

func New() string {
	// Global random generation functions from the math/rand package use a global
	// locked source, custom Rand objects need to be manually synchronized to avoid
	// race conditions.

	mutex.Lock()
	randomInt1 := int64(random.Int31n(discreteValues))
	randomInt2 := int64(random.Int31n(discreteValues))
	mutex.Unlock()

	return assembleCUID(randomInt1, randomInt2)
}

func NewCrypto(reader io.Reader) (string, error) {
	r1, err := cryptoRand.Int(reader, big.NewInt(int64(discreteValues)))
	if err != nil {
		return "", err
	}

	r2, err := cryptoRand.Int(reader, big.NewInt(int64(discreteValues)))
	if err != nil {
		return "", err
	}

	cuid := assembleCUID(r1.Int64(), r2.Int64())

	return cuid, nil
}

func Slug() string {
	timestamp := strconv.FormatInt(time.Now().Unix()*1000, base)
	counter := strconv.FormatInt(int64(counter.Next()), base)

	mutex.Lock()
	random := strconv.FormatInt(int64(random.Int31n(discreteValues)), base)
	mutex.Unlock()

	timestampBlock := timestamp[len(timestamp)-2:]
	printBlock := fingerprint[0:1] + fingerprint[len(fingerprint)-1:]
	var counterBlock string
	var randomBlock string

	if len(counter) < 4 {
		counterBlock = counter
	} else {
		counterBlock = counter[len(counter)-4:]
	}

	if len(random) < 4 {
		randomBlock = random
	} else {
		randomBlock = random[len(random)-4:]
	}

	return timestampBlock + counterBlock + printBlock + randomBlock
}

func IsCuid(c string) error {
	if !format.MatchString(c) {
		return errors.New("Incorrect format")
	}
	return nil
}

func IsSlug(s string) error {
	if len(s) < 6 || len(s) > 12 {
		return errors.New("Incorrect format")
	}
	return nil
}

func assembleCUID(randomInt1, randomInt2 int64) string {
	timestampBlock := strconv.FormatInt(time.Now().Unix()*1000, base)
	counterBlock := pad(strconv.FormatInt(int64(counter.Next()), base), blockSize)
	randomBlock1 := pad(strconv.FormatInt(randomInt1, base), blockSize)
	randomBlock2 := pad(strconv.FormatInt(randomInt2, base), blockSize)

	return "c" + timestampBlock + counterBlock + fingerprint + randomBlock1 + randomBlock2
}

func pad(str string, size int) string {
	if len(str) == size {
		return str
	}

	if len(str) < size {
		str = padding + str
	}

	i := len(str) - size

	return str[i:]
}

// Default counter implementation

type Counter interface {
	Next() int32
}

type DefaultCounter struct {
	count int32
	mutex sync.Mutex
}

func (c *DefaultCounter) Next() int32 {
	c.mutex.Lock()

	counterValue := c.count

	c.count = c.count + 1
	if c.count >= discreteValues {
		c.count = 0
	}

	c.mutex.Unlock()

	return counterValue
}
<commit_msg>Use timestamps with more precision<commit_after>package cuid

import (
	cryptoRand "crypto/rand"
	"errors"
	"fmt"
	"io"
	"math"
	"math/big"
	"math/rand"
	"os"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"
)

const (
	blockSize = 4
	base      = 36
)

var (
	mutex          sync.Mutex
	counter        Counter
	random         *rand.Rand
	discreteValues = int32(math.Pow(base, blockSize))
	padding        = strings.Repeat("0", blockSize)
	fingerprint    = ""
	format         = regexp.MustCompile(fmt.Sprintf("c[0-9a-z]{%d}", 6*blockSize))
)

func init() {
	SetRandomSource(rand.NewSource(time.Now().Unix()))
	SetCounter(&DefaultCounter{})

	hostname, err := os.Hostname()
	if err != nil {
		hostname = "dummy-host"
	}

	acc := len(hostname) + base
	for i := range hostname {
		acc = acc + int(hostname[i])
	}

	hostID := pad(strconv.FormatInt(int64(os.Getpid()), base), 2)
	host := pad(strconv.FormatInt(int64(acc), 10), 2)
	fingerprint = hostID + host
}

func SetRandomSource(src rand.Source) {
	SetRandom(rand.New(src))
}

func SetRandom(rnd *rand.Rand) {
	mutex.Lock()
	random = rnd
	mutex.Unlock()
}

func SetCounter(cnt Counter) {
	mutex.Lock()
	counter = cnt
	mutex.Unlock()
}

func New() string {
	// Global random generation functions from the math/rand package use a global
	// locked source, custom Rand objects need to be manually synchronized to avoid
	// race conditions.

	mutex.Lock()
	randomInt1 := int64(random.Int31n(discreteValues))
	randomInt2 := int64(random.Int31n(discreteValues))
	mutex.Unlock()

	return assembleCUID(randomInt1, randomInt2)
}

func NewCrypto(reader io.Reader) (string, error) {
	r1, err := cryptoRand.Int(reader, big.NewInt(int64(discreteValues)))
	if err != nil {
		return "", err
	}

	r2, err := cryptoRand.Int(reader, big.NewInt(int64(discreteValues)))
	if err != nil {
		return "", err
	}

	cuid := assembleCUID(r1.Int64(), r2.Int64())

	return cuid, nil
}

func Slug() string {
	timestamp := strconv.FormatInt(makeTimestamp(), base)
	counter := strconv.FormatInt(int64(counter.Next()), base)

	mutex.Lock()
	randomStr := strconv.FormatInt(int64(random.Int31n(discreteValues)), base)
	mutex.Unlock()

	timestampBlock := timestamp[len(timestamp)-2:]
	printBlock := fingerprint[0:1] + fingerprint[len(fingerprint)-1:]
	var counterBlock string
	var randomBlock string

	if len(counter) < 4 {
		counterBlock = counter
	} else {
		counterBlock = counter[len(counter)-4:]
	}

	if len(randomStr) < 4 {
		randomBlock = randomStr
	} else {
		randomBlock = randomStr[len(randomStr)-4:]
	}

	return timestampBlock + counterBlock + printBlock + randomBlock
}

func IsCuid(c string) error {
	if !format.MatchString(c) {
		return errors.New("Incorrect format")
	}
	return nil
}

func IsSlug(s string) error {
	if len(s) < 6 || len(s) > 12 {
		return errors.New("Incorrect format")
	}
	return nil
}

// Utility functions

func assembleCUID(randomInt1, randomInt2 int64) string {
	timestampBlock := strconv.FormatInt(makeTimestamp(), base)
	counterBlock := pad(strconv.FormatInt(int64(counter.Next()), base), blockSize)
	randomBlock1 := pad(strconv.FormatInt(randomInt1, base), blockSize)
	randomBlock2 := pad(strconv.FormatInt(randomInt2, base), blockSize)

	return "c" + timestampBlock + counterBlock + fingerprint + randomBlock1 + randomBlock2
}

func makeTimestamp() int64 {
	return time.Now().UnixNano() * int64(time.Nanosecond) / int64(time.Millisecond)
}

func pad(str string, size int) string {
	if len(str) == size {
		return str
	}

	if len(str) < size {
		str = padding + str
	}

	i := len(str) - size

	return str[i:]
}

// Default counter implementation

type Counter interface {
	Next() int32
}

type DefaultCounter struct {
	count int32
	mutex sync.Mutex
}

func (c *DefaultCounter) Next() int32 {
	c.mutex.Lock()

	counterValue := c.count

	c.count = c.count + 1
	if c.count >= discreteValues {
		c.count = 0
	}

	c.mutex.Unlock()

	return counterValue
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"sync"
)

// The authorization sequence, required for someone without a ~/.getconfig
func sequence_authorize(env Env) Env {
	log.Println("Begin authorization sequence...")

	// Let the user know what will happen.
	fmt.Println(`
Your username and password will be used once to obtain a unique
authorization token from GitHub's API, which will be stored in
~/.getconfig.
`)

	env = askForCredentials(env)

	log.Println(env.Config.Username, env.Config.Token)

	// Make the configuration file.
	createConfiguration(env)

	return env
}

// The update sequence, which retrieves the repos and fetches or clones
// each of them.
func sequence_update(env Env) {
	log.Println("Begin repository update sequence...")

	repos := listRemoteRepostories(env)

	fetches := []string{}
	clones := []string{}
	errors := []string{}
	ignores := []string{}

	var wg sync.WaitGroup
	for _, repo := range repos {
		wg.Add(1)

		go func(repo Repo) {
			switch checkRepo(repo, env) {
			case "fetch":
				fetches = append(fetches, repo.Name())
			case "clone":
				clones = append(clones, repo.Name())
			case "error":
				errors = append(errors, repo.Name())
			case "ignore":
				ignores = append(ignores, repo.Name())
			}
			wg.Done()
		}(repo)
	}

	wg.Wait()

	fmt.Println("Updated repositories:", len(fetches))

	fmt.Println("New repositories:", len(clones))
	for _, repo := range clones {
		fmt.Println("\t", repo)
	}

	if len(errors) > 0 {
		fmt.Println(len(errors), "error(s) encountered.")
	}
}

// The check sequence, which goes through the basic health checks for
// `get` to succesfully function.
func sequence_checks(env Env) Env {
	log.Println("Begin check sequence...")

	// Inject configuration
	env.Config = injectConfiguration()

	// Check supplied path
	checkPath(env)

	// Check Configuration
	checkConfiguration(env)

	// Check configured path
	checkPath(env)

	return env
}
<commit_msg>Add comments<commit_after>package main

import (
	"fmt"
	"log"
	"sync"
)

// The authorization sequence, required for someone without a ~/.getconfig
func sequence_authorize(env Env) Env {
	log.Println("Begin authorization sequence...")

	// Let the user know what will happen.
	fmt.Println(`
Your username and password will be used once to obtain a unique
authorization token from GitHub's API, which will be stored in
~/.getconfig.
`)

	env = askForCredentials(env)

	log.Println(env.Config.Username, env.Config.Token)

	// Make the configuration file.
	createConfiguration(env)

	return env
}

// The update sequence, which retrieves the repos and fetches or clones
// each of them.
func sequence_update(env Env) {
	log.Println("Begin repository update sequence...")

	repos := listRemoteRepostories(env)

	fetches := []string{}
	clones := []string{}
	errors := []string{}
	ignores := []string{}

	// Asynchronously update each repository
	var wg sync.WaitGroup
	for _, repo := range repos {
		wg.Add(1)
		go func(repo Repo) {
			switch checkRepo(repo, env) {
			case "fetch":
				fetches = append(fetches, repo.Name())
			case "clone":
				clones = append(clones, repo.Name())
			case "error":
				errors = append(errors, repo.Name())
			case "ignore":
				ignores = append(ignores, repo.Name())
			}
			wg.Done()
		}(repo)
	}

	// Wait for every update to be finished
	wg.Wait()

	fmt.Println("Updated repositories:", len(fetches))

	fmt.Println("New repositories:", len(clones))
	for _, repo := range clones {
		fmt.Println("\t", repo)
	}

	if len(errors) > 0 {
		fmt.Println(len(errors), "error(s) encountered.")
	}
}

// The check sequence, which goes through the basic health checks for
// `get` to succesfully function.
func sequence_checks(env Env) Env {
	log.Println("Begin check sequence...")

	// Inject configuration
	env.Config = injectConfiguration()

	// Check supplied path
	checkPath(env)

	// Check Configuration
	checkConfiguration(env)

	// Check configured path
	checkPath(env)

	return env
}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"time"

	"github.com/go-kit/kit/log"
	"github.com/moov-io/ach"
)

// Middleware describes a service (as opposed to endpoint) middleware.
type Middleware func(Service) Service

func LoggingMiddleware(logger log.Logger) Middleware {
	return func(next Service) Service {
		return &loggingMiddleware{
			next:   next,
			logger: logger,
		}
	}
}

type loggingMiddleware struct {
	next   Service
	logger log.Logger
}

// timer represents a one-time stoppable time tracker
// it's assumed startTimer() is called to initialize a timer
type timer struct {
	start, end time.Time
}
func startTimer() *timer {
	return &timer{
		start: time.Now(),
	}
}
// stop returns the number of milliseconds for the given timer
// and stops the timer.
func (t *timer) stop() int64 {
	when := time.Now()
	if t.end.IsZero() {
		t.end = when
	}
	return t.end.Sub(t.start).Nanoseconds()/1e6
}
func (t *timer) String() string {
	return fmt.Sprintf("%dms", t.stop())
}

// Middleware endpoints

func (mw loggingMiddleware) CreateFile(f ach.FileHeader) (id string, err error) {
	t := startTimer()
	defer func() {
		// f.ID can be empty here if the request does not specify it, do we care?
		// service's CreateFile generates and assigns one just fine
		mw.logger.Log("method", "CreateFile", "id", f.ID, "took", t, "err", err)
	}()
	return mw.next.CreateFile(f)
}

func (mw loggingMiddleware) GetFile(id string) (f ach.File, err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "GetFile", "id", id, "took", t, "err", err)
	}()
	return mw.next.GetFile(id)
}

func (mw loggingMiddleware) GetFiles() []ach.File {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "GetFiles", "took", t)
	}()
	return mw.next.GetFiles()
}

func (mw loggingMiddleware) DeleteFile(id string) (err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "DeleteFile", "id", id, "took", t)
	}()
	return mw.next.DeleteFile(id)
}

//** BATCHES ** //

func (mw loggingMiddleware) CreateBatch(fileID string, bh ach.BatchHeader) (id string, err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "CreateBatch", "FileID", fileID, "batchID", bh.ID, "took", t, "err", err)
	}()
	return mw.next.CreateBatch(fileID, bh)
}

func (mw loggingMiddleware) GetBatch(fileID string, batchID string) (b ach.Batcher, err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "GetBatch", "fileID", fileID, "batchID", batchID, "took", t, "err", err)
	}()
	return mw.next.GetBatch(fileID, batchID)
}

func (mw loggingMiddleware) GetBatches(fileID string) []ach.Batcher {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "GetBatches", "fileID", fileID, "took", t)
	}()
	return mw.next.GetBatches(fileID)
}

func (mw loggingMiddleware) DeleteBatch(fileID string, batchID string) (err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "DeleteBatch", "fileID", fileID, "batchID", batchID, "took", t, "err", err)
	}()
	return mw.next.DeleteBatch(fileID, batchID)
}
<commit_msg>go fmt<commit_after>package server

import (
	"fmt"
	"time"

	"github.com/go-kit/kit/log"
	"github.com/moov-io/ach"
)

// Middleware describes a service (as opposed to endpoint) middleware.
type Middleware func(Service) Service

func LoggingMiddleware(logger log.Logger) Middleware {
	return func(next Service) Service {
		return &loggingMiddleware{
			next:   next,
			logger: logger,
		}
	}
}

type loggingMiddleware struct {
	next   Service
	logger log.Logger
}

// timer represents a one-time stoppable time tracker
// it's assumed startTimer() is called to initialize a timer
type timer struct {
	start, end time.Time
}

func startTimer() *timer {
	return &timer{
		start: time.Now(),
	}
}

// stop returns the number of milliseconds for the given timer
// and stops the timer.
func (t *timer) stop() int64 {
	when := time.Now()
	if t.end.IsZero() {
		t.end = when
	}
	return t.end.Sub(t.start).Nanoseconds() / 1e6
}
func (t *timer) String() string {
	return fmt.Sprintf("%dms", t.stop())
}

// Middleware endpoints

func (mw loggingMiddleware) CreateFile(f ach.FileHeader) (id string, err error) {
	t := startTimer()
	defer func() {
		// f.ID can be empty here if the request does not specify it, do we care?
		// service's CreateFile generates and assigns one just fine
		mw.logger.Log("method", "CreateFile", "id", f.ID, "took", t, "err", err)
	}()
	return mw.next.CreateFile(f)
}

func (mw loggingMiddleware) GetFile(id string) (f ach.File, err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "GetFile", "id", id, "took", t, "err", err)
	}()
	return mw.next.GetFile(id)
}

func (mw loggingMiddleware) GetFiles() []ach.File {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "GetFiles", "took", t)
	}()
	return mw.next.GetFiles()
}

func (mw loggingMiddleware) DeleteFile(id string) (err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "DeleteFile", "id", id, "took", t)
	}()
	return mw.next.DeleteFile(id)
}

//** BATCHES ** //

func (mw loggingMiddleware) CreateBatch(fileID string, bh ach.BatchHeader) (id string, err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "CreateBatch", "FileID", fileID, "batchID", bh.ID, "took", t, "err", err)
	}()
	return mw.next.CreateBatch(fileID, bh)
}

func (mw loggingMiddleware) GetBatch(fileID string, batchID string) (b ach.Batcher, err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "GetBatch", "fileID", fileID, "batchID", batchID, "took", t, "err", err)
	}()
	return mw.next.GetBatch(fileID, batchID)
}

func (mw loggingMiddleware) GetBatches(fileID string) []ach.Batcher {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "GetBatches", "fileID", fileID, "took", t)
	}()
	return mw.next.GetBatches(fileID)
}

func (mw loggingMiddleware) DeleteBatch(fileID string, batchID string) (err error) {
	t := startTimer()
	defer func() {
		mw.logger.Log("method", "DeleteBatch", "fileID", fileID, "batchID", batchID, "took", t, "err", err)
	}()
	return mw.next.DeleteBatch(fileID, batchID)
}
<|endoftext|>


<commit_before>// Copyright 2016, RadiantBlue Technologies, 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 server

import (
	"encoding/json"
	"log"

	"github.com/venicegeo/pz-gocommon"
	"github.com/venicegeo/pz-gocommon/elasticsearch"
)

type TriggerDB struct {
	*ResourceDB
	mapping string
}

func NewTriggerDB(server *Server, esi elasticsearch.IIndex) (*TriggerDB, error) {

	rdb, err := NewResourceDB(server, esi)
	if err != nil {
		return nil, err
	}
	ardb := TriggerDB{ResourceDB: rdb, mapping: "Trigger"}
	return &ardb, nil
}

func (db *TriggerDB) PostTrigger(trigger *Trigger, id Ident) (Ident, error) {

	ifaceObj := trigger.Condition.Query
	body, err := json.Marshal(ifaceObj)
	if err != nil {
		return NoIdent, err
	}

	log.Printf("Posting percolation query: %s", string(body))
	indexResult, err := db.server.eventDB.Esi.AddPercolationQuery(string(trigger.ID), piazza.JsonString(body))
	if err != nil {
		return NoIdent, LoggedError("TriggerDB.PostData addpercquery failed: %s", err)
	}
	if indexResult == nil {
		return NoIdent, LoggedError("TriggerDB.PostData addpercquery failed: no indexResult")
	}
	if !indexResult.Created {
		return NoIdent, LoggedError("TriggerDB.PostData addpercquery failed: not created")
	}

	log.Printf("percolation indexResult: %v", indexResult)
	log.Printf("percolation id: %s", indexResult.Id)
	trigger.PercolationID = Ident(indexResult.Id)

	indexResult2, err := db.Esi.PostData(db.mapping, id.String(), trigger)
	if err != nil {
		return NoIdent, LoggedError("TriggerDB.PostData failed: %s", err)
	}
	if !indexResult2.Created {
		return NoIdent, LoggedError("TriggerDB.PostData failed: not created")
	}

	return id, nil
}

func (db *TriggerDB) GetAll(format elasticsearch.QueryFormat) (*[]Trigger, error) {
	triggers := []Trigger{}

	exists := db.Esi.TypeExists(db.mapping)
	if !exists {
		return &triggers, nil
	}

	searchResult, err := db.Esi.FilterByMatchAll(db.mapping, format)
	if err != nil {
		return nil, LoggedError("TriggerDB.GetAll failed: %s", err)
	}
	if searchResult == nil {
		return nil, LoggedError("TriggerDB.GetAll failed: no searchResult")
	}

	if searchResult != nil && searchResult.GetHits() != nil {

		for _, hit := range *searchResult.GetHits() {
			var trigger Trigger
			err := json.Unmarshal(*hit.Source, &trigger)
			if err != nil {
				return nil, err
			}
			triggers = append(triggers, trigger)
		}
	}
	return &triggers, nil
}

func (db *TriggerDB) GetAllWithCount(format elasticsearch.QueryFormat) (*[]Trigger, int64, error) {
	var triggers []Trigger
	var count = int64(-1)

	exists := db.Esi.TypeExists(db.mapping)
	if !exists {
		return &triggers, count, nil
	}

	searchResult, err := db.Esi.FilterByMatchAll(db.mapping, format)
	if err != nil {
		return nil, count, LoggedError("TriggerDB.GetAll failed: %s", err)
	}
	if searchResult == nil {
		return nil, count, LoggedError("TriggerDB.GetAll failed: no searchResult")
	}

	if searchResult != nil && searchResult.GetHits() != nil {
		count = searchResult.NumberMatched()

		for _, hit := range *searchResult.GetHits() {
			var trigger Trigger
			err := json.Unmarshal(*hit.Source, &trigger)
			if err != nil {
				return nil, count, err
			}
			triggers = append(triggers, trigger)
		}
	}
	return &triggers, count, nil
}

func (db *TriggerDB) GetOne(id Ident) (*Trigger, error) {

	getResult, err := db.Esi.GetByID(db.mapping, id.String())
	if err != nil {
		return nil, LoggedError("TriggerDB.GetOne failed: %s", err)
	}
	if getResult == nil {
		return nil, LoggedError("TriggerDB.GetOne failed: no getResult")
	}

	if !getResult.Found {
		return nil, nil
	}

	src := getResult.Source
	var obj Trigger
	err = json.Unmarshal(*src, &obj)
	if err != nil {
		return nil, err
	}

	return &obj, nil
}

func (db *TriggerDB) DeleteTrigger(id Ident) (bool, error) {

	trigger, err := db.GetOne(id)
	if err != nil {
		return false, err
	}
	if trigger == nil {
		return false, nil
	}

	deleteResult, err := db.Esi.DeleteByID(db.mapping, string(id))
	if err != nil {
		return false, LoggedError("TriggerDB.DeleteById failed: %s", err)
	}
	if deleteResult == nil {
		return false, LoggedError("TriggerDB.DeleteById failed: no deleteResult")
	}
	if !deleteResult.Found {
		return false, nil
	}

	deleteResult2, err := db.server.eventDB.Esi.DeletePercolationQuery(string(trigger.PercolationID))
	if err != nil {
		return false, LoggedError("TriggerDB.DeleteById percquery failed: %s", err)
	}
	if deleteResult2 == nil {
		return false, LoggedError("TriggerDB.DeleteById percquery failed: no deleteResult")
	}

	return deleteResult2.Found, nil
}
<commit_msg>Further logging for investigation<commit_after>// Copyright 2016, RadiantBlue Technologies, 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 server

import (
	"encoding/json"
	"log"

	"github.com/venicegeo/pz-gocommon"
	"github.com/venicegeo/pz-gocommon/elasticsearch"
)

type TriggerDB struct {
	*ResourceDB
	mapping string
}

func NewTriggerDB(server *Server, esi elasticsearch.IIndex) (*TriggerDB, error) {

	rdb, err := NewResourceDB(server, esi)
	if err != nil {
		return nil, err
	}
	ardb := TriggerDB{ResourceDB: rdb, mapping: "Trigger"}
	return &ardb, nil
}

func (db *TriggerDB) PostTrigger(trigger *Trigger, id Ident) (Ident, error) {

	ifaceObj := trigger.Condition.Query
	log.Printf("Query: %v", ifaceObj)
	body, err := json.Marshal(ifaceObj)
	if err != nil {
		return NoIdent, err
	}

	log.Printf("Posting percolation query: %s", string(body))
	indexResult, err := db.server.eventDB.Esi.AddPercolationQuery(string(trigger.ID), piazza.JsonString(body))
	if err != nil {
		return NoIdent, LoggedError("TriggerDB.PostData addpercquery failed: %s", err)
	}
	if indexResult == nil {
		return NoIdent, LoggedError("TriggerDB.PostData addpercquery failed: no indexResult")
	}
	if !indexResult.Created {
		return NoIdent, LoggedError("TriggerDB.PostData addpercquery failed: not created")
	}

	log.Printf("percolation indexResult: %v", indexResult)
	log.Printf("percolation id: %s", indexResult.Id)
	trigger.PercolationID = Ident(indexResult.Id)

	indexResult2, err := db.Esi.PostData(db.mapping, id.String(), trigger)
	if err != nil {
		return NoIdent, LoggedError("TriggerDB.PostData failed: %s", err)
	}
	if !indexResult2.Created {
		return NoIdent, LoggedError("TriggerDB.PostData failed: not created")
	}

	return id, nil
}

func (db *TriggerDB) GetAll(format elasticsearch.QueryFormat) (*[]Trigger, error) {
	triggers := []Trigger{}

	exists := db.Esi.TypeExists(db.mapping)
	if !exists {
		return &triggers, nil
	}

	searchResult, err := db.Esi.FilterByMatchAll(db.mapping, format)
	if err != nil {
		return nil, LoggedError("TriggerDB.GetAll failed: %s", err)
	}
	if searchResult == nil {
		return nil, LoggedError("TriggerDB.GetAll failed: no searchResult")
	}

	if searchResult != nil && searchResult.GetHits() != nil {

		for _, hit := range *searchResult.GetHits() {
			var trigger Trigger
			err := json.Unmarshal(*hit.Source, &trigger)
			if err != nil {
				return nil, err
			}
			triggers = append(triggers, trigger)
		}
	}
	return &triggers, nil
}

func (db *TriggerDB) GetAllWithCount(format elasticsearch.QueryFormat) (*[]Trigger, int64, error) {
	var triggers []Trigger
	var count = int64(-1)

	exists := db.Esi.TypeExists(db.mapping)
	if !exists {
		return &triggers, count, nil
	}

	searchResult, err := db.Esi.FilterByMatchAll(db.mapping, format)
	if err != nil {
		return nil, count, LoggedError("TriggerDB.GetAll failed: %s", err)
	}
	if searchResult == nil {
		return nil, count, LoggedError("TriggerDB.GetAll failed: no searchResult")
	}

	if searchResult != nil && searchResult.GetHits() != nil {
		count = searchResult.NumberMatched()

		for _, hit := range *searchResult.GetHits() {
			var trigger Trigger
			err := json.Unmarshal(*hit.Source, &trigger)
			if err != nil {
				return nil, count, err
			}
			triggers = append(triggers, trigger)
		}
	}
	return &triggers, count, nil
}

func (db *TriggerDB) GetOne(id Ident) (*Trigger, error) {

	getResult, err := db.Esi.GetByID(db.mapping, id.String())
	if err != nil {
		return nil, LoggedError("TriggerDB.GetOne failed: %s", err)
	}
	if getResult == nil {
		return nil, LoggedError("TriggerDB.GetOne failed: no getResult")
	}

	if !getResult.Found {
		return nil, nil
	}

	src := getResult.Source
	var obj Trigger
	err = json.Unmarshal(*src, &obj)
	if err != nil {
		return nil, err
	}

	return &obj, nil
}

func (db *TriggerDB) DeleteTrigger(id Ident) (bool, error) {

	trigger, err := db.GetOne(id)
	if err != nil {
		return false, err
	}
	if trigger == nil {
		return false, nil
	}

	deleteResult, err := db.Esi.DeleteByID(db.mapping, string(id))
	if err != nil {
		return false, LoggedError("TriggerDB.DeleteById failed: %s", err)
	}
	if deleteResult == nil {
		return false, LoggedError("TriggerDB.DeleteById failed: no deleteResult")
	}
	if !deleteResult.Found {
		return false, nil
	}

	deleteResult2, err := db.server.eventDB.Esi.DeletePercolationQuery(string(trigger.PercolationID))
	if err != nil {
		return false, LoggedError("TriggerDB.DeleteById percquery failed: %s", err)
	}
	if deleteResult2 == nil {
		return false, LoggedError("TriggerDB.DeleteById percquery failed: no deleteResult")
	}

	return deleteResult2.Found, nil
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 datastoreio

import (
	"context"
	"encoding/json"
	"fmt"
	"math"
	"reflect"
	"sort"
	"strconv"
	"strings"

	"cloud.google.com/go/datastore"
	"github.com/apache/beam/sdks/go/pkg/beam"
	"github.com/apache/beam/sdks/go/pkg/beam/core/runtime"
	"github.com/apache/beam/sdks/go/pkg/beam/log"
	"google.golang.org/api/iterator"
)

const (
	scatterPropertyName = "__scatter__"
)

func init() {
	beam.RegisterType(reflect.TypeOf((*queryFn)(nil)).Elem())
	beam.RegisterType(reflect.TypeOf((*splitQueryFn)(nil)).Elem())
}

// Read reads all rows from the given kind. The kind must have a schema  compatible with the given type, t, and Read
// returns a PCollection<t>. You must also register your type with runtime.RegisterType which allows you to implement
// datastore.PropertyLoadSaver
//
//
// Example:
// type Item struct {}
// itemKey = runtime.RegisterType(reflect.TypeOf((*Item)(nil)).Elem())
//
// datastoreio.Read(s, "project", "Item", 256, reflect.TypeOf(Item{}), itemKey)
func Read(s beam.Scope, project, kind string, shards int, t reflect.Type, typeKey string) beam.PCollection {
	s = s.Scope("datastore.Read")
	return query(s, project, kind, shards, t, typeKey)
}

func query(s beam.Scope, project, kind string, shards int, t reflect.Type, typeKey string) beam.PCollection {
	imp := beam.Impulse(s)
	ex := beam.ParDo(s, &splitQueryFn{Project: project, Kind: kind, Shards: shards}, imp)
	g := beam.GroupByKey(s, ex)
	return beam.ParDo(s, &queryFn{Project: project, Kind: kind, Type: typeKey}, g, beam.TypeDefinition{Var: beam.XType, T: t})
}

type splitQueryFn struct {
	Project string `json:"project"`
	Kind    string `json:"kind"`
	Shards  int    `json:"shards"`
}

// BoundedQuery represents a datastore Query with a bounded key range between [Start, End)
type BoundedQuery struct {
	Start *datastore.Key `json:"start"`
	End   *datastore.Key `json:"end"`
}

func (s *splitQueryFn) ProcessElement(ctx context.Context, _ []byte, emit func(k string, val string)) error {
	// Short circuit a single shard
	if s.Shards <= 1 {
		q := BoundedQuery{}
		b, err := json.Marshal(q)
		if err != nil {
			return err
		}
		emit(strconv.Itoa(1), string(b))
		return nil
	}

	client, err := datastore.NewClient(ctx, s.Project)
	if err != nil {
		return err
	}
	defer client.Close()

	splits := []*datastore.Key{}
	iter := client.Run(ctx, datastore.NewQuery(s.Kind).Order(scatterPropertyName).Limit((s.Shards - 1) * 32).KeysOnly())
	for {
		k, err := iter.Next(nil)
		if err != nil {
			if err == iterator.Done {
				break
			}
			return err
		}
		splits = append(splits, k)
	}
	sort.Slice(splits, func(i, j int) bool {
		return keyLessThan(splits[i], splits[j])
	})

	splitKeys := getSplits(splits, s.Shards-1)

	queries := make([]*BoundedQuery, len(splitKeys))
	var lastKey *datastore.Key
	for n, k := range splitKeys {
		q := BoundedQuery{End: k}
		if lastKey != nil {
			q.Start = lastKey
		}
		queries[n] = &q
		lastKey = k
	}
	queries = append(queries, &BoundedQuery{Start: lastKey})

	log.Debugf(ctx, "Datastore: Splitting into %d shards", len(queries))

	for n, q := range queries {
		b, err := json.Marshal(q)
		if err != nil {
			return err
		}
		log.Debugf(ctx, "Datastore: Emitting Bounded Query Shard `%d` Start: `%s` End:`%s`", n, q.Start.String(), q.End.String())
		emit(strconv.Itoa(n), string(b))
	}
	return nil
}

func keyLessThan(a *datastore.Key, b *datastore.Key) bool {
	af, bf := flatten(a), flatten(b)
	for n, k1 := range af {
		if n >= len(bf) {
			return true
		}
		k2 := bf[n]
		r := strings.Compare(k1.Name, k2.Name)
		if r == -1 {
			return true
		} else if r == 1 {
			return false
		}
	}
	return false
}

func flatten(k *datastore.Key) []*datastore.Key {
	pieces := []*datastore.Key{}
	if k.Parent != nil {
		pieces = append(pieces, flatten(k.Parent)...)
	}
	pieces = append(pieces, k)
	return pieces
}

func getSplits(keys []*datastore.Key, numSplits int) []*datastore.Key {
	if len(keys) == 0 || (len(keys) < (numSplits - 1)) {
		return keys
	}

	numKeysPerSplit := math.Max(1.0, float64(len(keys))) / float64((numSplits))

	splitKeys := make([]*datastore.Key, numSplits)
	for n := 1; n <= len(splitKeys); n++ {
		i := int(math.Round(float64(n) * float64(numKeysPerSplit)))
		splitKeys[n-1] = keys[i-1]
	}
	return splitKeys

}

type queryFn struct {
	// Project is the project
	Project string `json:"project"`
	// Kind is the datastore kind
	Kind string `json:"kind"`
	// Type is the name of the global schema type
	Type string `json:"type"`
}

func (f *queryFn) ProcessElement(ctx context.Context, _ string, v func(*string) bool, emit func(beam.X)) error {

	client, err := datastore.NewClient(ctx, f.Project)
	if err != nil {
		return err
	}
	defer client.Close()

	// deserialize Query
	var k string
	v(&k)
	q := BoundedQuery{}
	err = json.Unmarshal([]byte(k), &q)
	if err != nil {
		return err
	}

	// lookup type
	t, ok := runtime.LookupType(f.Type)
	if !ok {
		fmt.Errorf("No type registered %s", f.Type)
	}

	// Translate BoundedQuery to datastore.Query
	dq := datastore.NewQuery(f.Kind)
	if q.Start != nil {
		dq = dq.Filter("__key__ >=", q.Start)
	}
	if q.End != nil {
		dq = dq.Filter("__key__ <", q.End)
	}

	// Run Query
	iter := client.Run(ctx, dq)
	for {
		val := reflect.New(t).Interface() // val : *T
		if _, err := iter.Next(val); err != nil {
			if err == iterator.Done {
				break
			}
			return err
		}
		emit(reflect.ValueOf(val).Elem().Interface()) // emit(*val)
	}
	return nil
}
<commit_msg>- Add package doc<commit_after>// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 datastoreio provides transformations and utilities to interact with
// Google Datastore. See also: https://cloud.google.com/datastore/docs.
package datastoreio

import (
	"context"
	"encoding/json"
	"fmt"
	"math"
	"reflect"
	"sort"
	"strconv"
	"strings"

	"cloud.google.com/go/datastore"
	"github.com/apache/beam/sdks/go/pkg/beam"
	"github.com/apache/beam/sdks/go/pkg/beam/core/runtime"
	"github.com/apache/beam/sdks/go/pkg/beam/log"
	"google.golang.org/api/iterator"
)

const (
	scatterPropertyName = "__scatter__"
)

func init() {
	beam.RegisterType(reflect.TypeOf((*queryFn)(nil)).Elem())
	beam.RegisterType(reflect.TypeOf((*splitQueryFn)(nil)).Elem())
}

// Read reads all rows from the given kind. The kind must have a schema  compatible with the given type, t, and Read
// returns a PCollection<t>. You must also register your type with runtime.RegisterType which allows you to implement
// datastore.PropertyLoadSaver
//
//
// Example:
// type Item struct {}
// itemKey = runtime.RegisterType(reflect.TypeOf((*Item)(nil)).Elem())
//
// datastoreio.Read(s, "project", "Item", 256, reflect.TypeOf(Item{}), itemKey)
func Read(s beam.Scope, project, kind string, shards int, t reflect.Type, typeKey string) beam.PCollection {
	s = s.Scope("datastore.Read")
	return query(s, project, kind, shards, t, typeKey)
}

func query(s beam.Scope, project, kind string, shards int, t reflect.Type, typeKey string) beam.PCollection {
	imp := beam.Impulse(s)
	ex := beam.ParDo(s, &splitQueryFn{Project: project, Kind: kind, Shards: shards}, imp)
	g := beam.GroupByKey(s, ex)
	return beam.ParDo(s, &queryFn{Project: project, Kind: kind, Type: typeKey}, g, beam.TypeDefinition{Var: beam.XType, T: t})
}

type splitQueryFn struct {
	Project string `json:"project"`
	Kind    string `json:"kind"`
	Shards  int    `json:"shards"`
}

// BoundedQuery represents a datastore Query with a bounded key range between [Start, End)
type BoundedQuery struct {
	Start *datastore.Key `json:"start"`
	End   *datastore.Key `json:"end"`
}

func (s *splitQueryFn) ProcessElement(ctx context.Context, _ []byte, emit func(k string, val string)) error {
	// Short circuit a single shard
	if s.Shards <= 1 {
		q := BoundedQuery{}
		b, err := json.Marshal(q)
		if err != nil {
			return err
		}
		emit(strconv.Itoa(1), string(b))
		return nil
	}

	client, err := datastore.NewClient(ctx, s.Project)
	if err != nil {
		return err
	}
	defer client.Close()

	splits := []*datastore.Key{}
	iter := client.Run(ctx, datastore.NewQuery(s.Kind).Order(scatterPropertyName).Limit((s.Shards - 1) * 32).KeysOnly())
	for {
		k, err := iter.Next(nil)
		if err != nil {
			if err == iterator.Done {
				break
			}
			return err
		}
		splits = append(splits, k)
	}
	sort.Slice(splits, func(i, j int) bool {
		return keyLessThan(splits[i], splits[j])
	})

	splitKeys := getSplits(splits, s.Shards-1)

	queries := make([]*BoundedQuery, len(splitKeys))
	var lastKey *datastore.Key
	for n, k := range splitKeys {
		q := BoundedQuery{End: k}
		if lastKey != nil {
			q.Start = lastKey
		}
		queries[n] = &q
		lastKey = k
	}
	queries = append(queries, &BoundedQuery{Start: lastKey})

	log.Debugf(ctx, "Datastore: Splitting into %d shards", len(queries))

	for n, q := range queries {
		b, err := json.Marshal(q)
		if err != nil {
			return err
		}
		log.Debugf(ctx, "Datastore: Emitting Bounded Query Shard `%d` Start: `%s` End:`%s`", n, q.Start.String(), q.End.String())
		emit(strconv.Itoa(n), string(b))
	}
	return nil
}

func keyLessThan(a *datastore.Key, b *datastore.Key) bool {
	af, bf := flatten(a), flatten(b)
	for n, k1 := range af {
		if n >= len(bf) {
			return true
		}
		k2 := bf[n]
		r := strings.Compare(k1.Name, k2.Name)
		if r == -1 {
			return true
		} else if r == 1 {
			return false
		}
	}
	return false
}

func flatten(k *datastore.Key) []*datastore.Key {
	pieces := []*datastore.Key{}
	if k.Parent != nil {
		pieces = append(pieces, flatten(k.Parent)...)
	}
	pieces = append(pieces, k)
	return pieces
}

func getSplits(keys []*datastore.Key, numSplits int) []*datastore.Key {
	if len(keys) == 0 || (len(keys) < (numSplits - 1)) {
		return keys
	}

	numKeysPerSplit := math.Max(1.0, float64(len(keys))) / float64((numSplits))

	splitKeys := make([]*datastore.Key, numSplits)
	for n := 1; n <= len(splitKeys); n++ {
		i := int(math.Round(float64(n) * float64(numKeysPerSplit)))
		splitKeys[n-1] = keys[i-1]
	}
	return splitKeys

}

type queryFn struct {
	// Project is the project
	Project string `json:"project"`
	// Kind is the datastore kind
	Kind string `json:"kind"`
	// Type is the name of the global schema type
	Type string `json:"type"`
}

func (f *queryFn) ProcessElement(ctx context.Context, _ string, v func(*string) bool, emit func(beam.X)) error {

	client, err := datastore.NewClient(ctx, f.Project)
	if err != nil {
		return err
	}
	defer client.Close()

	// deserialize Query
	var k string
	v(&k)
	q := BoundedQuery{}
	err = json.Unmarshal([]byte(k), &q)
	if err != nil {
		return err
	}

	// lookup type
	t, ok := runtime.LookupType(f.Type)
	if !ok {
		fmt.Errorf("No type registered %s", f.Type)
	}

	// Translate BoundedQuery to datastore.Query
	dq := datastore.NewQuery(f.Kind)
	if q.Start != nil {
		dq = dq.Filter("__key__ >=", q.Start)
	}
	if q.End != nil {
		dq = dq.Filter("__key__ <", q.End)
	}

	// Run Query
	iter := client.Run(ctx, dq)
	for {
		val := reflect.New(t).Interface() // val : *T
		if _, err := iter.Next(val); err != nil {
			if err == iterator.Done {
				break
			}
			return err
		}
		emit(reflect.ValueOf(val).Elem().Interface()) // emit(*val)
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2012 The Gorilla 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 sessions

import (
	"bytes"
	"encoding/gob"
	"net/http"
	"time"

	"appengine/datastore"
	"appengine/memcache"

	"code.google.com/p/gorilla/appengine/context"
	"code.google.com/p/gorilla/securecookie"
	"code.google.com/p/gorilla/sessions"
)

// DatastoreStore -------------------------------------------------------------

// Session is used to load and save session data in the datastore.
type Session struct {
	Date  time.Time
	Value []byte
}

// NewDatastoreStore returns a new DatastoreStore.
//
// The kind argument is the kind name used to store the session data.
// If empty it will use "Session".
//
// See NewCookieStore() for a description of the other parameters.
func NewDatastoreStore(kind string, keyPairs ...[]byte) *DatastoreStore {
	if kind == "" {
		kind = "Session"
	}
	return &DatastoreStore{
		Codecs: securecookie.CodecsFromPairs(keyPairs...),
		Options: &sessions.Options{
			Path:   "/",
			MaxAge: 86400 * 30,
		},
		kind: kind,
	}
}

// DatastoreStore stores sessions in the App Engine datastore.
type DatastoreStore struct {
	Codecs  []securecookie.Codec
	Options *sessions.Options // default configuration
	kind    string
}

// Get returns a session for the given name after adding it to the registry.
//
// See CookieStore.Get().
func (s *DatastoreStore) Get(r *http.Request, name string) (*sessions.Session,
	error) {
	return sessions.GetRegistry(r).Get(s, name)
}

// New returns a session for the given name without adding it to the registry.
//
// See CookieStore.New().
func (s *DatastoreStore) New(r *http.Request, name string) (*sessions.Session,
	error) {
	session := sessions.NewSession(s, name)
	session.Options = &(*s.Options)
	session.IsNew = true
	var err error
	if c, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.Codecs...)
		if err == nil {
			err = s.load(r, session)
			if err == nil {
				session.IsNew = false
			}
		}
	}
	return session, err
}

// Save adds a single session to the response.
func (s *DatastoreStore) Save(r *http.Request, w http.ResponseWriter,
	session *sessions.Session) error {
	if session.ID == "" {
		session.ID = string(securecookie.GenerateRandomKey(32))
	}
	if err := s.save(r, session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
		s.Codecs...)
	if err != nil {
		return err
	}
	http.SetCookie(w, sessions.NewCookie(session.Name(), encoded,
		session.Options))
	return nil
}

// save writes encoded session.Values to datastore.
func (s *DatastoreStore) save(r *http.Request,
	session *sessions.Session) error {
	if len(session.Values) == 0 {
		// Don't need to write anything.
		return nil
	}
	serialized, err := serialize(session.Values)
	if err != nil {
		return err
	}
	c := context.New(r)
	k := datastore.NewKey(c, s.kind, session.ID, 0, nil)
	k, err = datastore.Put(c, k, &Session{
		Date:  time.Now(),
		Value: serialized,
	})
	if err != nil {
		return err
	}
	return nil
}

// load gets a value from datastore and decodes its content into
// session.Values.
func (s *DatastoreStore) load(r *http.Request,
	session *sessions.Session) error {
	c := context.New(r)
	k := datastore.NewKey(c, s.kind, session.ID, 0, nil)
	entity := Session{}
	if err := datastore.Get(c, k, &entity); err != nil {
		return err
	}
	if err := deserialize(entity.Value, &session.Values); err != nil {
		return err
	}
	return nil
}

// MemcacheStore --------------------------------------------------------------

// NewMemcacheStore returns a new MemcacheStore.
//
// The keyPrefix argument is the prefix used for memcache keys. If empty it
// will use "gorilla.appengine.sessions.".
//
// See NewCookieStore() for a description of the other parameters.
func NewMemcacheStore(keyPrefix string, keyPairs ...[]byte) *MemcacheStore {
	if keyPrefix == "" {
		keyPrefix = "gorilla.appengine.sessions."
	}
	return &MemcacheStore{
		Codecs: securecookie.CodecsFromPairs(keyPairs...),
		Options: &sessions.Options{
			Path:   "/",
			MaxAge: 86400 * 30,
		},
		prefix: keyPrefix,
	}
}

// MemcacheStore stores sessions in the App Engine memcache.
type MemcacheStore struct {
	Codecs  []securecookie.Codec
	Options *sessions.Options // default configuration
	prefix  string
}

// Get returns a session for the given name after adding it to the registry.
//
// See CookieStore.Get().
func (s *MemcacheStore) Get(r *http.Request, name string) (*sessions.Session,
	error) {
	return sessions.GetRegistry(r).Get(s, name)
}

// New returns a session for the given name without adding it to the registry.
//
// See CookieStore.New().
func (s *MemcacheStore) New(r *http.Request, name string) (*sessions.Session,
	error) {
	session := sessions.NewSession(s, name)
	session.Options = &(*s.Options)
	session.IsNew = true
	var err error
	if c, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.Codecs...)
		if err == nil {
			err = s.load(r, session)
			if err == nil {
				session.IsNew = false
			}
		}
	}
	return session, err
}

// Save adds a single session to the response.
func (s *MemcacheStore) Save(r *http.Request, w http.ResponseWriter,
	session *sessions.Session) error {
	if session.ID == "" {
		session.ID = s.prefix + string(securecookie.GenerateRandomKey(32))
	}
	if err := s.save(r, session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
		s.Codecs...)
	if err != nil {
		return err
	}
	http.SetCookie(w, sessions.NewCookie(session.Name(), encoded,
		session.Options))
	return nil
}

// save writes encoded session.Values to memcache.
func (s *MemcacheStore) save(r *http.Request,
	session *sessions.Session) error {
	if len(session.Values) == 0 {
		// Don't need to write anything.
		return nil
	}
	serialized, err := serialize(session.Values)
	if err != nil {
		return err
	}
	err = memcache.Set(context.New(r), &memcache.Item{
		Key:   session.ID,
		Value: serialized,
	})
	if err != nil {
		return err
	}
	return nil
}

// load gets a value from memcache and decodes its content into session.Values.
func (s *MemcacheStore) load(r *http.Request,
	session *sessions.Session) error {
	item, err := memcache.Get(context.New(r), session.ID)
	if err != nil {
		return err
	}
	if err := deserialize(item.Value, &session.Values); err != nil {
		return err
	}
	return nil
}

// Serialization --------------------------------------------------------------

// serialize encodes a value using gob.
func serialize(src interface{}) ([]byte, error) {
	buf := new(bytes.Buffer)
	enc := gob.NewEncoder(buf)
	if err := enc.Encode(src); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// deserialize decodes a value using gob.
func deserialize(src []byte, dst interface{}) error {
	dec := gob.NewDecoder(bytes.NewBuffer(src))
	if err := dec.Decode(dst); err != nil {
		return err
	}
	return nil
}
<commit_msg>Use appengine.NewContext() instead of context.New().<commit_after>// Copyright 2012 The Gorilla 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 sessions

import (
	"bytes"
	"encoding/gob"
	"net/http"
	"time"

	"appengine"
	"appengine/datastore"
	"appengine/memcache"

	"code.google.com/p/gorilla/securecookie"
	"code.google.com/p/gorilla/sessions"
)

// DatastoreStore -------------------------------------------------------------

// Session is used to load and save session data in the datastore.
type Session struct {
	Date  time.Time
	Value []byte
}

// NewDatastoreStore returns a new DatastoreStore.
//
// The kind argument is the kind name used to store the session data.
// If empty it will use "Session".
//
// See NewCookieStore() for a description of the other parameters.
func NewDatastoreStore(kind string, keyPairs ...[]byte) *DatastoreStore {
	if kind == "" {
		kind = "Session"
	}
	return &DatastoreStore{
		Codecs: securecookie.CodecsFromPairs(keyPairs...),
		Options: &sessions.Options{
			Path:   "/",
			MaxAge: 86400 * 30,
		},
		kind: kind,
	}
}

// DatastoreStore stores sessions in the App Engine datastore.
type DatastoreStore struct {
	Codecs  []securecookie.Codec
	Options *sessions.Options // default configuration
	kind    string
}

// Get returns a session for the given name after adding it to the registry.
//
// See CookieStore.Get().
func (s *DatastoreStore) Get(r *http.Request, name string) (*sessions.Session,
	error) {
	return sessions.GetRegistry(r).Get(s, name)
}

// New returns a session for the given name without adding it to the registry.
//
// See CookieStore.New().
func (s *DatastoreStore) New(r *http.Request, name string) (*sessions.Session,
	error) {
	session := sessions.NewSession(s, name)
	session.Options = &(*s.Options)
	session.IsNew = true
	var err error
	if c, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.Codecs...)
		if err == nil {
			err = s.load(r, session)
			if err == nil {
				session.IsNew = false
			}
		}
	}
	return session, err
}

// Save adds a single session to the response.
func (s *DatastoreStore) Save(r *http.Request, w http.ResponseWriter,
	session *sessions.Session) error {
	if session.ID == "" {
		session.ID = string(securecookie.GenerateRandomKey(32))
	}
	if err := s.save(r, session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
		s.Codecs...)
	if err != nil {
		return err
	}
	http.SetCookie(w, sessions.NewCookie(session.Name(), encoded,
		session.Options))
	return nil
}

// save writes encoded session.Values to datastore.
func (s *DatastoreStore) save(r *http.Request,
	session *sessions.Session) error {
	if len(session.Values) == 0 {
		// Don't need to write anything.
		return nil
	}
	serialized, err := serialize(session.Values)
	if err != nil {
		return err
	}
	c := appengine.NewContext(r)
	k := datastore.NewKey(c, s.kind, session.ID, 0, nil)
	k, err = datastore.Put(c, k, &Session{
		Date:  time.Now(),
		Value: serialized,
	})
	if err != nil {
		return err
	}
	return nil
}

// load gets a value from datastore and decodes its content into
// session.Values.
func (s *DatastoreStore) load(r *http.Request,
	session *sessions.Session) error {
	c := appengine.NewContext(r)
	k := datastore.NewKey(c, s.kind, session.ID, 0, nil)
	entity := Session{}
	if err := datastore.Get(c, k, &entity); err != nil {
		return err
	}
	if err := deserialize(entity.Value, &session.Values); err != nil {
		return err
	}
	return nil
}

// MemcacheStore --------------------------------------------------------------

// NewMemcacheStore returns a new MemcacheStore.
//
// The keyPrefix argument is the prefix used for memcache keys. If empty it
// will use "gorilla.appengine.sessions.".
//
// See NewCookieStore() for a description of the other parameters.
func NewMemcacheStore(keyPrefix string, keyPairs ...[]byte) *MemcacheStore {
	if keyPrefix == "" {
		keyPrefix = "gorilla.appengine.sessions."
	}
	return &MemcacheStore{
		Codecs: securecookie.CodecsFromPairs(keyPairs...),
		Options: &sessions.Options{
			Path:   "/",
			MaxAge: 86400 * 30,
		},
		prefix: keyPrefix,
	}
}

// MemcacheStore stores sessions in the App Engine memcache.
type MemcacheStore struct {
	Codecs  []securecookie.Codec
	Options *sessions.Options // default configuration
	prefix  string
}

// Get returns a session for the given name after adding it to the registry.
//
// See CookieStore.Get().
func (s *MemcacheStore) Get(r *http.Request, name string) (*sessions.Session,
	error) {
	return sessions.GetRegistry(r).Get(s, name)
}

// New returns a session for the given name without adding it to the registry.
//
// See CookieStore.New().
func (s *MemcacheStore) New(r *http.Request, name string) (*sessions.Session,
	error) {
	session := sessions.NewSession(s, name)
	session.Options = &(*s.Options)
	session.IsNew = true
	var err error
	if c, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.Codecs...)
		if err == nil {
			err = s.load(r, session)
			if err == nil {
				session.IsNew = false
			}
		}
	}
	return session, err
}

// Save adds a single session to the response.
func (s *MemcacheStore) Save(r *http.Request, w http.ResponseWriter,
	session *sessions.Session) error {
	if session.ID == "" {
		session.ID = s.prefix + string(securecookie.GenerateRandomKey(32))
	}
	if err := s.save(r, session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
		s.Codecs...)
	if err != nil {
		return err
	}
	http.SetCookie(w, sessions.NewCookie(session.Name(), encoded,
		session.Options))
	return nil
}

// save writes encoded session.Values to memcache.
func (s *MemcacheStore) save(r *http.Request,
	session *sessions.Session) error {
	if len(session.Values) == 0 {
		// Don't need to write anything.
		return nil
	}
	serialized, err := serialize(session.Values)
	if err != nil {
		return err
	}
	err = memcache.Set(appengine.NewContext(r), &memcache.Item{
		Key:   session.ID,
		Value: serialized,
	})
	if err != nil {
		return err
	}
	return nil
}

// load gets a value from memcache and decodes its content into session.Values.
func (s *MemcacheStore) load(r *http.Request,
	session *sessions.Session) error {
	item, err := memcache.Get(appengine.NewContext(r), session.ID)
	if err != nil {
		return err
	}
	if err := deserialize(item.Value, &session.Values); err != nil {
		return err
	}
	return nil
}

// Serialization --------------------------------------------------------------

// serialize encodes a value using gob.
func serialize(src interface{}) ([]byte, error) {
	buf := new(bytes.Buffer)
	enc := gob.NewEncoder(buf)
	if err := enc.Encode(src); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// deserialize decodes a value using gob.
func deserialize(src []byte, dst interface{}) error {
	dec := gob.NewDecoder(bytes.NewBuffer(src))
	if err := dec.Decode(dst); err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>// Package flac provides access to FLAC [1] (Free Lossless Audio Codec) files.
//
// The basic structure of a FLAC bitstream is:
//    - The four byte string signature "fLaC".
//    - The StreamInfo metadata block.
//    - Zero or more other metadata blocks.
//    - One or more audio frames.
//
// [1]: http://flac.sourceforge.net/format.html
package flac

import (
	"fmt"
	"io"
	"os"

	"github.com/mewkiz/flac/frame"
	"github.com/mewkiz/flac/meta"
)

// A Stream is a FLAC bitstream.
type Stream struct {
	// Metadata blocks.
	MetaBlocks []*meta.Block
	// Audio frames.
	Frames []*frame.Frame
	// The underlying reader of the stream.
	r io.ReadSeeker
}

// Parse reads the provided file and returns a parsed FLAC bitstream. It parses
// all metadata blocks and all audio frames. Use Open instead for more
// granularity.
func Parse(filePath string) (s *Stream, err error) {
	f, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	return ParseStream(f)
}

// Open validates the FLAC signature of the provided file and returns a handle
// to the FLAC bitstream. Callers should close the stream when done reading from
// it. Call either Stream.Parse or Stream.ParseBlocks and Stream.ParseFrames to
// parse the metadata blocks and audio frames.
func Open(filePath string) (s *Stream, err error) {
	f, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	return NewStream(f)
}

// Close closes the underlying reader of the stream.
func (s *Stream) Close() error {
	r, ok := s.r.(io.Closer)
	if ok {
		return r.Close()
	}
	return nil
}

// ParseStream reads from the provided io.ReadSeeker and returns a parsed FLAC
// bitstream. It parses all metadata blocks and all audio frames.  Use NewStream
// instead for more granularity.
func ParseStream(r io.ReadSeeker) (s *Stream, err error) {
	s, err = NewStream(r)
	if err != nil {
		return nil, err
	}
	err = s.Parse()
	if err != nil {
		return nil, err
	}
	return s, nil
}

// FlacSignature is present at the beginning of each FLAC file.
const FlacSignature = "fLaC"

// NewStream validates the FLAC signature of the provided io.ReadSeeker and
// returns a handle to the FLAC bitstream. Call either Stream.Parse or
// Stream.ParseBlocks and Stream.ParseFrames to parse the metadata blocks and
// audio frames.
func NewStream(r io.ReadSeeker) (s *Stream, err error) {
	// Verify "fLaC" signature (size: 4 bytes).
	buf := make([]byte, 4)
	_, err = io.ReadFull(r, buf)
	if err != nil {
		return nil, err
	}
	sig := string(buf)
	if sig != FlacSignature {
		return nil, fmt.Errorf("flac.NewStream: invalid signature; expected %q, got %q", FlacSignature, sig)
	}

	s = &Stream{r: r}
	return s, nil
}

// Parse reads and parses all metadata blocks and audio frames of the stream.
// Use Stream.ParseBlocks and Stream.ParseFrames instead for more granularity.
func (s *Stream) Parse() (err error) {
	err = s.ParseBlocks(meta.TypeAll)
	if err != nil {
		return err
	}
	err = s.ParseFrames()
	if err != nil {
		return err
	}
	return nil
}

// ParseBlocks reads and parses the specified metadata blocks of the stream,
// based on the provided types bitfield. The StreamInfo block type is always
// included.
func (s *Stream) ParseBlocks(types meta.BlockType) (err error) {
	// The StreamInfo block type is always included.
	types |= meta.TypeStreamInfo

	// Read metadata blocks.
	isFirst := true
	var isLast bool
	for !isLast {
		// Read metadata block header.
		block, err := meta.NewBlock(s.r)
		if err != nil {
			return err
		}
		if block.Header.IsLast {
			isLast = true
		}

		// The first block type must be StreamInfo.
		if isFirst {
			if block.Header.BlockType != meta.TypeStreamInfo {
				return fmt.Errorf("flac.NewStream: first block type is invalid; expected %d (StreamInfo), got %d", meta.TypeStreamInfo, block.Header.BlockType)
			}
			isFirst = false
		}

		// Check if the metadata block type is present in the provided types
		// bitfield.
		if block.Header.BlockType&types != 0 {
			// Read metadata block body.
			err = block.Parse()
			if err != nil {
				return err
			}
		} else {
			// Ignore metadata block body.
			err = block.Skip()
			if err != nil {
				return err
			}
		}

		// Store the decoded metadata block.
		s.MetaBlocks = append(s.MetaBlocks, block)
	}

	return nil
}

// ParseFrames reads and parses the audio frames of the stream.
func (s *Stream) ParseFrames() (err error) {
	// The first block is always a StreamInfo block.
	si := s.MetaBlocks[0].Body.(*meta.StreamInfo)

	// Read audio frames.
	// uint64 won't overflow since the max value of SampleCount is
	// 0x0000000FFFFFFFFF.
	var i uint64
	for i < si.SampleCount {
		f, err := frame.NewFrame(s.r)
		if err != nil {
			return err
		}
		s.Frames = append(s.Frames, f)
		i += uint64(len(f.SubFrames[0].Samples))
	}

	return nil
}
<commit_msg>flac: Make FLAC signature unexported.<commit_after>// Package flac provides access to FLAC (Free Lossless Audio Codec) files. [1]
//
// The basic structure of a FLAC bitstream is:
//    - The four byte string signature "fLaC".
//    - The StreamInfo metadata block.
//    - Zero or more other metadata blocks.
//    - One or more audio frames.
//
// [1]: http://flac.sourceforge.net/format.html
package flac

import (
	"fmt"
	"io"
	"os"

	"github.com/mewkiz/flac/frame"
	"github.com/mewkiz/flac/meta"
)

// A Stream is a FLAC bitstream.
type Stream struct {
	// Metadata blocks.
	MetaBlocks []*meta.Block
	// Audio frames.
	Frames []*frame.Frame
	// The underlying reader of the stream.
	r io.ReadSeeker
}

// Parse reads the provided file and returns a parsed FLAC bitstream. It parses
// all metadata blocks and all audio frames. Use Open instead for more
// granularity.
func Parse(filePath string) (s *Stream, err error) {
	f, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	return ParseStream(f)
}

// Open validates the FLAC signature of the provided file and returns a handle
// to the FLAC bitstream. Callers should close the stream when done reading from
// it. Call either Stream.Parse or Stream.ParseBlocks and Stream.ParseFrames to
// parse the metadata blocks and audio frames.
func Open(filePath string) (s *Stream, err error) {
	f, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	return NewStream(f)
}

// Close closes the underlying reader of the stream.
func (s *Stream) Close() error {
	r, ok := s.r.(io.Closer)
	if ok {
		return r.Close()
	}
	return nil
}

// ParseStream reads from the provided io.ReadSeeker and returns a parsed FLAC
// bitstream. It parses all metadata blocks and all audio frames.  Use NewStream
// instead for more granularity.
func ParseStream(r io.ReadSeeker) (s *Stream, err error) {
	s, err = NewStream(r)
	if err != nil {
		return nil, err
	}
	err = s.Parse()
	if err != nil {
		return nil, err
	}
	return s, nil
}

// NewStream validates the FLAC signature of the provided io.ReadSeeker and
// returns a handle to the FLAC bitstream. Call either Stream.Parse or
// Stream.ParseBlocks and Stream.ParseFrames to parse the metadata blocks and
// audio frames.
func NewStream(r io.ReadSeeker) (s *Stream, err error) {
	// signature is present at the beginning of each FLAC file.
	const signature = "fLaC"

	// Verify "fLaC" signature (size: 4 bytes).
	buf := make([]byte, 4)
	_, err = io.ReadFull(r, buf)
	if err != nil {
		return nil, err
	}
	sig := string(buf)
	if sig != signature {
		return nil, fmt.Errorf("flac.NewStream: invalid signature; expected %q, got %q", signature, sig)
	}

	s = &Stream{r: r}
	return s, nil
}

// Parse reads and parses all metadata blocks and audio frames of the stream.
// Use Stream.ParseBlocks and Stream.ParseFrames instead for more granularity.
func (s *Stream) Parse() (err error) {
	err = s.ParseBlocks(meta.TypeAll)
	if err != nil {
		return err
	}
	err = s.ParseFrames()
	if err != nil {
		return err
	}
	return nil
}

// ParseBlocks reads and parses the specified metadata blocks of the stream,
// based on the provided types bitfield. The StreamInfo block type is always
// included.
func (s *Stream) ParseBlocks(types meta.BlockType) (err error) {
	// The StreamInfo block type is always included.
	types |= meta.TypeStreamInfo

	// Read metadata blocks.
	isFirst := true
	var isLast bool
	for !isLast {
		// Read metadata block header.
		block, err := meta.NewBlock(s.r)
		if err != nil {
			return err
		}
		if block.Header.IsLast {
			isLast = true
		}

		// The first block type must be StreamInfo.
		if isFirst {
			if block.Header.BlockType != meta.TypeStreamInfo {
				return fmt.Errorf("flac.Stream.ParseBlocks: first block type is invalid; expected %d (StreamInfo), got %d", meta.TypeStreamInfo, block.Header.BlockType)
			}
			isFirst = false
		}

		// Check if the metadata block type is present in the provided types
		// bitfield.
		if block.Header.BlockType&types != 0 {
			// Read metadata block body.
			err = block.Parse()
			if err != nil {
				return err
			}
		} else {
			// Ignore metadata block body.
			err = block.Skip()
			if err != nil {
				return err
			}
		}

		// Store the decoded metadata block.
		s.MetaBlocks = append(s.MetaBlocks, block)
	}

	return nil
}

// ParseFrames reads and parses the audio frames of the stream.
func (s *Stream) ParseFrames() (err error) {
	// The first block is always a StreamInfo block.
	si := s.MetaBlocks[0].Body.(*meta.StreamInfo)

	// Read audio frames.
	// uint64 won't overflow since the max value of SampleCount is
	// 0x0000000FFFFFFFFF.
	var i uint64
	for i < si.SampleCount {
		f, err := frame.NewFrame(s.r)
		if err != nil {
			return err
		}
		s.Frames = append(s.Frames, f)
		i += uint64(len(f.SubFrames[0].Samples))
	}

	return nil
}
<|endoftext|>


<commit_before>package admin

import (
	"appengine/datastore"
	"fmt"
	"models/configuration/config"
	"models/presentation"
	"util"
)

//Bootstrap inserts fake presentation and config into datastore.
//Used when the system doesn't have any presentation inserted.
func Bootstrap(c util.Context) (err error) {
	p := presentation.New("test", "xxx", "DO NOT USE!", []byte("This is just a bootstrap presentation that can't be downloaded"), true)
	_, err = datastore.Put(c.Ac, datastore.NewIncompleteKey(c.Ac, "Presentation", nil), p)
	if err != nil {
		fmt.Fprintln(c.W, "Error with presentation: ", err)
		return nil
	}

	//	zeroTime := time.Date(0001, 01, 01, 00, 00, 00, 00, utc)

	conf := new(config.Config)

	err = conf.Save(c.Ac)

	if err != nil {
		fmt.Fprintln(c.W, "Error with config:", err)
		return nil
	}
	fmt.Fprint(c.W, "Do not start any clients until you have replaced this presentation.")
	return
}

//Migrate migrates Datastore data from a previous version.
func Migrate(c util.Context) (err error) {
	fmt.Fprintf(c.W, "There is nothing to migrate in current version.")
	return
}
<commit_msg>Added a migration function<commit_after>package admin

import (
	"appengine/datastore"
	"fmt"
	"models/configuration/config"
	"models/presentation"
	"util"
)

//Bootstrap inserts fake presentation and config into datastore.
//Used when the system doesn't have any presentation inserted.
func Bootstrap(c util.Context) (err error) {
	p := presentation.New("test", "xxx", "DO NOT USE!", []byte("This is just a bootstrap presentation that can't be downloaded"), true)
	_, err = datastore.Put(c.Ac, datastore.NewIncompleteKey(c.Ac, "Presentation", nil), p)
	if err != nil {
		fmt.Fprintln(c.W, "Error with presentation: ", err)
		return nil
	}

	//	zeroTime := time.Date(0001, 01, 01, 00, 00, 00, 00, utc)

	conf := new(config.Config)

	err = conf.Save(c.Ac)

	if err != nil {
		fmt.Fprintln(c.W, "Error with config:", err)
		return nil
	}
	fmt.Fprint(c.W, "Do not start any clients until you have replaced this presentation.")
	return
}

//Migrate migrates Datastore data from a previous version.
func Migrate(c util.Context) (err error) {
	keys, err := datastore.NewQuery("Action").KeysOnly().GetAll(c.Ac, nil)
	if err != nil {
		return err
	}
	err = datastore.DeleteMulti(c.Ac, keys)
	if err != nil {
		return
	}
	fmt.Fprintf(c.W, "Success, %d actions deleted", len(keys))
	return
}
<|endoftext|>


<commit_before>package controllers

import (
	"bytes"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/db"
	"github.com/eirka/eirka-libs/user"

	local "github.com/eirka/eirka-post/config"
)

func init() {

	// Database connection settings
	dbase := db.Database{

		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Proto,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Database.MaxIdle,
		MaxConnections: local.Settings.Database.MaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

	user.Secret = "secret"
}

func performRequest(r http.Handler, method, path string) *httptest.ResponseRecorder {
	req, _ := http.NewRequest(method, path, nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w
}

func performJwtJsonRequest(r http.Handler, method, path, token string, body []byte) *httptest.ResponseRecorder {
	req, _ := http.NewRequest(method, path, bytes.NewBuffer(body))
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	req.Header.Set("Content-Type", "application/json")
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w
}

func performJwtFormRequest(r http.Handler, method, path, token string, body bytes.Buffer) *httptest.ResponseRecorder {
	req, _ := http.NewRequest(method, path, &body)
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	req.Header.Set("Content-Type", "multipart/form-data")
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w
}

func TestEmailController(t *testing.T) {

	var err error

	gin.SetMode(gin.ReleaseMode)

	router := gin.New()

	router.Use(user.Auth(true))

	router.POST("/email", EmailController)

	first := performRequest(router, "POST", "/email")

	assert.Equal(t, first.Code, 401, "HTTP request code should match")

	u := user.DefaultUser()
	u.SetId(2)
	u.SetAuthenticated()
	u.Password()

	assert.True(t, u.ComparePassword("testpassword"), "Test user password should be set")

	token, err := u.CreateToken()
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotEmpty(t, token, "token should be returned")
	}

	request1 := []byte(`{"ib": 1, "email": "test@test.com"}`)

	second := performJwtJsonRequest(router, "POST", "/email", token, request1)

	assert.Equal(t, second.Code, 200, "HTTP request code should match")
	assert.JSONEq(t, second.Body.String(), `{"success_message":"Email Updated"}`, "HTTP response should match")

	request2 := []byte(`{"ib": 1, "email": "test@test.com"}`)

	third := performJwtJsonRequest(router, "POST", "/email", token, request2)

	assert.Equal(t, third.Code, 400, "HTTP request code should match")
	assert.JSONEq(t, third.Body.String(), `{"error_message":"Email address the same"}`, "HTTP response should match")

	request3 := []byte(`{"ib": 1, "email": "test@cool.com"}`)

	fourth := performJwtJsonRequest(router, "POST", "/email", token, request3)

	assert.Equal(t, fourth.Code, 200, "HTTP request code should match")
	assert.JSONEq(t, fourth.Body.String(), `{"success_message":"Email Updated"}`, "HTTP response should match")

}
<commit_msg>add email test<commit_after>package controllers

import (
	"bytes"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/db"
	"github.com/eirka/eirka-libs/user"

	local "github.com/eirka/eirka-post/config"
)

func init() {

	// Database connection settings
	dbase := db.Database{

		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Proto,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Database.MaxIdle,
		MaxConnections: local.Settings.Database.MaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

	user.Secret = "secret"
}

func performRequest(r http.Handler, method, path string) *httptest.ResponseRecorder {
	req, _ := http.NewRequest(method, path, nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w
}

func performJwtJsonRequest(r http.Handler, method, path, token string, body []byte) *httptest.ResponseRecorder {
	req, _ := http.NewRequest(method, path, bytes.NewBuffer(body))
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	req.Header.Set("Content-Type", "application/json")
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w
}

func performJwtFormRequest(r http.Handler, method, path, token string, body bytes.Buffer) *httptest.ResponseRecorder {
	req, _ := http.NewRequest(method, path, &body)
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	req.Header.Set("Content-Type", "multipart/form-data")
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w
}

func TestEmailController(t *testing.T) {

	var err error

	gin.SetMode(gin.ReleaseMode)

	router := gin.New()

	router.Use(user.Auth(true))

	router.POST("/email", EmailController)

	first := performRequest(router, "POST", "/email")

	assert.Equal(t, first.Code, 401, "HTTP request code should match")

	u := user.DefaultUser()
	u.SetId(2)
	u.SetAuthenticated()
	u.Password()

	assert.True(t, u.ComparePassword("testpassword"), "Test user password should be set")

	token, err := u.CreateToken()
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotEmpty(t, token, "token should be returned")
	}

	request1 := []byte(`{"ib": 1, "email": "test@test.com"}`)

	second := performJwtJsonRequest(router, "POST", "/email", token, request1)

	assert.Equal(t, second.Code, 200, "HTTP request code should match")
	assert.JSONEq(t, second.Body.String(), `{"success_message":"Email Updated"}`, "HTTP response should match")

	request2 := []byte(`{"ib": 1, "email": "test@test.com"}`)

	third := performJwtJsonRequest(router, "POST", "/email", token, request2)

	assert.Equal(t, third.Code, 400, "HTTP request code should match")
	assert.JSONEq(t, third.Body.String(), `{"error_message":"Email address the same"}`, "HTTP response should match")

	request3 := []byte(`{"ib": 1, "email": "test@cool.com"}`)

	fourth := performJwtJsonRequest(router, "POST", "/email", token, request3)

	assert.Equal(t, fourth.Code, 200, "HTTP request code should match")
	assert.JSONEq(t, fourth.Body.String(), `{"success_message":"Email Updated"}`, "HTTP response should match")

}

func TestEmailControllerBadRequests(t *testing.T) {

	var err error

	gin.SetMode(gin.ReleaseMode)

	router := gin.New()

	router.Use(user.Auth(true))

	router.POST("/email", EmailController)

	u := user.DefaultUser()
	u.SetId(2)
	u.SetAuthenticated()
	u.Password()

	assert.True(t, u.ComparePassword("testpassword"), "Test user password should be set")

	token, err := u.CreateToken()
	if assert.NoError(t, err, "An error was not expected") {
		assert.NotEmpty(t, token, "token should be returned")
	}

	request1 := []byte(`{"ib": 1}`)

	first := performJwtJsonRequest(router, "POST", "/email", token, request1)

	assert.Equal(t, first.Code, 400, "HTTP request code should match")
	assert.JSONEq(t, first.Body.String(), `{"error_message":"Bad Request"}`, "HTTP response should match")

	request2 := []byte(`{"email": "test@cool.com"}`)

	second := performJwtJsonRequest(router, "POST", "/email", token, request2)

	assert.Equal(t, second.Code, 400, "HTTP request code should match")
	assert.JSONEq(t, second.Body.String(), `{"error_message":"Bad Request"}`, "HTTP response should match")

}
<|endoftext|>


<commit_before>// Copyright 2009 The Go 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 time

import (
	"os";
	"time"
)

// Seconds since January 1, 1970 00:00:00 GMT
export func Seconds() int64 {
	sec, nsec, err := os.Time();
	if err != nil {
		panic("time: os.Time: ", err.String());
	}
	return sec
}

// Nanoseconds since January 1, 1970 00:00:00 GMT
export func Nanoseconds() int64 {
	sec, nsec, err := os.Time();
	if err != nil {
		panic("time: os.Time: ", err.String());
	}
	return sec*1e9 + nsec
}

export const (
	Sunday = iota;
	Monday;
	Tuesday;
	Wednesday;
	Thursday;
	Friday;
	Saturday;
)

export type Time struct {
	year int64;	// 2008 is 2008
	month, day int;	// Sep-17 is 9, 17
	hour, minute, second int;	// 10:43:12 is 10, 43, 12
	weekday int;		// Sunday = 0, Monday = 1, ...
	zoneoffset int;	// seconds west of UTC
	zone string;
}

var RegularMonths = []int{
	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
}
var LeapMonths = []int{
	31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
}

func Months(year int64) *[]int {
	if year%4 == 0 && (year%100 != 0 || year%400 == 0) {
		return &LeapMonths
	} else {
		return &RegularMonths
	}
	return nil	// not reached
}

const (
	SecondsPerDay = 24*60*60;

	DaysPer400Years = 365*400+97;
	DaysPer100Years = 365*100+24;
	DaysPer4Years = 365*4+1;

	Days1970To2001 = 31*365+8;
)

export func SecondsToUTC(sec int64) *Time {
	t := new(Time);

	// Split into time and day.
	day := sec/SecondsPerDay;
	sec -= day*SecondsPerDay;
	if sec < 0 {
		day--;
		sec += SecondsPerDay
	}

	// Time
	t.hour = int(sec/3600);
	t.minute = int((sec/60)%60);
	t.second = int(sec%60);

	// Day 0 = January 1, 1970 was a Thursday
	t.weekday = int((day + Thursday) % 7);
	if t.weekday < 0 {
		t.weekday += 7
	}

	// Change day from 0 = 1970 to 0 = 2001,
	// to make leap year calculations easier
	// (2001 begins 4-, 100-, and 400-year cycles ending in a leap year.)
	day -= Days1970To2001;

	year := int64(2001);
	if day < 0 {
		// Go back enough 400 year cycles to make day positive.
		n := -day/DaysPer400Years + 1;
		year -= 400*n;
		day += DaysPer400Years*n;
	} else {
		// Cut off 400 year cycles.
		n := day/DaysPer400Years;
		year += 400*n;
		day -= DaysPer400Years*n;
	}

	// Cut off 100-year cycles
	n := day/DaysPer100Years;
	year += 100*n;
	day -= DaysPer100Years*n;

	// Cut off 4-year cycles
	n = day/DaysPer4Years;
	year += 4*n;
	day -= DaysPer4Years*n;

	// Cut off non-leap years.
	n = day/365;
	year += n;
	day -= 365*n;

	t.year = year;

	// If someone ever needs yearday,
	// tyearday = day (+1?)

	months := Months(year);
	var m int;
	yday := int(day);
	for m = 0; m < 12 && yday >= months[m]; m++ {
		yday -= months[m]
	}
	t.month = m+1;
	t.day = yday+1;
	t.zone = "GMT";

	return t;
}

export func UTC() (t *Time, err *os.Error) {
	return SecondsToUTC(Seconds()), nil
}

// TODO: Should this return an error?
export func SecondsToLocalTime(sec int64) *Time {
	zone, offset, err := time.LookupTimezone(sec);
	if err != nil {
		return SecondsToUTC(sec)
	}
	t := SecondsToUTC(sec+int64(offset));
	t.zone = zone;
	t.zoneoffset = offset;
	return t
}

export func LocalTime() (t *Time, err *os.Error) {
	return SecondsToLocalTime(Seconds()), nil
}

// Compute number of seconds since January 1, 1970.
func (t *Time) Seconds() int64 {
	// First, accumulate days since January 1, 2001.
	// Using 2001 instead of 1970 makes the leap-year
	// handling easier (see SecondsToUTC), because
	// it is at the beginning of the 4-, 100-, and 400-year cycles.
	day := int64(0);

	// Rewrite year to be >= 2001.
	year := t.year;
	if year < 2001 {
		n := (2001 - year)/400 + 1;
		year += 400*n;
		day -= DaysPer400Years*n;
	}

	// Add in days from 400-year cycles.
	n := (year - 2001) / 400;
	year -= 400*n;
	day += DaysPer400Years*n;

	// Add in 100-year cycles.
	n = (year - 2001) / 100;
	year -= 100*n;
	day += DaysPer100Years*n;

	// Add in 4-year cycles.
	n = (year - 2001) / 4;
	year -= 4*n;
	day += DaysPer4Years*n;

	// Add in non-leap years.
	n = year - 2001;
	day += 365*n;

	// Add in days this year.
	months := Months(t.year);
	for m := 0; m < t.month-1; m++ {
		day += int64(months[m])
	}
	day += int64(t.day - 1);

	// Convert days to seconds since January 1, 2001.
	sec := day * SecondsPerDay;

	// Add in time elapsed today.
	sec += int64(t.hour) * 3600;
	sec += int64(t.minute) * 60;
	sec += int64(t.second);

	// Convert from seconds since 2001 to seconds since 1970.
	sec += Days1970To2001 * SecondsPerDay;

	// Account for local time zone.
	sec -= int64(t.zoneoffset);
	return sec
}

var LongDayNames = []string{
	"Sunday",
	"Monday",
	"Tuesday",
	"Wednesday",
	"Thursday",
	"Friday",
	"Saturday"
}

var ShortDayNames = []string{
	"Sun",
	"Mon",
	"Tue",
	"Wed",
	"Thu",
	"Fri",
	"Sat"
}

var ShortMonthNames = []string{
	"Jan",
	"Feb",
	"Mar",
	"Apr",
	"May",
	"Jun",
	"Jul",
	"Aug",
	"Sep",
	"Oct",
	"Nov",
	"Dec"
}

func Copy(dst *[]byte, s string) {
	for i := 0; i < len(s); i++ {
		dst[i] = s[i]
	}
}

func Decimal(dst *[]byte, n int) {
	if n < 0 {
		n = 0
	}
	for i := len(dst)-1; i >= 0; i-- {
		dst[i] = byte(n%10 + '0');
		n /= 10
	}
}

func AddString(buf *[]byte, bp int, s string) int {
	n := len(s);
	Copy(buf[bp:bp+n], s);
	return bp+n
}

// Just enough of strftime to implement the date formats below.
// Not exported.
func Format(t *Time, fmt string) string {
	buf := new([]byte, 128);
	bp := 0;

	for i := 0; i < len(fmt); i++ {
		if fmt[i] == '%' {
			i++;
			switch fmt[i] {
			case 'A':	// %A full weekday name
				bp = AddString(buf, bp, LongDayNames[t.weekday]);
			case 'a':	// %a abbreviated weekday name
				bp = AddString(buf, bp, ShortDayNames[t.weekday]);
			case 'b':	// %b abbreviated month name
				bp = AddString(buf, bp, ShortMonthNames[t.month-1]);
			case 'd':	// %d day of month (01-31)
				Decimal(buf[bp:bp+2], t.day);
				bp += 2;
			case 'e':	// %e day of month ( 1-31)
				if t.day >= 10 {
					Decimal(buf[bp:bp+2], t.day)
				} else {
					buf[bp] = ' ';
					buf[bp+1] = byte(t.day + '0')
				}
				bp += 2;
			case 'H':	// %H hour 00-23
				Decimal(buf[bp:bp+2], t.hour);
				bp += 2;
			case 'M':	// %M minute 00-59
				Decimal(buf[bp:bp+2], t.minute);
				bp += 2;
			case 'S':	// %S second 00-59
				Decimal(buf[bp:bp+2], t.second);
				bp += 2;
			case 'Y':	// %Y year 2008
				Decimal(buf[bp:bp+4], int(t.year));
				bp += 4;
			case 'y':	// %y year 08
				Decimal(buf[bp:bp+2], int(t.year%100));
				bp += 2;
			case 'Z':
				bp = AddString(buf, bp, t.zone);
			default:
				buf[bp] = '%';
				buf[bp+1] = fmt[i];
				bp += 2
			}
		} else {
			buf[bp] = fmt[i];
			bp++;
		}
	}
	return string(buf[0:bp])
}

// ANSI C asctime: Sun Nov  6 08:49:37 1994
func (t *Time) Asctime() string {
	return Format(t, "%a %b %e %H:%M:%S %Y")
}

// RFC 850: Sunday, 06-Nov-94 08:49:37 GMT
func (t *Time) RFC850() string {
	return Format(t, "%A, %d-%b-%y %H:%M:%S %Z")
}

// RFC 1123: Sun, 06 Nov 1994 08:49:37 GMT
func (t *Time) RFC1123() string {
	return Format(t, "%a, %d %b %Y %H:%M:%S %Z")
}

// date(1) - Sun Nov  6 08:49:37 GMT 1994
func (t *Time) String() string {
	return Format(t, "%a %b %e %H:%M:%S %Z %Y")
}

<commit_msg>more impossible time errors<commit_after>// Copyright 2009 The Go 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 time

import (
	"os";
	"time"
)

// Seconds since January 1, 1970 00:00:00 GMT
export func Seconds() int64 {
	sec, nsec, err := os.Time();
	if err != nil {
		panic("time: os.Time: ", err.String());
	}
	return sec
}

// Nanoseconds since January 1, 1970 00:00:00 GMT
export func Nanoseconds() int64 {
	sec, nsec, err := os.Time();
	if err != nil {
		panic("time: os.Time: ", err.String());
	}
	return sec*1e9 + nsec
}

export const (
	Sunday = iota;
	Monday;
	Tuesday;
	Wednesday;
	Thursday;
	Friday;
	Saturday;
)

export type Time struct {
	year int64;	// 2008 is 2008
	month, day int;	// Sep-17 is 9, 17
	hour, minute, second int;	// 10:43:12 is 10, 43, 12
	weekday int;		// Sunday = 0, Monday = 1, ...
	zoneoffset int;	// seconds west of UTC
	zone string;
}

var RegularMonths = []int{
	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
}
var LeapMonths = []int{
	31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
}

func Months(year int64) *[]int {
	if year%4 == 0 && (year%100 != 0 || year%400 == 0) {
		return &LeapMonths
	} else {
		return &RegularMonths
	}
	return nil	// not reached
}

const (
	SecondsPerDay = 24*60*60;

	DaysPer400Years = 365*400+97;
	DaysPer100Years = 365*100+24;
	DaysPer4Years = 365*4+1;

	Days1970To2001 = 31*365+8;
)

export func SecondsToUTC(sec int64) *Time {
	t := new(Time);

	// Split into time and day.
	day := sec/SecondsPerDay;
	sec -= day*SecondsPerDay;
	if sec < 0 {
		day--;
		sec += SecondsPerDay
	}

	// Time
	t.hour = int(sec/3600);
	t.minute = int((sec/60)%60);
	t.second = int(sec%60);

	// Day 0 = January 1, 1970 was a Thursday
	t.weekday = int((day + Thursday) % 7);
	if t.weekday < 0 {
		t.weekday += 7
	}

	// Change day from 0 = 1970 to 0 = 2001,
	// to make leap year calculations easier
	// (2001 begins 4-, 100-, and 400-year cycles ending in a leap year.)
	day -= Days1970To2001;

	year := int64(2001);
	if day < 0 {
		// Go back enough 400 year cycles to make day positive.
		n := -day/DaysPer400Years + 1;
		year -= 400*n;
		day += DaysPer400Years*n;
	} else {
		// Cut off 400 year cycles.
		n := day/DaysPer400Years;
		year += 400*n;
		day -= DaysPer400Years*n;
	}

	// Cut off 100-year cycles
	n := day/DaysPer100Years;
	year += 100*n;
	day -= DaysPer100Years*n;

	// Cut off 4-year cycles
	n = day/DaysPer4Years;
	year += 4*n;
	day -= DaysPer4Years*n;

	// Cut off non-leap years.
	n = day/365;
	year += n;
	day -= 365*n;

	t.year = year;

	// If someone ever needs yearday,
	// tyearday = day (+1?)

	months := Months(year);
	var m int;
	yday := int(day);
	for m = 0; m < 12 && yday >= months[m]; m++ {
		yday -= months[m]
	}
	t.month = m+1;
	t.day = yday+1;
	t.zone = "GMT";

	return t;
}

export func UTC() *Time {
	return SecondsToUTC(Seconds())
}

// TODO: Should this return an error?
export func SecondsToLocalTime(sec int64) *Time {
	zone, offset, err := time.LookupTimezone(sec);
	if err != nil {
		return SecondsToUTC(sec)
	}
	t := SecondsToUTC(sec+int64(offset));
	t.zone = zone;
	t.zoneoffset = offset;
	return t
}

export func LocalTime() *Time {
	return SecondsToLocalTime(Seconds())
}

// Compute number of seconds since January 1, 1970.
func (t *Time) Seconds() int64 {
	// First, accumulate days since January 1, 2001.
	// Using 2001 instead of 1970 makes the leap-year
	// handling easier (see SecondsToUTC), because
	// it is at the beginning of the 4-, 100-, and 400-year cycles.
	day := int64(0);

	// Rewrite year to be >= 2001.
	year := t.year;
	if year < 2001 {
		n := (2001 - year)/400 + 1;
		year += 400*n;
		day -= DaysPer400Years*n;
	}

	// Add in days from 400-year cycles.
	n := (year - 2001) / 400;
	year -= 400*n;
	day += DaysPer400Years*n;

	// Add in 100-year cycles.
	n = (year - 2001) / 100;
	year -= 100*n;
	day += DaysPer100Years*n;

	// Add in 4-year cycles.
	n = (year - 2001) / 4;
	year -= 4*n;
	day += DaysPer4Years*n;

	// Add in non-leap years.
	n = year - 2001;
	day += 365*n;

	// Add in days this year.
	months := Months(t.year);
	for m := 0; m < t.month-1; m++ {
		day += int64(months[m])
	}
	day += int64(t.day - 1);

	// Convert days to seconds since January 1, 2001.
	sec := day * SecondsPerDay;

	// Add in time elapsed today.
	sec += int64(t.hour) * 3600;
	sec += int64(t.minute) * 60;
	sec += int64(t.second);

	// Convert from seconds since 2001 to seconds since 1970.
	sec += Days1970To2001 * SecondsPerDay;

	// Account for local time zone.
	sec -= int64(t.zoneoffset);
	return sec
}

var LongDayNames = []string{
	"Sunday",
	"Monday",
	"Tuesday",
	"Wednesday",
	"Thursday",
	"Friday",
	"Saturday"
}

var ShortDayNames = []string{
	"Sun",
	"Mon",
	"Tue",
	"Wed",
	"Thu",
	"Fri",
	"Sat"
}

var ShortMonthNames = []string{
	"Jan",
	"Feb",
	"Mar",
	"Apr",
	"May",
	"Jun",
	"Jul",
	"Aug",
	"Sep",
	"Oct",
	"Nov",
	"Dec"
}

func Copy(dst *[]byte, s string) {
	for i := 0; i < len(s); i++ {
		dst[i] = s[i]
	}
}

func Decimal(dst *[]byte, n int) {
	if n < 0 {
		n = 0
	}
	for i := len(dst)-1; i >= 0; i-- {
		dst[i] = byte(n%10 + '0');
		n /= 10
	}
}

func AddString(buf *[]byte, bp int, s string) int {
	n := len(s);
	Copy(buf[bp:bp+n], s);
	return bp+n
}

// Just enough of strftime to implement the date formats below.
// Not exported.
func Format(t *Time, fmt string) string {
	buf := new([]byte, 128);
	bp := 0;

	for i := 0; i < len(fmt); i++ {
		if fmt[i] == '%' {
			i++;
			switch fmt[i] {
			case 'A':	// %A full weekday name
				bp = AddString(buf, bp, LongDayNames[t.weekday]);
			case 'a':	// %a abbreviated weekday name
				bp = AddString(buf, bp, ShortDayNames[t.weekday]);
			case 'b':	// %b abbreviated month name
				bp = AddString(buf, bp, ShortMonthNames[t.month-1]);
			case 'd':	// %d day of month (01-31)
				Decimal(buf[bp:bp+2], t.day);
				bp += 2;
			case 'e':	// %e day of month ( 1-31)
				if t.day >= 10 {
					Decimal(buf[bp:bp+2], t.day)
				} else {
					buf[bp] = ' ';
					buf[bp+1] = byte(t.day + '0')
				}
				bp += 2;
			case 'H':	// %H hour 00-23
				Decimal(buf[bp:bp+2], t.hour);
				bp += 2;
			case 'M':	// %M minute 00-59
				Decimal(buf[bp:bp+2], t.minute);
				bp += 2;
			case 'S':	// %S second 00-59
				Decimal(buf[bp:bp+2], t.second);
				bp += 2;
			case 'Y':	// %Y year 2008
				Decimal(buf[bp:bp+4], int(t.year));
				bp += 4;
			case 'y':	// %y year 08
				Decimal(buf[bp:bp+2], int(t.year%100));
				bp += 2;
			case 'Z':
				bp = AddString(buf, bp, t.zone);
			default:
				buf[bp] = '%';
				buf[bp+1] = fmt[i];
				bp += 2
			}
		} else {
			buf[bp] = fmt[i];
			bp++;
		}
	}
	return string(buf[0:bp])
}

// ANSI C asctime: Sun Nov  6 08:49:37 1994
func (t *Time) Asctime() string {
	return Format(t, "%a %b %e %H:%M:%S %Y")
}

// RFC 850: Sunday, 06-Nov-94 08:49:37 GMT
func (t *Time) RFC850() string {
	return Format(t, "%A, %d-%b-%y %H:%M:%S %Z")
}

// RFC 1123: Sun, 06 Nov 1994 08:49:37 GMT
func (t *Time) RFC1123() string {
	return Format(t, "%a, %d %b %Y %H:%M:%S %Z")
}

// date(1) - Sun Nov  6 08:49:37 GMT 1994
func (t *Time) String() string {
	return Format(t, "%a %b %e %H:%M:%S %Z %Y")
}

<|endoftext|>


<commit_before>package post

import (
	"github.com/hackform/governor"
	"github.com/hackform/governor/service/cache"
	"github.com/hackform/governor/service/db"
	"github.com/hackform/governor/service/post/model"
	"github.com/hackform/governor/service/user/gate"
	"github.com/labstack/echo"
	"github.com/sirupsen/logrus"
	"net/http"
	"time"
)

type (
	reqPostPost struct {
		Userid  string `json:"userid"`
		Tags    string `json:"group_tags"`
		Content string `json:"content"`
	}

	reqPostPut struct {
		Postid  string `json:"postid"`
		Content string `json:"content"`
	}

	resPost struct {
		Postid       string `json:"postid"`
		Userid       string `json:"userid"`
		Tags         string `json:"group_tags"`
		Content      string `json:"content"`
		CreationTime int64  `json:"creation_time"`
	}
)

func (r *reqPostPost) valid() *governor.Error {
	if err := hasUserid(r.Userid); err != nil {
		return err
	}
	if err := validContent(r.Content); err != nil {
		return err
	}
	if err := validRank(r.Tags); err != nil {
		return err
	}
	return nil
}

func (r *reqPostPut) valid() *governor.Error {
	if err := hasPostid(r.Postid); err != nil {
		return err
	}
	if err := validContent(r.Content); err != nil {
		return err
	}
	return nil
}

const (
	moduleID = "post"
)

type (
	// Post is a service for creating posts
	Post struct {
		db    *db.Database
		cache *cache.Cache
		gate  *gate.Gate
	}
)

// New creates a new Post service
func New(conf governor.Config, l *logrus.Logger, db *db.Database, ch *cache.Cache) *Post {
	ca := conf.Conf().GetStringMapString("userauth")

	l.Info("initialized post service")

	return &Post{
		db:    db,
		cache: ch,
		gate:  gate.New(ca["secret"], ca["issuer"]),
	}
}

// Mount is a collection of routes for accessing and modifying post data
func (p *Post) Mount(conf governor.Config, r *echo.Group, l *logrus.Logger) error {
	db := p.db.DB()

	r.POST("/", func(c echo.Context) error {
		rpost := &reqPostPost{}
		if err := c.Bind(rpost); err != nil {
			return governor.NewErrorUser(moduleID, err.Error(), 0, http.StatusBadRequest)
		}
		if err := rpost.valid(); err != nil {
			return err
		}

		m, err := postmodel.New(rpost.Userid, rpost.Tags, rpost.Content)
		if err != nil {
			err.AddTrace(moduleID)
			return err
		}

		if err := m.Insert(db); err != nil {
			if err.Code() == 3 {
				err.SetErrorUser()
			}
			err.AddTrace(moduleID)
			return err
		}

		t, _ := time.Now().MarshalText()
		postid, _ := m.IDBase64()
		userid, _ := m.UserIDBase64()
		l.WithFields(logrus.Fields{
			"time":   string(t),
			"origin": moduleID,
			"postid": postid,
			"userid": userid,
		}).Info("post created")

		return c.NoContent(http.StatusNoContent)
	}, p.gate.User())

	r.GET("/:id", func(c echo.Context) error {
		return c.JSON(http.StatusOK, &resPost{})
	})

	l.Info("mounted post service")

	return nil
}

// Health is a check for service health
func (p *Post) Health() *governor.Error {
	return nil
}
<commit_msg>get post<commit_after>package post

import (
	"github.com/hackform/governor"
	"github.com/hackform/governor/service/cache"
	"github.com/hackform/governor/service/db"
	"github.com/hackform/governor/service/post/model"
	"github.com/hackform/governor/service/user/gate"
	"github.com/labstack/echo"
	"github.com/sirupsen/logrus"
	"net/http"
	"time"
)

type (
	reqPostPost struct {
		Userid  string `json:"userid"`
		Tags    string `json:"group_tags"`
		Content string `json:"content"`
	}

	reqPostPut struct {
		Postid  string `json:"postid"`
		Content string `json:"content"`
	}

	reqPostGet struct {
		Postid string `json:"postid"`
	}

	resPost struct {
		Postid       []byte `json:"postid"`
		Userid       []byte `json:"userid"`
		Tags         string `json:"group_tags"`
		Content      string `json:"content"`
		CreationTime int64  `json:"creation_time"`
	}
)

func (r *reqPostPost) valid() *governor.Error {
	if err := hasUserid(r.Userid); err != nil {
		return err
	}
	if err := validContent(r.Content); err != nil {
		return err
	}
	if err := validRank(r.Tags); err != nil {
		return err
	}
	return nil
}

func (r *reqPostPut) valid() *governor.Error {
	if err := hasPostid(r.Postid); err != nil {
		return err
	}
	if err := validContent(r.Content); err != nil {
		return err
	}
	return nil
}

func (r *reqPostGet) valid() *governor.Error {
	if err := hasPostid(r.Postid); err != nil {
		return err
	}
	return nil
}

const (
	moduleID = "post"
)

type (
	// Post is a service for creating posts
	Post struct {
		db    *db.Database
		cache *cache.Cache
		gate  *gate.Gate
	}
)

// New creates a new Post service
func New(conf governor.Config, l *logrus.Logger, db *db.Database, ch *cache.Cache) *Post {
	ca := conf.Conf().GetStringMapString("userauth")

	l.Info("initialized post service")

	return &Post{
		db:    db,
		cache: ch,
		gate:  gate.New(ca["secret"], ca["issuer"]),
	}
}

// Mount is a collection of routes for accessing and modifying post data
func (p *Post) Mount(conf governor.Config, r *echo.Group, l *logrus.Logger) error {
	db := p.db.DB()

	r.POST("/", func(c echo.Context) error {
		rpost := &reqPostPost{}
		if err := c.Bind(rpost); err != nil {
			return governor.NewErrorUser(moduleID, err.Error(), 0, http.StatusBadRequest)
		}
		if err := rpost.valid(); err != nil {
			return err
		}

		m, err := postmodel.New(rpost.Userid, rpost.Tags, rpost.Content)
		if err != nil {
			err.AddTrace(moduleID)
			return err
		}

		if err := m.Insert(db); err != nil {
			if err.Code() == 3 {
				err.SetErrorUser()
			}
			err.AddTrace(moduleID)
			return err
		}

		t, _ := time.Now().MarshalText()
		postid, _ := m.IDBase64()
		userid, _ := m.UserIDBase64()
		l.WithFields(logrus.Fields{
			"time":   string(t),
			"origin": moduleID,
			"postid": postid,
			"userid": userid,
		}).Info("post created")

		return c.NoContent(http.StatusNoContent)
	}, p.gate.User())

	r.GET("/:id", func(c echo.Context) error {
		rpost := &reqPostGet{
			Postid: c.Param("id"),
		}
		if err := rpost.valid(); err != nil {
			return err
		}

		m, err := postmodel.GetByIDB64(db, rpost.Postid)
		if err != nil {
			if err.Code() == 2 {
				err.SetErrorUser()
			}
			return err
		}

		return c.JSON(http.StatusOK, &resPost{
			Postid:       m.Postid,
			Userid:       m.Userid,
			Tags:         m.Tags,
			Content:      m.Content,
			CreationTime: m.CreationTime,
		})
	})

	l.Info("mounted post service")

	return nil
}

// Health is a check for service health
func (p *Post) Health() *governor.Error {
	return nil
}
<|endoftext|>