<commit_before>package slack

import (
	"errors"
	"net/url"
)

// UserProfile contains all the information details of a given user
type UserProfile struct {
	FirstName          string `json:"first_name"`
	LastName           string `json:"last_name"`
	RealName           string `json:"real_name"`
	RealNameNormalized string `json:"real_name_normalized"`
	Email              string `json:"email"`
	Skype              string `json:"skype"`
	Phone              string `json:"phone"`
	Image24            string `json:"image_24"`
	Image32            string `json:"image_32"`
	Image48            string `json:"image_48"`
	Image72            string `json:"image_72"`
	Image192           string `json:"image_192"`
	ImageOriginal      string `json:"image_original"`
	Title              string `json:"title"`
}

// User contains all the information of a user
type User struct {
	ID                string      `json:"id"`
	Name              string      `json:"name"`
	Deleted           bool        `json:"deleted"`
	Color             string      `json:"color"`
	RealName          string      `json:"real_name"`
	TZ                string      `json:"tz,omitempty"`
	TZLabel           string      `json:"tz_label"`
	TZOffset          int         `json:"tz_offset"`
	Profile           UserProfile `json:"profile"`
	IsBot             bool        `json:"is_bot"`
	IsAdmin           bool        `json:"is_admin"`
	IsOwner           bool        `json:"is_owner"`
	IsPrimaryOwner    bool        `json:"is_primary_owner"`
	IsRestricted      bool        `json:"is_restricted"`
	IsUltraRestricted bool        `json:"is_ultra_restricted"`
	Has2FA            bool        `json:"has_2fa"`
	HasFiles          bool        `json:"has_files"`
	Presence          string      `json:"presence"`
}

// UserPresence contains details about a user online status
type UserPresence struct {
	Presence        string   `json:"presence,omitempty"`
	Online          bool     `json:"online,omitempty"`
	AutoAway        bool     `json:"auto_away,omitempty"`
	ManualAway      bool     `json:"manual_away,omitempty"`
	ConnectionCount int      `json:"connection_count,omitempty"`
	LastActivity    JSONTime `json:"last_activity,omitempty"`
}

type userResponseFull struct {
	Members      []User                  `json:"members,omitempty"` // ListUsers
	User         `json:"user,omitempty"` // GetUserInfo
	UserPresence                         // GetUserPresence
	SlackResponse
}

func userRequest(path string, values url.Values, debug bool) (*userResponseFull, error) {
	response := &userResponseFull{}
	err := post(path, values, response, debug)
	if err != nil {
		return nil, err
	}
	if !response.Ok {
		return nil, errors.New(response.Error)
	}
	return response, nil
}

// GetUserPresence will retrieve the current presence status of given user.
func (api *Client) GetUserPresence(user string) (*UserPresence, error) {
	values := url.Values{
		"token": {api.config.token},
		"user":  {user},
	}
	response, err := userRequest("users.getPresence", values, api.debug)
	if err != nil {
		return nil, err
	}
	return &response.UserPresence, nil
}

// GetUserInfo will retrive the complete user information
func (api *Client) GetUserInfo(user string) (*User, error) {
	values := url.Values{
		"token": {api.config.token},
		"user":  {user},
	}
	response, err := userRequest("users.info", values, api.debug)
	if err != nil {
		return nil, err
	}
	return &response.User, nil
}

// GetUsers returns the list of users (with their detailed information)
func (api *Client) GetUsers() ([]User, error) {
	values := url.Values{
		"token":    {api.config.token},
		"presence": {"1"},
	}
	response, err := userRequest("users.list", values, api.debug)
	if err != nil {
		return nil, err
	}
	return response.Members, nil
}

// SetUserAsActive marks the currently authenticated user as active
func (api *Client) SetUserAsActive() error {
	values := url.Values{
		"token": {api.config.token},
	}
	_, err := userRequest("users.setActive", values, api.debug)
	if err != nil {
		return err
	}
	return nil
}

// SetUserPresence changes the currently authenticated user presence
func (api *Client) SetUserPresence(presence string) error {
	values := url.Values{
		"token":    {api.config.token},
		"presence": {presence},
	}
	_, err := userRequest("users.setPresence", values, api.debug)
	if err != nil {
		return err
	}
	return nil

}
<commit_msg>Add missing bot_id and api_app_id to UserProfile<commit_after>package slack

import (
	"errors"
	"net/url"
)

// UserProfile contains all the information details of a given user
type UserProfile struct {
	FirstName          string `json:"first_name"`
	LastName           string `json:"last_name"`
	RealName           string `json:"real_name"`
	RealNameNormalized string `json:"real_name_normalized"`
	Email              string `json:"email"`
	Skype              string `json:"skype"`
	Phone              string `json:"phone"`
	Image24            string `json:"image_24"`
	Image32            string `json:"image_32"`
	Image48            string `json:"image_48"`
	Image72            string `json:"image_72"`
	Image192           string `json:"image_192"`
	ImageOriginal      string `json:"image_original"`
	Title              string `json:"title"`
	BotID              string `json:"bot_id,omitempty"`
	ApiAppID           string `json:"api_app_id,omitempty"`
}

// User contains all the information of a user
type User struct {
	ID                string      `json:"id"`
	Name              string      `json:"name"`
	Deleted           bool        `json:"deleted"`
	Color             string      `json:"color"`
	RealName          string      `json:"real_name"`
	TZ                string      `json:"tz,omitempty"`
	TZLabel           string      `json:"tz_label"`
	TZOffset          int         `json:"tz_offset"`
	Profile           UserProfile `json:"profile"`
	IsBot             bool        `json:"is_bot"`
	IsAdmin           bool        `json:"is_admin"`
	IsOwner           bool        `json:"is_owner"`
	IsPrimaryOwner    bool        `json:"is_primary_owner"`
	IsRestricted      bool        `json:"is_restricted"`
	IsUltraRestricted bool        `json:"is_ultra_restricted"`
	Has2FA            bool        `json:"has_2fa"`
	HasFiles          bool        `json:"has_files"`
	Presence          string      `json:"presence"`
}

// UserPresence contains details about a user online status
type UserPresence struct {
	Presence        string   `json:"presence,omitempty"`
	Online          bool     `json:"online,omitempty"`
	AutoAway        bool     `json:"auto_away,omitempty"`
	ManualAway      bool     `json:"manual_away,omitempty"`
	ConnectionCount int      `json:"connection_count,omitempty"`
	LastActivity    JSONTime `json:"last_activity,omitempty"`
}

type userResponseFull struct {
	Members      []User                  `json:"members,omitempty"` // ListUsers
	User         `json:"user,omitempty"` // GetUserInfo
	UserPresence                         // GetUserPresence
	SlackResponse
}

func userRequest(path string, values url.Values, debug bool) (*userResponseFull, error) {
	response := &userResponseFull{}
	err := post(path, values, response, debug)
	if err != nil {
		return nil, err
	}
	if !response.Ok {
		return nil, errors.New(response.Error)
	}
	return response, nil
}

// GetUserPresence will retrieve the current presence status of given user.
func (api *Client) GetUserPresence(user string) (*UserPresence, error) {
	values := url.Values{
		"token": {api.config.token},
		"user":  {user},
	}
	response, err := userRequest("users.getPresence", values, api.debug)
	if err != nil {
		return nil, err
	}
	return &response.UserPresence, nil
}

// GetUserInfo will retrive the complete user information
func (api *Client) GetUserInfo(user string) (*User, error) {
	values := url.Values{
		"token": {api.config.token},
		"user":  {user},
	}
	response, err := userRequest("users.info", values, api.debug)
	if err != nil {
		return nil, err
	}
	return &response.User, nil
}

// GetUsers returns the list of users (with their detailed information)
func (api *Client) GetUsers() ([]User, error) {
	values := url.Values{
		"token":    {api.config.token},
		"presence": {"1"},
	}
	response, err := userRequest("users.list", values, api.debug)
	if err != nil {
		return nil, err
	}
	return response.Members, nil
}

// SetUserAsActive marks the currently authenticated user as active
func (api *Client) SetUserAsActive() error {
	values := url.Values{
		"token": {api.config.token},
	}
	_, err := userRequest("users.setActive", values, api.debug)
	if err != nil {
		return err
	}
	return nil
}

// SetUserPresence changes the currently authenticated user presence
func (api *Client) SetUserPresence(presence string) error {
	values := url.Values{
		"token":    {api.config.token},
		"presence": {presence},
	}
	_, err := userRequest("users.setPresence", values, api.debug)
	if err != nil {
		return err
	}
	return nil

}
<|endoftext|>


<commit_before>package irelate

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/brentp/bix"
	"github.com/brentp/irelate/interfaces"
	"github.com/brentp/irelate/parsers"
	"github.com/brentp/vcfgo"
	"github.com/brentp/xopen"
)

const MaxUint32 = ^uint32(0)
const MaxInt32 = int(MaxUint32 >> 1)

// OpenScanFile sets up a (possibly gzipped) file for line-wise reading.
func OpenScanFile(fh io.Reader) (*bufio.Scanner, io.Reader) {
	scanner := bufio.NewScanner(fh)
	scanner.Split(bufio.ScanLines)
	return scanner, fh
}

type iterable struct {
	*bufio.Scanner
	fn func(line []byte) (interfaces.Relatable, error)
	fh io.Reader
}

func (it iterable) Next() (interfaces.Relatable, error) {
	v := it.Bytes()
	return it.fn(v)
}

func (it iterable) Close() error {
	if rc, ok := it.fh.(io.ReadCloser); ok {
		return rc.Close()
	}
	return nil
}

func ScanToIterator(file io.Reader, fn func(line []byte) (interfaces.Relatable, error)) interfaces.RelatableIterator {
	scanner, fh := OpenScanFile(file)
	return iterable{scanner, fn, fh}
}

// ScanToRelatable makes is easy to create a chan Relatable from a file of intervals.
func ScanToRelatable(file io.Reader, fn func(line []byte) (interfaces.Relatable, error)) interfaces.RelatableChannel {
	scanner, fh := OpenScanFile(file)
	ch := make(chan interfaces.Relatable, 32)
	go func() {
		i := 0
		for scanner.Scan() {
			v, err := fn(scanner.Bytes())
			if err != nil {
				if i > 0 { // break on the header.
					log.Println(err)
					break
				}
			} else {
				ch <- v
				i += 1
			}
		}
		if c, ok := fh.(io.ReadCloser); ok {
			c.Close()
		} else if c, ok := file.(io.ReadCloser); ok {
			c.Close()
		}
		close(ch)
	}()
	return ch
}

