<commit_before>package kdebug

import (
	"errors"
	"fmt"
	"io"
	"os"
	"reflect"
	"runtime"
)

func VarDump(s interface{}) {
	indent := ""
	switch s.(type) {
	case reflect.Value:
		varDump(s.(reflect.Value), indent, "")
	default:
		varDump(reflect.ValueOf(s), indent, "")
	}
	//varDump(reflect.ValueOf(s), indent, "")
}

func varDump(value reflect.Value, indent string, preStr string) {
	var vKind = value.Kind()
	rIndent := indent
	if preStr != "" {
		rIndent = preStr
	}

	switch {
	case vKind == 0:
		fmt.Printf("%s[%s] : %v\n", rIndent, "nil", value)

	//bool + int +uint
	case vKind < 12:
		fmt.Printf("%s[%s] : %v\n", rIndent, value.Type(), value)

	//uintptr
	case vKind == 12:
		//fmt.Printf("%s[%s] ", r_indent, value.Type())
		varDump(value, indent, fmt.Sprintf("%s[%s] --> ", rIndent, value.Type()))

	//float + complex
	case vKind < 17:
		fmt.Printf("%s[%s] : %v\n", rIndent, value.Type(), value)

	//Array
	case vKind == 17:
		fmt.Printf("%sarray[%s](%d) ==>\n", rIndent, value.Type(), value.Len())
		index := 0
		for {
			if index >= value.Len() {
				break
			}
			//fmt.Printf("%s[%d] :", r_indent+"    ", index)
			varDump(value.Index(index), "    "+indent, fmt.Sprintf("%s[%d] :", rIndent+"    ", index))
			index++
		}

	//chan\func\Interface
	case vKind < 21:
		fmt.Printf("%s[%s]%v", rIndent, value.Type(), value)

	//Map
	case vKind == 21:
		fmt.Printf("%smap[%s](%d) ==>\n", rIndent, value.Type(), value.Len())
		keys := value.MapKeys()
		for _, key := range keys {
			//fmt.Printf("%s[%s] : ", indent+"    ", key)
			varDump(value.MapIndex(key), "    "+indent, fmt.Sprintf("%s\"%v\" : ", indent+"    ", key))
		}

	//ptr
	case vKind == 22:
		//fmt.Printf("%s[%s] -->\n", indent, value.Type())
		varDump(reflect.Indirect(value), indent, fmt.Sprintf("%s[%s] --> ", rIndent, value.Type()))

	//slice
	case vKind == 23:
		fmt.Printf("%sslice[%s](%d) ==>\n", rIndent, value.Type(), value.Len())
		//fmt.Printf("%s%s", indent+"    ", t.Field(k).Name)
		index := 0
		for {
			if index >= value.Len() {
				break
			}
			//fmt.Printf("%s[%d] : ", r_indent+"    ", index)
			varDump(value.Index(index), "    "+indent, fmt.Sprintf("%s[%d] : ", indent+"    ", index))
			index++
		}
		fmt.Printf("%s//end %s\n", indent, vKind.String())

	//string
	case vKind == 24:
		fmt.Printf("%s[%s](%d) ==> \"%s\"\n", rIndent, value.Type(), value.Len(), value)

	//Struct
	case vKind == 25:
		fmt.Printf("%sstruct[%s] ==> {\n", rIndent, value.Type())

		t := value.Type()
		for k := 0; k < value.NumField(); k++ {
			varDump(value.Field(k), indent+"    ", fmt.Sprintf("%s%s ", indent+"    ", t.Field(k).Name))
		}
		fmt.Printf("%s} //end %s\n", indent, vKind.String())

	//Unsafeptr
	case vKind == 26:
		//fmt.Printf("%s[%s] -->\n", r_indent, vKind.String())
		varDump(reflect.Indirect(value), indent, fmt.Sprintf("%s[%s] --> ", rIndent, vKind.String()))

	default:
		fmt.Printf("%s[%s] : %v\n", rIndent, "Unknown", value)
	}

	return
}

func GetFuncName() (string, error) {
	pc, _, _, succ := runtime.Caller(1)
	if !succ {
		return "", errors.New("get current function name failed")
	}

	return runtime.FuncForPC(pc).Name(), nil
}

//note: 如果字段的tag 设置不是符合规范的，则用tag返回时值是不确定的
func Struct2Map(obj interface{}, useTag bool, tag string) map[string]interface{} {
	defer func() {
		if err := recover(); err != nil {
			io.WriteString(os.Stderr, fmt.Sprintf("%v", err))
		}
	}()

	obj_type := reflect.TypeOf(obj)
	obj_value := reflect.ValueOf(obj)

	res := make(map[string]interface{})

	for i := 0; i < obj_type.NumField(); i++ {
		r_fields := obj_type.Field(i)

		//check type
		if useTag {
			if r_fields.Tag.Get(tag) != "" {
				res[r_fields.Tag.Get(tag)] = obj_value.FieldByName(r_fields.Name)
				continue
			}
		}

		//use param
		res[r_fields.Name] = obj_value.FieldByName(r_fields.Name)
	}

	return res

}
<commit_msg>fix format bug<commit_after>package kdebug

import (
	"errors"
	"fmt"
	"io"
	"os"
	"reflect"
	"runtime"
)

func VarDump(s interface{}) {
	indent := ""
	switch s.(type) {
	case reflect.Value:
		varDump(s.(reflect.Value), indent, "")
	default:
		varDump(reflect.ValueOf(s), indent, "")
	}
	//varDump(reflect.ValueOf(s), indent, "")
}

func varDump(value reflect.Value, indent string, preStr string) {
	var vKind = value.Kind()
	rIndent := indent
	if preStr != "" {
		rIndent = preStr
	}

	switch {
	case vKind == 0:
		fmt.Printf("%s[%s] : %v\n", rIndent, "nil", value)

	//bool + int +uint
	case vKind < 12:
		fmt.Printf("%s[%s] : %v\n", rIndent, value.Type(), value)

	//uintptr
	case vKind == 12:
		//fmt.Printf("%s[%s] ", r_indent, value.Type())
		varDump(value, indent, fmt.Sprintf("%s[%s] --> ", rIndent, value.Type()))

	//float + complex
	case vKind < 17:
		fmt.Printf("%s[%s] : %v\n", rIndent, value.Type(), value)

	//Array
	case vKind == 17:
		fmt.Printf("%sarray[%s](%d) ==>\n", rIndent, value.Type(), value.Len())
		index := 0
		for {
			if index >= value.Len() {
				break
			}
			//fmt.Printf("%s[%d] :", r_indent+"    ", index)
			varDump(value.Index(index), "    "+indent, fmt.Sprintf("%s[%d] :", rIndent+"    ", index))
			index++
		}

	//chan\func\Interface
	case vKind < 21:
		fmt.Printf("%s[%s]%v\n", rIndent, value.Type(), value)

	//Map
	case vKind == 21:
		fmt.Printf("%smap[%s](%d) ==>\n", rIndent, value.Type(), value.Len())
		keys := value.MapKeys()
		for _, key := range keys {
			//fmt.Printf("%s[%s] : ", indent+"    ", key)
			varDump(value.MapIndex(key), "    "+indent, fmt.Sprintf("%s\"%v\" : ", indent+"    ", key))
		}

	//ptr
	case vKind == 22:
		//fmt.Printf("%s[%s] -->\n", indent, value.Type())
		varDump(reflect.Indirect(value), indent, fmt.Sprintf("%s[%s] --> ", rIndent, value.Type()))

	//slice
	case vKind == 23:
		fmt.Printf("%sslice[%s](%d) ==>\n", rIndent, value.Type(), value.Len())
		//fmt.Printf("%s%s", indent+"    ", t.Field(k).Name)
		index := 0
		for {
			if index >= value.Len() {
				break
			}
			//fmt.Printf("%s[%d] : ", r_indent+"    ", index)
			varDump(value.Index(index), "    "+indent, fmt.Sprintf("%s[%d] : ", indent+"    ", index))
			index++
		}
		fmt.Printf("%s//end %s\n", indent, vKind.String())

	//string
	case vKind == 24:
		fmt.Printf("%s[%s](%d) ==> \"%s\"\n", rIndent, value.Type(), value.Len(), value)

	//Struct
	case vKind == 25:
		fmt.Printf("%sstruct[%s] ==> {\n", rIndent, value.Type())

		t := value.Type()
		for k := 0; k < value.NumField(); k++ {
			varDump(value.Field(k), indent+"    ", fmt.Sprintf("%s%s ", indent+"    ", t.Field(k).Name))

		}
		fmt.Printf("%s} //end %s\n", indent, vKind.String())

	//Unsafeptr
	case vKind == 26:
		//fmt.Printf("%s[%s] -->\n", r_indent, vKind.String())
		varDump(reflect.Indirect(value), indent, fmt.Sprintf("%s[%s] --> ", rIndent, vKind.String()))

	default:
		fmt.Printf("%s[%s] : %v\n", rIndent, "Unknown", value)
	}

	return
}

func GetFuncName() (string, error) {
	pc, _, _, succ := runtime.Caller(1)
	if !succ {
		return "", errors.New("get current function name failed")
	}

	return runtime.FuncForPC(pc).Name(), nil
}

