<commit_before>// Package sskg provides a Go implementation of Seekable Sequential Key
// Generators (SSKGs).
//
// An SSKG generates a sequence of forward-secure keys (e.g., for use as
// time-bounded authentication keys), while also providing a fast-forward
// functionality. This package provides an HKDF-based implementation of a binary
// tree-based SSKG as described by Marson and Poettering:
// https://eprint.iacr.org/2014/479.pdf.
//
// The canonical example of SSKG usage is cryptographically protected local
// logs. In this scenario, we have logs on a computer which are secured via
// MACs. If the MAC key is constant, an attacker can extract the key and forge
// or modify log entries in the past. The traditional solution to this is to use
// a foward-secure solution like a hash chain (e.g., K1 = H(K0); K2 =
// H(K1)). This ensures that an attacker who compromises the state of the logger
// cannot establish the state of the logger at an arbitrary point in time in the
// past (and therefore cannot forge log entries in the past).
//
// The use of hash chains presents a large computational expense to the
// auditors, however. In order to verify the MAC using the Nth key, the auditor
// must calculate (N-1) hashes, which may be cumbersome. An SSKG, in contrast,
// allows quickly seeking forward to arbitrary points of time (specifically,
// Marson and Poettering's tree-based SSKG can perform O(log N) seeks).
package sskg

import (
	"hash"
	"math"

	"code.google.com/p/go.crypto/hkdf"
)

// A Seq is a sequence of forward-secure keys.
type Seq struct {
	nodes []node
	alg   func() hash.Hash
	size  int
}

// New creates a new Seq with the given hash algorithm, seed, and maximum number
// of keys.
func New(alg func() hash.Hash, seed []byte, maxKeys uint) Seq {
	size := alg().Size()
	return Seq{
		nodes: []node{{
			k: prf(alg, size, []byte("seed"), seed),
			h: uint(math.Ceil(math.Log2(float64(maxKeys) + 1))),
		}},
		alg:  alg,
		size: size,
	}
}

// Key returns the Seq's current key.
func (s Seq) Key() []byte {
	return prf(s.alg, s.size, []byte("key"), s.nodes[len(s.nodes)-1].k)
}

// Next advances the Seq's current key to the next in the sequence.
//
// (In the literature, this function is called Evolve.)
func (s *Seq) Next() {
	k, h := s.pop()

	if h > 1 {
		s.push(prf(s.alg, s.size, right, k), h-1)
		s.push(prf(s.alg, s.size, left, k), h-1)
	}
}

// Seek moves the Seq to the n-th key without having to calculate all of the
// intermediary keys. It is equivalent to, but faster than, n invocations of
// Next().
func (s *Seq) Seek(n int) {
	k, h := s.pop()

	for n > 0 {
		h--

		if h <= 0 {
			panic("keyspace exhausted")
		}

		pow := 1 << h
		if n < pow {
			s.push(prf(s.alg, s.size, right, k), h)
			k = prf(s.alg, s.size, left, k)
			n--
		} else {
			k = prf(s.alg, s.size, right, k)
			n -= pow
		}
	}

	s.push(k, h)
}

func (s *Seq) pop() ([]byte, uint) {
	node := s.nodes[len(s.nodes)-1]
	s.nodes = s.nodes[:len(s.nodes)-1]
	return node.k, node.h
}

func (s *Seq) push(k []byte, h uint) {
	s.nodes = append(s.nodes, node{k: k, h: h})
}

type node struct {
	k []byte
	h uint
}

var (
	right = []byte("right")
	left  = []byte("left")
)

func prf(alg func() hash.Hash, size int, label, seed []byte) []byte {
	buf := make([]byte, size)
	kdf := hkdf.New(alg, seed, nil, label)
	_, _ = kdf.Read(buf)
	return buf
}
<commit_msg>Freshen docs!<commit_after>// Package sskg provides a Go implementation of Seekable Sequential Key
// Generators (SSKGs). Specifically, this package provides an HKDF-based
// implementation of a binary tree-based SSKG as described by Marson and
// Poettering (https://eprint.iacr.org/2014/479.pdf) which features fast key
// advancing (~6μs) and low memory usage (O(log N)).
//
// An example of SSKG usage is cryptographically protected local logs. In this
// scenario, logs on a computer are secured via MACs. If the MAC key is
// constant, an attacker can extract the key and forge or modify log entries in
// the past.
//
// The traditional solution to this is to use a foward-secure solution like a
// hash chain, but this presents a large computational expense to auditors: in
// order to verify the MAC using the Nth key, the auditor must calculate N-1
// hashes, which may be cumbersome. An SSKG, in contrast, allows quickly seeking
// forward to arbitrary points of time (specifically, Marson and Poettering's
// tree-based SSKG can perform O(log N) seeks).
package sskg

import (
	"hash"
	"math"

	"code.google.com/p/go.crypto/hkdf"
)

// A Seq is a sequence of forward-secure keys.
type Seq struct {
	nodes []node
	alg   func() hash.Hash
	size  int
}

// New creates a new Seq with the given hash algorithm, seed, and maximum number
// of keys.
func New(alg func() hash.Hash, seed []byte, maxKeys uint) Seq {
	size := alg().Size()
	return Seq{
		nodes: []node{{
			k: prf(alg, size, []byte("seed"), seed),
			h: uint(math.Ceil(math.Log2(float64(maxKeys) + 1))),
		}},
		alg:  alg,
		size: size,
	}
}

// Key returns the Seq's current key.
func (s Seq) Key() []byte {
	return prf(s.alg, s.size, []byte("key"), s.nodes[len(s.nodes)-1].k)
}

// Next advances the Seq's current key to the next in the sequence.
//
// (In the literature, this function is called Evolve.)
func (s *Seq) Next() {
	k, h := s.pop()

	if h > 1 {
		s.push(prf(s.alg, s.size, right, k), h-1)
		s.push(prf(s.alg, s.size, left, k), h-1)
	}
}

// Seek moves the Seq to the N-th key without having to calculate all of the
// intermediary keys. It is equivalent to, but faster than, N invocations of
// Next().
func (s *Seq) Seek(n int) {
	k, h := s.pop()

	for n > 0 {
		h--

		if h <= 0 {
			panic("keyspace exhausted")
		}

		pow := 1 << h
		if n < pow {
			s.push(prf(s.alg, s.size, right, k), h)
			k = prf(s.alg, s.size, left, k)
			n--
		} else {
			k = prf(s.alg, s.size, right, k)
			n -= pow
		}
	}

	s.push(k, h)
}

func (s *Seq) pop() ([]byte, uint) {
	node := s.nodes[len(s.nodes)-1]
	s.nodes = s.nodes[:len(s.nodes)-1]
	return node.k, node.h
}

func (s *Seq) push(k []byte, h uint) {
	s.nodes = append(s.nodes, node{k: k, h: h})
}

type node struct {
	k []byte
	h uint
}

var (
	right = []byte("right")
	left  = []byte("left")
)

func prf(alg func() hash.Hash, size int, label, seed []byte) []byte {
	buf := make([]byte, size)
	kdf := hkdf.New(alg, seed, nil, label)
	_, _ = kdf.Read(buf)
	return buf
}
<|endoftext|>


<commit_before>// Package mux implements request routers.
package mux

import (
	"errors"
	"mime"
	"net/http"
	"sort"
	"strconv"
	"strings"
)

// Method maps http methods to different handlers. If no match is found a 405
// Method Not Allowed response is returned.
type Method map[string]http.Handler

func (route Method) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	method := strings.ToUpper(r.Method)

	handler, ok := route[method]
	if ok {
		handler.ServeHTTP(w, r)
		return
	}

	ks := []string{}
	for k := range route {
		ks = append(ks, k)
	}
	ks = append(ks, "OPTIONS")
	sort.Strings(ks)

	w.Header().Set("Accept", strings.Join(ks, ","))

	if method != "OPTIONS" {
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}

// ContentType maps media-types to different handlers. Keys can contain
// wildcards, so application/* will be routed to for application/xml,
// application/json, etc. but only if there is no specific match. You can also
// define */* as a fallback handler, otherwise when no match is found a 415
// Unsupported Media Type response is returned.
type ContentType map[string]http.Handler

func (route ContentType) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	contentType := r.Header.Get("Content-Type")

	mediaType, _, err := mime.ParseMediaType(contentType)
	if err != nil {
		mediaType = contentType
	}

	// 1. Check if we have an exact match

	handler, ok := route[mediaType]
	if ok {
		handler.ServeHTTP(w, r)
		return
	}

	possibleTypes := map[string]http.Handler{}
	for k, v := range route {
		if strings.HasSuffix(k, "/*") {
			possibleTypes[k[:len(k)-2]] = v
		}
	}

	// 2. Check if we have a handler with the same subtype

	handler, ok = possibleTypes[strings.SplitN(mediaType, "/", 2)[0]]
	if ok {
		handler.ServeHTTP(w, r)
		return
	}

	// 3. Check if we have a */* handler

	handler, ok = route["*/*"]
	if ok {
		handler.ServeHTTP(w, r)
		return
	}

	// 4. Otherwise return "415 Unsupported Media Type"

	w.WriteHeader(http.StatusUnsupportedMediaType)
}

// Accept maps Accept header values to different handlers. This will attempt to
// match the acceptable content type with the highest requested quality and
// greatest specificity. A fallback of */* can be specified which will always
// match if no others do, otherwise a 406 Not Acceptable response is returned.
type Accept map[string]http.Handler

func (route Accept) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	accept := r.Header.Get("Accept")

	contentTypes := parseContentTypeList(accept)

	sort.Sort(byQuality(contentTypes))

	for _, ct := range contentTypes {
		for rout, handler := range route {
			rsplit := strings.Split(rout, "/")

			// 1. Check for exact match
			// 2. Check for subtype match
			// 3. Check for wildcard
			//
			// Since the contentTypes are ordered with wildcards below specifics we
			// can check in this order with no problems.
			if ct.Type == rsplit[0] && ct.Subtype == rsplit[1] ||
				ct.Type == rsplit[0] && ct.Subtype == "*" ||
				ct.Type == "*" && ct.Subtype == "*" {

				handler.ServeHTTP(w, r)
				return
			}
		}
	}

	if handler, ok := route["*/*"]; ok {
		handler.ServeHTTP(w, r)
		return
	}

	w.WriteHeader(http.StatusNotAcceptable)
}

type byQuality []clause

func (cs byQuality) Len() int {
	return len(cs)
}

func (cs byQuality) Swap(i, j int) {
	cs[i], cs[j] = cs[j], cs[i]
}

func (cs byQuality) Less(i, j int) bool {
	return cs[i].Quality > cs[j].Quality ||
		cs[i].Type != "*" && cs[j].Type == "*" ||
		cs[i].Subtype != "*" && cs[j].Subtype == "*"
}

type clause struct {
	Type    string
	Subtype string
	Quality float32
}

func parseContentTypeList(s string) []clause {
	s = strings.Trim(s, " ")
	if len(s) == 0 {
		return []clause{}
	}

	parts := strings.Split(s, ",")
	cts := make([]clause, 0, len(parts))
	for _, part := range parts {
		ct, err := parseContentType(part)
		if err != nil {
			continue
		}

		cts = append(cts, ct)
	}

	return cts
}