func Imin(a uint32, b uint32) uint32 {
	if b < a {
		return b
	}
	return a
}

func Imax(a uint32, b uint32) uint32 {
	if b > a {
		return b
	}
	return a
}

func RegionToParts(region string) (string, int, int, error) {
	parts := strings.Split(region, ":")
	// e.g. just "chr"
	if len(parts) == 1 {
		parts = append(parts, fmt.Sprintf("1-%d", MaxInt32))
	}

	se := strings.Split(parts[1], "-")
	if len(se) != 2 {
		return "", 0, 0, errors.New(fmt.Sprintf("unable to parse region: %s", region))
	}
	s, err := strconv.Atoi(se[0])
	if err != nil {
		return "", 0, 0, errors.New(fmt.Sprintf("unable to parse region: %s", region))
	}
	e, err := strconv.Atoi(se[1])
	if err != nil {
		return "", 0, 0, errors.New(fmt.Sprintf("unable to parse region: %s", region))
	}
	return parts[0], s, e, nil
}

type location struct {
	chrom string
	start int
	end   int
}

func (l location) RefName() string {
	return l.chrom
}

func (l location) Start() int {
	return l.start
}
func (l location) End() int {
	return l.end
}

func getReader(f, region string) (io.Reader, error) {
	var err error

	var rdr io.Reader
	if region != "" {
		bx, err := bix.New(f, 1)
		if err != nil {
			return nil, err
		}
		chrom, start, end, err := RegionToParts(region)
		if err != nil {
			return nil, err
		}
		rdr, err = bx.ChunkedReader(location{chrom, start, end}, true)
	} else {
		rdr, err = os.Open(f)
	}
	if err != nil {
		return nil, err
	}
	var buf io.Reader
	if !strings.HasSuffix(f, ".bam") {
		/*
			bufr := bufio.NewReader(rdr)
			used := false
			if region == "" {
				if is, err := xopen.IsGzip(bufr); is {
					buf, err = gzip.NewReader(bufr)
					used = true
					if err != nil {
						return nil, err
					}
				}
			}
			if !used {
				buf = bufr
			}*/
		buf = xopen.Buf(rdr)

	} else {
		buf = rdr
	}
	return buf, nil
}

func Iterator(f string, region string) (interfaces.RelatableIterator, error) {
	var iterator interfaces.RelatableIterator
	buf, err := getReader(f, region)
	if err != nil {
		return nil, err
	}
	// TODO: gff, bam
	if strings.HasSuffix(f, ".vcf") || strings.HasSuffix(f, ".vcf.gz") {
		iterator, _, err = parsers.VCFIterator(buf)
		if err != nil {
			return nil, err
		}

	} else {
		iterator = ScanToIterator(buf, parsers.IntervalFromBedLine)
	}
	return iterator, nil
}

func Streamer(f string, region string) (interfaces.RelatableChannel, error) {
	var stream chan interfaces.Relatable

	buf, err := getReader(f, region)
	if err != nil {
		return nil, err
	}

	if strings.HasSuffix(f, ".bam") {
		stream, err = parsers.BamToRelatable(buf)
	} else if strings.HasSuffix(f, ".gff") {
		stream, err = parsers.GFFToRelatable(buf)
	} else if strings.HasSuffix(f, ".vcf") || strings.HasSuffix(f, ".vcf.gz") {
		var v *vcfgo.Reader
		v, err = parsers.Vopen(buf, nil)
		stream = parsers.StreamVCF(v)
	} else {
		stream = ScanToRelatable(buf, parsers.IntervalFromBedLine)
	}
	return stream, err
}
<commit_msg>just need closer<commit_after>package irelate

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/brentp/bix"
	"github.com/brentp/irelate/interfaces"
	"github.com/brentp/irelate/parsers"
	"github.com/brentp/vcfgo"
	"github.com/brentp/xopen"
)

const MaxUint32 = ^uint32(0)
const MaxInt32 = int(MaxUint32 >> 1)

// OpenScanFile sets up a (possibly gzipped) file for line-wise reading.
func OpenScanFile(fh io.Reader) (*bufio.Scanner, io.Reader) {
	scanner := bufio.NewScanner(fh)
	scanner.Split(bufio.ScanLines)
	return scanner, fh
}

type iterable struct {
	*bufio.Scanner
	fn func(line []byte) (interfaces.Relatable, error)
	fh io.Reader
}

func (it iterable) Next() (interfaces.Relatable, error) {
	v := it.Bytes()
	return it.fn(v)
}

func (it iterable) Close() error {
	if rc, ok := it.fh.(io.Closer); ok {
		return rc.Close()
	}
	return nil
}

func ScanToIterator(file io.Reader, fn func(line []byte) (interfaces.Relatable, error)) interfaces.RelatableIterator {
	scanner, fh := OpenScanFile(file)
	return iterable{scanner, fn, fh}
}

// ScanToRelatable makes is easy to create a chan Relatable from a file of intervals.
func ScanToRelatable(file io.Reader, fn func(line []byte) (interfaces.Relatable, error)) interfaces.RelatableChannel {
	scanner, fh := OpenScanFile(file)
	ch := make(chan interfaces.Relatable, 32)
	go func() {
		i := 0
		for scanner.Scan() {
			v, err := fn(scanner.Bytes())
			if err != nil {
				if i > 0 { // break on the header.
					log.Println(err)
					break
				}
			} else {
				ch <- v
				i += 1
			}
		}
		if c, ok := fh.(io.ReadCloser); ok {
			c.Close()
		} else if c, ok := file.(io.ReadCloser); ok {
			c.Close()
		}
		close(ch)
	}()
	return ch
}

func Imin(a uint32, b uint32) uint32 {
	if b < a {
		return b
	}
	return a
}

func Imax(a uint32, b uint32) uint32 {
	if b > a {
		return b
	}
	return a
}

func RegionToParts(region string) (string, int, int, error) {
	parts := strings.Split(region, ":")
	// e.g. just "chr"
	if len(parts) == 1 {
		parts = append(parts, fmt.Sprintf("1-%d", MaxInt32))
	}

	se := strings.Split(parts[1], "-")
	if len(se) != 2 {
		return "", 0, 0, errors.New(fmt.Sprintf("unable to parse region: %s", region))
	}
	s, err := strconv.Atoi(se[0])
	if err != nil {
		return "", 0, 0, errors.New(fmt.Sprintf("unable to parse region: %s", region))
	}
	e, err := strconv.Atoi(se[1])
	if err != nil {
		return "", 0, 0, errors.New(fmt.Sprintf("unable to parse region: %s", region))
	}
	return parts[0], s, e, nil
}

type location struct {
	chrom string
	start int
	end   int
}

func (l location) RefName() string {
	return l.chrom
}

func (l location) Start() int {
	return l.start
}
func (l location) End() int {
	return l.end
}

func getReader(f, region string) (io.Reader, error) {
	var err error

	var rdr io.Reader
	if region != "" {
		bx, err := bix.New(f, 1)
		if err != nil {
			return nil, err
		}
		chrom, start, end, err := RegionToParts(region)
		if err != nil {
			return nil, err
		}
		rdr, err = bx.ChunkedReader(location{chrom, start, end}, true)
	} else {
		rdr, err = os.Open(f)
	}
	if err != nil {
		return nil, err
	}
	var buf io.Reader
	if !strings.HasSuffix(f, ".bam") {
		/*
			bufr := bufio.NewReader(rdr)
			used := false
			if region == "" {
				if is, err := xopen.IsGzip(bufr); is {
					buf, err = gzip.NewReader(bufr)
					used = true
					if err != nil {
						return nil, err
					}
				}
			}
			if !used {
				buf = bufr
			}*/
		buf = xopen.Buf(rdr)

	} else {
		buf = rdr
	}
	return buf, nil
}

func Iterator(f string, region string) (interfaces.RelatableIterator, error) {
	var iterator interfaces.RelatableIterator
	buf, err := getReader(f, region)
	if err != nil {
		return nil, err
	}
	// TODO: gff, bam
	if strings.HasSuffix(f, ".vcf") || strings.HasSuffix(f, ".vcf.gz") {
		iterator, _, err = parsers.VCFIterator(buf)
		if err != nil {
			return nil, err
		}

	} else {
		iterator = ScanToIterator(buf, parsers.IntervalFromBedLine)
	}
	return iterator, nil
}

func Streamer(f string, region string) (interfaces.RelatableChannel, error) {
	var stream chan interfaces.Relatable

	buf, err := getReader(f, region)
	if err != nil {
		return nil, err
	}

	if strings.HasSuffix(f, ".bam") {
		stream, err = parsers.BamToRelatable(buf)
	} else if strings.HasSuffix(f, ".gff") {
		stream, err = parsers.GFFToRelatable(buf)
	} else if strings.HasSuffix(f, ".vcf") || strings.HasSuffix(f, ".vcf.gz") {
		var v *vcfgo.Reader
		v, err = parsers.Vopen(buf, nil)
		stream = parsers.StreamVCF(v)
	} else {
		stream = ScanToRelatable(buf, parsers.IntervalFromBedLine)
	}
	return stream, err
}
<|endoftext|>


<commit_before>package main

import (
	"runtime"

	"github.com/sirupsen/logrus"
)

func funcName() string {
	pc, _, _, _ := runtime.Caller(1)
	return runtime.FuncForPC(pc).Name()
}

func logFatal(err error, fct string, msg string, param string) {
	log.WithFields(logrus.Fields{
		"param": param,
		"error": err,
		"fct":   fct,
	}).Fatal(msg)
}

func logDebug(fct string, msg string, param string) {
	log.WithFields(logrus.Fields{
		"param": param,
		"fct":   fct,
	}).Debug(msg)
}

func logWarn(fct string, msg string, param string) {
	logrus.WithFields(logrus.Fields{
		"param": param,
	}).Warn(msg)
	log.WithFields(logrus.Fields{
		"param": param,
		"fct":   fct,
	}).Warn(msg)
}

func logInfo(fct string, msg string, param string) {
	logrus.WithFields(logrus.Fields{
		"param": param,
	}).Info(msg)
	log.WithFields(logrus.Fields{
		"param": param,
		"fct":   fct,
	}).Info(msg)
}

func checkErr(err error, fct string, msg string, param string) {
	if err != nil {
		logFatal(err, msg, fct, param)
	}
}
<commit_msg>display fatal error on console<commit_after>package main

import (
	"runtime"

	"github.com/sirupsen/logrus"
)

func funcName() string {
	pc, _, _, _ := runtime.Caller(1)
	return runtime.FuncForPC(pc).Name()
}