//note: 如果字段的tag 设置不是符合规范的，则用tag返回时值是不确定的
func Struct2Map(obj interface{}, useTag bool, tag string) map[string]interface{} {
	defer func() {
		if err := recover(); err != nil {
			io.WriteString(os.Stderr, fmt.Sprintf("%v", err))
		}
	}()

	obj_type := reflect.TypeOf(obj)
	obj_value := reflect.ValueOf(obj)

	res := make(map[string]interface{})

	for i := 0; i < obj_type.NumField(); i++ {
		r_fields := obj_type.Field(i)

		//check type
		if useTag {
			if r_fields.Tag.Get(tag) != "" {
				res[r_fields.Tag.Get(tag)] = obj_value.FieldByName(r_fields.Name)
				continue
			}
		}

		//use param
		res[r_fields.Name] = obj_value.FieldByName(r_fields.Name)
	}

	return res

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Seth Hoenig
 *    Allan Stockdill-Mander
 *    Mike Robertson
 */

package mqtt

import (
	"bufio"
	"encoding/binary"
)

//decodeQos returns the QoS of the message
func decodeQos(header byte) QoS {
	qos := (header & 0x06) >> 1
	return QoS(qos)
}

//decodeMsgType returns the type of the message
func decodeMsgType(header byte) MsgType {
	mtype := (header & 0xF0) >> 4
	return MsgType(mtype)
}

// return (number of bytes needed, the remaining length)
func decodeRemlen(bytes []byte) (int, uint32) {
	// bytes[1,2,3,4] are the only ones we could care about
	idx := uint32(0)
	mult := uint32(1)
	value := uint32(0)
	for {
		idx++
		digit := uint32((bytes[idx]))
		value += (digit & 127) * mult
		mult *= 128
		if digit&128 == 0 {
			break
		}
	}
	return int(idx), value
}

func decodeRemlenFromNetwork(src *bufio.ReadWriter) ([]byte, uint32) {
	var bytes []byte
	var rLength uint32
	var count int
	var multiplier uint32 = 1
	var digit byte
	count = 1
	for {
		digit, _ = src.ReadByte()
		bytes = append(bytes, digit)
		rLength += uint32(digit&127) * multiplier
		if (digit & 128) == 0 {
			break
		}
		multiplier *= 128
		count++
	}
	return bytes, rLength
}

// return length of topic string, the topic string
func decodeTopic(bytes []byte) (tlen uint16, t string) {
	tlen = binary.BigEndian.Uint16(bytes[:2])
	t = string(bytes[2 : 2+tlen])
	return tlen, t
}

//decode takes a slice of bytes as received over the network
//and returns a Message pointer to a Message struct
func decode(bytes []byte, protocolVersion byte) *Message {
	m := &Message{}

	m.SetQoS(decodeQos(bytes[0]))

	m.setMsgType(decodeMsgType(bytes[0]))

	n, r := decodeRemlen(bytes)
	m.setRemLen(r)

	bytes = bytes[n+1:] // skip past fixed header and variable length byte(s)

	switch m.msgType() {
	case CONNACK:
		m.vheader = append(m.vheader, 0x00) // bytes[0] of vheader not used
		m.vheader = append(m.vheader, bytes[1])
		/* No Payload */

	case PINGRESP:
		/* No vheader */
		/* No Payload */

	case PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK:
		if protocolVersion == 0x03 {
			m.setMsgId(MId(binary.BigEndian.Uint16(bytes[:2])))
		}else if protocolVersion == 0x13 {
			m.setMsgId(MId(binary.BigEndian.Uint64(bytes[:8])))
		}
		/* No Payload */

	case SUBACK:
		if protocolVersion == 0x03 {
			m.setMsgId(MId(binary.BigEndian.Uint16(bytes[:2])))
			m.appendPayloadField(bytes[2:])
		}else if protocolVersion == 0x13 {
			m.setMsgId(MId(binary.BigEndian.Uint64(bytes[:8])))
			m.appendPayloadField(bytes[8:])
		}

	case PUBLISH:
		// we are past the fixed header and variable remlen

		// now bytes[0] and bytes[1] are the length of the topic name (n)
		// bytes[2]... bytes[n] are the topic string
		// bytes[n+1] and bytes[n+2] are message id IFF QoS > 0
		// bytes[n+3]+ are the payload (if any)

		// bytes 0 and 1 are topic length
		tlen, topic := decodeTopic(bytes)

		m.appendVHeaderField(topic) // auto inserts length

		bytes = bytes[tlen+2:]
		// bytes[0] is now either msgid OR payload

		// if QoS > 0, 2 message id bytes are after the topic string
		if m.QoS() != QOS_ZERO {
			if protocolVersion == 0x03 {
				m.setMsgId(MId(binary.BigEndian.Uint16(bytes[:2])))
				m.appendPayloadField(bytes[2:])
			}else if protocolVersion == 0x13 {
				m.setMsgId(MId(binary.BigEndian.Uint64(bytes[:8])))
				m.appendPayloadField(bytes[8:])
			}
		} else {
			m.appendPayloadField(bytes[0:])
		}
	}

	return m
}

//Bytes operates on a Message pointer and returns a slice of bytes
//representing the Message ready for transmission over the network
func (m *Message) Bytes(protocolVersion byte) []byte {
	var b []byte
	b = append(b, m.header)
	if m.remlen&0xFF000000 > 0 {
		b = append(b, byte((m.remlen&0xFF000000)>>24))
		b = append(b, byte((m.remlen&0x00FF0000)>>16))
		b = append(b, byte((m.remlen&0x0000FF00)>>8))
		b = append(b, byte(m.remlen&0x000000FF))
	} else if m.remlen&0x00FF0000 > 0 {
		b = append(b, byte((m.remlen&0x00FF0000)>>16))
		b = append(b, byte((m.remlen&0x0000FF00)>>8))
		b = append(b, byte(m.remlen&0x000000FF))
	} else if m.remlen&0x0000FF00 > 0 {
		b = append(b, byte((m.remlen&0x0000FF00)>>8))
		b = append(b, byte(m.remlen&0x000000FF))
	} else {
		b = append(b, byte(m.remlen&0x000000FF))
	}
	for i := range m.vheader {
		b = append(b, m.vheader[i])
	}
	if msgId :=m.MsgId(); msgId!= 0 {
		if protocolVersion == 0x03{
			mid := make([]byte, 2)
			binary.BigEndian.PutUint16(mid, uint16(m.messageId))
			b = append(b, mid...)
		}else if protocolVersion == 0x13 {
			mid := make([]byte, 8)
			binary.BigEndian.PutUint64(mid, uint64(m.messageId))
			b = append(b, mid...)
		}
	}
	for i := range m.payload {
		b = append(b, m.payload[i])
	}

	return b
}
<commit_msg>export decode function<commit_after>/*
 * Copyright (c) 2013 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Seth Hoenig
 *    Allan Stockdill-Mander
 *    Mike Robertson
 */

package mqtt

import (
	"bufio"
	"encoding/binary"
)

//decodeQos returns the QoS of the message
func decodeQos(header byte) QoS {
	qos := (header & 0x06) >> 1
	return QoS(qos)
}

//decodeMsgType returns the type of the message
func DecodeMsgType(header byte) MsgType {
	return decodeMsgType(header)
}

//decodeMsgType returns the type of the message
func decodeMsgType(header byte) MsgType {
	mtype := (header & 0xF0) >> 4
	return MsgType(mtype)
}

// return (number of bytes needed, the remaining length)
func decodeRemlen(bytes []byte) (int, uint32) {
	// bytes[1,2,3,4] are the only ones we could care about
	idx := uint32(0)
	mult := uint32(1)
	value := uint32(0)
	for {
		idx++
		digit := uint32((bytes[idx]))
		value += (digit & 127) * mult
		mult *= 128
		if digit&128 == 0 {
			break
		}
	}
	return int(idx), value
}

func decodeRemlenFromNetwork(src *bufio.ReadWriter) ([]byte, uint32) {
	var bytes []byte
	var rLength uint32
	var count int
	var multiplier uint32 = 1
	var digit byte
	count = 1
	for {
		digit, _ = src.ReadByte()
		bytes = append(bytes, digit)
		rLength += uint32(digit&127) * multiplier
		if (digit & 128) == 0 {
			break
		}
		multiplier *= 128
		count++
	}
	return bytes, rLength
}

// return length of topic string, the topic string
func decodeTopic(bytes []byte) (tlen uint16, t string) {
	tlen = binary.BigEndian.Uint16(bytes[:2])
	t = string(bytes[2 : 2+tlen])
	return tlen, t
}

func Decode(bytes []byte, protocolVersion byte) *Message{
	return decode(bytes, protocolVersion)
}

//decode takes a slice of bytes as received over the network
//and returns a Message pointer to a Message struct
func decode(bytes []byte, protocolVersion byte) *Message {
	m := &Message{}

	m.SetQoS(decodeQos(bytes[0]))

	m.setMsgType(decodeMsgType(bytes[0]))

	n, r := decodeRemlen(bytes)
	m.setRemLen(r)

	bytes = bytes[n+1:] // skip past fixed header and variable length byte(s)

	switch m.msgType() {
	case CONNACK:
		m.vheader = append(m.vheader, 0x00) // bytes[0] of vheader not used
		m.vheader = append(m.vheader, bytes[1])
		/* No Payload */

	case PINGRESP:
		/* No vheader */
		/* No Payload */

	case PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK:
		if protocolVersion == 0x03 {
			m.setMsgId(MId(binary.BigEndian.Uint16(bytes[:2])))
		}else if protocolVersion == 0x13 {
			m.setMsgId(MId(binary.BigEndian.Uint64(bytes[:8])))
		}
		/* No Payload */

	case SUBACK:
		if protocolVersion == 0x03 {
			m.setMsgId(MId(binary.BigEndian.Uint16(bytes[:2])))
			m.appendPayloadField(bytes[2:])
		}else if protocolVersion == 0x13 {
			m.setMsgId(MId(binary.BigEndian.Uint64(bytes[:8])))
			m.appendPayloadField(bytes[8:])
		}

	case PUBLISH:
		// we are past the fixed header and variable remlen

		// now bytes[0] and bytes[1] are the length of the topic name (n)
		// bytes[2]... bytes[n] are the topic string
		// bytes[n+1] and bytes[n+2] are message id IFF QoS > 0
		// bytes[n+3]+ are the payload (if any)

		// bytes 0 and 1 are topic length
		tlen, topic := decodeTopic(bytes)

		m.appendVHeaderField(topic) // auto inserts length

		bytes = bytes[tlen+2:]
		// bytes[0] is now either msgid OR payload

		// if QoS > 0, 2 message id bytes are after the topic string
		if m.QoS() != QOS_ZERO {
			if protocolVersion == 0x03 {
				m.setMsgId(MId(binary.BigEndian.Uint16(bytes[:2])))
				m.appendPayloadField(bytes[2:])
			}else if protocolVersion == 0x13 {
				m.setMsgId(MId(binary.BigEndian.Uint64(bytes[:8])))
				m.appendPayloadField(bytes[8:])
			}
		} else {
			m.appendPayloadField(bytes[0:])
		}
	}

	return m
}

//Bytes operates on a Message pointer and returns a slice of bytes
//representing the Message ready for transmission over the network
func (m *Message) Bytes(protocolVersion byte) []byte {
	var b []byte
	b = append(b, m.header)
	if m.remlen&0xFF000000 > 0 {
		b = append(b, byte((m.remlen&0xFF000000)>>24))
		b = append(b, byte((m.remlen&0x00FF0000)>>16))
		b = append(b, byte((m.remlen&0x0000FF00)>>8))
		b = append(b, byte(m.remlen&0x000000FF))
	} else if m.remlen&0x00FF0000 > 0 {
		b = append(b, byte((m.remlen&0x00FF0000)>>16))
		b = append(b, byte((m.remlen&0x0000FF00)>>8))
		b = append(b, byte(m.remlen&0x000000FF))
	} else if m.remlen&0x0000FF00 > 0 {
		b = append(b, byte((m.remlen&0x0000FF00)>>8))
		b = append(b, byte(m.remlen&0x000000FF))
	} else {
		b = append(b, byte(m.remlen&0x000000FF))
	}
	for i := range m.vheader {
		b = append(b, m.vheader[i])
	}
	if msgId :=m.MsgId(); msgId!= 0 {
		if protocolVersion == 0x03{
			mid := make([]byte, 2)
			binary.BigEndian.PutUint16(mid, uint16(m.messageId))
			b = append(b, mid...)
		}else if protocolVersion == 0x13 {
			mid := make([]byte, 8)
			binary.BigEndian.PutUint64(mid, uint64(m.messageId))
			b = append(b, mid...)
		}
	}
	for i := range m.payload {
		b = append(b, m.payload[i])
	}

	return b
}
<|endoftext|>


<commit_before>package pps

import (
	"hash/adler32"
)

// A Hasher represents a job/pipeline hasher.
type Hasher struct {
	JobModulus      uint64
	PipelineModulus uint64
}

// NewHasher creates a hasher.
func NewHasher(jobModulus uint64, pipelineModulus uint64) *Hasher {
	return &Hasher{
		JobModulus:      jobModulus,
		PipelineModulus: pipelineModulus,
	}
}

// HashJob computes and returns the hash of a job.
func (s *Hasher) HashJob(jobID string) uint64 {
	return uint64(adler32.Checksum([]byte(jobID))) % s.PipelineModulus
}

// HashPipeline computes and returns the hash of a pipeline.
func (s *Hasher) HashPipeline(pipelineName string) uint64 {
	return uint64(adler32.Checksum([]byte(pipelineName))) % s.JobModulus
}
<commit_msg>Fix a bug where hasher uses the wrong modulus<commit_after>package pps

import (
	"hash/adler32"
)

// A Hasher represents a job/pipeline hasher.
type Hasher struct {
	JobModulus      uint64
	PipelineModulus uint64
}

// NewHasher creates a hasher.
func NewHasher(jobModulus uint64, pipelineModulus uint64) *Hasher {
	return &Hasher{
		JobModulus:      jobModulus,
		PipelineModulus: pipelineModulus,
	}
}

// HashJob computes and returns the hash of a job.
func (s *Hasher) HashJob(jobID string) uint64 {
	return uint64(adler32.Checksum([]byte(jobID))) % s.JobModulus
}

// HashPipeline computes and returns the hash of a pipeline.
func (s *Hasher) HashPipeline(pipelineName string) uint64 {
	return uint64(adler32.Checksum([]byte(pipelineName))) % s.PipelineModulus
}
<|endoftext|>


<commit_before>package activitypub

import (
	"crypto"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"github.com/writeas/openssl-go"
	"log"
)

const keyBitSize = 2048

// GenerateKeys creates an RSA keypair and returns the public and private key,
// in that order.
func GenerateKeys() (pubPEM []byte, privPEM []byte) {
	var err error
	privPEM, err = openssl.Call(nil, "genrsa", fmt.Sprintf("%d", keyBitSize))
	if err != nil {
		log.Printf("Unable to generate private key: %v", err)
		return nil, nil
	}

	pubPEM, err = openssl.Call(privPEM, "rsa", "-in", "/dev/stdin", "-pubout")
	if err != nil {
		log.Printf("Unable to get public key: %v", err)
		return nil, nil
	}
	return
}

func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
		return key, nil
	}
	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
		switch key := key.(type) {
		case *rsa.PrivateKey:
			return key, nil
		default:
			return nil, fmt.Errorf("found unknown private key type in PKCS#8 wrapping")
		}
	}
	if key, err := x509.ParseECPrivateKey(der); err == nil {
		return key, nil
	}

	return nil, fmt.Errorf("failed to parse private key")
}