func parseContentType(s string) (clause, error) {
	s = strings.Trim(s, " ")
	parts := strings.Split(s, ";")

	contentType := parts[0]

	contentTypeParts := strings.Split(contentType, "/")
	if len(contentTypeParts) != 2 {
		return clause{}, errors.New("Invalid media type " + s)
	}

	q := 1.0

	if len(parts) > 1 {
		for _, param := range parts[1:] {
			paramParts := strings.Split(param, "=")
			if len(paramParts) != 2 {
				return clause{}, errors.New("Malformed paramter " + param + " in clause " + s)
			}
			key := strings.Trim(paramParts[0], " ")
			if key == "q" {
				var err error
				q, err = strconv.ParseFloat(paramParts[1], 32)
				if err != nil {
					return clause{}, errors.New("Quality parameter " + paramParts[1] + " can not be parsed from " + s)
				}
			}
		}
	}

	return clause{contentTypeParts[0], contentTypeParts[1], float32(q)}, nil
}
<commit_msg>Use mime package to parse for Accept<commit_after>// Package mux implements request routers.
package mux

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

// Method maps http methods to different handlers. If no match is found a 405
// Method Not Allowed response is returned.
type Method map[string]http.Handler

func (route Method) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	method := strings.ToUpper(r.Method)

	handler, ok := route[method]
	if ok {
		handler.ServeHTTP(w, r)
		return
	}

	ks := []string{}
	for k := range route {
		ks = append(ks, k)
	}
	ks = append(ks, "OPTIONS")
	sort.Strings(ks)

	w.Header().Set("Accept", strings.Join(ks, ","))

	if method != "OPTIONS" {
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}

// ContentType maps media-types to different handlers. Keys can contain
// wildcards, so application/* will be routed to for application/xml,
// application/json, etc. but only if there is no specific match. You can also
// define */* as a fallback handler, otherwise when no match is found a 415
// Unsupported Media Type response is returned.
type ContentType map[string]http.Handler

func (route ContentType) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	contentType := r.Header.Get("Content-Type")

	mediaType, _, err := mime.ParseMediaType(contentType)
	if err != nil {
		mediaType = contentType
	}

	// 1. Check if we have an exact match

	handler, ok := route[mediaType]
	if ok {
		handler.ServeHTTP(w, r)
		return
	}

	possibleTypes := map[string]http.Handler{}
	for k, v := range route {
		if strings.HasSuffix(k, "/*") {
			possibleTypes[k[:len(k)-2]] = v
		}
	}

	// 2. Check if we have a handler with the same subtype

	handler, ok = possibleTypes[strings.SplitN(mediaType, "/", 2)[0]]
	if ok {
		handler.ServeHTTP(w, r)
		return
	}

	// 3. Check if we have a */* handler

	handler, ok = route["*/*"]
	if ok {
		handler.ServeHTTP(w, r)
		return
	}

	// 4. Otherwise return "415 Unsupported Media Type"

	w.WriteHeader(http.StatusUnsupportedMediaType)
}

// Accept maps Accept header values to different handlers. This will attempt to
// match the acceptable content type with the highest requested quality and
// greatest specificity. A fallback of */* can be specified which will always
// match if no others do, otherwise a 406 Not Acceptable response is returned.
type Accept map[string]http.Handler

func (route Accept) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	accept := r.Header.Get("Accept")

	contentTypes := parseContentTypeList(accept)

	sort.Sort(byQuality(contentTypes))

	for _, ct := range contentTypes {
		for rout, handler := range route {
			rsplit := strings.Split(rout, "/")

			// 1. Check for exact match
			// 2. Check for subtype match
			// 3. Check for wildcard
			//
			// Since the contentTypes are ordered with wildcards below specifics we
			// can check in this order with no problems.
			if ct.Type == rsplit[0] && ct.Subtype == rsplit[1] ||
				ct.Type == rsplit[0] && ct.Subtype == "*" ||
				ct.Type == "*" && ct.Subtype == "*" {

				handler.ServeHTTP(w, r)
				return
			}
		}
	}

	if handler, ok := route["*/*"]; ok {
		handler.ServeHTTP(w, r)
		return
	}

	w.WriteHeader(http.StatusNotAcceptable)
}

type byQuality []clause

func (cs byQuality) Len() int {
	return len(cs)
}

func (cs byQuality) Swap(i, j int) {
	cs[i], cs[j] = cs[j], cs[i]
}

func (cs byQuality) Less(i, j int) bool {
	return cs[i].Quality > cs[j].Quality ||
		cs[i].Type != "*" && cs[j].Type == "*" ||
		cs[i].Subtype != "*" && cs[j].Subtype == "*"
}

type clause struct {
	Type    string
	Subtype string
	Quality float32
}

func parseContentTypeList(s string) []clause {
	s = strings.Trim(s, " ")
	if len(s) == 0 {
		return []clause{}
	}

	parts := strings.Split(s, ",")
	cts := make([]clause, 0, len(parts))
	for _, part := range parts {
		ct, ok := parseContentType(part)
		if !ok {
			continue
		}

		cts = append(cts, ct)
	}

	return cts
}

func parseContentType(s string) (clause, bool) {
	mediaType, params, err := mime.ParseMediaType(s)
	if err != nil {
		return clause{}, false
	}

	q := 1.0

	if qs, ok := params["q"]; ok {
		q, err = strconv.ParseFloat(qs, 32)
		if err != nil {
			return clause{}, false
		}
	}

	mediaTypeParts := strings.Split(mediaType, "/")
	if len(mediaTypeParts) != 2 {
		return clause{}, false
	}

	return clause{mediaTypeParts[0], mediaTypeParts[1], float32(q)}, true
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 Iori Mizutani
//
// Use of this source code is governed by The MIT License
// that can be found in the LICENSE file.

package golemu

import (
//"bytes"
//"encoding/gob"
)

// Tags holds a slice of pointers to Tag
type Tags []*Tag

// BuildTagReportDataStack takes []*Tag and PDU value to build a new trds
func (tags Tags) BuildTagReportDataStack(pdu int) TagReportDataStack {
	var param []byte
	var trd *TagReportData
	var trds TagReportDataStack
	si := 0 // stack count

	// Iterate through tags and divide them into TRD stacks
	for _, tag := range tags {
		// When exceeds maxTag per TRD, append another TRD in the stack
		// or maximum PDU=int(^uint(0)>>1)
		param = tag.BuildTagReportDataParameter()
		if len(trds) != 0 &&
			(10+len(trds[si].Parameter)+4+len(param) >= pdu || int(^uint(0)>>1) > pdu) {
			trd = &TagReportData{Parameter: param, TagCount: 1}
			trds = append(trds, trd)
			si++
		} else {
			if len(trds) == 0 {
				// First TRD
				trd = &TagReportData{Parameter: param, TagCount: 1}
				trds = []*TagReportData{trd}
			} else {
				// Append TRD to an existing TRD
				trds[si].Parameter = append(trds[si].Parameter, param...)
				trds[si].TagCount++
			}
		}
	}
	return trds
}

// GetIndexOfTag find the index in []*Tag
func (tags Tags) GetIndexOf(t *Tag) int {
	index := 0
	for _, tag := range tags {
		if tag.IsDuplicate(*t) {
			return index
		}
		index++
	}
	return -1
}

/*
// MarshalBinary overwrites the marshaller in gob encoding Tags
func (tags Tags) MarshalBinary() (_ []byte, err error) {
}

// UnmarshalBinary overwrites the unmarshaller in gob decoding Tags
func (tags Tags) UnmarshalBinary(data []byte) (err error) {
	return
}
*/

/*
func (tags Tags) writeTagsToCSV(output string) {
	file, err := os.Create(output)
	check(err)

	w := csv.NewWriter(file)
	for _, tag := range tags {
		record := []string{strconv.FormatUint(uint64(tag.PCBits), 16), strconv.FormatUint(uint64(tag.Length), 10), strconv.FormatUint(uint64(tag.EPCLengthBits), 10), hex.EncodeToString(tag.EPC)}
		if err := w.Write(record); err != nil {
			logger.Criticalf("Writing record to csv: %v", err.Error())
		}
		w.Flush()
		if err := w.Error(); err != nil {
			logger.Errorf(err.Error())
		}
	}
	file.Close()
}
*/
<commit_msg>add (un)marshaller for Tags type<commit_after>// Copyright (c) 2018 Iori Mizutani
//
// Use of this source code is governed by The MIT License
// that can be found in the LICENSE file.

package golemu

import (
	"bytes"
	"encoding/gob"
)

// Tags holds a slice of pointers to Tag
type Tags []*Tag

// BuildTagReportDataStack takes []*Tag and PDU value to build a new trds
func (tags Tags) BuildTagReportDataStack(pdu int) TagReportDataStack {
	var param []byte
	var trd *TagReportData
	var trds TagReportDataStack
	si := 0 // stack count

	// Iterate through tags and divide them into TRD stacks
	for _, tag := range tags {
		// When exceeds maxTag per TRD, append another TRD in the stack
		// or maximum PDU=int(^uint(0)>>1)
		param = tag.BuildTagReportDataParameter()
		if len(trds) != 0 &&
			(10+len(trds[si].Parameter)+4+len(param) >= pdu || int(^uint(0)>>1) > pdu) {
			trd = &TagReportData{Parameter: param, TagCount: 1}
			trds = append(trds, trd)
			si++
		} else {
			if len(trds) == 0 {
				// First TRD
				trd = &TagReportData{Parameter: param, TagCount: 1}
				trds = []*TagReportData{trd}
			} else {
				// Append TRD to an existing TRD
				trds[si].Parameter = append(trds[si].Parameter, param...)
				trds[si].TagCount++
			}
		}
	}
	return trds
}

// GetIndexOfTag find the index in []*Tag
func (tags Tags) GetIndexOf(t *Tag) int {
	index := 0
	for _, tag := range tags {
		if tag.IsDuplicate(*t) {
			return index
		}
		index++
	}
	return -1
}

// MarshalBinary overwrites the marshaller in gob encoding Tags
func (tags Tags) MarshalBinary() (_ []byte, err error) {
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)

	// Size of List
	enc.Encode(len(tags))
	for _, tag := range tags {
		// Tag
		enc.Encode(tag)
	}

	return buf.Bytes(), err
}

// UnmarshalBinary overwrites the unmarshaller in gob decoding Tags
func (tags Tags) UnmarshalBinary(data []byte) (err error) {
	dec := gob.NewDecoder(bytes.NewReader(data))

	// Size of Tags
	var tagsSize int
	if err = dec.Decode(&tagsSize); err != nil {
		return
	}

	for i := 0; i < tagsSize; i++ {
		var tag Tag
		// Tag
		if err = dec.Decode(&tag); err != nil {
			return
		}
		tags = append(tags, &tag)
	}

	return
}

/*
func (tags Tags) writeTagsToCSV(output string) {
	file, err := os.Create(output)
	check(err)

	w := csv.NewWriter(file)
	for _, tag := range tags {
		record := []string{strconv.FormatUint(uint64(tag.PCBits), 16), strconv.FormatUint(uint64(tag.Length), 10), strconv.FormatUint(uint64(tag.EPCLengthBits), 10), hex.EncodeToString(tag.EPC)}
		if err := w.Write(record); err != nil {
			logger.Criticalf("Writing record to csv: %v", err.Error())
		}
		w.Flush()
		if err := w.Error(); err != nil {
			logger.Errorf(err.Error())
		}
	}
	file.Close()
}
*/
<|endoftext|>