func logFatal(err error, fct string, msg string, param string) {
	logrus.WithFields(logrus.Fields{
		"param": param,
		"error": err,
		"fct":   fct,
	}).Warn(msg)
	log.WithFields(logrus.Fields{
		"param": param,
		"error": err,
		"fct":   fct,
	}).Fatal(msg)
}

func logDebug(fct string, msg string, param string) {
	log.WithFields(logrus.Fields{
		"param": param,
		"fct":   fct,
	}).Debug(msg)
}

func logWarn(fct string, msg string, param string) {
	logrus.WithFields(logrus.Fields{
		"param": param,
	}).Warn(msg)
	log.WithFields(logrus.Fields{
		"param": param,
		"fct":   fct,
	}).Warn(msg)
}

func logInfo(fct string, msg string, param string) {
	logrus.WithFields(logrus.Fields{
		"param": param,
	}).Info(msg)
	log.WithFields(logrus.Fields{
		"param": param,
		"fct":   fct,
	}).Info(msg)
}

func checkErr(err error, fct string, msg string, param string) {
	if err != nil {
		logFatal(err, msg, fct, param)
	}
}
<|endoftext|>


<commit_before>//import "github.com/solomonooo/mercury"
//author : solomonooo
//create time : 2016-09-08

package mercury

import (
	"io"
	"net"
	"os"
	"time"
)