// DecodePrivateKey encodes public and private key to PEM format, returning
// them in that order.
func DecodePrivateKey(k []byte) (crypto.PrivateKey, error) {
	block, _ := pem.Decode(k)
	if block == nil || block.Type != "RSA PRIVATE KEY" {
		return nil, fmt.Errorf("failed to decode PEM block containing private key")
	}

	return parsePrivateKey(block.Bytes)
}
<commit_msg>Support decoding public keys<commit_after>package activitypub

import (
	"crypto"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"github.com/writeas/openssl-go"
	"log"
)

const keyBitSize = 2048

// GenerateKeys creates an RSA keypair and returns the public and private key,
// in that order.
func GenerateKeys() (pubPEM []byte, privPEM []byte) {
	var err error
	privPEM, err = openssl.Call(nil, "genrsa", fmt.Sprintf("%d", keyBitSize))
	if err != nil {
		log.Printf("Unable to generate private key: %v", err)
		return nil, nil
	}

	pubPEM, err = openssl.Call(privPEM, "rsa", "-in", "/dev/stdin", "-pubout")
	if err != nil {
		log.Printf("Unable to get public key: %v", err)
		return nil, nil
	}
	return
}

func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
		return key, nil
	}
	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
		switch key := key.(type) {
		case *rsa.PrivateKey:
			return key, nil
		default:
			return nil, fmt.Errorf("found unknown private key type in PKCS#8 wrapping")
		}
	}
	if key, err := x509.ParseECPrivateKey(der); err == nil {
		return key, nil
	}

	return nil, fmt.Errorf("failed to parse private key")
}

func parsePublicKey(der []byte) (crypto.PublicKey, error) {
	if key, err := x509.ParsePKCS1PublicKey(der); err == nil {
		return key, nil
	}
	if key, err := x509.ParsePKIXPublicKey(der); err == nil {
		switch key := key.(type) {
		case *rsa.PublicKey:
			return key, nil
		default:
			return nil, fmt.Errorf("found unknown public key type in PKIX wrapping")
		}
	}

	return nil, fmt.Errorf("failed to parse public key")
}

// DecodePrivateKey encodes public and private key to PEM format, returning
// them in that order.
func DecodePrivateKey(k []byte) (crypto.PrivateKey, error) {
	block, _ := pem.Decode(k)
	if block == nil || block.Type != "RSA PRIVATE KEY" {
		return nil, fmt.Errorf("failed to decode PEM block containing private key")
	}

	return parsePrivateKey(block.Bytes)
}

// DecodePublicKey decodes public keys
func DecodePublicKey(k []byte) (crypto.PublicKey, error) {
	block, _ := pem.Decode(k)
	if block == nil || block.Type != "PUBLIC KEY" {
		if block != nil {
			return nil, fmt.Errorf("failed to decode PEM block containing public key. type: %v", block.Type)
		} else {
			return nil, fmt.Errorf("failed to decode PEM block containing public key.")
		}
	}

	return parsePublicKey(block.Bytes)
}
<|endoftext|>


<commit_before>package elk

import (
	"errors"
	"log"
	"log/syslog"
	"net"
	"os"
	"strings"
	"text/template"
	"time"

	"github.com/delectable/logspout/router"
)

func init() {
	router.AdapterFactories.Register(NewElkAdapter, "elk")
}

func getopt(name, dfault string) string {
	value := os.Getenv(name)
	if value == "" {
		value = dfault
	}
	return value
}

func NewElkAdapter(route *router.Route) (router.LogAdapter, error) {
	transport, found := router.AdapterTransports.Lookup(route.AdapterTransport("udp"))
	if !found {
		return nil, errors.New("unable to find adapter: " + route.Adapter)
	}
	conn, err := transport.Dial(route.Address, route.Options)
	if err != nil {
		return nil, err
	}

	// priority := getopt("ELK_PRIORITY", "{{.Priority}}")
	// hostname := getopt("ELK_HOSTNAME", "{{.Container.Config.Hostname}}")
	// pid := getopt("ELK_PID", "{{.Container.State.Pid}}")
	// tag := getopt("ELK_TAG", "{{.ContainerName}}"+route.Options["append_tag"])
	// structuredData := getopt("ELK_STRUCTURED_DATA", "")
	// if route.Options["structured_data"] != "" {
	// 	structuredData = route.Options["structured_data"]
	// }

	// tmplStr := fmt.Sprintf("CRUNCHY BACON: <%d> {{.Timestamp}} %s %s %d - [%s] %s",
	// 	priority, hostname, tag, pid, structuredData, data)

	// fmt.Println("GOT A LOG ENTRY.")

	tmplStr := "CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY CRUNCHY {{.TestStr}} BACON"

	tmpl, err := template.New("elk").Parse(tmplStr)
	if err != nil {
		return nil, err
	}
	return &ElkAdapter{
		route: route,
		conn:  conn,
		tmpl:  tmpl,
	}, nil
}

type ElkAdapter struct {
	conn  net.Conn
	route *router.Route
	tmpl  *template.Template
}

func (a *ElkAdapter) Stream(logstream chan *router.Message) {
	for message := range logstream {
		err := a.tmpl.Execute(a.conn, &ElkMessage{message, a})
		if err != nil {
			log.Println("syslog:", err)
			a.route.Close()
			return
		}
	}
}

type ElkMessage struct {
	*router.Message
	adapter *ElkAdapter
}

func (m *ElkMessage) Priority() syslog.Priority {
	switch m.Message.Source {
	case "stdout":
		return syslog.LOG_USER | syslog.LOG_INFO
	case "stderr":
		return syslog.LOG_USER | syslog.LOG_ERR
	default:
		return syslog.LOG_DAEMON | syslog.LOG_INFO
	}
}

func (m *ElkMessage) Hostname() string {
	h, _ := os.Hostname()
	return h
}

func (m *ElkMessage) CleanData() string {
	return strings.Replace(m.Data, "\n", " ", -1)
}

func (m ElkMessage) TestStr() string {
	return "test_string"
}

func (m *ElkMessage) LocalAddr() string {
	return m.adapter.conn.LocalAddr().String()
}

func (m *ElkMessage) Timestamp() string {
	return m.Message.Time.Format(time.RFC3339)
}

func (m *ElkMessage) ContainerName() string {
	return m.Message.Container.Name[1:]
}
<commit_msg>Testing ELK Adapter<commit_after>package elk

import (
	"errors"
	"io"
	"log"
	"log/syslog"
	"net"
	"os"
	"strings"
	"time"

	"github.com/delectable/logspout/router"
)

func init() {
	router.AdapterFactories.Register(NewElkAdapter, "elk")
}

func getopt(name, dfault string) string {
	value := os.Getenv(name)
	if value == "" {
		value = dfault
	}
	return value
}

func NewElkAdapter(route *router.Route) (router.LogAdapter, error) {
	transport, found := router.AdapterTransports.Lookup(route.AdapterTransport("udp"))
	if !found {
		return nil, errors.New("unable to find adapter: " + route.Adapter)
	}
	conn, err := transport.Dial(route.Address, route.Options)
	if err != nil {
		return nil, err
	}

	return &ElkAdapter{
		route: route,
		conn:  conn,
	}, nil
}

type ElkAdapter struct {
	conn  net.Conn
	route *router.Route
}

func (a *ElkAdapter) Stream(logstream chan *router.Message) {
	for message := range logstream {
		io.WriteString(message.Data)
		// err := a.tmpl.Execute(a.conn, &ElkMessage{message, a})
		if err != nil {
			log.Println("syslog:", err)
			a.route.Close()
			return
		}
	}
}

type ElkMessage struct {
	*router.Message
	adapter *ElkAdapter
}

func (m *ElkMessage) Priority() syslog.Priority {
	switch m.Message.Source {
	case "stdout":
		return syslog.LOG_USER | syslog.LOG_INFO
	case "stderr":
		return syslog.LOG_USER | syslog.LOG_ERR
	default:
		return syslog.LOG_DAEMON | syslog.LOG_INFO
	}
}

func (m *ElkMessage) Hostname() string {
	h, _ := os.Hostname()
	return h
}

func (m *ElkMessage) CleanData() string {
	return strings.Replace(m.Data, "\n", " ", -1)
}

func (m ElkMessage) TestStr() string {
	return "test_string"
}

func (m *ElkMessage) LocalAddr() string {
	return m.adapter.conn.LocalAddr().String()
}

func (m *ElkMessage) Timestamp() string {
	return m.Message.Time.Format(time.RFC3339)
}

func (m *ElkMessage) ContainerName() string {
	return m.Message.Container.Name[1:]
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	log "github.com/cihub/seelog"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
	"os"
	"time"
	m "vorimport/models"
)

const (
	ODIN_MONGO_DATABASENAME = "revor"
)

//
func createMongoCdr(session *mgo.Session, cdr m.RawCall) (err error) {
	collection := session.DB(ODIN_MONGO_DATABASENAME).C("cdrs")
	//
	err = collection.Insert(cdr)
	if err != nil {
		log.Criticalf("Can't insert document: %v", err)
		os.Exit(1)
	} else {
		log.Debugf("Row inserted into mongo database: %s", cdr.ClidName)
	}
	return
}

//
func processMonthlyAnalytics(session *mgo.Session, cdr m.RawCall) (err error) {
	//
	var collectionName = ""
	var dst = ""
	if cdr.InoutStatus == DIRECTION_CALL_OUT {
		collectionName = "monthlyanalytics_outgoing"
		dst = cdr.Src
	} else if cdr.InoutStatus == DIRECTION_CALL_IN {
		collectionName = "monthlyanalytics__incomming"
		dst = cdr.Dst
	} else {
		return errors.New("Can't detect the call context")
	}
	//
	var id = fmt.Sprintf("%04d%02d-%s-%d", cdr.Calldate.Year(),
		cdr.Calldate.Month(), dst, cdr.Disposition)
	var metaDate = time.Date(cdr.Calldate.Year(), cdr.Calldate.Month(),
		cdr.Calldate.Day(), 1, 0, 0, 0, time.UTC)
	//
	log.Debugf("Import monthly analytics :  %s for the id %s.", collectionName, id)
	var collection = session.DB(ODIN_MONGO_DATABASENAME).C(collectionName)
	metaDoc := m.MetaData{Dst: dst, Dt: metaDate, Disposition: cdr.Disposition}
	doc := m.MonthlyCall{Id: id, Meta: metaDoc, AnswereWaitTime: cdr.AnswerWaitTime,
		CallMonthly: 0, DurationMonthly: 0}
	//
	var selector = bson.M{"_id": id, "metadata": metaDoc}
	//
	var change = mgo.Change{
		Update: bson.M{"$inc": bson.M{"call_monthly": 1, "duration_monthly": cdr.Billsec,
			"answer_wait_time": cdr.AnswerWaitTime},
		},
		ReturnNew: false,
	}
	//
	var info = new(mgo.ChangeInfo)
	info, err = collection.Find(selector).Apply(change, &doc)
	//check if the can execute changes
	if info == nil || info.Updated == 0 {
		log.Debugf("Monthly update can't be executed , get the error: [ %v], Try execute insert.", err)
		err = collection.Insert(doc)
		if err != nil {
			log.Error("[mongo] Monthly insert failed with error : [%v].", err)
			return err
		}
		info, err = collection.Find(selector).Apply(change, &doc)
		if info != nil {
			log.Debugf("[mongo] New record inserted : %s.", doc.Id)
		} else {
			log.Debugf("New record inserted : %s.", doc.Id)
		}
	} else {
		if err != nil {
			log.Debugf("Document [%s] was updated, the update numbers: [%s].", doc.Id, info.Updated)
		} else {
			return err
		}

	}
	//
	return nil
}