<commit_before>package now

import (
	"errors"
	"regexp"
	"time"
)

func (now *Now) BeginningOfMinute() time.Time {
	return now.Truncate(time.Minute)
}

func (now *Now) BeginningOfHour() time.Time {
	return now.Truncate(time.Hour)
}

func (now *Now) BeginningOfDay() time.Time {
	d := time.Duration(-now.Hour()) * time.Hour
	return now.Truncate(time.Hour).Add(d)
}

func (now *Now) BeginningOfWeek() time.Time {
	t := now.BeginningOfDay()
	weekday := int(t.Weekday())
	if FirstDayMonday {
		if weekday == 0 {
			weekday = 7
		}
		weekday = weekday - 1
	}

	d := time.Duration(-weekday) * 24 * time.Hour
	return t.Truncate(time.Hour).Add(d)
}

func (now *Now) BeginningOfMonth() time.Time {
	t := now.BeginningOfDay()
	d := time.Duration(-int(t.Day())+1) * 24 * time.Hour
	return t.Truncate(time.Hour).Add(d)
}

func (now *Now) BeginningOfYear() time.Time {
	t := now.BeginningOfDay()
	d := time.Duration(-int(t.YearDay())+1) * 24 * time.Hour
	return t.Truncate(time.Hour).Add(d)
}

func (now *Now) EndOfMinute() time.Time {
	return now.BeginningOfMinute().Add(time.Minute - time.Nanosecond)
}

func (now *Now) EndOfHour() time.Time {
	return now.BeginningOfHour().Add(time.Hour - time.Nanosecond)
}

func (now *Now) EndOfDay() time.Time {
	return now.BeginningOfDay().Add(24*time.Hour - time.Nanosecond)
}

func (now *Now) EndOfWeek() time.Time {
	return now.BeginningOfWeek().AddDate(0, 0, 7).Add(-time.Nanosecond)
}

func (now *Now) EndOfMonth() time.Time {
	return now.BeginningOfMonth().AddDate(0, 1, 0).Add(-time.Nanosecond)
}

func (now *Now) EndOfYear() time.Time {
	return now.BeginningOfYear().AddDate(1, 0, 0).Add(-time.Nanosecond)
}

func (now *Now) Monday() time.Time {
	t := now.BeginningOfDay()
	weekday := int(t.Weekday())
	if weekday == 0 {
		weekday = 7
	}
	d := time.Duration(-weekday+1) * 24 * time.Hour
	return t.Truncate(time.Hour).Add(d)
}

func (now *Now) Sunday() time.Time {
	t := now.BeginningOfDay()
	weekday := int(t.Weekday())
	if weekday == 0 {
		return t
	} else {
		d := time.Duration(7-weekday) * 24 * time.Hour
		return t.Truncate(time.Hour).Add(d)
	}
}

func (now *Now) EndOfSunday() time.Time {
	return now.Sunday().Add(24*time.Hour - time.Nanosecond)
}

func (now *Now) Parse(str string) (t time.Time, err error) {
	formats := []string{"2006-01-02 15:04:05", "2006-01-02 15:04", "2006-01-02", "01-02", "15:04:05", "15:04", "15"}

	parseTime := []int{}
	currentTime := []int{now.Second(), now.Minute(), now.Hour(), now.Day(), int(now.Month()), now.Year()}
	currentLocation := now.Location()
	hasDate := regexp.MustCompile(`-\d`).MatchString(str)

	for _, format := range formats {
		t, e := time.Parse(format, str)
		if e == nil {
			parseTime = []int{t.Second(), t.Minute(), t.Hour(), t.Day(), int(t.Month()), t.Year()}

			var setCurrentTime bool
			for i, v := range parseTime {
				// Fill up missed information with current time
				if v == 0 {
					if setCurrentTime {
						parseTime[i] = currentTime[i]
					}
				} else {
					setCurrentTime = true
				}

				// Default day and month is 1, fill up it if missing it
				if (i == 3 || i == 4) && !hasDate {
					parseTime[i] = currentTime[i]
				}
			}
			break
		}
	}

	if len(parseTime) > 0 {
		t = time.Date(parseTime[5], time.Month(parseTime[4]), parseTime[3], parseTime[2], parseTime[1], parseTime[0], 0, currentLocation)
	} else {
		err = errors.New("Can't parse string: " + str)
	}
	return
}

func (now *Now) MustParse(str string) (t time.Time) {
	t, err := now.Parse(str)
	if err != nil {
		panic(err)
	}
	return t
}
<commit_msg>Format Parse method<commit_after>package now

import (
	"errors"
	"regexp"
	"time"
)

func (now *Now) BeginningOfMinute() time.Time {
	return now.Truncate(time.Minute)
}

func (now *Now) BeginningOfHour() time.Time {
	return now.Truncate(time.Hour)
}

func (now *Now) BeginningOfDay() time.Time {
	d := time.Duration(-now.Hour()) * time.Hour
	return now.Truncate(time.Hour).Add(d)
}

func (now *Now) BeginningOfWeek() time.Time {
	t := now.BeginningOfDay()
	weekday := int(t.Weekday())
	if FirstDayMonday {
		if weekday == 0 {
			weekday = 7
		}
		weekday = weekday - 1
	}

	d := time.Duration(-weekday) * 24 * time.Hour
	return t.Truncate(time.Hour).Add(d)
}

func (now *Now) BeginningOfMonth() time.Time {
	t := now.BeginningOfDay()
	d := time.Duration(-int(t.Day())+1) * 24 * time.Hour
	return t.Truncate(time.Hour).Add(d)
}

func (now *Now) BeginningOfYear() time.Time {
	t := now.BeginningOfDay()
	d := time.Duration(-int(t.YearDay())+1) * 24 * time.Hour
	return t.Truncate(time.Hour).Add(d)
}

func (now *Now) EndOfMinute() time.Time {
	return now.BeginningOfMinute().Add(time.Minute - time.Nanosecond)
}

func (now *Now) EndOfHour() time.Time {
	return now.BeginningOfHour().Add(time.Hour - time.Nanosecond)
}

func (now *Now) EndOfDay() time.Time {
	return now.BeginningOfDay().Add(24*time.Hour - time.Nanosecond)
}

func (now *Now) EndOfWeek() time.Time {
	return now.BeginningOfWeek().AddDate(0, 0, 7).Add(-time.Nanosecond)
}

func (now *Now) EndOfMonth() time.Time {
	return now.BeginningOfMonth().AddDate(0, 1, 0).Add(-time.Nanosecond)
}

func (now *Now) EndOfYear() time.Time {
	return now.BeginningOfYear().AddDate(1, 0, 0).Add(-time.Nanosecond)
}

func (now *Now) Monday() time.Time {
	t := now.BeginningOfDay()
	weekday := int(t.Weekday())
	if weekday == 0 {
		weekday = 7
	}
	d := time.Duration(-weekday+1) * 24 * time.Hour
	return t.Truncate(time.Hour).Add(d)
}

func (now *Now) Sunday() time.Time {
	t := now.BeginningOfDay()
	weekday := int(t.Weekday())
	if weekday == 0 {
		return t
	} else {
		d := time.Duration(7-weekday) * 24 * time.Hour
		return t.Truncate(time.Hour).Add(d)
	}
}

func (now *Now) EndOfSunday() time.Time {
	return now.Sunday().Add(24*time.Hour - time.Nanosecond)
}

func parseWithFormat(str string) (t time.Time, err error) {
	formats := []string{"2006-01-02 15:04:05", "2006-01-02 15:04", "2006-01-02", "01-02", "15:04:05", "15:04", "15"}
	for _, format := range formats {
		t, err = time.Parse(format, str)
		if err == nil {
			return
		}
	}
	err = errors.New("Can't parse string: " + str)
	return
}

func (now *Now) Parse(str string) (t time.Time, err error) {

	parseTime := []int{}
	currentTime := []int{now.Second(), now.Minute(), now.Hour(), now.Day(), int(now.Month()), now.Year()}
	currentLocation := now.Location()
	hasDate := regexp.MustCompile(`-\d`).MatchString(str)

	t, err = parseWithFormat(str)
	if err == nil {
		parseTime = []int{t.Second(), t.Minute(), t.Hour(), t.Day(), int(t.Month()), t.Year()}

		var setCurrentTime bool
		for i, v := range parseTime {
			// Fill up missed information with current time
			if v == 0 {
				if setCurrentTime {
					parseTime[i] = currentTime[i]
				}
			} else {
				setCurrentTime = true
			}

			// Default day and month is 1, fill up it if missing it
			if (i == 3 || i == 4) && !hasDate {
				parseTime[i] = currentTime[i]
			}
		}
	}

	if len(parseTime) > 0 {
		t = time.Date(parseTime[5], time.Month(parseTime[4]), parseTime[3], parseTime[2], parseTime[1], parseTime[0], 0, currentLocation)
	}
	return
}

func (now *Now) MustParse(str string) (t time.Time) {
	t, err := now.Parse(str)
	if err != nil {
		panic(err)
	}
	return t
}
<|endoftext|>


<commit_before>package meritop

// These interface is useful for safety check.
type TGMeta interface {
	EpochID() uint64
	TaskID() uint64
	FromTaskID() uint64
	UUID() uint64
}

// Task is a logic repersentation of a computing unit.
// Each task contain at least one Node.
// Each task has exact one master Node and might have multiple salve Nodes.
type Task interface {
	// This is useful to bring the task up to speed from scratch or if it recovers.
	Init(taskID uint64, framework Framework, config Config)

	// Task need to finish up for exit, last chance to save work?
	Exit()

	// These are called by framework implementation so that task implementation can
	// reacts to parent or children restart.
	ParentRestart(parentID uint64)
	ChildRestart(childID uint64)

	ParentDie(parentID uint64)
	ChildDie(childID uint64)

	// Ideally, we should also have the following:
	ParentReady(parentID uint64, meta TGMeta)
	ChildReady(childID uint64, meta TGMeta)

	// This give the task an opportunity to cleanup and regroup.
	SetEpoch(epochID uint64)

	// These are payload for application purpose.
	ServeAsParent(req TGMeta) TGMeta
	ServeAsChild(reg TGMeta) TGMeta

	ParentDataReady(req, response TGMeta)
	ChildDataReady(req, response TGMeta)
}

// Backupable is an interface that task need to implement if they want to have
// hot standby copy. This is another can of beans.
type Backupable interface {
	// Some hooks that need for master slave etc.
	BecameMaster()
	BecameBackup()
}
<commit_msg>Add payload rpc interface<commit_after>package meritop

// These interface is useful for safety check, TG stands for TaskGraph.
type TGMeta interface {
	EpochID() uint64
	ToTaskID() uint64
	FromTaskID() uint64
	SetToTaskID(toID uint64)
	SetFromTaskID(fromID uint64)
	UUID() uint64
}