// FileExists reports whether the named file or directory exists.
func FileExists(name string) bool {
	if _, err := os.Stat(name); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

func RecvReq(conn net.Conn, data []byte) (int, error) {
<<<<<<< HEAD
	timeout := time.Duration(uint64(mercury.config.RecvTimeout) * 1000 * 1000)
=======
	timeout := time.Duration(mercury.config.RecvTimeout * 1000 * 1000)
>>>>>>> origin/master
	conn.SetReadDeadline(time.Now().Add(timeout))
	ret, err := conn.Read(data)
	if err == io.EOF {
		Debug("client close, remote[%s]", conn.RemoteAddr().String())
	} else if err != nil {
		Warn("recv req error, remote:%s, err:%s", conn.RemoteAddr().String(), err.Error())
		return ret, err
	}
	if ret != 0 {
		Debug("recv req success, remote:%s size:%d", conn.RemoteAddr().String(), ret)
	}
	return ret, err
}

func SendRsp(conn net.Conn, reqid uint64, data []byte) (int, error) {
<<<<<<< HEAD
	timeout := time.Duration(uint64(mercury.config.SendTimeout) * 1000 * 1000)
=======
	timeout := time.Duration(mercury.config.SendTimeout * 1000 * 1000)
>>>>>>> origin/master
	conn.SetWriteDeadline(time.Now().Add(timeout))
	ret, err := conn.Write(data)
	if err != nil {
		Warn("logid[%d] send rsp failed, remote[%s], err[%s]", reqid, conn.RemoteAddr().String(), err.Error())
		return ret, err
	}
	Debug("logid[%d] send rsp success, remote[%s], size[%d]", reqid, conn.RemoteAddr().String(), ret)
	return ret, err
}
<commit_msg>fix bug<commit_after>//import "github.com/solomonooo/mercury"
//author : solomonooo
//create time : 2016-09-08

package mercury

import (
	"io"
	"net"
	"os"
	"time"
)

// FileExists reports whether the named file or directory exists.
func FileExists(name string) bool {
	if _, err := os.Stat(name); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

func RecvReq(conn net.Conn, data []byte) (int, error) {
	timeout := time.Duration(uint64(mercury.config.RecvTimeout) * 1000 * 1000)
	conn.SetReadDeadline(time.Now().Add(timeout))
	ret, err := conn.Read(data)
	if err == io.EOF {
		Debug("client close, remote[%s]", conn.RemoteAddr().String())
	} else if err != nil {
		Warn("recv req error, remote:%s, err:%s", conn.RemoteAddr().String(), err.Error())
		return ret, err
	}
	if ret != 0 {
		Debug("recv req success, remote:%s size:%d", conn.RemoteAddr().String(), ret)
	}
	return ret, err
}

func SendRsp(conn net.Conn, reqid uint64, data []byte) (int, error) {
	timeout := time.Duration(uint64(mercury.config.SendTimeout) * 1000 * 1000)
	conn.SetWriteDeadline(time.Now().Add(timeout))
	ret, err := conn.Write(data)
	if err != nil {
		Warn("logid[%d] send rsp failed, remote[%s], err[%s]", reqid, conn.RemoteAddr().String(), err.Error())
		return ret, err
	}
	Debug("logid[%d] send rsp success, remote[%s], size[%d]", reqid, conn.RemoteAddr().String(), ret)
	return ret, err
}
<|endoftext|>


<commit_before>package cml

import (
	"math/rand"
	"strconv"

	"code.google.com/p/gofarmhash"
)

func randFloat() float64 {
	return rand.Float64()
}

func hash(s []byte, i, w uint) uint {
	str := strconv.Itoa(int(i)) + string(s)
	return uint(farmhash.Hash64([]byte(str))) % w
}
<commit_msg>Added marshalling and unmarshalling<commit_after>package cml

import (
	"math/rand"

	"github.com/dgryski/go-farm"
)

func randFloat() float64 {
	return rand.Float64()
}

func hash(s []byte, i, w uint) uint {
	return uint(farm.Hash64WithSeed(s, uint64(i))) % w
}
<|endoftext|>


<commit_before>package pongo2

import (
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"time"
)

type Value struct {
	v reflect.Value
}

// Converts any given value to a pongo2.Value
// Usually being used within own functions passed to a template
// through a Context or within filter functions.
//
// Example:
//     AsValue("my string")
func AsValue(i interface{}) *Value {
	return &Value{
		v: reflect.ValueOf(i),
	}
}

func (v *Value) getResolvedValue() reflect.Value {
	if v.v.IsValid() && v.v.Kind() == reflect.Ptr {
		return v.v.Elem()
	}
	return v.v
}

// Checks whether the underlying value is a string
func (v *Value) IsString() bool {
	return v.getResolvedValue().Kind() == reflect.String
}

// Checks whether the underlying value is a bool
func (v *Value) IsBool() bool {
	return v.getResolvedValue().Kind() == reflect.Bool
}

// Checks whether the underlying value is a float
func (v *Value) IsFloat() bool {
	return v.getResolvedValue().Kind() == reflect.Float32 ||
		v.getResolvedValue().Kind() == reflect.Float64
}

// Checks whether the underlying value is an integer
func (v *Value) IsInteger() bool {
	return v.getResolvedValue().Kind() == reflect.Int ||
		v.getResolvedValue().Kind() == reflect.Int8 ||
		v.getResolvedValue().Kind() == reflect.Int16 ||
		v.getResolvedValue().Kind() == reflect.Int32 ||
		v.getResolvedValue().Kind() == reflect.Int64 ||
		v.getResolvedValue().Kind() == reflect.Uint ||
		v.getResolvedValue().Kind() == reflect.Uint8 ||
		v.getResolvedValue().Kind() == reflect.Uint16 ||
		v.getResolvedValue().Kind() == reflect.Uint32 ||
		v.getResolvedValue().Kind() == reflect.Uint64
}

// Checks whether the underlying value is either an integer
// or a float.
func (v *Value) IsNumber() bool {
	return v.IsInteger() || v.IsFloat()
}

// Checks whether the underlying value is NIL
func (v *Value) IsNil() bool {
	//fmt.Printf("%+v\n", v.getResolvedValue().Type().String())
	return !v.getResolvedValue().IsValid()
}

// Returns a string for the underlying value. If this value is not
// of type string, pongo2 tries to convert it. Currently the following
// types for underlying values are supported:
//
//     1. string
//     2. int/uint (any size)
//     3. float (any precision)
//     4. bool
//     5. time.Time
//     6. String() will be called on the underlying value if provided
//
// NIL values will lead to an empty string. Unsupported types are leading
// to their respective type name.
func (v *Value) String() string {
	if v.IsNil() {
		return ""
	}

	switch v.getResolvedValue().Kind() {
	case reflect.String:
		return v.getResolvedValue().String()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return strconv.FormatInt(v.getResolvedValue().Int(), 10)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return strconv.FormatUint(v.getResolvedValue().Uint(), 10)
	case reflect.Float32, reflect.Float64:
		return fmt.Sprintf("%f", v.getResolvedValue().Float())
	case reflect.Bool:
		if v.Bool() {
			return "True"
		} else {
			return "False"
		}
	case reflect.Struct:
		if t, ok := v.Interface().(fmt.Stringer); ok {
			return t.String()
		}
	}

	logf("Value.String() not implemented for type: %s\n", v.getResolvedValue().Kind().String())
	return v.getResolvedValue().String()
}

// Returns the underlying value as an integer (converts the underlying
// value, if necessary). If it's not possible to convert the underlying value,
// it will return 0.
func (v *Value) Integer() int {
	switch v.getResolvedValue().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return int(v.getResolvedValue().Int())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return int(v.getResolvedValue().Uint())
	case reflect.Float32, reflect.Float64:
		return int(v.getResolvedValue().Float())
	case reflect.String:
		// Try to convert from string to int (base 10)
		f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
		if err != nil {
			return 0
		}
		return int(f)
	default:
		logf("Value.Integer() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return 0
	}
}

// Returns the underlying value as a float (converts the underlying
// value, if necessary). If it's not possible to convert the underlying value,
// it will return 0.0.
func (v *Value) Float() float64 {
	switch v.getResolvedValue().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return float64(v.getResolvedValue().Int())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return float64(v.getResolvedValue().Uint())
	case reflect.Float32, reflect.Float64:
		return v.getResolvedValue().Float()
	case reflect.String:
		// Try to convert from string to float64 (base 10)
		f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
		if err != nil {
			return 0.0
		}
		return f
	default:
		logf("Value.Float() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return 0.0
	}
}

// Returns the underlying value as bool. If the value is not bool, false
// will always be returned. If you're looking for true/false-evaluation of the
// underlying value, have a look on the IsTrue()-function.
func (v *Value) Bool() bool {
	switch v.getResolvedValue().Kind() {
	case reflect.Bool:
		return v.getResolvedValue().Bool()
	default:
		logf("Value.Bool() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return false
	}
}

// Tries to evaluate the underlying value the Pythonic-way:
//
// Returns TRUE in one the following cases:
//
//     * int != 0
//     * uint != 0
//     * float != 0.0
//     * len(array/chan/map/slice/string) > 0
//     * bool == true
//     * underlying value is a struct
//
// Otherwise returns always FALSE.
func (v *Value) IsTrue() bool {
	switch v.getResolvedValue().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.getResolvedValue().Int() != 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return v.getResolvedValue().Uint() != 0
	case reflect.Float32, reflect.Float64:
		return v.getResolvedValue().Float() != 0
	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
		return v.getResolvedValue().Len() > 0
	case reflect.Bool:
		return v.getResolvedValue().Bool()
	case reflect.Struct:
		return true // struct instance is always true
	default:
		logf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return false
	}
}

// Tries to negate the underlying value. It's mainly used for
// the NOT-operator and in conjunction with a call to
// return_value.IsTrue() afterwards.
//
// Example:
//     AsValue(1).Negate().IsTrue() == false
func (v *Value) Negate() *Value {
	switch v.getResolvedValue().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if v.Integer() != 0 {
			return AsValue(0)
		} else {
			return AsValue(1)
		}
	case reflect.Float32, reflect.Float64:
		if v.Float() != 0.0 {
			return AsValue(float64(0.0))
		} else {
			return AsValue(float64(1.1))
		}
	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
		return AsValue(v.getResolvedValue().Len() == 0)
	case reflect.Bool:
		return AsValue(!v.getResolvedValue().Bool())
	default:
		logf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return AsValue(true)
	}
}

// Returns the length for an array, chan, map, slice or string.
// Otherwise it will return 0.
func (v *Value) Len() int {
	switch v.getResolvedValue().Kind() {
	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
		return v.getResolvedValue().Len()
	default:
		logf("Value.Len() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return 0
	}
}

// Slices an array, slice or string. Otherwise it will
// return an empty []int.
func (v *Value) Slice(i, j int) *Value {
	switch v.getResolvedValue().Kind() {
	case reflect.Array, reflect.Slice, reflect.String:
		return AsValue(v.getResolvedValue().Slice(i, j).Interface())
	default:
		logf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return AsValue([]int{})
	}
}

// Get the i-th item of an array, slice or string. Otherwise
// it will return NIL.
func (v *Value) Index(i int) *Value {
	switch v.getResolvedValue().Kind() {
	case reflect.Array, reflect.Slice:
		if i >= v.Len() {
			return AsValue(nil)
		}
		return AsValue(v.getResolvedValue().Index(i).Interface())
	case reflect.String:
		return AsValue(v.getResolvedValue().Slice(i, i+1).Interface())
	default:
		logf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return AsValue([]int{})
	}
}

// Checks whether the underlying value (which must be of type struct, map,
// string, array or slice) contains of another Value (e. g. used to check
// whether a struct contains of a specific field or a map contains a specific key).
//
// Example:
//     AsValue("Hello, World!").Contains(AsValue("World")) == true
func (v *Value) Contains(other *Value) bool {
	switch v.getResolvedValue().Kind() {
	case reflect.Struct:
		field_value := v.getResolvedValue().FieldByName(other.String())
		return field_value.IsValid()
	case reflect.Map:
		var map_value reflect.Value
		switch other.Interface().(type) {
		case int:
			map_value = v.getResolvedValue().MapIndex(other.getResolvedValue())
		case string:
			map_value = v.getResolvedValue().MapIndex(other.getResolvedValue())
		default:
			logf("Value.Contains() does not support lookup type '%s'\n", other.getResolvedValue().Kind().String())
			return false
		}

		return map_value.IsValid()
	case reflect.String:
		return strings.Contains(v.getResolvedValue().String(), other.String())

	// TODO: reflect.Array, reflect.Slice

	default:
		logf("Value.Contains() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return false
	}
}

// Checks whether the underlying value is of type array, slice or string.
// You normally would use CanSlice() before using the Slice() operation.
func (v *Value) CanSlice() bool {
	switch v.getResolvedValue().Kind() {
	case reflect.Array, reflect.Slice, reflect.String:
		return true
	}
	return false
}

// Iterates over a map, array, slice or a string. It calls the
// function's first argument for every value with the following arguments:
//
//     idx      current 0-index
//     count    total amount of items
//     key      *Value for the key or item
//     value    *Value (only for maps, the respective value for a specific key)
//
// If the underlying value has no items or is not one of the types above,
// the empty function (function's second argument) will be called.
func (v *Value) Iterate(fn func(idx, count int, key, value *Value) bool, empty func()) {
	switch v.getResolvedValue().Kind() {
	case reflect.Map:
		keys := v.getResolvedValue().MapKeys()
		keyLen := len(keys)
		for idx, key := range keys {
			value := v.getResolvedValue().MapIndex(key)
			if !fn(idx, keyLen, &Value{key}, &Value{value}) {
				return
			}
		}
		if keyLen == 0 {
			empty()
		}
		return // done
	case reflect.Array, reflect.Slice:
		itemCount := v.getResolvedValue().Len()
		if itemCount > 0 {
			for i := 0; i < itemCount; i++ {
				if !fn(i, itemCount, &Value{v.getResolvedValue().Index(i)}, nil) {
					return
				}
			}
		} else {
			empty()
		}
		return // done
	case reflect.String:
		// TODO: Not utf8-compatible (utf8-decoding neccessary)
		charCount := v.getResolvedValue().Len()
		if charCount > 0 {
			for i := 0; i < charCount; i++ {
				if !fn(i, charCount, &Value{v.getResolvedValue().Slice(i, i+1)}, nil) {
					return
				}
			}
		} else {
			empty()
		}
		return // done
	default:
		logf("Value.Iterate() not available for type: %s\n", v.getResolvedValue().Kind().String())
	}
	empty()
}

// Gives you access to the underlying value.
func (v *Value) Interface() interface{} {
	if v.v.IsValid() {
		return v.v.Interface()
	}
	return nil
}

// Checks whether two values are containing the same value or object.
func (v *Value) EqualValueTo(other *Value) bool {
	return v.Interface() == other.Interface()
}
<commit_msg>Remove unnecessary import.<commit_after>package pongo2

import (
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

type Value struct {
	v reflect.Value
}

// Converts any given value to a pongo2.Value
// Usually being used within own functions passed to a template
// through a Context or within filter functions.
//
// Example:
//     AsValue("my string")
func AsValue(i interface{}) *Value {
	return &Value{
		v: reflect.ValueOf(i),
	}
}

func (v *Value) getResolvedValue() reflect.Value {
	if v.v.IsValid() && v.v.Kind() == reflect.Ptr {
		return v.v.Elem()
	}
	return v.v
}

// Checks whether the underlying value is a string
func (v *Value) IsString() bool {
	return v.getResolvedValue().Kind() == reflect.String
}

// Checks whether the underlying value is a bool
func (v *Value) IsBool() bool {
	return v.getResolvedValue().Kind() == reflect.Bool
}

// Checks whether the underlying value is a float
func (v *Value) IsFloat() bool {
	return v.getResolvedValue().Kind() == reflect.Float32 ||
		v.getResolvedValue().Kind() == reflect.Float64
}

// Checks whether the underlying value is an integer
func (v *Value) IsInteger() bool {
	return v.getResolvedValue().Kind() == reflect.Int ||
		v.getResolvedValue().Kind() == reflect.Int8 ||
		v.getResolvedValue().Kind() == reflect.Int16 ||
		v.getResolvedValue().Kind() == reflect.Int32 ||
		v.getResolvedValue().Kind() == reflect.Int64 ||
		v.getResolvedValue().Kind() == reflect.Uint ||
		v.getResolvedValue().Kind() == reflect.Uint8 ||
		v.getResolvedValue().Kind() == reflect.Uint16 ||
		v.getResolvedValue().Kind() == reflect.Uint32 ||
		v.getResolvedValue().Kind() == reflect.Uint64
}

// Checks whether the underlying value is either an integer
// or a float.
func (v *Value) IsNumber() bool {
	return v.IsInteger() || v.IsFloat()
}

// Checks whether the underlying value is NIL
func (v *Value) IsNil() bool {
	//fmt.Printf("%+v\n", v.getResolvedValue().Type().String())
	return !v.getResolvedValue().IsValid()
}

// Returns a string for the underlying value. If this value is not
// of type string, pongo2 tries to convert it. Currently the following
// types for underlying values are supported:
//
//     1. string
//     2. int/uint (any size)
//     3. float (any precision)
//     4. bool
//     5. time.Time
//     6. String() will be called on the underlying value if provided
//
// NIL values will lead to an empty string. Unsupported types are leading
// to their respective type name.
func (v *Value) String() string {
	if v.IsNil() {
		return ""
	}

	switch v.getResolvedValue().Kind() {
	case reflect.String:
		return v.getResolvedValue().String()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return strconv.FormatInt(v.getResolvedValue().Int(), 10)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return strconv.FormatUint(v.getResolvedValue().Uint(), 10)
	case reflect.Float32, reflect.Float64:
		return fmt.Sprintf("%f", v.getResolvedValue().Float())
	case reflect.Bool:
		if v.Bool() {
			return "True"
		} else {
			return "False"
		}
	case reflect.Struct:
		if t, ok := v.Interface().(fmt.Stringer); ok {
			return t.String()
		}
	}

	logf("Value.String() not implemented for type: %s\n", v.getResolvedValue().Kind().String())
	return v.getResolvedValue().String()
}

// Returns the underlying value as an integer (converts the underlying
// value, if necessary). If it's not possible to convert the underlying value,
// it will return 0.
func (v *Value) Integer() int {
	switch v.getResolvedValue().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return int(v.getResolvedValue().Int())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return int(v.getResolvedValue().Uint())
	case reflect.Float32, reflect.Float64:
		return int(v.getResolvedValue().Float())
	case reflect.String:
		// Try to convert from string to int (base 10)
		f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
		if err != nil {
			return 0
		}
		return int(f)
	default:
		logf("Value.Integer() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return 0
	}
}

// Returns the underlying value as a float (converts the underlying
// value, if necessary). If it's not possible to convert the underlying value,
// it will return 0.0.
func (v *Value) Float() float64 {
	switch v.getResolvedValue().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return float64(v.getResolvedValue().Int())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return float64(v.getResolvedValue().Uint())
	case reflect.Float32, reflect.Float64:
		return v.getResolvedValue().Float()
	case reflect.String:
		// Try to convert from string to float64 (base 10)
		f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
		if err != nil {
			return 0.0
		}
		return f
	default:
		logf("Value.Float() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return 0.0
	}
}

// Returns the underlying value as bool. If the value is not bool, false
// will always be returned. If you're looking for true/false-evaluation of the
// underlying value, have a look on the IsTrue()-function.
func (v *Value) Bool() bool {
	switch v.getResolvedValue().Kind() {
	case reflect.Bool:
		return v.getResolvedValue().Bool()
	default:
		logf("Value.Bool() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return false
	}
}

// Tries to evaluate the underlying value the Pythonic-way:
//
// Returns TRUE in one the following cases:
//
//     * int != 0
//     * uint != 0
//     * float != 0.0
//     * len(array/chan/map/slice/string) > 0
//     * bool == true
//     * underlying value is a struct
//
// Otherwise returns always FALSE.
func (v *Value) IsTrue() bool {
	switch v.getResolvedValue().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.getResolvedValue().Int() != 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return v.getResolvedValue().Uint() != 0
	case reflect.Float32, reflect.Float64:
		return v.getResolvedValue().Float() != 0
	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
		return v.getResolvedValue().Len() > 0
	case reflect.Bool:
		return v.getResolvedValue().Bool()
	case reflect.Struct:
		return true // struct instance is always true
	default:
		logf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return false
	}
}

// Tries to negate the underlying value. It's mainly used for
// the NOT-operator and in conjunction with a call to
// return_value.IsTrue() afterwards.
//
// Example:
//     AsValue(1).Negate().IsTrue() == false
func (v *Value) Negate() *Value {
	switch v.getResolvedValue().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if v.Integer() != 0 {
			return AsValue(0)
		} else {
			return AsValue(1)
		}
	case reflect.Float32, reflect.Float64:
		if v.Float() != 0.0 {
			return AsValue(float64(0.0))
		} else {
			return AsValue(float64(1.1))
		}
	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
		return AsValue(v.getResolvedValue().Len() == 0)
	case reflect.Bool:
		return AsValue(!v.getResolvedValue().Bool())
	default:
		logf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return AsValue(true)
	}
}

// Returns the length for an array, chan, map, slice or string.
// Otherwise it will return 0.
func (v *Value) Len() int {
	switch v.getResolvedValue().Kind() {
	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
		return v.getResolvedValue().Len()
	default:
		logf("Value.Len() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return 0
	}
}

// Slices an array, slice or string. Otherwise it will
// return an empty []int.
func (v *Value) Slice(i, j int) *Value {
	switch v.getResolvedValue().Kind() {
	case reflect.Array, reflect.Slice, reflect.String:
		return AsValue(v.getResolvedValue().Slice(i, j).Interface())
	default:
		logf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return AsValue([]int{})
	}
}

// Get the i-th item of an array, slice or string. Otherwise
// it will return NIL.
func (v *Value) Index(i int) *Value {
	switch v.getResolvedValue().Kind() {
	case reflect.Array, reflect.Slice:
		if i >= v.Len() {
			return AsValue(nil)
		}
		return AsValue(v.getResolvedValue().Index(i).Interface())
	case reflect.String:
		return AsValue(v.getResolvedValue().Slice(i, i+1).Interface())
	default:
		logf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return AsValue([]int{})
	}
}

// Checks whether the underlying value (which must be of type struct, map,
// string, array or slice) contains of another Value (e. g. used to check
// whether a struct contains of a specific field or a map contains a specific key).
//
// Example:
//     AsValue("Hello, World!").Contains(AsValue("World")) == true
func (v *Value) Contains(other *Value) bool {
	switch v.getResolvedValue().Kind() {
	case reflect.Struct:
		field_value := v.getResolvedValue().FieldByName(other.String())
		return field_value.IsValid()
	case reflect.Map:
		var map_value reflect.Value
		switch other.Interface().(type) {
		case int:
			map_value = v.getResolvedValue().MapIndex(other.getResolvedValue())
		case string:
			map_value = v.getResolvedValue().MapIndex(other.getResolvedValue())
		default:
			logf("Value.Contains() does not support lookup type '%s'\n", other.getResolvedValue().Kind().String())
			return false
		}

		return map_value.IsValid()
	case reflect.String:
		return strings.Contains(v.getResolvedValue().String(), other.String())

	// TODO: reflect.Array, reflect.Slice

	default:
		logf("Value.Contains() not available for type: %s\n", v.getResolvedValue().Kind().String())
		return false
	}
}

// Checks whether the underlying value is of type array, slice or string.
// You normally would use CanSlice() before using the Slice() operation.
func (v *Value) CanSlice() bool {
	switch v.getResolvedValue().Kind() {
	case reflect.Array, reflect.Slice, reflect.String:
		return true
	}
	return false
}

// Iterates over a map, array, slice or a string. It calls the
// function's first argument for every value with the following arguments:
//
//     idx      current 0-index
//     count    total amount of items
//     key      *Value for the key or item
//     value    *Value (only for maps, the respective value for a specific key)
//
// If the underlying value has no items or is not one of the types above,
// the empty function (function's second argument) will be called.
func (v *Value) Iterate(fn func(idx, count int, key, value *Value) bool, empty func()) {
	switch v.getResolvedValue().Kind() {
	case reflect.Map:
		keys := v.getResolvedValue().MapKeys()
		keyLen := len(keys)
		for idx, key := range keys {
			value := v.getResolvedValue().MapIndex(key)
			if !fn(idx, keyLen, &Value{key}, &Value{value}) {
				return
			}
		}
		if keyLen == 0 {
			empty()
		}
		return // done
	case reflect.Array, reflect.Slice:
		itemCount := v.getResolvedValue().Len()
		if itemCount > 0 {
			for i := 0; i < itemCount; i++ {
				if !fn(i, itemCount, &Value{v.getResolvedValue().Index(i)}, nil) {
					return
				}
			}
		} else {
			empty()
		}
		return // done
	case reflect.String:
		// TODO: Not utf8-compatible (utf8-decoding neccessary)
		charCount := v.getResolvedValue().Len()
		if charCount > 0 {
			for i := 0; i < charCount; i++ {
				if !fn(i, charCount, &Value{v.getResolvedValue().Slice(i, i+1)}, nil) {
					return
				}
			}
		} else {
			empty()
		}
		return // done
	default:
		logf("Value.Iterate() not available for type: %s\n", v.getResolvedValue().Kind().String())
	}
	empty()
}

// Gives you access to the underlying value.
func (v *Value) Interface() interface{} {
	if v.v.IsValid() {
		return v.v.Interface()
	}
	return nil
}

// Checks whether two values are containing the same value or object.
func (v *Value) EqualValueTo(other *Value) bool {
	return v.Interface() == other.Interface()
}
<|endoftext|>


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

package main

import (
	"fmt"
	"strings"

	"github.com/minio-io/mc/pkg/console"
	"github.com/minio-io/minio/pkg/iodine"
	"github.com/minio-io/minio/pkg/utils/log"
)

const (
	pathSeparator = "/"
)

// doCopyCmdRecursive - copy bucket to bucket
func doCopyCmdRecursive(manager clientManager, sourceURLConfigMap map[string]*hostConfig, targetURLConfigMap map[string]*hostConfig) (string, error) {
	for sourceURL, sourceConfig := range sourceURLConfigMap {
		// get source list
		clnt, err := manager.getNewClient(sourceURL, sourceConfig, false)
		if err != nil {
			return fmt.Sprintf("instantiating a new client for URL [%s]", sourceURL), iodine.New(err, nil)
		}
		items, err := clnt.List()
		if err != nil {
			return fmt.Sprintf("listing objects failed for URL [%s]", sourceURL), iodine.New(err, nil)
		}
		for _, item := range items {
			// populate source urls
			sourceURLs := make(map[string]*hostConfig)
			sourceObjectURL := strings.TrimSuffix(sourceURL, pathSeparator) + pathSeparator + item.Name
			sourceURLs[sourceObjectURL] = sourceConfig
			// populate target urls
			targetURLs := make(map[string]*hostConfig)
			for targetURL, targetConfig := range targetURLConfigMap {
				targetObjectURL := strings.TrimSuffix(targetURL, pathSeparator) + pathSeparator + item.Name
				targetURLs[targetObjectURL] = targetConfig
			}
			humanReadable, err := doCopyCmd(manager, sourceURLs, targetURLs)
			if err != nil {
				err := iodine.New(err, nil)
				log.Debug.Println(err)
				console.Errorf("%s with following reason: [%s]\n", humanReadable, iodine.ToError(err))
			}
		}
	}
	return "", nil
}
<commit_msg>Remove printing stack trace in cmd cp recursive<commit_after>/*
 * Mini Copy, (C) 2015 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"fmt"
	"strings"

	"github.com/minio-io/mc/pkg/console"
	"github.com/minio-io/minio/pkg/iodine"
	"github.com/minio-io/minio/pkg/utils/log"
)

const (
	pathSeparator = "/"
)

// doCopyCmdRecursive - copy bucket to bucket
func doCopyCmdRecursive(manager clientManager, sourceURLConfigMap map[string]*hostConfig, targetURLConfigMap map[string]*hostConfig) (string, error) {
	for sourceURL, sourceConfig := range sourceURLConfigMap {
		// get source list
		clnt, err := manager.getNewClient(sourceURL, sourceConfig, false)
		if err != nil {
			return fmt.Sprintf("instantiating a new client for URL [%s]", sourceURL), iodine.New(err, nil)
		}
		items, err := clnt.List()
		if err != nil {
			return fmt.Sprintf("listing objects failed for URL [%s]", sourceURL), iodine.New(err, nil)
		}
		for _, item := range items {
			// populate source urls
			sourceURLs := make(map[string]*hostConfig)
			sourceObjectURL := strings.TrimSuffix(sourceURL, pathSeparator) + pathSeparator + item.Name
			sourceURLs[sourceObjectURL] = sourceConfig
			// populate target urls
			targetURLs := make(map[string]*hostConfig)
			for targetURL, targetConfig := range targetURLConfigMap {
				targetObjectURL := strings.TrimSuffix(targetURL, pathSeparator) + pathSeparator + item.Name
				targetURLs[targetObjectURL] = targetConfig
			}
			humanReadable, err := doCopyCmd(manager, sourceURLs, targetURLs)
			if err != nil {
				err := iodine.New(err, nil)
				log.Debug.Println(err)
				console.Errorln(humanReadable)
			}
		}
	}
	return "", nil
}
<|endoftext|>


<commit_before>// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.

package main

import (
	"flag"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/chihaya/chihaya/config"
	"github.com/chihaya/chihaya/server"
	"github.com/chihaya/chihaya/tracker"

	_ "github.com/chihaya/chihaya/server/store/middleware/ip"
	_ "github.com/chihaya/chihaya/server/http"
)

var configPath string

func init() {
	flag.StringVar(&configPath, "config", "", "path to the configuration file")
}

func main() {
	flag.Parse()

	cfg, err := config.Open(configPath)
	if err != nil {
		log.Fatal("failed to load config: " + err.Error())
	}

	tkr, err := tracker.NewTracker(&cfg.Tracker)
	if err != nil {
		log.Fatal("failed to create tracker: " + err.Error())
	}

	pool, err := server.StartPool(cfg.Servers, tkr)
	if err != nil {
		log.Fatal("failed to create server pool: " + err.Error())
	}

	shutdown := make(chan os.Signal)
	signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM)
	<-shutdown
	pool.Stop()
}
<commit_msg>cmd/chihaya: added useful dependencies<commit_after>// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.

package main

import (
	"flag"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/chihaya/chihaya/config"
	"github.com/chihaya/chihaya/server"
	"github.com/chihaya/chihaya/tracker"

	_ "github.com/chihaya/chihaya/server/http"
	_ "github.com/chihaya/chihaya/server/store"
	_ "github.com/chihaya/chihaya/server/store/memory"
	_ "github.com/chihaya/chihaya/server/store/middleware/client"
	_ "github.com/chihaya/chihaya/server/store/middleware/ip"
)

var configPath string

func init() {
	flag.StringVar(&configPath, "config", "", "path to the configuration file")
}

func main() {
	flag.Parse()

	cfg, err := config.Open(configPath)
	if err != nil {
		log.Fatal("failed to load config: " + err.Error())
	}

	tkr, err := tracker.NewTracker(&cfg.Tracker)
	if err != nil {
		log.Fatal("failed to create tracker: " + err.Error())
	}

	pool, err := server.StartPool(cfg.Servers, tkr)
	if err != nil {
		log.Fatal("failed to create server pool: " + err.Error())
	}

	shutdown := make(chan os.Signal)
	signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM)
	<-shutdown
	pool.Stop()
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/urfave/cli"
	"time"
)

var statsCmd = cli.Command{
	Name:   "stats",
	Usage:  "view stats",
	Action: stats,
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "start-date",
			Usage: "start date, expects a date in format 2006-01-02",
		},
		cli.StringFlag{
			Name:  "end-date",
			Usage: "end date, expects a date in format 2006-01-02",
		},
	},
}

func stats(c *cli.Context) error {
	start, _ := time.Parse("2006-01-02", c.String("start-date"))
	if start.IsZero() {
		return errors.New("Invalid argument: supply a valid --start-date")
	}

	end, _ := time.Parse("2006-01-02", c.String("end-date"))
	if end.IsZero() {
		return errors.New("Invalid argument: supply a valid --end-date")
	}

	result, err := app.database.GetAggregatedSiteStats(start, end)
	if err != nil {
		return err
	}

	fmt.Printf("%s - %s\n", start.Format("Jan 01, 2006"), end.Format("Jan 01, 2006"))
	fmt.Printf("===========================\n")
	fmt.Printf("Visitors: \t%d\n", result.Visitors)
	fmt.Printf("Pageviews: \t%d\n", result.Pageviews)
	fmt.Printf("Sessions: \t%d\n", result.Sessions)
	fmt.Printf("Avg duration: \t%s\n", result.FormattedDuration())
	fmt.Printf("Bounce rate: \t%.0f%%\n", result.BounceRate*100.00)
	return nil
}
<commit_msg>add --json flag to stats command<commit_after>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/urfave/cli"
	"os"
	"time"
)

var statsCmd = cli.Command{
	Name:   "stats",
	Usage:  "view stats",
	Action: stats,
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "start-date",
			Usage: "start date, expects a date in format 2006-01-02",
		},
		cli.StringFlag{
			Name:  "end-date",
			Usage: "end date, expects a date in format 2006-01-02",
		},
		cli.BoolFlag{
			Name:  "json",
			Usage: "get a json response",
		},
	},
}

func stats(c *cli.Context) error {
	start, _ := time.Parse("2006-01-02", c.String("start-date"))
	if start.IsZero() {
		return errors.New("Invalid argument: supply a valid --start-date")
	}

	end, _ := time.Parse("2006-01-02", c.String("end-date"))
	if end.IsZero() {
		return errors.New("Invalid argument: supply a valid --end-date")
	}

	result, err := app.database.GetAggregatedSiteStats(start, end)
	if err != nil {
		return err
	}

	if c.Bool("json") {
		if err := json.NewEncoder(os.Stdout).Encode(result); err != nil {
			return err
		}

		return nil
	}

	fmt.Printf("%s - %s\n", start.Format("Jan 01, 2006"), end.Format("Jan 01, 2006"))
	fmt.Printf("===========================\n")
	fmt.Printf("Visitors: \t%d\n", result.Visitors)
	fmt.Printf("Pageviews: \t%d\n", result.Pageviews)
	fmt.Printf("Sessions: \t%d\n", result.Sessions)
	fmt.Printf("Avg duration: \t%s\n", result.FormattedDuration())
	fmt.Printf("Bounce rate: \t%.0f%%\n", result.BounceRate*100.00)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"io"
	"strings"

	"github.com/DeedleFake/wdte/scanner"
)

type Grammar struct {
	NTerms map[string]NTerm
}

func LoadGrammar(r io.Reader) (g Grammar, err error) {
	g = Grammar{
		NTerms: make(map[string]NTerm),
	}

	var cur NTerm
	s := bufio.NewScanner(r)
	for s.Scan() {
		line := s.Text()

		parts := strings.SplitN(line, "->", 2)
		if len(parts) < 2 {
			parts = strings.SplitN(line, "|", 2)
			parts[0] = cur.Name
		}
		name := strings.TrimSpace(parts[0])
		if nt, ok := g.NTerms[name]; ok {
			cur = nt
		}
		cur.Name = name
	}
	if s.Err() != nil {
		return g, s.Err()
	}

	panic("Not implemented.")
}

type Term scanner.TokenType

type NTerm struct {
	Name   string
	First  map[scanner.TokenType]struct{}
	Follow map[scanner.TokenType]struct{}
}

type Epsilon struct{}
<commit_msg>cmd/pgen: Working on calculating first and follow sets.<commit_after>package main

import (
	"bufio"
	"io"
	"math"
	"strings"

	"github.com/DeedleFake/wdte/scanner"
)

type Grammar struct {
	First  map[NTerm]TermSet
	Follow map[NTerm]TermSet
}

func LoadGrammar(r io.Reader) (g Grammar, err error) {
	var cur NTerm
	rules := make(map[NTerm][][]interface{})

	s := bufio.NewScanner(r)
	for s.Scan() {
		line := strings.TrimSpace(s.Text())
		if (len(line) == 0) || (line[0] == '#') {
			continue
		}

		parts := strings.SplitN(line, "->", 2)
		if len(parts) < 2 {
			parts = strings.SplitN(line, "|", 2)
			parts[0] = string(cur)
		}
		cur = NTerm(strings.TrimSpace(parts[0]))

		parts = strings.Fields(parts[1])

		rule := make([]interface{}, 0, len(parts))
		for _, p := range parts {
			rule = append(rule, part(p))
		}
		rules[cur] = append(rules[cur], rule)
	}
	if s.Err() != nil {
		return g, s.Err()
	}

	g.First = make(map[NTerm]TermSet)
	for nt := range rules {
		g.first(nt, rules)
	}

	g.Follow = make(map[NTerm]TermSet)
	for nt := range rules {
		g.follow(nt, rules)
	}

	return g, nil
}

func (g *Grammar) first(nt NTerm, rules map[NTerm][][]interface{}) TermSet {
	if s, ok := g.First[nt]; ok {
		return s
	}
	g.First[nt] = make(TermSet)

	for _, rule := range rules[nt] {
	loop:
		for _, p := range rule {
			switch p := p.(type) {
			case Term:
				g.First[nt].Add(p)

			case NTerm:
				g.First[nt].AddAll(g.first(p, rules))

				if !g.nullable(p, rules) {
					break loop
				}

			case Epsilon:
				g.First[nt].Add(Term{Type: EpsilonToken})
			}
		}
	}

	return g.First[nt]
}

func (g *Grammar) follow(nt NTerm, rules map[NTerm][][]interface{}) TermSet {
	g.Follow = make(map[NTerm]TermSet)

	panic("Not implemented.")
}

func (g *Grammar) nullable(nt NTerm, rules map[NTerm][][]interface{}) bool {
	return g.first(nt, rules).Contains(Term{Type: EpsilonToken})
}

func part(str string) interface{} {
	if (str[0] == '<') && (str[len(str)-1] == '>') {
		return NTerm(str)
	}

	if str == "ε" {
		return Epsilon{}
	}

	switch str {
	case "number":
		return Term{Type: scanner.Number}
	case "string":
		return Term{Type: scanner.String}
	case "id":
		return Term{Type: scanner.ID}
	}

	return Term{
		Type:    scanner.Keyword,
		Keyword: str,
	}
}

const EpsilonToken scanner.TokenType = scanner.TokenType(math.MaxUint32)

type Term struct {
	Type    scanner.TokenType
	Keyword string
}

type NTerm string

type Epsilon struct{}

type TermSet map[Term]struct{}

func (s TermSet) Add(t Term) {
	s[t] = struct{}{}
}

func (s TermSet) AddAll(o TermSet) {
	for t := range o {
		s.Add(t)
	}
}

func (s TermSet) Contains(t Term) bool {
	_, ok := s[t]
	return ok
}
<|endoftext|>


<commit_before>package controller

import (
	"encoding/json"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"path/filepath"
	"strings"

	"github.com/longkai/xiaolongtongxue.com/config"
	"github.com/longkai/xiaolongtongxue.com/github"
	"github.com/longkai/xiaolongtongxue.com/medium"
	"github.com/longkai/xiaolongtongxue.com/render"
)

const (
	pageSize = 7
)

var (
	templs = template.Must(template.New(`sakura`).Funcs(template.FuncMap{
		`escapeCDN`: EscapeCDN,
		`bgImg`:     render.BgImg,
		`tags`:      render.Tags,
		`format`:    render.Format,
		`daysAgo`:   render.DaysAgo,
	}).ParseGlob(`templ/*`))

	env    *config.Configuration
	sakura render.Engine
)

// Ctrl main controller.
func Ctrl() {
	env = config.Env
	sakura = render.NewSakura()
	sakura.Post(env.Repo)
	initFS(env.Meta.CDN, env.Meta.Origin)

	github.Init(`/api/github/hook`, env.Repo, env.HookSecret, env.AccessToken, revalidate)
	if env.MediumToken != "" {
		medium.Init(env.MediumToken, env.Meta.Origin)
	}

	http.HandleFunc("/", home)
	http.HandleFunc("/ls/", ls)
	for _, v := range config.Roots() {
		installHanlder(v)
	}
}

var installHanlder = func(p string) {
	p = fmt.Sprintf("/%s/", p)
	log.Printf("mapping url %s*", p)
	http.HandleFunc(p, entry)
}

var revalidate = func(a, m, d []string) {
	for i := range a {
		p := filepath.Join(env.Repo, a[i])
		// check if new router(i.e., URL starts with /balalaba/...)
		if v := config.Root(p); v != "" {
			installHanlder(v)
		}
		// TODO: better handling path travel stuffs...
		if env.MediumToken != "" && config.Ignored(p) && strings.HasSuffix(p, ".md") {
			// meidum only allow posting new stuff, no other editing allow right now...
			go func() {
				if err := medium.Post(p); err != nil {
					log.Printf("medium.Post(%q) fail: %v", p, err)
				}
			}()
		}
	}
	if err := sakura.Revalidate(a, m, d); err != nil {
		log.Printf("revalidate fail: %v", err)
	}
}

func home(w http.ResponseWriter, r *http.Request) {
	if r.RequestURI != "/" {
		http.NotFound(w, r)
		return
	}

	v, err := sakura.Ls("", pageSize)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	data := &struct {
		List interface{}
		Meta interface{}
	}{v, config.Env.Meta}
	if err := templs.ExecuteTemplate(w, "index.html", data); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func entry(w http.ResponseWriter, r *http.Request) {
	if !strings.HasSuffix(r.RequestURI, "/") {
		serveFile(w, r)
		return
	}

	v, err := sakura.Get(r.RequestURI)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	data := &struct {
		A    interface{}
		Meta interface{}
	}{v, config.Env.Meta}
	if err = templs.ExecuteTemplate(w, "entry.html", data); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func ls(w http.ResponseWriter, r *http.Request) {
	key := r.RequestURI[len("/ls"):]
	if len(key) <= 1 { // `/` is not allowed
		http.Error(w, fmt.Sprintf("RequestURI %q, last segment not found", r.RequestURI), http.StatusBadRequest)
		return
	}
	v, err := sakura.Ls(key, pageSize)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	b, err := json.Marshal(v)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(b)
}
<commit_msg>Fix a silly bug without `!`<commit_after>package controller

import (
	"encoding/json"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"path/filepath"
	"strings"

	"github.com/longkai/xiaolongtongxue.com/config"
	"github.com/longkai/xiaolongtongxue.com/github"
	"github.com/longkai/xiaolongtongxue.com/medium"
	"github.com/longkai/xiaolongtongxue.com/render"
)

const (
	pageSize = 7
)

var (
	templs = template.Must(template.New(`sakura`).Funcs(template.FuncMap{
		`escapeCDN`: EscapeCDN,
		`bgImg`:     render.BgImg,
		`tags`:      render.Tags,
		`format`:    render.Format,
		`daysAgo`:   render.DaysAgo,
	}).ParseGlob(`templ/*`))

	env    *config.Configuration
	sakura render.Engine
)

// Ctrl main controller.
func Ctrl() {
	env = config.Env
	sakura = render.NewSakura()
	sakura.Post(env.Repo)
	initFS(env.Meta.CDN, env.Meta.Origin)

	github.Init(`/api/github/hook`, env.Repo, env.HookSecret, env.AccessToken, revalidate)
	if env.MediumToken != "" {
		medium.Init(env.MediumToken, env.Meta.Origin)
	}

	http.HandleFunc("/", home)
	http.HandleFunc("/ls/", ls)
	for _, v := range config.Roots() {
		installHanlder(v)
	}
}

var installHanlder = func(p string) {
	p = fmt.Sprintf("/%s/", p)
	log.Printf("mapping url %s*", p)
	http.HandleFunc(p, entry)
}

var revalidate = func(a, m, d []string) {
	for i := range a {
		p := filepath.Join(env.Repo, a[i])
		// check if new router(i.e., URL starts with /balalaba/...)
		if v := config.Root(p); v != "" {
			installHanlder(v)
		}
		// TODO: better handling path travel stuffs...
		if env.MediumToken != "" && !config.Ignored(p) && strings.HasSuffix(p, ".md") {
			// meidum only allow posting new stuff, no other editing allow right now...
			go func() {
				if err := medium.Post(p); err != nil {
					log.Printf("medium.Post(%q) fail: %v", p, err)
				}
			}()
		}
	}
	if err := sakura.Revalidate(a, m, d); err != nil {
		log.Printf("revalidate fail: %v", err)
	}
}

func home(w http.ResponseWriter, r *http.Request) {
	if r.RequestURI != "/" {
		http.NotFound(w, r)
		return
	}

	v, err := sakura.Ls("", pageSize)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	data := &struct {
		List interface{}
		Meta interface{}
	}{v, config.Env.Meta}
	if err := templs.ExecuteTemplate(w, "index.html", data); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func entry(w http.ResponseWriter, r *http.Request) {
	if !strings.HasSuffix(r.RequestURI, "/") {
		serveFile(w, r)
		return
	}

	v, err := sakura.Get(r.RequestURI)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	data := &struct {
		A    interface{}
		Meta interface{}
	}{v, config.Env.Meta}
	if err = templs.ExecuteTemplate(w, "entry.html", data); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func ls(w http.ResponseWriter, r *http.Request) {
	key := r.RequestURI[len("/ls"):]
	if len(key) <= 1 { // `/` is not allowed
		http.Error(w, fmt.Sprintf("RequestURI %q, last segment not found", r.RequestURI), http.StatusBadRequest)
		return
	}
	v, err := sakura.Ls(key, pageSize)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	b, err := json.Marshal(v)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write(b)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"sort"
	"strings"
	"time"

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

var (
	Info *log.Logger
)

func main() {
	initLogs()
	flag.Parse()
	err := parseFlags(flag.Args())
	if err != nil {
		log.Fatalln(err.Error())
		os.Exit(1)
	}
}

func parseFlags(args []string) error {
	if len(args) < 1 {
		printHelp()
		return nil
	}
	cmd := args[0]
	switch cmd {
	case "new":
		if len(args) < 2 {
			return errors.New("No infile specified")
		}
		writeNewWorkflowFile(args[1])
	case "audit2html", "audit2htmlflat":
		if len(args) < 2 {
			return errors.New("No infile specified")
		}
		inFile := args[1]
		if len(args) < 3 {
			return errors.New("No outfile specified")
		}
		outFile := args[2]
		err := errors.New("")
		if cmd == "audit2htmlflat" {
			err = auditInfoToHTML(inFile, outFile, true)
		} else {
			err = auditInfoToHTML(inFile, outFile, false)
		}
		if err != nil {
			return errors.Wrap(err, "Could not convert Audit file to HTML")
		}
	default:
		return errors.New("Unknown command: " + cmd)
	}
	return nil
}

func printNewUsage() {
	Info.Println(`
Usage:
$ scipipe new <filename.go>`)
}
func printAudit2HTMLUsage() {
	Info.Print(`
Usage:
$ scipipe audit2html <infile.audit.json> [<outfile.html>]
`)
}

func printHelp() {
	Info.Printf(`________________________________________________________________________

SciPipe (http://scipipe.org)
Version: %s
________________________________________________________________________

Usage:
$ scipipe <command> [command options]

Available commands:
$ scipipe new <filename.go>
$ scipipe audit2html <infile.audit.json> [<outfile.html>]
$ scipipe audit2htmlflat <infile.audit.json> [<outfile.html>]
________________________________________________________________________
`, scipipe.Version)
}

func writeNewWorkflowFile(fileName string) {
	f, err := os.Create(fileName)
	if err != nil {
		scipipe.Fail("Could not create file:", fileName)
	}
	defer f.Close()
	_, err = f.Write([]byte(workflowStub))
	if err != nil {
		scipipe.Fail("Could not write to file:", fileName)
	}
	Info.Println("Successfully wrote new workflow file to:", fileName, "\n\nNow you can run it with:\ngo run ", fileName)
}

func auditInfoToHTML(inFilePath string, outFilePath string, flatten bool) error {
	ip := scipipe.NewFileIP(strings.Replace(inFilePath, ".audit.json", "", 1))
	auditInfo := ip.AuditInfo()

	outHTML := fmt.Sprintf(`<html><head><title>Audit info for: %s</title></head><body>`, ip.Path())
	if flatten {
		auditInfosByID := extractAuditInfosByID(auditInfo)
		auditInfosByStartTime := sortAuditInfosByStartTime(auditInfosByID)
		for _, ai := range auditInfosByStartTime {
			ai.Upstream = nil
			outHTML += formatTaskHTML(ai.ProcessName, ai)
		}
	} else {
		outHTML += formatTaskHTML(ip.Path(), auditInfo)
	}
	outHTML += `</body></html>`

	if _, err := os.Stat(outFilePath); os.IsExist(err) {
		return errors.Wrap(err, "File already exists:"+outFilePath)
	}
	outFile, err := os.Create(outFilePath)
	if err != nil {
		return errors.Wrap(err, "Could not create file:"+outFilePath)
	}
	outFile.WriteString(outHTML)
	outFile.Close()
	return nil
}

func formatTaskHTML(fileName string, auditInfo *scipipe.AuditInfo) (outHTML string) {
	outHTML = "
\n"
	outHTML += fmt.Sprintf(`<tr><td colspan="2" style="font-size: 1.2em; font-weight: bold; text-align: left; padding: .2em .4em; ">%s</td></tr>`, fileName)
	outHTML += fmt.Sprintf("
ID:	%s
\n", auditInfo.ID)
	outHTML += fmt.Sprintf("
Process:	%s
\n", auditInfo.ProcessName)
	outHTML += fmt.Sprintf("
Command:
%s

\n", auditInfo.Command)

	params := []string{}
	for pname, p := range auditInfo.Params {
		params = append(params, fmt.Sprintf("%s: %s", pname, p))
	}
	outHTML += fmt.Sprintf("
Parameters:	%s
\n", strings.Join(params, ", "))
	tags := []string{}
	for pname, p := range auditInfo.Tags {
		tags = append(tags, fmt.Sprintf("%s: %s", pname, p))
	}
	outHTML += fmt.Sprintf("
Tags:
%v

\n", strings.Join(tags, ", "))

	outHTML += fmt.Sprintf("
Start time:	%v
\n", auditInfo.StartTime)
	outHTML += fmt.Sprintf("
Finish time:	%v
\n", auditInfo.FinishTime)
	outHTML += fmt.Sprintf("
Execution time:	%d ms
\n", auditInfo.ExecTimeMS)
	upStreamHTML := ""
	for filePath, uai := range auditInfo.Upstream {
		upStreamHTML += formatTaskHTML(filePath, uai)
	}
	if outHTML != "" {
		outHTML += "
Upstreams:	" + upStreamHTML + "
\n"
	}
	outHTML += "
\n"
	return
}

func extractAuditInfosByID(auditInfo *scipipe.AuditInfo) (auditInfosByID map[string]*scipipe.AuditInfo) {
	auditInfosByID = make(map[string]*scipipe.AuditInfo)
	auditInfosByID[auditInfo.ID] = auditInfo
	for _, ai := range auditInfo.Upstream {
		auditInfosByID = mergeStringAuditInfoMaps(auditInfosByID, extractAuditInfosByID(ai))
	}
	return auditInfosByID
}

func mergeStringAuditInfoMaps(ms ...map[string]*scipipe.AuditInfo) (merged map[string]*scipipe.AuditInfo) {
	merged = make(map[string]*scipipe.AuditInfo)
	for _, m := range ms {
		for k, v := range m {
			merged[k] = v
		}
	}
	return merged
}

func sortAuditInfosByStartTime(auditInfosByID map[string]*scipipe.AuditInfo) []*scipipe.AuditInfo {
	sorted := []*scipipe.AuditInfo{}

	auditInfosByStartTime := map[time.Time]*scipipe.AuditInfo{}
	startTimes := []time.Time{}
	for _, ai := range auditInfosByID {
		auditInfosByStartTime[ai.StartTime] = ai
		startTimes = append(startTimes, ai.StartTime)
	}
	sort.Slice(startTimes, func(i, j int) bool { return startTimes[i].Before(startTimes[j]) })
	for _, t := range startTimes {
		sorted = append(sorted, auditInfosByStartTime[t])
	}
	return sorted
}
func initLogs() {
	Info = log.New(os.Stdout, "", 0)
}

func initLogsTest() {
	Info = log.New(ioutil.Discard, "", 0)
}

const (
	workflowStub = `// Workflow written in SciPipe.
// For more information about SciPipe, see: http://scipipe.org
package main

import sp "github.com/scipipe/scipipe"

func main() {
	// Create a workflow, using 4 cpu cores
	wf := sp.NewWorkflow("my_workflow", 4)

	// Initialize processes
	foo := wf.NewProc("fooer", "echo foo > {o:foo}")
	foo.SetPathStatic("foo", "foo.txt")

	f2b := wf.NewProc("foo2bar", "sed 's/foo/bar/g' {i:foo} > {o:bar}")
	f2b.SetPathExtend("foo", "bar", ".bar.txt")

	// From workflow dependency network
	f2b.In("foo").From(foo.Out("foo"))

	// Run the workflow
	wf.Run()
}`
)
<commit_msg>Initialize all logs used in scipipe, in scipipe cmd<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"sort"
	"strings"
	"time"

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

var (
	Info *log.Logger
)

func main() {
	scipipe.InitLogError()
	flag.Parse()
	err := parseFlags(flag.Args())
	if err != nil {
		log.Fatalln(err.Error())
		os.Exit(1)
	}
}

func parseFlags(args []string) error {
	if len(args) < 1 {
		printHelp()
		return nil
	}
	cmd := args[0]
	switch cmd {
	case "new":
		if len(args) < 2 {
			return errors.New("No infile specified")
		}
		writeNewWorkflowFile(args[1])
	case "audit2html", "audit2htmlflat":
		if len(args) < 2 {
			return errors.New("No infile specified")
		}
		inFile := args[1]
		if len(args) < 3 {
			return errors.New("No outfile specified")
		}
		outFile := args[2]
		err := errors.New("")
		if cmd == "audit2htmlflat" {
			err = auditInfoToHTML(inFile, outFile, true)
		} else {
			err = auditInfoToHTML(inFile, outFile, false)
		}
		if err != nil {
			return errors.Wrap(err, "Could not convert Audit file to HTML")
		}
	default:
		return errors.New("Unknown command: " + cmd)
	}
	return nil
}

func printNewUsage() {
	Info.Println(`
Usage:
$ scipipe new <filename.go>`)
}
func printAudit2HTMLUsage() {
	Info.Print(`
Usage:
$ scipipe audit2html <infile.audit.json> [<outfile.html>]
`)
}

func printHelp() {
	Info.Printf(`________________________________________________________________________

SciPipe (http://scipipe.org)
Version: %s
________________________________________________________________________

Usage:
$ scipipe <command> [command options]

Available commands:
$ scipipe new <filename.go>
$ scipipe audit2html <infile.audit.json> [<outfile.html>]
$ scipipe audit2htmlflat <infile.audit.json> [<outfile.html>]
________________________________________________________________________
`, scipipe.Version)
}

func writeNewWorkflowFile(fileName string) {
	f, err := os.Create(fileName)
	if err != nil {
		scipipe.Fail("Could not create file:", fileName)
	}
	defer f.Close()
	_, err = f.Write([]byte(workflowStub))
	if err != nil {
		scipipe.Fail("Could not write to file:", fileName)
	}
	Info.Println("Successfully wrote new workflow file to:", fileName, "\n\nNow you can run it with:\ngo run ", fileName)
}

func auditInfoToHTML(inFilePath string, outFilePath string, flatten bool) error {
	ip := scipipe.NewFileIP(strings.Replace(inFilePath, ".audit.json", "", 1))
	auditInfo := ip.AuditInfo()

	outHTML := fmt.Sprintf(`<html><head><title>Audit info for: %s</title></head><body>`, ip.Path())
	if flatten {
		auditInfosByID := extractAuditInfosByID(auditInfo)
		auditInfosByStartTime := sortAuditInfosByStartTime(auditInfosByID)
		for _, ai := range auditInfosByStartTime {
			ai.Upstream = nil
			outHTML += formatTaskHTML(ai.ProcessName, ai)
		}
	} else {
		outHTML += formatTaskHTML(ip.Path(), auditInfo)
	}
	outHTML += `</body></html>`

	if _, err := os.Stat(outFilePath); os.IsExist(err) {
		return errors.Wrap(err, "File already exists:"+outFilePath)
	}
	outFile, err := os.Create(outFilePath)
	if err != nil {
		return errors.Wrap(err, "Could not create file:"+outFilePath)
	}
	outFile.WriteString(outHTML)
	outFile.Close()
	return nil
}

func formatTaskHTML(fileName string, auditInfo *scipipe.AuditInfo) (outHTML string) {
	outHTML = "
\n"
	outHTML += fmt.Sprintf(`<tr><td colspan="2" style="font-size: 1.2em; font-weight: bold; text-align: left; padding: .2em .4em; ">%s</td></tr>`, fileName)
	outHTML += fmt.Sprintf("
ID:	%s
\n", auditInfo.ID)
	outHTML += fmt.Sprintf("
Process:	%s
\n", auditInfo.ProcessName)
	outHTML += fmt.Sprintf("
Command:
%s

\n", auditInfo.Command)

	params := []string{}
	for pname, p := range auditInfo.Params {
		params = append(params, fmt.Sprintf("%s: %s", pname, p))
	}
	outHTML += fmt.Sprintf("
Parameters:	%s
\n", strings.Join(params, ", "))
	tags := []string{}
	for pname, p := range auditInfo.Tags {
		tags = append(tags, fmt.Sprintf("%s: %s", pname, p))
	}
	outHTML += fmt.Sprintf("
Tags:
%v

\n", strings.Join(tags, ", "))

	outHTML += fmt.Sprintf("
Start time:	%v
\n", auditInfo.StartTime)
	outHTML += fmt.Sprintf("
Finish time:	%v
\n", auditInfo.FinishTime)
	outHTML += fmt.Sprintf("
Execution time:	%d ms
\n", auditInfo.ExecTimeMS)
	upStreamHTML := ""
	for filePath, uai := range auditInfo.Upstream {
		upStreamHTML += formatTaskHTML(filePath, uai)
	}
	if outHTML != "" {
		outHTML += "
Upstreams:	" + upStreamHTML + "
\n"
	}
	outHTML += "
\n"
	return
}

func extractAuditInfosByID(auditInfo *scipipe.AuditInfo) (auditInfosByID map[string]*scipipe.AuditInfo) {
	auditInfosByID = make(map[string]*scipipe.AuditInfo)
	auditInfosByID[auditInfo.ID] = auditInfo
	for _, ai := range auditInfo.Upstream {
		auditInfosByID = mergeStringAuditInfoMaps(auditInfosByID, extractAuditInfosByID(ai))
	}
	return auditInfosByID
}

func mergeStringAuditInfoMaps(ms ...map[string]*scipipe.AuditInfo) (merged map[string]*scipipe.AuditInfo) {
	merged = make(map[string]*scipipe.AuditInfo)
	for _, m := range ms {
		for k, v := range m {
			merged[k] = v
		}
	}
	return merged
}

func sortAuditInfosByStartTime(auditInfosByID map[string]*scipipe.AuditInfo) []*scipipe.AuditInfo {
	sorted := []*scipipe.AuditInfo{}

	auditInfosByStartTime := map[time.Time]*scipipe.AuditInfo{}
	startTimes := []time.Time{}
	for _, ai := range auditInfosByID {
		auditInfosByStartTime[ai.StartTime] = ai
		startTimes = append(startTimes, ai.StartTime)
	}
	sort.Slice(startTimes, func(i, j int) bool { return startTimes[i].Before(startTimes[j]) })
	for _, t := range startTimes {
		sorted = append(sorted, auditInfosByStartTime[t])
	}
	return sorted
}
func initLogs() {
	Info = log.New(os.Stdout, "", 0)
}

func initLogsTest() {
	Info = log.New(ioutil.Discard, "", 0)
}

const (
	workflowStub = `// Workflow written in SciPipe.
// For more information about SciPipe, see: http://scipipe.org
package main

import sp "github.com/scipipe/scipipe"

func main() {
	// Create a workflow, using 4 cpu cores
	wf := sp.NewWorkflow("my_workflow", 4)

	// Initialize processes
	foo := wf.NewProc("fooer", "echo foo > {o:foo}")
	foo.SetPathStatic("foo", "foo.txt")

	f2b := wf.NewProc("foo2bar", "sed 's/foo/bar/g' {i:foo} > {o:bar}")
	f2b.SetPathExtend("foo", "bar", ".bar.txt")

	// From workflow dependency network
	f2b.In("foo").From(foo.Out("foo"))

	// Run the workflow
	wf.Run()
}`
)
<|endoftext|>