func processDailyAnalytics(session *mgo.Session, cdr m.RawCall) (err error) {
	//
	var collectionName = ""
	var dst = ""
	if cdr.InoutStatus == DIRECTION_CALL_OUT {
		collectionName = "dailyanalytics_outgoing"
		dst = cdr.Src
	} else if cdr.InoutStatus == DIRECTION_CALL_IN {
		collectionName = "dailyanalytics_incomming"
		dst = cdr.Dst
	} else {
		return errors.New("[mongo] Can't detect the call context")
	}
	//var t = time.Unix(cdr.calldate, 0)
	var id = fmt.Sprintf("%04d%02d%02d-%s-%d", cdr.Calldate.Year(), cdr.Calldate.Month(),
		cdr.Calldate.Day(), dst, cdr.Disposition)
	var metaDate = time.Date(cdr.Calldate.Year(), cdr.Calldate.Month(), cdr.Calldate.Day(), 1, 0, 0, 0, time.UTC)
	log.Debugf("Import daily analytics :  %s for the id %s.", collectionName, id)
	var collection = session.DB(ODIN_MONGO_DATABASENAME).C(collectionName)
	metaDoc := m.MetaData{Dst: dst, Dt: metaDate, Disposition: cdr.Disposition}
	doc := m.DailyCall{Id: id, Meta: metaDoc, AnswereWaitTime: cdr.AnswerWaitTime, CallDaily: 0,
		DurationDaily: 0}
	//err = collection.Insert(doc)
	var selector = bson.M{"_id": id, "metadata": metaDoc}
	var hourlyInc = fmt.Sprintf("call_hourly.%d", cdr.Calldate.Hour())
	var durationHourlyInc = fmt.Sprintf("duration_hourly.%d", cdr.Calldate.Hour())
	//
	var change = mgo.Change{
		Update: bson.M{"$inc": bson.M{"call_daily": 1, "duration_daily": cdr.Billsec,
			"answer_wait_time": cdr.AnswerWaitTime, hourlyInc: 1, durationHourlyInc: cdr.Billsec},
		},
		ReturnNew: false,
	}
	//
	var info = new(mgo.ChangeInfo)
	info, err = collection.Find(selector).Apply(change, &doc)
	//check if the can execute changes
	if info == nil || info.Updated == 0 {
		log.Debugf("Daily update can't be executed , get the error: [ %v], Try execute insert.", err)
		err = collection.Insert(doc)
		if err != nil {
			log.Error("Daily insert failed with error : [%v].", err)
			return err
		}
		info, err = collection.Find(selector).Apply(change, &doc)
		if info != nil {
			log.Debugf("Daily document updated with success for the document : %s", doc.Id)
		} else {
			log.Debugf("Daily document can't be updated, get the error : [%v] for the document : %s", err, doc.Id)
		}
	} else {
		log.Debugf("Document updated : %s\n", doc.Id)
	}
	//
	return nil
}

//
func processDidImport(session *mgo.Session, cdr m.RawCall) (err error) {
	log.Debugf("Import by did : %s\n", cdr.Dnid)
	err = processDidDailyAnalytics(session, cdr)
	if err != nil {
		return nil
	}
	err = processDidMonthlyAnalytics(session, cdr)
	return nil
}

//
func processDidMonthlyAnalytics(session *mgo.Session, cdr m.RawCall) (err error) {
	//
	var collectionName = ""
	var dst = cdr.Dnid
	collectionName = "monthlydid_incomming"
	//
	var id = fmt.Sprintf("%04d%02d-%s-%d", cdr.Calldate.Year(),
		cdr.Calldate.Month(), dst, cdr.Disposition)
	log.Debugf("Import monthly did :  %s for the id %s.", collectionName, id)
	var collection = session.DB(ODIN_MONGO_DATABASENAME).C(collectionName)
	metaDoc := m.MetaData{Dst: dst, Disposition: cdr.Disposition}
	doc := m.MonthlyCall{Id: id, Meta: metaDoc, AnswereWaitTime: cdr.AnswerWaitTime,
		CallMonthly: 0, DurationMonthly: 0}
	//
	var selector = bson.M{"_id": id}
	//
	var change = mgo.Change{
		Update: bson.M{"$inc": bson.M{"call_monthly": 1, "duration_monthly": cdr.Billsec,
			"answer_wait_time": cdr.AnswerWaitTime},
		},
		ReturnNew: false,
	}
	//
	var info = new(mgo.ChangeInfo)
	info, err = collection.Find(selector).Apply(change, &doc)
	//check if the can execute changes
	if info == nil || info.Updated == 0 {
		log.Debugf("Monthly update can't be executed , get the error: [ %v], Try execute insert.", err)
		err = collection.Insert(doc)
		if err != nil {
			log.Errorf("[did] Monthly insert failed with error : [%v].", err)
			return err
		}
		info, err = collection.Find(selector).Apply(change, &doc)
		if info != nil {
			log.Debugf("[did] New record inserted : %s.", doc.Id)
		} else {
			log.Debugf("New record inserted : %s.", doc.Id)
		}
	} else {
		if err != nil {
			log.Debugf("Document [%s] was updated, the update numbers: [%s].\n", doc.Id, info.Updated)
		} else {
			return err
		}

	}
	//
	return nil
}

//
func processDidDailyAnalytics(session *mgo.Session, cdr m.RawCall) (err error) {
	//
	var collectionName = ""
	var dst = cdr.Dnid
	collectionName = "dailydid_incomming"
	//
	var id = fmt.Sprintf("%04d%02d%02d-%s-%d", cdr.Calldate.Year(), cdr.Calldate.Month(),
		cdr.Calldate.Day(), dst, cdr.Disposition)
	var metaDate = time.Date(cdr.Calldate.Year(), cdr.Calldate.Month(), cdr.Calldate.Day(), 1, 0, 0, 0, time.UTC)
	log.Debugf("Import daily did :  %s for the id %s.", collectionName, id)
	var collection = session.DB(ODIN_MONGO_DATABASENAME).C(collectionName)
	metaDoc := m.MetaData{Dst: dst, Dt: metaDate, Disposition: cdr.Disposition}
	doc := m.DailyCall{Id: id, Meta: metaDoc, AnswereWaitTime: cdr.AnswerWaitTime, CallDaily: 0,
		DurationDaily: 0}
	//err = collection.Insert(doc)
	var selector = bson.M{"_id": id, "metadata": metaDoc}
	var hourlyInc = fmt.Sprintf("call_hourly.%d", cdr.Calldate.Hour())
	var durationHourlyInc = fmt.Sprintf("duration_hourly.%d", cdr.Calldate.Hour())
	//
	var change = mgo.Change{
		Update: bson.M{"$inc": bson.M{"call_daily": 1, "duration_daily": cdr.Billsec,
			"answer_wait_time": cdr.AnswerWaitTime, hourlyInc: 1, durationHourlyInc: cdr.Billsec},
		},
		ReturnNew: false,
	}
	//
	var info = new(mgo.ChangeInfo)
	info, err = collection.Find(selector).Apply(change, &doc)
	//check if the can execute changes
	if info == nil || info.Updated == 0 {
		log.Debugf("Daily did update can't be executed , get the error: [ %v], Try execute insert.", err)
		err = collection.Insert(doc)
		if err != nil {
			log.Error("Daily did insert failed with error : [%v].", err)
			return err
		}
		info, err = collection.Find(selector).Apply(change, &doc)
		if info != nil {
			log.Debugf("Daily did document updated with success for the document : %s", doc.Id)
		} else {
			log.Debugf("Daily did document can't be updated, get the error : [%v] for the document : %s", err, doc.Id)
		}
	} else {
		log.Debugf("Document did updated : %s\n", doc.Id)
	}
	//
	return nil
}

func importCdrToMongo(session *mgo.Session, cdr m.RawCall) (err error) {
	log.Debugf("Start analyze data for mongo database.")
	createMongoCdr(session, cdr)
	err = processDailyAnalytics(session, cdr)
	if err != nil {
		return err
	}
	err = processMonthlyAnalytics(session, cdr)
	if err != nil {
		return err
	}
	if cdr.InoutStatus == DIRECTION_CALL_IN {
		err = processDidImport(session, cdr)
	}
	err = nil
	return
}
<commit_msg>Fix date for monthly reports<commit_after>package main

import (
	"errors"
	"fmt"
	log "github.com/cihub/seelog"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
	"os"
	"time"
	m "vorimport/models"
)

const (
	ODIN_MONGO_DATABASENAME = "revor"
)

//
func createMongoCdr(session *mgo.Session, cdr m.RawCall) (err error) {
	collection := session.DB(ODIN_MONGO_DATABASENAME).C("cdrs")
	//
	err = collection.Insert(cdr)
	if err != nil {
		log.Criticalf("Can't insert document: %v", err)
		os.Exit(1)
	} else {
		log.Debugf("Row inserted into mongo database: %s", cdr.ClidName)
	}
	return
}

//
func processMonthlyAnalytics(session *mgo.Session, cdr m.RawCall) (err error) {
	//
	var collectionName = ""
	var dst = ""
	if cdr.InoutStatus == DIRECTION_CALL_OUT {
		collectionName = "monthlyanalytics_outgoing"
		dst = cdr.Src
	} else if cdr.InoutStatus == DIRECTION_CALL_IN {
		collectionName = "monthlyanalytics__incomming"
		dst = cdr.Dst
	} else {
		return errors.New("Can't detect the call context")
	}
	//
	var id = fmt.Sprintf("%04d%02d-%s-%d", cdr.Calldate.Year(),
		cdr.Calldate.Month(), dst, cdr.Disposition)
	//
	var metaDate = time.Date(cdr.Calldate.Year(), cdr.Calldate.Month(),
		1, 1, 0, 0, 0, time.UTC)
	//
	log.Debugf("Import monthly analytics :  %s for the id %s.", collectionName, id)
	var collection = session.DB(ODIN_MONGO_DATABASENAME).C(collectionName)
	metaDoc := m.MetaData{Dst: dst, Dt: metaDate, Disposition: cdr.Disposition}
	doc := m.MonthlyCall{Id: id, Meta: metaDoc, AnswereWaitTime: cdr.AnswerWaitTime,
		CallMonthly: 0, DurationMonthly: 0}
	//
	var selector = bson.M{"_id": id, "metadata": metaDoc}
	//
	var change = mgo.Change{
		Update: bson.M{"$inc": bson.M{"call_monthly": 1, "duration_monthly": cdr.Billsec,
			"answer_wait_time": cdr.AnswerWaitTime},
		},
		ReturnNew: false,
	}
	//
	var info = new(mgo.ChangeInfo)
	info, err = collection.Find(selector).Apply(change, &doc)
	//check if the can execute changes
	if info == nil || info.Updated == 0 {
		log.Debugf("Monthly update can't be executed , get the error: [ %v], Try execute insert.", err)
		err = collection.Insert(doc)
		if err != nil {
			log.Error("Monthly insert failed with error : [%v].", err)
			return err
		}
		info, err = collection.Find(selector).Apply(change, &doc)
		if info != nil {
			log.Debugf("Monthly analytics wew record inserted : %s.", doc.Id)
		} else {
			log.Errorf("Monthly analytics can't be updated, get the error : [%v] for the document : %s", err, doc.Id)
		}
	} else {
		if err != nil {
			log.Debugf("Document [%s] was updated, the update numbers: [%s].", doc.Id, info.Updated)
		} else {
			return err
		}

	}
	//
	return nil
}