// Task is a logic repersentation of a computing unit.
// Each task contain at least one Node.
// Each task has exact one master Node and might have multiple salve Nodes.
type Task interface {
	// This is useful to bring the task up to speed from scratch or if it recovers.
	Init(taskID uint64, framework Framework, config Config)

	// Task need to finish up for exit, last chance to save work?
	Exit()

	// These are called by framework implementation so that task implementation can
	// reacts to parent or children restart.
	ParentRestart(parentID uint64)
	ChildRestart(childID uint64)

	ParentDie(parentID uint64)
	ChildDie(childID uint64)

	// Ideally, we should also have the following:
	ParentReady(parentID uint64, meta TGMeta)
	ChildReady(childID uint64, meta TGMeta)

	// This give the task an opportunity to cleanup and regroup.
	SetEpoch(epochID uint64)

	// These are payload for application purpose.
	ServeAsParent(req TGMeta) TGMeta
	ServeAsChild(reg TGMeta) TGMeta

	ParentDataReady(req, response TGMeta)
	ChildDataReady(req, response TGMeta)
}

// Backupable is an interface that task need to implement if they want to have
// hot standby copy. This is another can of beans.
type Backupable interface {
	// Some hooks that need for master slave etc.
	BecameMaster()
	BecameBackup()
}
<|endoftext|>


<commit_before>package php

import (
	"strconv"
)

func IsNumeric(x interface{}) bool {

	// Initialize
		result := false

	// Figure out result
		switch x.(type) {
			default:
				result = false

			case uint8:
				result = true
			case uint16:
				result = true
			case uint32:
				result = true
			case uint64:
				result = true

			case int8:
				result = true
			case int16:
				result = true
			case int32:
				result = true
			case int64:
				result = true

			case float32:
				result = true
			case float64:
				result = true

			case complex64:
				result = true
			case complex128:
				result = true

			//case byte:
			//	result = true
			//case rune:
			//	result = true

			case uint:
				result = true
			case int:
				result = true

			case string:
				if xAsString, ok := x.(string); ok {
					result = isStringNumeric( xAsString )
				} else {
					result = false
				}
		} // switch

	// Return.
		return result
}

func isStringNumeric(x string) bool {

	result := true

	isFirstLoop := true

	hasPeriod := false

	for i, c := range x {

		switch c {
			default:
				result = false; return result

			case '-':
				if isFirstLoop {
					// Nothing here.
				} else {
					result = false; return result
				}

			case '.':
				if hasPeriod {
					result = false; return result
				}

				if isFirstLoop {
					result = false; return result
				}

				if len(x) == 1+i {
					result = false; return result
				}

				hasPeriod = true

			case '0': // Nothing here.
			case '1': // Nothing here.
			case '2': // Nothing here.
			case '3': // Nothing here.
			case '4': // Nothing here.
			case '5': // Nothing here.
			case '6': // Nothing here.
			case '7': // Nothing here.
			case '8': // Nothing here.
			case '9': // Nothing here.
		} // switch

		isFirstLoop = false

	} // for

	return result
}
<commit_msg>removed unused import<commit_after>package php

func IsNumeric(x interface{}) bool {

	// Initialize
		result := false

	// Figure out result
		switch x.(type) {
			default:
				result = false

			case uint8:
				result = true
			case uint16:
				result = true
			case uint32:
				result = true
			case uint64:
				result = true

			case int8:
				result = true
			case int16:
				result = true
			case int32:
				result = true
			case int64:
				result = true

			case float32:
				result = true
			case float64:
				result = true

			case complex64:
				result = true
			case complex128:
				result = true

			//case byte:
			//	result = true
			//case rune:
			//	result = true

			case uint:
				result = true
			case int:
				result = true

			case string:
				if xAsString, ok := x.(string); ok {
					result = isStringNumeric( xAsString )
				} else {
					result = false
				}
		} // switch

	// Return.
		return result
}

func isStringNumeric(x string) bool {

	result := true

	isFirstLoop := true

	hasPeriod := false

	for i, c := range x {

		switch c {
			default:
				result = false; return result

			case '-':
				if isFirstLoop {
					// Nothing here.
				} else {
					result = false; return result
				}

			case '.':
				if hasPeriod {
					result = false; return result
				}

				if isFirstLoop {
					result = false; return result
				}

				if len(x) == 1+i {
					result = false; return result
				}

				hasPeriod = true

			case '0': // Nothing here.
			case '1': // Nothing here.
			case '2': // Nothing here.
			case '3': // Nothing here.
			case '4': // Nothing here.
			case '5': // Nothing here.
			case '6': // Nothing here.
			case '7': // Nothing here.
			case '8': // Nothing here.
			case '9': // Nothing here.
		} // switch

		isFirstLoop = false

	} // for

	return result
}
<|endoftext|>


<commit_before>package r

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"mime/multipart"
	"net/http"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/gorilla/mux"
)

var r *rand.Rand
var rootDir string

type Session struct {
	Key     string
	Dir     string
	Output  string
	Command string
}

type RCall struct {
	Package   string
	Function  string
	Arguments string
}

func Init(dir, packages string) error {
	r = rand.New(rand.NewSource(time.Now().UnixNano()))
	rootDir = dir

	if packages != "" {
		err := installPackages(packages)
		return err
	}
	return nil
}

// Installs the given packages on the server. packages is a space
// separated list with the packages.
func installPackages(packages string) error {
	cmd := exec.Command("R", "-q", "-e", "install.packages(c("+packages+"),  repos='http://cran.us.r-project.org')")

	var out bytes.Buffer
	cmd.Stdout = &out

	fmt.Println(out.String())
	err := cmd.Run()
	if err != nil {
		fmt.Println("Could not install packages:", out.String())
		return err
	}
	return nil
}

// Installs the package found at src. Should be a tgz ball.
func InstallPackageFromSource(src string) (string, error) {

	cmd := exec.Command("R", "CMD", "INSTALL", src)

	var out bytes.Buffer
	cmd.Stdout = &out

	err := cmd.Run()
	if err != nil {
		fmt.Println("Could not install local package:", out.String())
		return "", err
	}
	return out.String(), nil

}

// Executes function. Returns tmp key for use in Get
func Call(pkg, fun, args string) (*Session, error) {

	h := md5.New()
	k := h.Sum([]byte(strconv.Itoa(r.Int())))

	hash := hex.EncodeToString(k)
	key := ".s" + hash

	wd := rootDir + "/" + key
	err := os.MkdirAll(wd, 0755)
	if err != nil {
		return nil, err
	}

	err = os.Chdir(wd)

	if err != nil {
		return nil, err
	}

	// Replace argument names with real argument names using the
	// keys from previous calls. Also load data from previous
	// calls before running cmd

	argList := strings.Split(args, ",")
	loadArgs := []string{}

	if argList[0] != "" {
		finalArgs := []string{}

		for _, arg := range argList {
			argName := strings.Split(arg, "=")[0]
			argVal := strings.Split(arg, "=")[1]
			if strings.HasPrefix(argVal, ".s") {
				loadArgs = append(loadArgs, "load('"+rootDir+"/"+argVal+"/.RData');")

				argVal = strings.TrimPrefix(argVal, ".")

			}
			finalArgs = append(finalArgs, argName+"="+argVal)
		}

		args = strings.Join(finalArgs, ",")
	}

	varName := strings.TrimPrefix(key, ".")
	command := varName + "=" + pkg + "::" + fun + "(" + args + "); " + varName

	if len(loadArgs) > 0 {
		loadString := strings.Join(loadArgs, "")
		command = loadString + command
	}

	cmd := exec.Command("R", "--save", "-q", "-e", command)
	cmd.Dir = wd

	var out bytes.Buffer
	cmd.Stdout = &out

	err = cmd.Run()

	return &Session{key, wd, out.String(), command}, err
}

// get results for a func call
func Get(key, format string) ([]byte, error) {

	dir := rootDir + "/" + key
	err := os.Chdir(dir)
	if err != nil {
		return nil, err
	}

	varName := strings.TrimPrefix(key, ".")

	extension := "." + format
	_, err = os.Stat("output" + extension)
	if err == nil {
		return ioutil.ReadFile(dir + "/output" + extension)
	}

	var command string
	if format == "csv" {
		command = "write.csv(" + varName + ", sep=',', file='output" + extension + "')"
	} else if format == "json" {
		command = "js=jsonlite::toJSON(" + varName + "); write(js, file='output" + extension + "')"
	} else if format == "pdf" {
		return ioutil.ReadFile(dir + "/Rplots.pdf")
	} else {
		return nil, errors.New("Unknown format")
	}

	cmd := exec.Command("R", "--save", "-q", "-e", command)
	cmd.Dir = dir

	var out bytes.Buffer
	cmd.Stdout = &out

	err = cmd.Run()

	if err != nil {
		fmt.Println("ERROR", out.String())
		return nil, err
	}

	return ioutil.ReadFile(dir + "/output" + extension)

}

type Server struct {
	Addr     string
	Username string
	Server   string
}

// Remote call.
func (s *Server) Call(pkg, fun, args string) (string, error) {
	url := "http://" + s.Addr + "/call"

	c := RCall{pkg, fun, args}

	b, err := json.Marshal(c)
	if err != nil {
		fmt.Println(err)
		return "", err
	}

	postArgs := strings.NewReader(string(b))

	resp, err := http.Post(url, "application/json", postArgs)
	if err != nil {
		return "", err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	return string(body), nil
}

// Remote get results
func (s *Server) Get(key, format string) ([]byte, error) {

	resp, err := http.Get("http://" + s.Addr + "/get/" + key + "/" + format)
	if err != nil {
		return []byte{}, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return []byte{}, err
	}

	return body, nil

}

// Uploads and installs package to remote R Server
func (s *Server) UploadPackage(src string) error {
	file, err := os.Open(src)
	if err != nil {
		return err
	}
	fileContents, err := ioutil.ReadAll(file)
	if err != nil {
		return err
	}
	fi, err := file.Stat()
	if err != nil {
		return err
	}
	file.Close()
	body := new(bytes.Buffer)
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile("file", fi.Name())
	if err != nil {
		return err
	}
	part.Write(fileContents)
	err = writer.Close()
	if err != nil {
		return err
	}

	url := "http://" + s.Addr + "/install"

	request, err := http.NewRequest("POST", url, body)
	if err != nil {
		return err
	}
	request.Header.Add("Content-Type", writer.FormDataContentType())

	client := &http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		return err
	}

	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	fmt.Println("Response:", string(responseBody))
	return nil
}

var cache map[string]string
var logTime = "02-01-2006 15:04:05.000"

func CallHandler(w http.ResponseWriter, r *http.Request) {
	printTime()

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Fprintf(w, "Call failed %s", err)
		fmt.Println(err)
		return
	}

	call := RCall{}
	err = json.Unmarshal(body, &call)
	if err != nil {
		fmt.Fprintf(w, "Call failed. %s", body)
		fmt.Println(err)
		return
	}

	fmt.Println("Call:", call.Package, call.Function, call.Arguments)

	cacheKey := call.Package + call.Function + call.Arguments

	if cache[cacheKey] != "" {
		printTime()
		fmt.Println("CACHE HIT")
		w.Write([]byte(cache[cacheKey]))
		return
	} else {
		printTime()
		fmt.Println("CACHE MISS")
	}

	s, err := Call(call.Package, call.Function, call.Arguments)
	if err != nil {
		fmt.Println("ERROR", err)
		fmt.Println(s.Output)
		fmt.Fprintf(w, "Call failed. %s returned %s", s.Output, err)
		return
	}

	if cache == nil {
		cache = make(map[string]string, 0)
	}

	cache[cacheKey] = s.Key

	w.Write([]byte(s.Key))

}

func GetHandler(w http.ResponseWriter, r *http.Request) {
	printTime()
	vars := mux.Vars(r)
	key := vars["key"]
	format := vars["format"]

	fmt.Println("Get: key:", key, "format", format)

	res, err := Get(key, format)

	if err != nil {
		fmt.Println(err)
		fmt.Println(string(res))
		w.Write([]byte(err.Error()))
		return
	}

	w.Write(res)
}

func IndexHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Nothing to see here. Try /call, /get/{key}/{format} or /install"))
}

func InstallHandler(w http.ResponseWriter, r *http.Request) {
	file, header, err := r.FormFile("file")
	defer file.Close()

	if err != nil {
		fmt.Fprintln(w, err)
		return
	}

	fileLoc := "/tmp/file"

	out, err := os.Create(fileLoc)
	if err != nil {
		fmt.Fprintf(w, "Failed to open the file for writing")
		return
	}
	defer out.Close()
	_, err = io.Copy(out, file)
	if err != nil {
		fmt.Fprintln(w, err)
		return
	}

	printTime()
	fmt.Println("Installing package", header.Filename)

	output, err := InstallPackageFromSource(fileLoc)
	if err != nil {
		fmt.Fprintln(w, err)
		return
	}

	fmt.Fprintf(w, "%s", output)

}

func printTime() {
	fmt.Print(time.Now().Format(logTime), " ")
}

func StartServer(port, tmpDir string) error {
	err := Init("/tmp/kvik", "")
	if err != nil {
		fmt.Println(err)
		return err
	}

	r := mux.NewRouter()

	r.HandleFunc("/", IndexHandler)
	r.HandleFunc("/call", CallHandler)
	r.HandleFunc("/get/{key}/{format}", GetHandler)
	r.HandleFunc("/install", InstallHandler)

	http.Handle("/", r)

	printTime()
	fmt.Println("Starting server at ", port)

	return http.ListenAndServe(port, r)

}
<commit_msg>update r server<commit_after>package r

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"mime/multipart"
	"net/http"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/gorilla/mux"
)

var r *rand.Rand
var rootDir string

type Session struct {
	Key     string
	Dir     string
	Output  string
	Command string
}

type RCall struct {
	Package   string
	Function  string
	Arguments string
}

func Init(dir, packages string) error {
	r = rand.New(rand.NewSource(time.Now().UnixNano()))
	rootDir = dir

	if packages != "" {
		err := installPackages(packages)
		return err
	}
	return nil
}

// Installs the given packages on the server. packages is a space
// separated list with the packages.
func installPackages(packages string) error {
	cmd := exec.Command("R", "-q", "-e", "install.packages(c("+packages+"),  repos='http://cran.us.r-project.org')")

	var out bytes.Buffer
	cmd.Stdout = &out

	fmt.Println(out.String())
	err := cmd.Run()
	if err != nil {
		fmt.Println("Could not install packages:", out.String())
		return err
	}
	return nil
}

// Installs the package found at src. Should be a tgz ball.
func InstallPackageFromSource(src string) (string, error) {

	cmd := exec.Command("R", "CMD", "INSTALL", src)

	var out bytes.Buffer
	cmd.Stdout = &out

	err := cmd.Run()
	if err != nil {
		fmt.Println("Could not install local package:", out.String())
		return "", err
	}
	return out.String(), nil

}

// Executes function. Returns tmp key for use in Get
func Call(pkg, fun, args string) (*Session, error) {

	h := md5.New()
	k := h.Sum([]byte(strconv.Itoa(r.Int())))

	hash := hex.EncodeToString(k)
	key := ".s" + hash

	wd := rootDir + "/" + key
	err := os.MkdirAll(wd, 0755)
	if err != nil {
		return nil, err
	}

	err = os.Chdir(wd)

	if err != nil {
		return nil, err
	}

	// Replace argument names with real argument names using the
	// keys from previous calls. Also load data from previous
	// calls before running cmd

	argList := strings.Split(args, ",")
	loadArgs := []string{}

	if argList[0] != "" {
		finalArgs := []string{}

		for _, arg := range argList {

			// special case when we use a column vector as argument value
			// e,g. d = c(2,1,3,4) only d=c(2, is added. we need to
			// append the rest to get the full vector.
			if len(strings.Split(arg, "=")) == 1 {
				finalArgs[len(finalArgs)-1] = finalArgs[len(finalArgs)-1] + "," + arg
				continue
			}

			argName := strings.Split(arg, "=")[0]
			argVal := strings.Split(arg, "=")[1]
			if strings.HasPrefix(argVal, ".s") {
				loadArgs = append(loadArgs, "load('"+rootDir+"/"+argVal+"/.RData');")

				argVal = strings.TrimPrefix(argVal, ".")

			}
			finalArgs = append(finalArgs, argName+"="+argVal)
		}

		args = strings.Join(finalArgs, ",")
	}

	varName := strings.TrimPrefix(key, ".")
	command := varName + "=" + pkg + "::" + fun + "(" + args + "); " + varName

	if len(loadArgs) > 0 {
		loadString := strings.Join(loadArgs, "")
		command = loadString + command
	}

	cmd := exec.Command("R", "--save", "-q", "-e", command)
	cmd.Dir = wd

	var out bytes.Buffer
	cmd.Stdout = &out

	err = cmd.Run()

	return &Session{key, wd, out.String(), command}, err
}

// get results for a func call
func Get(key, format string) ([]byte, error) {

	dir := rootDir + "/" + key
	err := os.Chdir(dir)
	if err != nil {
		return nil, err
	}

	varName := strings.TrimPrefix(key, ".")

	extension := "." + format
	_, err = os.Stat("output" + extension)
	if err == nil {
		return ioutil.ReadFile(dir + "/output" + extension)
	}

	var command string
	if format == "csv" {
		command = "write.table(" + varName + ", sep=',', row.names=FALSE, file='output" + extension + "')"
	} else if format == "json" {
		command = "js=jsonlite::toJSON(" + varName + "); write(js, file='output" + extension + "')"
	} else if format == "pdf" {
		return ioutil.ReadFile(dir + "/Rplots.pdf")
	} else if format == "png" {
		cmd := exec.Command("pdftoppm", "-png", dir+"/Rplots.pdf", "plot")

		var out bytes.Buffer
		cmd.Stdout = &out

		err := cmd.Run()
		if err != nil {
			fmt.Println("Could not convert rplot to png:", out.String())
			return nil, err
		}

		return ioutil.ReadFile(dir + "/plot-1.png")
	} else {
		return nil, errors.New("Unknown format")
	}

	cmd := exec.Command("R", "--save", "-q", "-e", command)
	cmd.Dir = dir

	var out bytes.Buffer
	cmd.Stdout = &out

	err = cmd.Run()

	if err != nil {
		fmt.Println("ERROR", out.String())
		return nil, err
	}

	return ioutil.ReadFile(dir + "/output" + extension)

}

type Server struct {
	Addr     string
	Username string
	Server   string
}

// Remote call.
func (s *Server) Call(pkg, fun, args string) (string, error) {
	url := "http://" + s.Addr + "/call"

	c := RCall{pkg, fun, args}

	b, err := json.Marshal(c)
	if err != nil {
		fmt.Println(err)
		return "", err
	}

	postArgs := strings.NewReader(string(b))

	resp, err := http.Post(url, "application/json", postArgs)
	if err != nil {
		return "", err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	if strings.Contains(string(body), "exit status 1") {
		return "exit status 1", errors.New(string(body))
	}

	return string(body), nil
}

// Remote get results
func (s *Server) Get(key, format string) ([]byte, error) {

	resp, err := http.Get("http://" + s.Addr + "/get/" + key + "/" + format)
	if err != nil {
		return []byte{}, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return []byte{}, err
	}

	return body, nil

}

// Uploads and installs package to remote R Server
func (s *Server) UploadPackage(src string) error {
	file, err := os.Open(src)
	if err != nil {
		return err
	}
	fileContents, err := ioutil.ReadAll(file)
	if err != nil {
		return err
	}
	fi, err := file.Stat()
	if err != nil {
		return err
	}
	file.Close()
	body := new(bytes.Buffer)
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile("file", fi.Name())
	if err != nil {
		return err
	}
	part.Write(fileContents)
	err = writer.Close()
	if err != nil {
		return err
	}

	url := "http://" + s.Addr + "/install"

	request, err := http.NewRequest("POST", url, body)
	if err != nil {
		return err
	}
	request.Header.Add("Content-Type", writer.FormDataContentType())

	client := &http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		return err
	}

	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	fmt.Println("Response:", string(responseBody))
	return nil
}

var cache map[string]string
var logTime = "02-01-2006 15:04:05.000"

func CallHandler(w http.ResponseWriter, r *http.Request) {
	printTime()

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Fprintf(w, "Call failed %s", err)
		fmt.Println(err)
		return
	}

	call := RCall{}
	err = json.Unmarshal(body, &call)
	if err != nil {
		fmt.Fprintf(w, "Call failed. %s", body)
		fmt.Println(err)
		return
	}

	fmt.Println("Call:", call.Package, call.Function, call.Arguments)

	cacheKey := call.Package + call.Function + call.Arguments

	if cache[cacheKey] != "" {
		printTime()
		fmt.Println("CACHE HIT")
		w.Write([]byte(cache[cacheKey]))
		return
	} else {
		printTime()
		fmt.Println("CACHE MISS")
	}

	s, err := Call(call.Package, call.Function, call.Arguments)
	if err != nil {
		fmt.Println("ERROR", err)
		fmt.Println(s.Output)
		fmt.Fprintf(w, "Call failed. %s returned %s", s.Output, err)
		return
	}

	if cache == nil {
		cache = make(map[string]string, 0)
	}

	cache[cacheKey] = s.Key

	w.Write([]byte(s.Key))

}

func GetHandler(w http.ResponseWriter, r *http.Request) {
	printTime()
	vars := mux.Vars(r)
	key := vars["key"]
	format := vars["format"]

	fmt.Println("Get: key:", key, "format", format)

	res, err := Get(key, format)

	if err != nil {
		fmt.Println(err)
		fmt.Println(string(res))
		w.Write([]byte(err.Error()))
		return
	}

	w.Write(res)
}

func IndexHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Nothing to see here. Try /call, /get/{key}/{format} or /install"))
}

func InstallHandler(w http.ResponseWriter, r *http.Request) {
	file, header, err := r.FormFile("file")
	defer file.Close()

	if err != nil {
		fmt.Fprintln(w, err)
		return
	}

	fileLoc := "/tmp/file"

	out, err := os.Create(fileLoc)
	if err != nil {
		fmt.Fprintf(w, "Failed to open the file for writing")
		return
	}
	defer out.Close()
	_, err = io.Copy(out, file)
	if err != nil {
		fmt.Fprintln(w, err)
		return
	}

	printTime()
	fmt.Println("Installing package", header.Filename)

	output, err := InstallPackageFromSource(fileLoc)
	if err != nil {
		fmt.Fprintln(w, err)
		return
	}

	fmt.Fprintf(w, "%s", output)

}