func processDailyAnalytics(session *mgo.Session, cdr m.RawCall) (err error) {
	//
	var collectionName = ""
	var dst = ""
	if cdr.InoutStatus == DIRECTION_CALL_OUT {
		collectionName = "dailyanalytics_outgoing"
		dst = cdr.Src
	} else if cdr.InoutStatus == DIRECTION_CALL_IN {
		collectionName = "dailyanalytics_incomming"
		dst = cdr.Dst
	} else {
		return errors.New("[mongo] Can't detect the call context")
	}
	//var t = time.Unix(cdr.calldate, 0)
	var id = fmt.Sprintf("%04d%02d%02d-%s-%d", cdr.Calldate.Year(), cdr.Calldate.Month(),
		cdr.Calldate.Day(), dst, cdr.Disposition)
	var metaDate = time.Date(cdr.Calldate.Year(), cdr.Calldate.Month(), cdr.Calldate.Day(), 1, 0, 0, 0, time.UTC)
	log.Debugf("Import daily analytics :  %s for the id %s.", collectionName, id)
	var collection = session.DB(ODIN_MONGO_DATABASENAME).C(collectionName)
	metaDoc := m.MetaData{Dst: dst, Dt: metaDate, Disposition: cdr.Disposition}
	doc := m.DailyCall{Id: id, Meta: metaDoc, AnswereWaitTime: cdr.AnswerWaitTime, CallDaily: 0,
		DurationDaily: 0}
	//err = collection.Insert(doc)
	var selector = bson.M{"_id": id, "metadata": metaDoc}
	var hourlyInc = fmt.Sprintf("call_hourly.%d", cdr.Calldate.Hour())
	var durationHourlyInc = fmt.Sprintf("duration_hourly.%d", cdr.Calldate.Hour())
	//
	var change = mgo.Change{
		Update: bson.M{"$inc": bson.M{"call_daily": 1, "duration_daily": cdr.Billsec,
			"answer_wait_time": cdr.AnswerWaitTime, hourlyInc: 1, durationHourlyInc: cdr.Billsec},
		},
		ReturnNew: false,
	}
	//
	var info = new(mgo.ChangeInfo)
	info, err = collection.Find(selector).Apply(change, &doc)
	//check if the can execute changes
	if info == nil || info.Updated == 0 {
		log.Debugf("Daily update can't be executed , get the error: [ %v], Try execute insert.", err)
		err = collection.Insert(doc)
		if err != nil {
			log.Error("Daily insert failed with error : [%v].", err)
			return err
		}
		info, err = collection.Find(selector).Apply(change, &doc)
		if info != nil {
			log.Debugf("Daily document updated with success for the document : %s", doc.Id)
		} else {
			log.Debugf("Daily document can't be updated, get the error : [%v] for the document : %s", err, doc.Id)
		}
	} else {
		log.Debugf("Document updated : %s\n", doc.Id)
	}
	//
	return nil
}

//
func processDidImport(session *mgo.Session, cdr m.RawCall) (err error) {
	log.Debugf("Import by did : %s\n", cdr.Dnid)
	err = processDidDailyAnalytics(session, cdr)
	if err != nil {
		return nil
	}
	err = processDidMonthlyAnalytics(session, cdr)
	return nil
}

//
func processDidMonthlyAnalytics(session *mgo.Session, cdr m.RawCall) (err error) {
	//
	var collectionName = ""
	var dst = cdr.Dnid
	collectionName = "monthlydid_incomming"
	//
	var id = fmt.Sprintf("%04d%02d-%s-%d", cdr.Calldate.Year(),
		cdr.Calldate.Month(), dst, cdr.Disposition)
	//
	var metaDate = time.Date(cdr.Calldate.Year(), cdr.Calldate.Month(),
		1, 1, 0, 0, 0, time.UTC)
	//
	log.Debugf("Import monthly did :  %s for the id %s.", collectionName, id)
	var collection = session.DB(ODIN_MONGO_DATABASENAME).C(collectionName)
	metaDoc := m.MetaData{Dst: dst, Disposition: cdr.Disposition, Dt: metaDate}
	doc := m.MonthlyCall{Id: id, Meta: metaDoc, AnswereWaitTime: cdr.AnswerWaitTime,
		CallMonthly: 0, DurationMonthly: 0}
	//
	var selector = bson.M{"_id": id, "metadata": metaDoc}
	//
	var change = mgo.Change{
		Update: bson.M{"$inc": bson.M{"call_monthly": 1, "duration_monthly": cdr.Billsec,
			"answer_wait_time": cdr.AnswerWaitTime},
		},
		ReturnNew: false,
	}
	//
	var info = new(mgo.ChangeInfo)
	info, err = collection.Find(selector).Apply(change, &doc)
	//check if the can execute changes
	if info == nil || info.Updated == 0 {
		log.Debugf("Monthly update can't be executed , get the error: [ %v], Try execute insert.", err)
		err = collection.Insert(doc)
		if err != nil {
			log.Errorf("[did] Monthly insert failed with error : [%v].", err)
			return err
		}
		info, err = collection.Find(selector).Apply(change, &doc)
		if info != nil {
			log.Debugf("Monthly did new record inserted : %s.", doc.Id)
		} else {
			log.Errorf("Monthly did can't be updated, get the error : [%v] for the document : %s", err, doc.Id)
		}
	} else {
		if err != nil {
			log.Debugf("Document [%s] was updated, the update numbers: [%s].\n", doc.Id, info.Updated)
		} else {
			return err
		}

	}
	//
	return nil
}

//
func processDidDailyAnalytics(session *mgo.Session, cdr m.RawCall) (err error) {
	//
	var collectionName = ""
	var dst = cdr.Dnid
	collectionName = "dailydid_incomming"
	//
	var id = fmt.Sprintf("%04d%02d%02d-%s-%d", cdr.Calldate.Year(), cdr.Calldate.Month(),
		cdr.Calldate.Day(), dst, cdr.Disposition)
	var metaDate = time.Date(cdr.Calldate.Year(), cdr.Calldate.Month(), cdr.Calldate.Day(), 1, 0, 0, 0, time.UTC)
	log.Debugf("Import daily did :  %s for the id %s.", collectionName, id)
	var collection = session.DB(ODIN_MONGO_DATABASENAME).C(collectionName)
	metaDoc := m.MetaData{Dst: dst, Dt: metaDate, Disposition: cdr.Disposition}
	doc := m.DailyCall{Id: id, Meta: metaDoc, AnswereWaitTime: cdr.AnswerWaitTime, CallDaily: 0,
		DurationDaily: 0}
	//err = collection.Insert(doc)
	var selector = bson.M{"_id": id, "metadata": metaDoc}
	var hourlyInc = fmt.Sprintf("call_hourly.%d", cdr.Calldate.Hour())
	var durationHourlyInc = fmt.Sprintf("duration_hourly.%d", cdr.Calldate.Hour())
	//
	var change = mgo.Change{
		Update: bson.M{"$inc": bson.M{"call_daily": 1, "duration_daily": cdr.Billsec,
			"answer_wait_time": cdr.AnswerWaitTime, hourlyInc: 1, durationHourlyInc: cdr.Billsec},
		},
		ReturnNew: false,
	}
	//
	var info = new(mgo.ChangeInfo)
	info, err = collection.Find(selector).Apply(change, &doc)
	//check if the can execute changes
	if info == nil || info.Updated == 0 {
		log.Debugf("Daily did update can't be executed , get the error: [ %v], Try execute insert.", err)
		err = collection.Insert(doc)
		if err != nil {
			log.Error("Daily did insert failed with error : [%v].", err)
			return err
		}
		info, err = collection.Find(selector).Apply(change, &doc)
		if info != nil {
			log.Debugf("Daily did document updated with success for the document : %s", doc.Id)
		} else {
			log.Debugf("Daily did document can't be updated, get the error : [%v] for the document : %s", err, doc.Id)
		}
	} else {
		log.Debugf("Document did updated : %s\n", doc.Id)
	}
	//
	return nil
}

func importCdrToMongo(session *mgo.Session, cdr m.RawCall) (err error) {
	log.Debugf("Start analyze data for mongo database.")
	createMongoCdr(session, cdr)
	err = processDailyAnalytics(session, cdr)
	if err != nil {
		return err
	}
	err = processMonthlyAnalytics(session, cdr)
	if err != nil {
		return err
	}
	if cdr.InoutStatus == DIRECTION_CALL_IN {
		err = processDidImport(session, cdr)
	}
	err = nil
	return
}
<|endoftext|>


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

package math

import "math"

// x^y: exponentation
export func Pow(x, y float64) float64 {
	// TODO: x or y NaN, ±Inf, maybe ±0.
	switch {
	case y == 0:
		return 1;
	case y == 1:
		return x;
	case x == 0 && y > 0:
		return 0;
	case x == 0 && y < 0:
		return sys.Inf(1);
	case y == 0.5:
		return Sqrt(x);
	case y == -0.5:
		return 1 / Sqrt(x);
	}

	absy := y;
	flip := false;
	if absy < 0 {
		absy = -absy;
		flip = true;
	}
	yi, yf := sys.modf(absy);
	if yf != 0 && x < 0 {
		return sys.NaN();
	}
	if yi >= 1<<63 {
		return Exp(y * Log(x));
	}

	ans := float64(1);

	// ans *= x^yf
	if yf != 0 {
		if yf > 0.5 {
			yf--;
			yi++;
		}
		ans = Exp(yf * Log(x));
	}

	// ans *= x^yi
	// by multiplying in successive squarings
	// of x according to bits of yi.
	// accumulate powers of two into exp.
	// will still have to do ans *= 2^exp later.
	x1, xe := sys.frexp(x);
	exp := 0;
	if i := int64(yi); i != 0 {
		for {
			if i&1 == 1 {
				ans *= x1;
				exp += xe;
			}
			i >>= 1;
			if i == 0 {
				break;
			}
			x1 *= x1;
			xe <<= 1;
			if x1 < .5 {
				x1 += x1;
				xe--;
			}
		}
	}

	// ans *= 2^exp
	// if flip { ans = 1 / ans }
	// but in the opposite order
	if flip {
		ans = 1 / ans;
		exp = -exp;
	}
	return sys.ldexp(ans, exp);
}

<commit_msg>slightly simpler math.Pow per gri's suggestion<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package math

import "math"

// x^y: exponentiation
export func Pow(x, y float64) float64 {
	// TODO: x or y NaN, ±Inf, maybe ±0.
	switch {
	case y == 0:
		return 1;
	case y == 1:
		return x;
	case x == 0 && y > 0:
		return 0;
	case x == 0 && y < 0:
		return sys.Inf(1);
	case y == 0.5:
		return Sqrt(x);
	case y == -0.5:
		return 1 / Sqrt(x);
	}

	absy := y;
	flip := false;
	if absy < 0 {
		absy = -absy;
		flip = true;
	}
	yi, yf := sys.modf(absy);
	if yf != 0 && x < 0 {
		return sys.NaN();
	}
	if yi >= 1<<63 {
		return Exp(y * Log(x));
	}

	// ans = a1 * 2^ae (= 1 for now).
	a1 := float64(1);
	ae := 0;

	// ans *= x^yf
	if yf != 0 {
		if yf > 0.5 {
			yf--;
			yi++;
		}
		a1 = Exp(yf * Log(x));
	}

	// ans *= x^yi
	// by multiplying in successive squarings
	// of x according to bits of yi.
	// accumulate powers of two into exp.
	x1, xe := sys.frexp(x);
	for i := int64(yi); i != 0; i >>= 1 {
		if i&1 == 1 {
			a1 *= x1;
			ae += xe;
		}
		x1 *= x1;
		xe <<= 1;
		if x1 < .5 {
			x1 += x1;
			xe--;
		}
	}

	// ans = a1*2^ae
	// if flip { ans = 1 / ans }
	// but in the opposite order
	if flip {
		a1 = 1 / a1;
		ae = -ae;
	}
	return sys.ldexp(a1, ae);
}
<|endoftext|>