func printTime() {
	fmt.Print(time.Now().Format(logTime), " ")
}

func StartServer(port, tmpDir string) error {
	err := Init("/tmp/kvik", "")
	if err != nil {
		fmt.Println(err)
		return err
	}

	r := mux.NewRouter()

	r.HandleFunc("/", IndexHandler)
	r.HandleFunc("/call", CallHandler)
	r.HandleFunc("/get/{key}/{format}", GetHandler)
	r.HandleFunc("/install", InstallHandler)

	http.Handle("/", r)

	printTime()
	fmt.Println("Starting server at ", port)

	return http.ListenAndServe(port, r)

}
<|endoftext|>


<commit_before>package rio

import (
	"go.polydawn.net/rio/fs"
)

// A content-addressable Ware ID.
// Serialized as a string "kind:hash" -- Kinds are a whitelist and hashes also must avoid special chars.
//
// A ware is a packed filesystem.
// It contains one or more files and directories, and metadata for each.
//
// You can expect to enumerate the standard metadata for any ware.
// For some formats, traversing to inner bits of ware for extraction will be efficient;
// for most, the unit of fetch is the entire ware, so asking for a subpath is not consequential.
type WareID struct {
	Kind string
	Hash string
}

type WarehouseAddr struct{}

type WarehouseDialer interface {
	Ping(WarehouseAddr) (writable bool, err error)
	NewAgent(WarehouseAddr) (WarehouseAgent, error)
}

type Justification struct{}

type WarehouseAgent interface {
	Has(WareID) (bool, Justification, error)

	CanWrite() bool

	// Modify the warehouse to contain the requested WareID,
	// tagging it immediately with the given Justification,
	// fetching from any (or all, if the protocols are smart enough)
	// of the sources in the given WarehouseAddr list.
	//
	// Mirroring locally is also just a special case of 'Put':
	//  `dialer.NewAgent("./mirror/").Put(theWare, reasons, publicMirror)`.
	Put(WareID, Justification, sources []WarehouseAgent) error
}

type Transmat interface {
	Materialize(path fs.AbsolutePath, WareID, sources []WarehouseAgent, caches []Depot) error
	Scan(path fs.AbsolutePath, destination WarehouseAgent) (WareID, error)
}

// A local filesystem area where CAS caching is maintained.
type Depot struct {
	base fs.AbsolutePath
}

// Helper that yields the path to the ware,
// getting it directly from the Depot if already present,
// or invoking the transmat to get it into the Depot if necessary.
func (d *Depot) YieldFilesystem(WareID, Transmat) (fs.AbsolutePath, error) {
	return fs.MustAbsolutePath("/"), nil
}
<commit_msg>Propose more args to transmat methods to describe how concurrency is going to go.<commit_after>package rio

import (
	"context"

	"go.polydawn.net/rio/fs"
)

// A content-addressable Ware ID.
// Serialized as a string "kind:hash" -- Kinds are a whitelist and hashes also must avoid special chars.
//
// A ware is a packed filesystem.
// It contains one or more files and directories, and metadata for each.
//
// You can expect to enumerate the standard metadata for any ware.
// For some formats, traversing to inner bits of ware for extraction will be efficient;
// for most, the unit of fetch is the entire ware, so asking for a subpath is not consequential.
type WareID struct {
	Kind string
	Hash string
}

type WarehouseAddr struct{}

type WarehouseDialer interface {
	Ping(WarehouseAddr) (writable bool, err error)
	NewAgent(WarehouseAddr) (WarehouseAgent, error)
}

type Justification struct{}

type WarehouseAgent interface {
	Has(WareID) (bool, Justification, error)

	CanWrite() bool

	// Modify the warehouse to contain the requested WareID,
	// tagging it immediately with the given Justification,
	// fetching from any (or all, if the protocols are smart enough)
	// of the sources in the given WarehouseAddr list.
	//
	// Mirroring locally is also just a special case of 'Put':
	//  `dialer.NewAgent("./mirror/").Put(theWare, reasons, publicMirror)`.
	Put(WareID, Justification, sources []WarehouseAgent) error
}

type Transmat interface {
	Materialize(
		ctx context.Context, // Long-running call.  Cancellable.
		path fs.AbsolutePath, // Where to put a filesystem.
		wareID WareID, // What filesystem slice ware to unpack.
		sources []WarehouseAgent, // Warehouses we can talk to.
		monitor MaterializeMonitor, // Optionally: callbacks for progress monitoring.
	) error
	Scan(
		ctx context.Context, // Long-running call.  Cancellable.
		path fs.AbsolutePath, // What path to scan contents of.
		destination WarehouseAgent, // Warehouse to upload to.  (Use mirroring later for multiple warehouses.)
		monitor ScanMonitor, // Optionally: callbacks for progress monitoring.
	) (WareID, error)
}
type MaterializeMonitor interface {
	Progress(at, max int)
}
type ScanMonitor interface {
	Progress(at, max int)
}

// A local filesystem area where CAS caching is maintained.
type Depot struct {
	base fs.AbsolutePath
}

// Helper that yields the path to the ware,
// getting it directly from the Depot if already present,
// or invoking the transmat to get it into the Depot if necessary.
func (d *Depot) YieldFilesystem(WareID, Transmat) (fs.AbsolutePath, error) {
	return fs.MustAbsolutePath("/"), nil
}
<|endoftext|>


<commit_before>// An library for playing the classic game of Rock, Paper, Scissors, intended as a learning tool.
package rps

import (
	"math/rand"
)

const (
	// Hands
	Rock int = iota
	Paper
	Scissors

	// Results
	WinP1
	WinP2
	Tie
)

// RandomHand returns a random Hand.
func RandomHand() int {
	return rand.Intn(3)
}

// Play a single game of Rock, Paper, Scissors and return the result.
func Play(p1, p2 int) int {
	switch {
	case p1 == p2:
		return Tie
	case (p1 == Rock && p2 != Paper),
		(p1 == Paper && p2 != Scissors),
		(p1 == Scissors && p2 != Rock):
		return WinP1
	default:
		return WinP2
	}
}
<commit_msg>Use untyped constants<commit_after>// An library for playing the classic game of Rock, Paper, Scissors, intended as a learning tool.
package rps

import (
	"math/rand"
)

const (
	// Hands
	Rock = iota
	Paper
	Scissors

	// Results
	WinP1
	WinP2
	Tie
)

// RandomHand returns a random Hand.
func RandomHand() int {
	return rand.Intn(3)
}

// Play a single game of Rock, Paper, Scissors and return the result.
func Play(p1, p2 int) int {
	switch {
	case p1 == p2:
		return Tie
	case (p1 == Rock && p2 != Paper),
		(p1 == Paper && p2 != Scissors),
		(p1 == Scissors && p2 != Rock):
		return WinP1
	default:
		return WinP2
	}
}
<|endoftext|>


<commit_before>// Simple wrapper for rrdtool C library
package rrd

import (
	"fmt"
	"math"
	"os"
	"strings"
	"sync"
	"time"
	"unsafe"
)

type Error string

func (e Error) Error() string {
	return string(e)
}

type cstring []byte

func newCstring(s string) cstring {
	cs := make(cstring, len(s)+1)
	copy(cs, s)
	return cs
}

func (cs cstring) p() unsafe.Pointer {
	if len(cs) == 0 {
		return nil
	}
	return unsafe.Pointer(&cs[0])
}

func (cs cstring) String() string {
	return string(cs[:len(cs)-1])
}

func join(args []interface{}) string {
	sa := make([]string, len(args))
	for i, a := range args {
		var s string
		switch v := a.(type) {
		case time.Time:
			s = fmt.Sprint(v.Unix())
		default:
			s = fmt.Sprint(v)
		}
		sa[i] = s
	}
	return strings.Join(sa, ":")
}

type Creator struct {
	filename string
	start    time.Time
	step     uint
	args     []string
}

// NewCreator returns new Creator object. You need to call Create to really
// create database file.
//	filename - name of database file
//	start    - don't accept any data timed before or at time specified
//	step     - base interval in seconds with which data will be fed into RRD
func NewCreator(filename string, start time.Time, step uint) *Creator {
	return &Creator{
		filename: filename,
		start:    start,
		step:     step,
	}
}

func (c *Creator) DS(name, compute string, args ...interface{}) {
	c.args = append(c.args, "DS:"+name+":"+compute+":"+join(args))
}

func (c *Creator) RRA(cf string, args ...interface{}) {
	c.args = append(c.args, "RRA:"+cf+":"+join(args))
}

func (c *Creator) Create(overwrite bool) error {
	if !overwrite {
		f, err := os.OpenFile(
			c.filename,
			os.O_WRONLY|os.O_CREATE|os.O_EXCL,
			0666,
		)
		if err != nil {
			return err
		}
		f.Close()
	}
	return c.create()
}

// Use cstring and unsafe.Pointer to avoid alocations for C calls

type Updater struct {
	filename cstring
	template cstring

	args []unsafe.Pointer
}

func NewUpdater(filename string) *Updater {
	return &Updater{filename: newCstring(filename)}
}

func (u *Updater) SetTemplate(dsName ...string) {
	u.template = newCstring(strings.Join(dsName, ":"))
}

// Cache chaches data for later save using Update(). Use it to avoid
// open/read/write/close for every update.
func (u *Updater) Cache(args ...interface{}) {
	u.args = append(u.args, newCstring(join(args)).p())
}

// Update saves data in RRDB.
// Without args Update saves all subsequent updates buffered by Cache method.
// If you specify args it saves them immediately.
func (u *Updater) Update(args ...interface{}) error {
	if len(args) != 0 {
		a := make([]unsafe.Pointer, 1)
		a[0] = newCstring(join(args)).p()
		return u.update(a)
	} else if len(u.args) != 0 {
		err := u.update(u.args)
		u.args = nil
		return err
	}
	return nil
}

type GraphInfo struct {
	Print         []string
	Width, Height uint
	Ymin, Ymax    float64
}

type Grapher struct {
	m               sync.Mutex
	title           string
	vlabel          string
	width, height   uint
	upperLimit      float64
	lowerLimit      float64
	rigid           bool
	altAutoscale    bool
	altAutoscaleMin bool
	altAutoscaleMax bool
	noGridFit       bool

	logarithmic bool

	noLegend bool

	lazy bool

	color string

	slopeMode bool

	watermark   string
	base        uint
	imageFormat string
	interlaced  bool

	args []string
}

func NewGrapher() *Grapher {
	return &Grapher{
		upperLimit: -math.MaxFloat64,
		lowerLimit: math.MaxFloat64,
	}
}

func (g *Grapher) SetTitle(title string) {
	g.title = title
}

func (g *Grapher) SetVLabel(vlabel string) {
	g.vlabel = vlabel
}

func (g *Grapher) SetSize(width, height uint) {
	g.width = width
	g.height = height
}

func (g *Grapher) SetLowerLimit(limit float64) {
	g.lowerLimit = limit
}

func (g *Grapher) SetUpperLimit(limit float64) {
	g.upperLimit = limit
}

func (g *Grapher) SetRigid() {
	g.rigid = true
}