<commit_before>package webhooks

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

type User struct {
	ID           int64   `json:"id"`
	Email        string  `json:"email"`
	Name         string  `json:"name"`
	Blocked      bool    `json:"blocked"`
	CreatedAt    string  `json:"create_at"`
	Username     string  `json:"username"`
	Password     string  `json:"password"`
	Skype        string  `json:"skype"`
	LinkedIn     string  `json:"linkedin"`
	Twitter      string  `json:"twitter"`
	ProjectLimit int64   `json:"projects_limit"`
	ExternalUID  *string `json:"external_UID"`
	Provider     *string `json:"provider"`
	Bio          *string `json:"bio"`
	DarkScheme   bool    `json:"dark_scheme"`
	ThemeID      int64   `json:"theme_id"`
}

func ListUsers(conf ConfigFile) ([]User, error) {
	resp, err := http.Get(
		fmt.Sprintf("%s/%s?private_token=%s", conf.Endpoint, "users", conf.APIKey),
	)
	if err != nil {
		return nil, err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	users := []User{}
	return users, json.Unmarshal(body, &users)
}

func CreateUser(conf ConfigFile, u User) error {
	jsonstr, err := json.Marshal(u)
	if err != nil {
		return err
	}
	resp, err := http.Post(
		fmt.Sprintf("%s/%s?private_token=%s", conf.Endpoint, "users", conf.APIKey),
		"application/json", strings.NewReader(string(jsonstr)),
	)
	if err != nil {
		return err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	fmt.Println(string(body))
	return nil
}

func DeleteUser(conf ConfigFile, ID int64) error {
	req, err := http.NewRequest(
		"DELETE",
		fmt.Sprintf("%s/%s/%d?private_token=%s", conf.Endpoint, "users", ID, conf.APIKey),
		nil,
	)
	if err != nil {
		return err
	}
	c := http.Client{}
	resp, err := c.Do(req)
	if err != nil {
		return err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	fmt.Println(string(body))
	return nil
}

func AddUserToAllProjects(conf ConfigFile, ID int64) error {
	for _, project := range ListProjects(conf) {

	}
}
<commit_msg>Unfucked the stub function.<commit_after>package webhooks

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

type User struct {
	ID           int64   `json:"id"`
	Email        string  `json:"email"`
	Name         string  `json:"name"`
	Blocked      bool    `json:"blocked"`
	CreatedAt    string  `json:"create_at"`
	Username     string  `json:"username"`
	Password     string  `json:"password"`
	Skype        string  `json:"skype"`
	LinkedIn     string  `json:"linkedin"`
	Twitter      string  `json:"twitter"`
	ProjectLimit int64   `json:"projects_limit"`
	ExternalUID  *string `json:"external_UID"`
	Provider     *string `json:"provider"`
	Bio          *string `json:"bio"`
	DarkScheme   bool    `json:"dark_scheme"`
	ThemeID      int64   `json:"theme_id"`
}

func ListUsers(conf ConfigFile) ([]User, error) {
	resp, err := http.Get(
		fmt.Sprintf("%s/%s?private_token=%s", conf.Endpoint, "users", conf.APIKey),
	)
	if err != nil {
		return nil, err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	users := []User{}
	return users, json.Unmarshal(body, &users)
}

func CreateUser(conf ConfigFile, u User) error {
	jsonstr, err := json.Marshal(u)
	if err != nil {
		return err
	}
	resp, err := http.Post(
		fmt.Sprintf("%s/%s?private_token=%s", conf.Endpoint, "users", conf.APIKey),
		"application/json", strings.NewReader(string(jsonstr)),
	)
	if err != nil {
		return err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	fmt.Println(string(body))
	return nil
}

func DeleteUser(conf ConfigFile, ID int64) error {
	req, err := http.NewRequest(
		"DELETE",
		fmt.Sprintf("%s/%s/%d?private_token=%s", conf.Endpoint, "users", ID, conf.APIKey),
		nil,
	)
	if err != nil {
		return err
	}
	c := http.Client{}
	resp, err := c.Do(req)
	if err != nil {
		return err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	fmt.Println(string(body))
	return nil
}

func AddUserToAllProjects(conf ConfigFile, ID int64) error {
	projects, err := ListProjects(conf)
	if err != nil {
		return err
	}
	for _, project := range projects {
		fmt.Println(project)
	}
	return nil
}
<|endoftext|>


<commit_before>package dropbox

import (
	"encoding/json"
)

// Users client for user accounts.
type Users struct {
	*Client
}

// NewUsers client.
func NewUsers(config *Config) *Users {
	return &Users{
		Client: &Client{
			Config: config,
		},
	}
}

// GetAccountInput request input.
type GetAccountInput struct {
	AccountID string `json:"account_id"`
}

// GetAccountOutput request output.
type GetAccountOutput struct {
	AccountID string `json:"account_id"`
	Name      struct {
		GivenName    string `json:"given_name"`
		Surname      string `json:"surname"`
		FamiliarName string `json:"familiar_name"`
		DisplayName  string `json:"display_name"`
	} `json:"name"`
}

// GetAccount returns information about a user's account.
func (c *Users) GetAccount(in *GetAccountInput) (out *GetAccountOutput, err error) {
	body, err := c.call("/users/get_account", in)
	if err != nil {
		return
	}
	defer body.Close()

	err = json.NewDecoder(body).Decode(&out)
	return
}

// GetAccountBatchInput request input. At most 300 ids may be listed.
type GetAccountBatchInput struct {
	AccountIDs []string `json:"account_ids"`
}

// GetAccountBatchOutput request output.
type GetAccountBatchOutput []*GetAccountOutput

// GetAccountBatch returns a list of information about users' accounts.
func (c *Users) GetAccountBatch(in *GetAccountBatchInput) (out GetAccountBatchOutput, err error) {
	body, err := c.call("/users/get_account_batch", in)
	if err != nil {
		return
	}
	defer body.Close()

	err = json.NewDecoder(body).Decode(&out)
	return
}

// GetCurrentAccountOutput request output.
type GetCurrentAccountOutput struct {
	AccountID string `json:"account_id"`
	Name      struct {
		GivenName    string `json:"given_name"`
		Surname      string `json:"surname"`
		FamiliarName string `json:"familiar_name"`
		DisplayName  string `json:"display_name"`
	} `json:"name"`
	Email        string `json:"email"`
	Locale       string `json:"locale"`
	ReferralLink string `json:"referral_link"`
	IsPaired     bool   `json:"is_paired"`
	AccountType  struct {
		Tag string `json:".tag"`
	} `json:"account_type"`
	Country string `json:"country"`
}

// GetCurrentAccount returns information about the current user's account.
func (c *Users) GetCurrentAccount() (out *GetCurrentAccountOutput, err error) {
	body, err := c.call("/users/get_current_account", nil)
	if err != nil {
		return
	}
	defer body.Close()

	err = json.NewDecoder(body).Decode(&out)
	return
}

// GetSpaceUsageOutput request output.
type GetSpaceUsageOutput struct {
	Used       uint64 `json:"used"`
	Allocation struct {
		Used      uint64 `json:"used"`
		Allocated uint64 `json:"allocated"`
	} `json:"allocation"`
}

// GetSpaceUsage returns space usage information for the current user's account.
func (c *Users) GetSpaceUsage() (out *GetSpaceUsageOutput, err error) {
	body, err := c.call("/users/get_space_usage", nil)
	if err != nil {
		return
	}
	defer body.Close()

	err = json.NewDecoder(body).Decode(&out)
	return
}
<commit_msg>add email field to get account output<commit_after>package dropbox

import (
	"encoding/json"
)

// Users client for user accounts.
type Users struct {
	*Client
}

// NewUsers client.
func NewUsers(config *Config) *Users {
	return &Users{
		Client: &Client{
			Config: config,
		},
	}
}

// GetAccountInput request input.
type GetAccountInput struct {
	AccountID string `json:"account_id"`
}

// GetAccountOutput request output.
type GetAccountOutput struct {
	AccountID string `json:"account_id"`
	Name      struct {
		GivenName    string `json:"given_name"`
		Surname      string `json:"surname"`
		FamiliarName string `json:"familiar_name"`
		DisplayName  string `json:"display_name"`
	} `json:"name"`
	Email         string `json:"email"`
	EmailVerified bool   `json:"email_verified"`
	Disabled      bool   `json:"disabled"`
	IsTeammate    bool   `json:"is_teammate"`
}

// GetAccount returns information about a user's account.
func (c *Users) GetAccount(in *GetAccountInput) (out *GetAccountOutput, err error) {
	body, err := c.call("/users/get_account", in)
	if err != nil {
		return
	}
	defer body.Close()

	err = json.NewDecoder(body).Decode(&out)
	return
}

// GetAccountBatchInput request input. At most 300 ids may be listed.
type GetAccountBatchInput struct {
	AccountIDs []string `json:"account_ids"`
}

// GetAccountBatchOutput request output.
type GetAccountBatchOutput []*GetAccountOutput

// GetAccountBatch returns a list of information about users' accounts.
func (c *Users) GetAccountBatch(in *GetAccountBatchInput) (out GetAccountBatchOutput, err error) {
	body, err := c.call("/users/get_account_batch", in)
	if err != nil {
		return
	}
	defer body.Close()

	err = json.NewDecoder(body).Decode(&out)
	return
}

// GetCurrentAccountOutput request output.
type GetCurrentAccountOutput struct {
	AccountID string `json:"account_id"`
	Name      struct {
		GivenName    string `json:"given_name"`
		Surname      string `json:"surname"`
		FamiliarName string `json:"familiar_name"`
		DisplayName  string `json:"display_name"`
	} `json:"name"`
	Email        string `json:"email"`
	Locale       string `json:"locale"`
	ReferralLink string `json:"referral_link"`
	IsPaired     bool   `json:"is_paired"`
	AccountType  struct {
		Tag string `json:".tag"`
	} `json:"account_type"`
	Country string `json:"country"`
}

// GetCurrentAccount returns information about the current user's account.
func (c *Users) GetCurrentAccount() (out *GetCurrentAccountOutput, err error) {
	body, err := c.call("/users/get_current_account", nil)
	if err != nil {
		return
	}
	defer body.Close()

	err = json.NewDecoder(body).Decode(&out)
	return
}

// GetSpaceUsageOutput request output.
type GetSpaceUsageOutput struct {
	Used       uint64 `json:"used"`
	Allocation struct {
		Used      uint64 `json:"used"`
		Allocated uint64 `json:"allocated"`
	} `json:"allocation"`
}

// GetSpaceUsage returns space usage information for the current user's account.
func (c *Users) GetSpaceUsage() (out *GetSpaceUsageOutput, err error) {
	body, err := c.call("/users/get_space_usage", nil)
	if err != nil {
		return
	}
	defer body.Close()

	err = json.NewDecoder(body).Decode(&out)
	return
}
<|endoftext|>


<commit_before>package admin

import (
	"encoding/json"
	"fmt"
	"net/http"
	"path"
	"strings"

	"github.com/qor/qor/responder"
)

type controller struct {
	*Admin
}

func (ac *controller) Dashboard(context *Context) {
	context.Execute("dashboard", nil)
}

func (ac *controller) Index(context *Context) {
	if result, err := context.FindAll(); err == nil {
		responder.With("html", func() {
			context.Execute("index", result)
		}).With("json", func() {
			res := context.Resource
			js, _ := json.Marshal(res.ConvertObjectToMap(context, result, res.IndexMetas()))
			context.Writer.Write(js)
		}).Respond(context.Writer, context.Request)
	} else {
		http.NotFound(context.Writer, context.Request)
	}
}

func (ac *controller) Show(context *Context) {
	result, _ := context.FindOne()

	responder.With("html", func() {
		context.Execute("show", result)
	}).With("json", func() {
		res := context.Resource
		js, _ := json.Marshal(res.ConvertObjectToMap(context, result, res.ShowMetas()))
		context.Writer.Write(js)
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) New(context *Context) {
	context.Execute("new", nil)
}

func (ac *controller) Create(context *Context) {
	res := ac.GetResource(context.ResourcePath())
	result := res.NewStruct()
	if errs := res.Decode(context, result); len(errs) == 0 {
		res.CallSaver(result, context.Context)
		responder.With("html", func() {
			primaryKey := fmt.Sprintf("%v", context.GetDB().NewScope(result).PrimaryKeyValue())
			http.Redirect(context.Writer, context.Request, path.Join(context.Request.RequestURI, primaryKey), http.StatusFound)
		}).With("json", func() {
			res := context.Resource
			js, _ := json.Marshal(res.ConvertObjectToMap(context, result, res.ShowMetas()))
			context.Writer.Write(js)
		}).Respond(context.Writer, context.Request)
	}
}

func (ac *controller) Update(context *Context) {
	if result, err := context.FindOne(); err == nil {
		if errs := context.Resource.Decode(context, result); len(errs) == 0 {
			context.Resource.CallSaver(result, context.Context)
			responder.With("html", func() {
				http.Redirect(context.Writer, context.Request, context.Request.RequestURI, http.StatusFound)
			}).With("json", func() {
				res := context.Resource
				js, _ := json.Marshal(res.ConvertObjectToMap(context, result, res.ShowMetas()))
				context.Writer.Write(js)
			}).Respond(context.Writer, context.Request)
		}
	}
}

func (ac *controller) Delete(context *Context) {
	res := ac.GetResource(context.ResourcePath())

	responder.With("html", func() {
		if res.CallDeleter(res.NewStruct(), context.Context) == nil {
			http.Redirect(context.Writer, context.Request, path.Join(ac.GetRouter().Prefix, res.ToParam()), http.StatusFound)
		} else {
			http.Redirect(context.Writer, context.Request, path.Join(ac.GetRouter().Prefix, res.ToParam()), http.StatusNotFound)
		}
	}).With("json", func() {
		if res.CallDeleter(res.NewStruct(), context.Context) == nil {
			context.Writer.WriteHeader(http.StatusOK)
		} else {
			context.Writer.WriteHeader(http.StatusNotFound)
		}
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) Action(context *Context) {
	var err error
	name := strings.Split(context.Request.URL.Path, "/")[4]

	for _, action := range context.Resource.actions {
		if action.Name == name {
			ids := context.Request.Form.Get("ids")
			scope := context.GetDB().Where(fmt.Sprintf("%v IN (?)", context.Resource.PrimaryField().DBName), ids)
			err = action.Handle(scope, context.Context)
		}
	}

	responder.With("html", func() {
		http.Redirect(context.Writer, context.Request, context.Request.Referer(), http.StatusFound)
	}).With("json", func() {
		if err == nil {
			context.Writer.Write([]byte("OK"))
		} else {
			context.Writer.Write([]byte(err.Error()))
		}
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) Asset(context *Context) {
	file := strings.TrimPrefix(context.Request.URL.Path, ac.GetRouter().Prefix)
	if filename, err := context.findFile(file); err == nil {
		http.ServeFile(context.Writer, context.Request, filename)
	} else {
		http.NotFound(context.Writer, context.Request)
	}
}
<commit_msg>admin: handle errors in update handler<commit_after>package admin

import (
	"encoding/json"
	"fmt"
	"net/http"
	"path"
	"strings"

	"github.com/qor/qor/responder"
)

type controller struct {
	*Admin
}

func renderError(context *Context, err error) {
	responder.With("html", func() {
		context.Writer.WriteHeader(http.StatusNotAcceptable)
		if _, er := context.Writer.Write([]byte(err.Error())); er != nil {
			println("failed to write response", er.Error())
		}
	}).With("json", func() {
		data, er := json.Marshal(map[string]string{"error": err.Error()})
		if er != nil {
			println("failed to marshal error json")
		}
		context.Writer.WriteHeader(http.StatusNotAcceptable)
		if _, er := context.Writer.Write(data); er != nil {
			println("failed to write reponse", er.Error())
		}
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) Dashboard(context *Context) {
	context.Execute("dashboard", nil)
}

func (ac *controller) Index(context *Context) {
	if result, err := context.FindAll(); err == nil {
		responder.With("html", func() {
			context.Execute("index", result)
		}).With("json", func() {
			res := context.Resource
			js, _ := json.Marshal(res.ConvertObjectToMap(context, result, res.IndexMetas()))
			context.Writer.Write(js)
		}).Respond(context.Writer, context.Request)
	} else {
		http.NotFound(context.Writer, context.Request)
	}
}

func (ac *controller) Show(context *Context) {
	result, _ := context.FindOne()

	responder.With("html", func() {
		context.Execute("show", result)
	}).With("json", func() {
		res := context.Resource
		js, _ := json.Marshal(res.ConvertObjectToMap(context, result, res.ShowMetas()))
		context.Writer.Write(js)
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) New(context *Context) {
	context.Execute("new", nil)
}

func (ac *controller) Create(context *Context) {
	res := ac.GetResource(context.ResourcePath())
	result := res.NewStruct()
	if errs := res.Decode(context, result); len(errs) == 0 {
		res.CallSaver(result, context.Context)
		responder.With("html", func() {
			primaryKey := fmt.Sprintf("%v", context.GetDB().NewScope(result).PrimaryKeyValue())
			http.Redirect(context.Writer, context.Request, path.Join(context.Request.RequestURI, primaryKey), http.StatusFound)
		}).With("json", func() {
			res := context.Resource
			js, _ := json.Marshal(res.ConvertObjectToMap(context, result, res.ShowMetas()))
			context.Writer.Write(js)
		}).Respond(context.Writer, context.Request)
	}
}

func (ac *controller) Update(context *Context) {
	if result, err := context.FindOne(); err == nil {
		if errs := context.Resource.Decode(context, result); len(errs) == 0 {
			if err := context.Resource.CallSaver(result, context.Context); err != nil {
				renderError(context, err)
				return
			}
			responder.With("html", func() {
				http.Redirect(context.Writer, context.Request, context.Request.RequestURI, http.StatusFound)
			}).With("json", func() {
				res := context.Resource
				js, _ := json.Marshal(res.ConvertObjectToMap(context, result, res.ShowMetas()))
				context.Writer.Write(js)
			}).Respond(context.Writer, context.Request)
		}
	} else {
		renderError(context, err)
	}
}

func (ac *controller) Delete(context *Context) {
	res := ac.GetResource(context.ResourcePath())

	responder.With("html", func() {
		if res.CallDeleter(res.NewStruct(), context.Context) == nil {
			http.Redirect(context.Writer, context.Request, path.Join(ac.GetRouter().Prefix, res.ToParam()), http.StatusFound)
		} else {
			http.Redirect(context.Writer, context.Request, path.Join(ac.GetRouter().Prefix, res.ToParam()), http.StatusNotFound)
		}
	}).With("json", func() {
		if res.CallDeleter(res.NewStruct(), context.Context) == nil {
			context.Writer.WriteHeader(http.StatusOK)
		} else {
			context.Writer.WriteHeader(http.StatusNotFound)
		}
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) Action(context *Context) {
	var err error
	name := strings.Split(context.Request.URL.Path, "/")[4]

	for _, action := range context.Resource.actions {
		if action.Name == name {
			ids := context.Request.Form.Get("ids")
			scope := context.GetDB().Where(fmt.Sprintf("%v IN (?)", context.Resource.PrimaryField().DBName), ids)
			err = action.Handle(scope, context.Context)
		}
	}

	responder.With("html", func() {
		http.Redirect(context.Writer, context.Request, context.Request.Referer(), http.StatusFound)
	}).With("json", func() {
		if err == nil {
			context.Writer.Write([]byte("OK"))
		} else {
			context.Writer.Write([]byte(err.Error()))
		}
	}).Respond(context.Writer, context.Request)
}

func (ac *controller) Asset(context *Context) {
	file := strings.TrimPrefix(context.Request.URL.Path, ac.GetRouter().Prefix)
	if filename, err := context.findFile(file); err == nil {
		http.ServeFile(context.Writer, context.Request, filename)
	} else {
		http.NotFound(context.Writer, context.Request)
	}
}
<|endoftext|>


<commit_before>package dalga

// TODO backoff

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"strings"
	"sync"
	"time"

	"github.com/cenkalti/dalga/vendor/github.com/cenkalti/backoff"
	"github.com/cenkalti/dalga/vendor/github.com/go-sql-driver/mysql"
)

var debugging = flag.Bool("debug", false, "turn on debug messages")

func debug(args ...interface{}) {
	if *debugging {
		log.Println(args...)
	}
}

type Dalga struct {
	config     Config
	db         *sql.DB
	table      *table
	listener   net.Listener
	client     http.Client
	activeJobs map[string]struct{}
	m          sync.Mutex
	// to wake up publisher when a new job is scheduled or cancelled
	notify chan struct{}
	// will be closed when dalga is ready to accept requests
	ready chan struct{}
	// will be closed by Shutdown method
	shutdown chan struct{}
	// to stop publisher goroutine
	stopPublisher chan struct{}
	// will be closed when publisher goroutine is stopped
	publisherStopped chan struct{}
}

func New(config Config) *Dalga {
	d := &Dalga{
		config:           config,
		activeJobs:       make(map[string]struct{}),
		notify:           make(chan struct{}, 1),
		ready:            make(chan struct{}),
		shutdown:         make(chan struct{}),
		stopPublisher:    make(chan struct{}),
		publisherStopped: make(chan struct{}),
	}
	d.client.Timeout = time.Duration(config.Endpoint.Timeout) * time.Second
	return d
}

// Run Dalga. This function is blocking. Returns nil if Shutdown is called.
func (d *Dalga) Run() error {
	if err := d.connectDB(); err != nil {
		return err
	}
	defer d.db.Close()

	var err error
	d.listener, err = net.Listen("tcp", d.config.Listen.Addr())
	if err != nil {
		return err
	}
	log.Println("Listening", d.listener.Addr())

	close(d.ready)

	go d.publisher()
	defer func() {
		close(d.stopPublisher)
		<-d.publisherStopped
	}()

	if err = d.serveHTTP(); err != nil {
		select {
		case _, ok := <-d.shutdown:
			if !ok {
				// shutdown in progress, do not return error
				return nil
			}
		default:
		}
	}
	return err
}

// Shutdown running Dalga.
func (d *Dalga) Shutdown() error {
	close(d.shutdown)
	return d.listener.Close()
}

// NotifyReady returns a channel that will be closed when Dalga is running.
func (d *Dalga) NotifyReady() <-chan struct{} {
	return d.ready
}

func (d *Dalga) connectDB() error {
	var err error
	d.db, err = sql.Open("mysql", d.config.MySQL.DSN())
	if err != nil {
		return err
	}
	if err = d.db.Ping(); err != nil {
		return err
	}
	log.Print("Connected to MySQL")
	d.table = &table{d.db, d.config.MySQL.Table}
	return nil
}

// CreateTable creates the table for storing jobs.
func (d *Dalga) CreateTable() error {
	db, err := sql.Open("mysql", d.config.MySQL.DSN())
	if err != nil {
		return err
	}
	defer db.Close()
	t := &table{db, d.config.MySQL.Table}
	return t.Create()
}

// GetJob returns the job with description routing key.
func (d *Dalga) GetJob(description, routingKey string) (*Job, error) {
	return d.table.Get(description, routingKey)
}

// ScheduleJob inserts a new job to the table or replaces existing one.
// Returns the created or replaced job.
func (d *Dalga) ScheduleJob(description, routingKey string, interval uint32, oneOff bool) (*Job, error) {
	job := newJob(description, routingKey, interval, oneOff)
	err := d.table.Insert(job)
	if err != nil {
		return nil, err
	}
	d.notifyPublisher("new job")
	debug("Job is scheduled:", job)
	return job, nil
}

// TriggerJob publishes the job to RabbitMQ immediately and resets the next run time of the job.
func (d *Dalga) TriggerJob(description, routingKey string) (*Job, error) {
	job, err := d.GetJob(description, routingKey)
	if err != nil {
		return nil, err
	}
	job.NextRun = time.Now().UTC()
	if err := d.table.Insert(job); err != nil {
		return nil, err
	}
	d.notifyPublisher("job is triggered")
	debug("Job is triggered:", job)
	return job, nil
}

// CancelJob deletes the job with description and routing key.
func (d *Dalga) CancelJob(description, routingKey string) error {
	err := d.table.Delete(description, routingKey)
	if err != nil {
		return err
	}
	d.notifyPublisher("job cancelled")
	debug("Job is cancelled")
	return nil
}

func (d *Dalga) notifyPublisher(debugMessage string) {
	select {
	case d.notify <- struct{}{}:
		debug("notifying publisher:", debugMessage)
	default:
	}
}

// publisher runs a loop that reads the next Job from the queue and publishes it.
func (d *Dalga) publisher() {
	defer close(d.publisherStopped)

	for {
		debug("---")

		var after <-chan time.Time

		job, err := d.table.Front()
		if err != nil {
			if err == sql.ErrNoRows {
				debug("No scheduled jobs in the table")
			} else if myErr, ok := err.(*mysql.MySQLError); ok && myErr.Number == 1146 {
				// Table doesn't exist
				log.Fatal(myErr)
			} else {
				log.Print(err)
				time.Sleep(time.Second)
				continue
			}
		} else {
			remaining := job.Remaining()
			after = time.After(remaining)
			debug("Next job:", job, "Remaining:", remaining)
		}

		// Sleep until the next job's run time or the webserver's wakes us up.
		select {
		case <-after:
			debug("Job sleep time finished")
			if err = d.publish(job); err != nil {
				log.Print(err)
				time.Sleep(time.Second)
			}
		case <-d.notify:
			debug("Woken up from sleep by notification")
			continue
		case <-d.stopPublisher:
			debug("Came quit message")
			return
		}
	}
}

// publish makes a POST request to the endpoint and updates the Job's next run time.
func (d *Dalga) publish(j *Job) error {
	debug("publish", *j)

	var add time.Duration
	if j.Interval == 0 {
		add = d.client.Timeout
	} else {
		add = j.Interval
	}

	j.NextRun = time.Now().UTC().Add(add)

	if err := d.table.UpdateNextRun(j); err != nil {
		return err
	}

	go func() {
		// Do not do multiple POSTs for the same job at the same time.
		key := j.Path + j.Body
		d.m.Lock()
		if _, ok := d.activeJobs[key]; ok {
			d.m.Unlock()
			return
		}
		d.activeJobs[key] = struct{}{}
		d.m.Unlock()

		d.retryPostJob(j)
		if j.Interval == 0 {
			debug("deleting one-off job")
			d.retryDeleteJob(j)
		}

		d.m.Lock()
		delete(d.activeJobs, key)
		d.m.Unlock()
	}()

	return nil
}

func (d *Dalga) postJob(j *Job) error {
	var resp *http.Response
	var err error
	resp, err = d.client.Post(d.config.Endpoint.BaseURL+j.Path, "text/plain", strings.NewReader(j.Body))
	if err != nil {
		return err
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("endpoint error: %d", resp.StatusCode)
	}
	return nil
}

func (d *Dalga) retryPostJob(j *Job) {
	b := backoff.NewExponentialBackOff()
	b.MaxElapsedTime = 0 // retry forever
	if j.Interval > 0 {
		b.MaxInterval = j.Interval
	}
	f := func() error { return d.postJob(j) }
	retry(b, f, d.stopPublisher)
}

func (d *Dalga) retryDeleteJob(j *Job) {
	b := backoff.NewConstantBackOff(time.Second)
	f := func() error { return d.table.Delete(j.Path, j.Body) }
	retry(b, f, nil)
}

func retry(b backoff.BackOff, f func() error, stop chan struct{}) {
	ticker := backoff.NewTicker(b)
	for {
		select {
		case <-ticker.C:
			if err := f(); err != nil {
				log.Print(err)
				continue
			}
			return
		case <-stop:
			return
		}
	}
}
<commit_msg>remove done todo<commit_after>package dalga

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"strings"
	"sync"
	"time"

	"github.com/cenkalti/dalga/vendor/github.com/cenkalti/backoff"
	"github.com/cenkalti/dalga/vendor/github.com/go-sql-driver/mysql"
)

var debugging = flag.Bool("debug", false, "turn on debug messages")

func debug(args ...interface{}) {
	if *debugging {
		log.Println(args...)
	}
}

type Dalga struct {
	config     Config
	db         *sql.DB
	table      *table
	listener   net.Listener
	client     http.Client
	activeJobs map[string]struct{}
	m          sync.Mutex
	// to wake up publisher when a new job is scheduled or cancelled
	notify chan struct{}
	// will be closed when dalga is ready to accept requests
	ready chan struct{}
	// will be closed by Shutdown method
	shutdown chan struct{}
	// to stop publisher goroutine
	stopPublisher chan struct{}
	// will be closed when publisher goroutine is stopped
	publisherStopped chan struct{}
}

func New(config Config) *Dalga {
	d := &Dalga{
		config:           config,
		activeJobs:       make(map[string]struct{}),
		notify:           make(chan struct{}, 1),
		ready:            make(chan struct{}),
		shutdown:         make(chan struct{}),
		stopPublisher:    make(chan struct{}),
		publisherStopped: make(chan struct{}),
	}
	d.client.Timeout = time.Duration(config.Endpoint.Timeout) * time.Second
	return d
}

// Run Dalga. This function is blocking. Returns nil if Shutdown is called.
func (d *Dalga) Run() error {
	if err := d.connectDB(); err != nil {
		return err
	}
	defer d.db.Close()

	var err error
	d.listener, err = net.Listen("tcp", d.config.Listen.Addr())
	if err != nil {
		return err
	}
	log.Println("Listening", d.listener.Addr())

	close(d.ready)

	go d.publisher()
	defer func() {
		close(d.stopPublisher)
		<-d.publisherStopped
	}()

	if err = d.serveHTTP(); err != nil {
		select {
		case _, ok := <-d.shutdown:
			if !ok {
				// shutdown in progress, do not return error
				return nil
			}
		default:
		}
	}
	return err
}

// Shutdown running Dalga.
func (d *Dalga) Shutdown() error {
	close(d.shutdown)
	return d.listener.Close()
}

// NotifyReady returns a channel that will be closed when Dalga is running.
func (d *Dalga) NotifyReady() <-chan struct{} {
	return d.ready
}

func (d *Dalga) connectDB() error {
	var err error
	d.db, err = sql.Open("mysql", d.config.MySQL.DSN())
	if err != nil {
		return err
	}
	if err = d.db.Ping(); err != nil {
		return err
	}
	log.Print("Connected to MySQL")
	d.table = &table{d.db, d.config.MySQL.Table}
	return nil
}

// CreateTable creates the table for storing jobs.
func (d *Dalga) CreateTable() error {
	db, err := sql.Open("mysql", d.config.MySQL.DSN())
	if err != nil {
		return err
	}
	defer db.Close()
	t := &table{db, d.config.MySQL.Table}
	return t.Create()
}

// GetJob returns the job with description routing key.
func (d *Dalga) GetJob(description, routingKey string) (*Job, error) {
	return d.table.Get(description, routingKey)
}

// ScheduleJob inserts a new job to the table or replaces existing one.
// Returns the created or replaced job.
func (d *Dalga) ScheduleJob(description, routingKey string, interval uint32, oneOff bool) (*Job, error) {
	job := newJob(description, routingKey, interval, oneOff)
	err := d.table.Insert(job)
	if err != nil {
		return nil, err
	}
	d.notifyPublisher("new job")
	debug("Job is scheduled:", job)
	return job, nil
}

// TriggerJob publishes the job to RabbitMQ immediately and resets the next run time of the job.
func (d *Dalga) TriggerJob(description, routingKey string) (*Job, error) {
	job, err := d.GetJob(description, routingKey)
	if err != nil {
		return nil, err
	}
	job.NextRun = time.Now().UTC()
	if err := d.table.Insert(job); err != nil {
		return nil, err
	}
	d.notifyPublisher("job is triggered")
	debug("Job is triggered:", job)
	return job, nil
}

// CancelJob deletes the job with description and routing key.
func (d *Dalga) CancelJob(description, routingKey string) error {
	err := d.table.Delete(description, routingKey)
	if err != nil {
		return err
	}
	d.notifyPublisher("job cancelled")
	debug("Job is cancelled")
	return nil
}

func (d *Dalga) notifyPublisher(debugMessage string) {
	select {
	case d.notify <- struct{}{}:
		debug("notifying publisher:", debugMessage)
	default:
	}
}

// publisher runs a loop that reads the next Job from the queue and publishes it.
func (d *Dalga) publisher() {
	defer close(d.publisherStopped)

	for {
		debug("---")

		var after <-chan time.Time

		job, err := d.table.Front()
		if err != nil {
			if err == sql.ErrNoRows {
				debug("No scheduled jobs in the table")
			} else if myErr, ok := err.(*mysql.MySQLError); ok && myErr.Number == 1146 {
				// Table doesn't exist
				log.Fatal(myErr)
			} else {
				log.Print(err)
				time.Sleep(time.Second)
				continue
			}
		} else {
			remaining := job.Remaining()
			after = time.After(remaining)
			debug("Next job:", job, "Remaining:", remaining)
		}

		// Sleep until the next job's run time or the webserver's wakes us up.
		select {
		case <-after:
			debug("Job sleep time finished")
			if err = d.publish(job); err != nil {
				log.Print(err)
				time.Sleep(time.Second)
			}
		case <-d.notify:
			debug("Woken up from sleep by notification")
			continue
		case <-d.stopPublisher:
			debug("Came quit message")
			return
		}
	}
}

// publish makes a POST request to the endpoint and updates the Job's next run time.
func (d *Dalga) publish(j *Job) error {
	debug("publish", *j)

	var add time.Duration
	if j.Interval == 0 {
		add = d.client.Timeout
	} else {
		add = j.Interval
	}

	j.NextRun = time.Now().UTC().Add(add)

	if err := d.table.UpdateNextRun(j); err != nil {
		return err
	}

	go func() {
		// Do not do multiple POSTs for the same job at the same time.
		key := j.Path + j.Body
		d.m.Lock()
		if _, ok := d.activeJobs[key]; ok {
			d.m.Unlock()
			return
		}
		d.activeJobs[key] = struct{}{}
		d.m.Unlock()

		d.retryPostJob(j)
		if j.Interval == 0 {
			debug("deleting one-off job")
			d.retryDeleteJob(j)
		}

		d.m.Lock()
		delete(d.activeJobs, key)
		d.m.Unlock()
	}()

	return nil
}

func (d *Dalga) postJob(j *Job) error {
	var resp *http.Response
	var err error
	resp, err = d.client.Post(d.config.Endpoint.BaseURL+j.Path, "text/plain", strings.NewReader(j.Body))
	if err != nil {
		return err
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("endpoint error: %d", resp.StatusCode)
	}
	return nil
}

func (d *Dalga) retryPostJob(j *Job) {
	b := backoff.NewExponentialBackOff()
	b.MaxElapsedTime = 0 // retry forever
	if j.Interval > 0 {
		b.MaxInterval = j.Interval
	}
	f := func() error { return d.postJob(j) }
	retry(b, f, d.stopPublisher)
}

func (d *Dalga) retryDeleteJob(j *Job) {
	b := backoff.NewConstantBackOff(time.Second)
	f := func() error { return d.table.Delete(j.Path, j.Body) }
	retry(b, f, nil)
}

func retry(b backoff.BackOff, f func() error, stop chan struct{}) {
	ticker := backoff.NewTicker(b)
	for {
		select {
		case <-ticker.C:
			if err := f(); err != nil {
				log.Print(err)
				continue
			}
			return
		case <-stop:
			return
		}
	}
}
<|endoftext|>