func (g *Grapher) SetAltAutoscale() {
	g.altAutoscale = true
}

func (g *Grapher) SetAltAutoscaleMin() {
	g.altAutoscaleMin = true
}

func (g *Grapher) SetAltAutoscaleMax() {

	g.altAutoscaleMax = true
}

func (g *Grapher) SetNoGridFit() {
	g.noGridFit = true
}

func (g *Grapher) SetLogarithmic() {
	g.logarithmic = true
}

func (g *Grapher) SetNoLegend() {
	g.noLegend = true
}

func (g *Grapher) SetLazy() {
	g.lazy = true
}

func (g *Grapher) SetColor(colortag, color string) {
	g.color = colortag + "#" + color
}

func (g *Grapher) SetSlopeMode() {
	g.slopeMode = true
}

func (g *Grapher) SetImageFormat(format string) {
	g.imageFormat = format
}

func (g *Grapher) SetInterlaced() {
	g.interlaced = true
}

func (g *Grapher) SetBase(base uint) {
	g.base = base
}

func (g *Grapher) SetWatermark(watermark string) {
	g.watermark = watermark
}

func (g *Grapher) push(cmd string, options []string) {
	if len(options) > 0 {
		cmd += ":" + strings.Join(options, ":")
	}
	g.args = append(g.args, cmd)
}

func (g *Grapher) Def(vname, rrdfile, dsname, cf string, options ...string) {
	g.push(
		fmt.Sprintf("DEF:%s=%s:%s:%s", vname, rrdfile, dsname, cf),
		options,
	)
}

func (g *Grapher) VDef(vname, rpn string) {
	g.push("VDEF:"+vname+"="+rpn, nil)
}

func (g *Grapher) CDef(vname, rpn string) {
	g.push("CDEF:"+vname+"="+rpn, nil)
}

func (g *Grapher) Print(vname, format string) {
	g.push("PRINT:"+vname+":"+format, nil)
}

func (g *Grapher) PrintT(vname, format string) {
	g.push("PRINT:"+vname+":"+format+":strftime", nil)
}
func (g *Grapher) GPrint(vname, format string) {
	g.push("GPRINT:"+vname+":"+format, nil)
}

func (g *Grapher) GPrintT(vname, format string) {
	g.push("GPRINT:"+vname+":"+format+":strftime", nil)
}

func (g *Grapher) Comment(s string) {
	g.push("COMMENT:"+s, nil)
}

func (g *Grapher) VRule(t interface{}, color string, options ...string) {
	if v, ok := t.(time.Time); ok {
		t = v.Unix()
	}
	vr := fmt.Sprintf("VRULE:%s#%s", t, color)
	g.push(vr, options)
}

func (g *Grapher) HRule(value, color string, options ...string) {
	hr := "HRULE:" + value + "#" + color
	g.push(hr, options)
}

func (g *Grapher) Line(width float32, value, color string, options ...string) {
	line := fmt.Sprintf("LINE%f:%s", width, value)
	if color != "" {
		line += "#" + color
	}
	g.push(line, options)
}

func (g *Grapher) Area(value, color string, options ...string) {
	area := "AREA:" + value
	if color != "" {
		area += "#" + color
	}
	g.push(area, options)
}

func (g *Grapher) Tick(vname, color string, options ...string) {
	tick := "TICK:" + vname
	if color != "" {
		tick += "#" + color
	}
	g.push(tick, options)
}

func (g *Grapher) Shift(vname string, offset interface{}) {
	if v, ok := offset.(time.Duration); ok {
		offset = int64((v + time.Second/2) / time.Second)
	}
	shift := fmt.Sprintf("SHIFT:%s:%s", offset)
	g.push(shift, nil)
}

func (g *Grapher) TextAlign(align string) {
	g.push("TEXTALIGN:"+align, nil)
}

// Graph returns GraphInfo and image as []byte or error
func (g *Grapher) Graph(start, end time.Time) (GraphInfo, []byte, error) {
	return g.graph("-", start, end)
}

// SaveGraph saves image to file and returns GraphInfo or error
func (g *Grapher) SaveGraph(filename string, start, end time.Time) (GraphInfo, error) {
	gi, _, err := g.graph(filename, start, end)
	return gi, err
}
<commit_msg>Add comment about Creator.Create<commit_after>// Simple wrapper for rrdtool C library
package rrd

import (
	"fmt"
	"math"
	"os"
	"strings"
	"sync"
	"time"
	"unsafe"
)

type Error string

func (e Error) Error() string {
	return string(e)
}

type cstring []byte

func newCstring(s string) cstring {
	cs := make(cstring, len(s)+1)
	copy(cs, s)
	return cs
}

func (cs cstring) p() unsafe.Pointer {
	if len(cs) == 0 {
		return nil
	}
	return unsafe.Pointer(&cs[0])
}

func (cs cstring) String() string {
	return string(cs[:len(cs)-1])
}

func join(args []interface{}) string {
	sa := make([]string, len(args))
	for i, a := range args {
		var s string
		switch v := a.(type) {
		case time.Time:
			s = fmt.Sprint(v.Unix())
		default:
			s = fmt.Sprint(v)
		}
		sa[i] = s
	}
	return strings.Join(sa, ":")
}

type Creator struct {
	filename string
	start    time.Time
	step     uint
	args     []string
}

// NewCreator returns new Creator object. You need to call Create to really
// create database file.
//	filename - name of database file
//	start    - don't accept any data timed before or at time specified
//	step     - base interval in seconds with which data will be fed into RRD
func NewCreator(filename string, start time.Time, step uint) *Creator {
	return &Creator{
		filename: filename,
		start:    start,
		step:     step,
	}
}

func (c *Creator) DS(name, compute string, args ...interface{}) {
	c.args = append(c.args, "DS:"+name+":"+compute+":"+join(args))
}

func (c *Creator) RRA(cf string, args ...interface{}) {
	c.args = append(c.args, "RRA:"+cf+":"+join(args))
}

// Create creates new database file. If overwrite is true it overwrites
// database file if exists. If overwrite is false it returns error if file
// exists (you can use os.IsExist function to check this case).
func (c *Creator) Create(overwrite bool) error {
	if !overwrite {
		f, err := os.OpenFile(
			c.filename,
			os.O_WRONLY|os.O_CREATE|os.O_EXCL,
			0666,
		)
		if err != nil {
			return err
		}
		f.Close()
	}
	return c.create()
}

// Use cstring and unsafe.Pointer to avoid alocations for C calls

type Updater struct {
	filename cstring
	template cstring

	args []unsafe.Pointer
}

func NewUpdater(filename string) *Updater {
	return &Updater{filename: newCstring(filename)}
}

func (u *Updater) SetTemplate(dsName ...string) {
	u.template = newCstring(strings.Join(dsName, ":"))
}

// Cache chaches data for later save using Update(). Use it to avoid
// open/read/write/close for every update.
func (u *Updater) Cache(args ...interface{}) {
	u.args = append(u.args, newCstring(join(args)).p())
}

// Update saves data in RRDB.
// Without args Update saves all subsequent updates buffered by Cache method.
// If you specify args it saves them immediately.
func (u *Updater) Update(args ...interface{}) error {
	if len(args) != 0 {
		a := make([]unsafe.Pointer, 1)
		a[0] = newCstring(join(args)).p()
		return u.update(a)
	} else if len(u.args) != 0 {
		err := u.update(u.args)
		u.args = nil
		return err
	}
	return nil
}

type GraphInfo struct {
	Print         []string
	Width, Height uint
	Ymin, Ymax    float64
}

type Grapher struct {
	m               sync.Mutex
	title           string
	vlabel          string
	width, height   uint
	upperLimit      float64
	lowerLimit      float64
	rigid           bool
	altAutoscale    bool
	altAutoscaleMin bool
	altAutoscaleMax bool
	noGridFit       bool

	logarithmic bool

	noLegend bool

	lazy bool

	color string

	slopeMode bool

	watermark   string
	base        uint
	imageFormat string
	interlaced  bool

	args []string
}

func NewGrapher() *Grapher {
	return &Grapher{
		upperLimit: -math.MaxFloat64,
		lowerLimit: math.MaxFloat64,
	}
}

func (g *Grapher) SetTitle(title string) {
	g.title = title
}

func (g *Grapher) SetVLabel(vlabel string) {
	g.vlabel = vlabel
}

func (g *Grapher) SetSize(width, height uint) {
	g.width = width
	g.height = height
}

func (g *Grapher) SetLowerLimit(limit float64) {
	g.lowerLimit = limit
}

func (g *Grapher) SetUpperLimit(limit float64) {
	g.upperLimit = limit
}

func (g *Grapher) SetRigid() {
	g.rigid = true
}

func (g *Grapher) SetAltAutoscale() {
	g.altAutoscale = true
}

func (g *Grapher) SetAltAutoscaleMin() {
	g.altAutoscaleMin = true
}

func (g *Grapher) SetAltAutoscaleMax() {

	g.altAutoscaleMax = true
}

func (g *Grapher) SetNoGridFit() {
	g.noGridFit = true
}

func (g *Grapher) SetLogarithmic() {
	g.logarithmic = true
}

func (g *Grapher) SetNoLegend() {
	g.noLegend = true
}

func (g *Grapher) SetLazy() {
	g.lazy = true
}

func (g *Grapher) SetColor(colortag, color string) {
	g.color = colortag + "#" + color
}

func (g *Grapher) SetSlopeMode() {
	g.slopeMode = true
}

func (g *Grapher) SetImageFormat(format string) {
	g.imageFormat = format
}

func (g *Grapher) SetInterlaced() {
	g.interlaced = true
}

func (g *Grapher) SetBase(base uint) {
	g.base = base
}

func (g *Grapher) SetWatermark(watermark string) {
	g.watermark = watermark
}

func (g *Grapher) push(cmd string, options []string) {
	if len(options) > 0 {
		cmd += ":" + strings.Join(options, ":")
	}
	g.args = append(g.args, cmd)
}

func (g *Grapher) Def(vname, rrdfile, dsname, cf string, options ...string) {
	g.push(
		fmt.Sprintf("DEF:%s=%s:%s:%s", vname, rrdfile, dsname, cf),
		options,
	)
}

func (g *Grapher) VDef(vname, rpn string) {
	g.push("VDEF:"+vname+"="+rpn, nil)
}

func (g *Grapher) CDef(vname, rpn string) {
	g.push("CDEF:"+vname+"="+rpn, nil)
}

func (g *Grapher) Print(vname, format string) {
	g.push("PRINT:"+vname+":"+format, nil)
}

func (g *Grapher) PrintT(vname, format string) {
	g.push("PRINT:"+vname+":"+format+":strftime", nil)
}
func (g *Grapher) GPrint(vname, format string) {
	g.push("GPRINT:"+vname+":"+format, nil)
}

func (g *Grapher) GPrintT(vname, format string) {
	g.push("GPRINT:"+vname+":"+format+":strftime", nil)
}

func (g *Grapher) Comment(s string) {
	g.push("COMMENT:"+s, nil)
}

func (g *Grapher) VRule(t interface{}, color string, options ...string) {
	if v, ok := t.(time.Time); ok {
		t = v.Unix()
	}
	vr := fmt.Sprintf("VRULE:%s#%s", t, color)
	g.push(vr, options)
}

func (g *Grapher) HRule(value, color string, options ...string) {
	hr := "HRULE:" + value + "#" + color
	g.push(hr, options)
}

func (g *Grapher) Line(width float32, value, color string, options ...string) {
	line := fmt.Sprintf("LINE%f:%s", width, value)
	if color != "" {
		line += "#" + color
	}
	g.push(line, options)
}

func (g *Grapher) Area(value, color string, options ...string) {
	area := "AREA:" + value
	if color != "" {
		area += "#" + color
	}
	g.push(area, options)
}

func (g *Grapher) Tick(vname, color string, options ...string) {
	tick := "TICK:" + vname
	if color != "" {
		tick += "#" + color
	}
	g.push(tick, options)
}

func (g *Grapher) Shift(vname string, offset interface{}) {
	if v, ok := offset.(time.Duration); ok {
		offset = int64((v + time.Second/2) / time.Second)
	}
	shift := fmt.Sprintf("SHIFT:%s:%s", offset)
	g.push(shift, nil)
}

func (g *Grapher) TextAlign(align string) {
	g.push("TEXTALIGN:"+align, nil)
}

// Graph returns GraphInfo and image as []byte or error
func (g *Grapher) Graph(start, end time.Time) (GraphInfo, []byte, error) {
	return g.graph("-", start, end)
}

// SaveGraph saves image to file and returns GraphInfo or error
func (g *Grapher) SaveGraph(filename string, start, end time.Time) (GraphInfo, error) {
	gi, _, err := g.graph(filename, start, end)
	return gi, err
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/xml"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const (
	ATOM_XLMNS = "http://www.w3.org/2005/Atom"
)

type rss struct {
	name    xml.Name   `xml:"rss"`
	Xmlns   string     `xml:"xmlns:atom,attr"`
	Version string     `xml:"version,attr"`
	Channel RssChannel `xml:"channel"`
}

type RssChannel struct {
	Title       string `xml:"title"`
	Link        string `xml:"link"`
	Description string `xml:"description"`
	Language    string `xml:"language"`
	AtomLink    struct {
		Href string `xml:"href,attr"`
		Rel  string `xml:"rel,attr"`
		Type string `xml:"type,attr"`
	} `xml:"atom:link"`
	Items []RssItem `xml:"item"`
}

type RssItem struct {
	Title       string `xml:"title"`
	Link        string `xml:"link"`
	Description string `xml:"description"`
	Category    string `xml:"category"`
	PubDate     string `xml:"pubDate"`
	Enclosure   struct {
		Url    string `xml:"url,attr"`
		Length int64  `xml:"length,attr"`
		Type   string `xml:"type,attr"`
	} `xml:"enclosure"`
	Guid struct {
		Perma string `xml:"isPermalink,attr"`
		Guid  string `xml:",innerxml"`
	} `xml:"guid"`
}

func genrss(ctx *context, res http.ResponseWriter, req *http.Request) {
	req.ParseForm()
	var searchQuery string
	//var category string
	var max int
	if q, ok := req.Form["q"]; ok {
		if q[0] == "" {
			searchQuery = "*"
		} else {
			searchQuery = q[0]
		}
	} else {
		switch req.URL.Path {
		case "/rss":
			searchQuery = "*"
		}
	}
	/*
		category = req.FormValue("cat")
		categoryName := "All"
		switch category {
		case "anime":
			categoryName = "Anime"
		default:
			category = ""
		}
	*/
	if n, err := strconv.Atoi(req.FormValue("max")); err == nil {
		max = n
	} else {
		max = 50
	}
	if searchQuery == "" {
		if f, err := ctx.HtmlDir.Open("/home.html"); err == nil {
			defer f.Close()
			if fi, err := f.Stat(); err != nil {
				panic("Failed to stat index.html file.")
			} else {
				mod := fi.ModTime()
				http.ServeContent(res, req, "/index.html", mod, f)
			}
		}
	} else {
		res.Header().Set("Content-Type", "text/html")
		sResults, _ := searchBackend(ctx, searchQuery, 0, max, true)
		feed := rss{
			Xmlns:   ATOM_XLMNS,
			Version: "2.0",
			Channel: RssChannel{
				Title:       searchQuery + " — Animezb",
				Link:        "http://animezb.com",
				Description: "Usenet Indexer for Japanese Media",
				Language:    "en-us",
			},
		}
		feed.Channel.AtomLink.Href = "http://animezb.com" + req.URL.String()
		feed.Channel.AtomLink.Rel = "self"
		feed.Channel.AtomLink.Type = "application/rss+xml"
		feed.Channel.Items = make([]RssItem, len(sResults))
		hostname := req.Host
		for idx, res := range sResults {
			var postCat string
			switch res.Group {
			case "alt.binaries.anime", "alt.binaries.multimedia.anime", "alt.binaries.multimedia.anime.repost", "alt.binaries.multimedia.anime.highspeed":
				postCat = "Anime"
			default:
				postCat = "Anime"
			}
			pDate, _ := time.Parse(time.UnixDate, res.Date)
			item := RssItem{
				Title:       res.Name,
				Link:        "http://" + hostname + "/nzb/" + res.UploadId,
				Description: formatRssDesc(res),
				Category:    postCat,
				PubDate:     pDate.Format(time.RFC1123Z),
			}
			item.Enclosure.Url = "http://" + hostname + "/nzb/" + res.UploadId + "/" + strings.Replace(url.QueryEscape(res.Name), "+", "%20", -1) + ".nzb"
			item.Enclosure.Length = res.Bytes
			item.Enclosure.Type = "application/x-nzb"
			item.Guid.Guid = "http://" + hostname + "/nzb/" + res.UploadId
			item.Guid.Perma = "false"
			feed.Channel.Items[idx] = item
		}
		if output, err := xml.Marshal(feed); err == nil {
			res.Header().Set("Content-Type", "text/xml; charset=utf-8")
			res.WriteHeader(200)
			res.Write([]byte(xml.Header))
			res.Write(output)
		} else {
			panic(err)
		}
	}
}

func formatRssDesc(sr searchResult) string {
	format := `<i>Age</i>: %s<br /><i>Size</i>: %s<br /><i>Parts</i>: %s<br /><i>Files</i>: %s<br /><i>Subject</i>: %s`
	return fmt.Sprintf(format, sr.Age, sr.Size, sr.Completion, sr.ExtTypes, sr.Subject)
}
<commit_msg>Use same scheme<commit_after>package main

import (
	"encoding/xml"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const (
	ATOM_XLMNS = "http://www.w3.org/2005/Atom"
)

type rss struct {
	name    xml.Name   `xml:"rss"`
	Xmlns   string     `xml:"xmlns:atom,attr"`
	Version string     `xml:"version,attr"`
	Channel RssChannel `xml:"channel"`
}

type RssChannel struct {
	Title       string `xml:"title"`
	Link        string `xml:"link"`
	Description string `xml:"description"`
	Language    string `xml:"language"`
	AtomLink    struct {
		Href string `xml:"href,attr"`
		Rel  string `xml:"rel,attr"`
		Type string `xml:"type,attr"`
	} `xml:"atom:link"`
	Items []RssItem `xml:"item"`
}

type RssItem struct {
	Title       string `xml:"title"`
	Link        string `xml:"link"`
	Description string `xml:"description"`
	Category    string `xml:"category"`
	PubDate     string `xml:"pubDate"`
	Enclosure   struct {
		Url    string `xml:"url,attr"`
		Length int64  `xml:"length,attr"`
		Type   string `xml:"type,attr"`
	} `xml:"enclosure"`
	Guid struct {
		Perma string `xml:"isPermalink,attr"`
		Guid  string `xml:",innerxml"`
	} `xml:"guid"`
}

func genrss(ctx *context, res http.ResponseWriter, req *http.Request) {
	req.ParseForm()
	var searchQuery string
	//var category string
	var max int
	if q, ok := req.Form["q"]; ok {
		if q[0] == "" {
			searchQuery = "*"
		} else {
			searchQuery = q[0]
		}
	} else {
		switch req.URL.Path {
		case "/rss":
			searchQuery = "*"
		}
	}
	/*
		category = req.FormValue("cat")
		categoryName := "All"
		switch category {
		case "anime":
			categoryName = "Anime"
		default:
			category = ""
		}
	*/
	if n, err := strconv.Atoi(req.FormValue("max")); err == nil {
		max = n
	} else {
		max = 50
	}
	if searchQuery == "" {
		if f, err := ctx.HtmlDir.Open("/home.html"); err == nil {
			defer f.Close()
			if fi, err := f.Stat(); err != nil {
				panic("Failed to stat index.html file.")
			} else {
				mod := fi.ModTime()
				http.ServeContent(res, req, "/index.html", mod, f)
			}
		}
	} else {
		res.Header().Set("Content-Type", "text/html")
		sResults, _ := searchBackend(ctx, searchQuery, 0, max, true)
		protocol := req.URL.Scheme + "://"
		hostname := req.Host
		feed := rss{
			Xmlns:   ATOM_XLMNS,
			Version: "2.0",
			Channel: RssChannel{
				Title:       searchQuery + " — Animezb",
				Link:        protocol + hostname,
				Description: "Usenet Indexer for Japanese Media",
				Language:    "en-us",
			},
		}
		feed.Channel.AtomLink.Href = protocol + hostname + req.URL.String()
		feed.Channel.AtomLink.Rel = "self"
		feed.Channel.AtomLink.Type = "application/rss+xml"
		feed.Channel.Items = make([]RssItem, len(sResults))

		for idx, res := range sResults {
			var postCat string
			switch res.Group {
			case "alt.binaries.anime", "alt.binaries.multimedia.anime", "alt.binaries.multimedia.anime.repost", "alt.binaries.multimedia.anime.highspeed":
				postCat = "Anime"
			default:
				postCat = "Anime"
			}
			pDate, _ := time.Parse(time.UnixDate, res.Date)
			item := RssItem{
				Title:       res.Name,
				Link:        protocol + hostname + "/nzb/" + res.UploadId,
				Description: formatRssDesc(res),
				Category:    postCat,
				PubDate:     pDate.Format(time.RFC1123Z),
			}
			item.Enclosure.Url = protocol + hostname + "/nzb/" + res.UploadId + "/" + strings.Replace(url.QueryEscape(res.Name), "+", "%20", -1) + ".nzb"
			item.Enclosure.Length = res.Bytes
			item.Enclosure.Type = "application/x-nzb"
			item.Guid.Guid = protocol + hostname + "/nzb/" + res.UploadId
			item.Guid.Perma = "false"
			feed.Channel.Items[idx] = item
		}
		if output, err := xml.Marshal(feed); err == nil {
			res.Header().Set("Content-Type", "text/xml; charset=utf-8")
			res.WriteHeader(200)
			res.Write([]byte(xml.Header))
			res.Write(output)
		} else {
			panic(err)
		}
	}
}

func formatRssDesc(sr searchResult) string {
	format := `<i>Age</i>: %s<br /><i>Size</i>: %s<br /><i>Parts</i>: %s<br /><i>Files</i>: %s<br /><i>Subject</i>: %s`
	return fmt.Sprintf(format, sr.Age, sr.Size, sr.Completion, sr.ExtTypes, sr.Subject)
}
<|endoftext|>