<commit_before>package pg // import "gopkg.in/pg.v4"

import (
	"io"
	"time"

	"gopkg.in/pg.v4/internal/pool"
	"gopkg.in/pg.v4/orm"
	"gopkg.in/pg.v4/types"
)

const defaultBackoff = 500 * time.Millisecond

// Connect connects to a database using provided options.
//
// The returned DB is safe for concurrent use by multiple goroutines
// and maintains its own connection pool.
func Connect(opt *Options) *DB {
	return &DB{
		opt:  opt,
		pool: newConnPool(opt),
	}
}

// DB is a database handle representing a pool of zero or more
// underlying connections. It's safe for concurrent use by multiple
// goroutines.
type DB struct {
	opt  *Options
	pool *pool.ConnPool
}

// Options returns read-only Options that were used to connect to the DB.
func (db *DB) Options() *Options {
	return db.opt
}

// WithTimeout returns a DB that uses d as the read/write timeout.
func (db *DB) WithTimeout(d time.Duration) *DB {
	newopt := *db.opt
	newopt.ReadTimeout = d
	newopt.WriteTimeout = d
	return &DB{
		opt:  &newopt,
		pool: db.pool,
	}
}

func (db *DB) conn() (*pool.Conn, error) {
	cn, err := db.pool.Get()
	if err != nil {
		return nil, err
	}

	if !cn.Inited {
		if err := db.initConn(cn); err != nil {
			_ = db.pool.Remove(cn, err)
			return nil, err
		}
	}

	cn.SetReadTimeout(db.opt.ReadTimeout)
	cn.SetWriteTimeout(db.opt.WriteTimeout)
	return cn, nil
}

func (db *DB) initConn(cn *pool.Conn) error {
	if db.opt.getSSL() {
		if err := enableSSL(cn); err != nil {
			return err
		}
	}

	err := startup(cn, db.opt.getUser(), db.opt.getPassword(), db.opt.getDatabase())
	if err != nil {
		return err
	}

	if err := setParams(cn, db.opt.Params); err != nil {
		return err
	}

	cn.Inited = true
	return nil
}

func (db *DB) freeConn(cn *pool.Conn, err error) error {
	if !isBadConn(err, false) {
		return db.pool.Put(cn)
	}
	return db.pool.Remove(cn, err)
}

// Close closes the database client, releasing any open resources.
//
// It is rare to Close a DB, as the DB handle is meant to be
// long-lived and shared between many goroutines.
func (db *DB) Close() error {
	return db.pool.Close()
}

// Exec executes a query ignoring returned rows. The params are for
// any placeholder parameters in the query.
func (db *DB) Exec(query interface{}, params ...interface{}) (res *types.Result, err error) {
	for i := 0; ; i++ {
		var cn *pool.Conn

		cn, err = db.conn()
		if err != nil {
			return nil, err
		}

		res, err = simpleQuery(cn, query, params...)
		db.freeConn(cn, err)

		if i >= db.opt.MaxRetries {
			return res, err
		}
		if !shouldRetry(err) {
			return res, err
		}

		time.Sleep(defaultBackoff << uint(i))
	}
	return
}

// ExecOne acts like Exec, but query must affect only one row. It
// returns ErrNoRows error when query returns zero rows or
// ErrMultiRows when query returns multiple rows.
func (db *DB) ExecOne(query interface{}, params ...interface{}) (*types.Result, error) {
	res, err := db.Exec(query, params...)
	if err != nil {
		return nil, err
	}
	return assertOneAffected(res)
}

// Query executes a query that returns rows, typically a SELECT.
// The params are for any placeholder parameters in the query.
func (db *DB) Query(model, query interface{}, params ...interface{}) (res *types.Result, err error) {
	for i := 0; i < 3; i++ {
		var cn *pool.Conn

		cn, err = db.conn()
		if err != nil {
			return nil, err
		}

		res, err = simpleQueryData(cn, model, query, params...)
		db.freeConn(cn, err)

		if i >= db.opt.MaxRetries {
			return res, err
		}
		if !shouldRetry(err) {
			return res, err
		}

		time.Sleep(defaultBackoff << uint(i))
	}
	return
}

// QueryOne acts like Query, but query must return only one row. It
// returns ErrNoRows error when query returns zero rows or
// ErrMultiRows when query returns multiple rows.
func (db *DB) QueryOne(model, query interface{}, params ...interface{}) (*types.Result, error) {
	mod, err := newSingleModel(model)
	if err != nil {
		return nil, err
	}
	res, err := db.Query(mod, query, params...)
	if err != nil {
		return nil, err
	}
	return assertOneAffected(res)
}

// Listen listens for notifications sent by NOTIFY statement.
func (db *DB) Listen(channels ...string) (*Listener, error) {
	l := &Listener{
		db: db,
	}
	if err := l.Listen(channels...); err != nil {
		l.Close()
		return nil, err
	}
	return l, nil
}

// CopyFrom copies data from reader to a table.
func (db *DB) CopyFrom(r io.Reader, query interface{}, params ...interface{}) (*types.Result, error) {
	cn, err := db.conn()
	if err != nil {
		return nil, err
	}
	res, err := copyFrom(cn, r, query, params...)
	if err != nil {
		db.freeConn(cn, err)
		return nil, err
	}
	db.pool.Put(cn)
	return res, nil
}

// CopyTo copies data from a table to writer.
func (db *DB) CopyTo(w io.Writer, query interface{}, params ...interface{}) (*types.Result, error) {
	cn, err := db.conn()
	if err != nil {
		return nil, err
	}

	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		db.pool.Put(cn)
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	if err := readCopyOutResponse(cn); err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	res, err := readCopyData(cn, w)
	if err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	return res, nil
}

// Model returns new query for the model.
func (db *DB) Model(model interface{}) *orm.Query {
	return orm.NewQuery(db, model)
}

// Select selects the model by primary key.
func (db *DB) Select(model interface{}) error {
	return orm.Select(db, model)
}

// Create inserts the model updating primary keys if they are empty.
func (db *DB) Create(model interface{}) error {
	return orm.Create(db, model)
}

// Update updates the model by primary key.
func (db *DB) Update(model interface{}) error {
	return orm.Update(db, model)
}

// Delete deletes the model by primary key.
func (db *DB) Delete(model interface{}) error {
	return orm.Delete(db, model)
}

func (db *DB) FormatQuery(dst []byte, query string, params ...interface{}) []byte {
	return orm.Formatter{}.Append(dst, query, params...)
}

func setParams(cn *pool.Conn, params map[string]interface{}) error {
	for key, value := range params {
		_, err := simpleQuery(cn, "SET ? = ?", F(key), value)
		if err != nil {
			return err
		}
	}
	return nil
}

func (db *DB) cancelRequest(processId, secretKey int32) error {
	cn, err := db.pool.NewConn()
	if err != nil {
		return err
	}

	writeCancelRequestMsg(cn.Wr, processId, secretKey)
	if err = cn.Wr.Flush(); err != nil {
		return err
	}
	cn.Close()

	return nil
}

func simpleQuery(cn *pool.Conn, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	res, err := readSimpleQuery(cn)
	if err != nil {
		return nil, err
	}

	return res, nil
}

func simpleQueryData(cn *pool.Conn, model, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	res, err := readSimpleQueryData(cn, model)
	if err != nil {
		return nil, err
	}

	return res, nil
}

type singleModel struct {
	orm.Model
}

var _ orm.Collection = (*singleModel)(nil)

func newSingleModel(mod interface{}) (*singleModel, error) {
	model, ok := mod.(orm.Model)
	if !ok {
		var err error
		model, err = orm.NewModel(mod)
		if err != nil {
			return nil, err
		}
	}
	return &singleModel{
		Model: model,
	}, nil
}

func (m *singleModel) AddModel(_ orm.ColumnScanner) error {
	return nil
}

func assertOne(l int) error {
	switch {
	case l == 0:
		return ErrNoRows
	case l > 1:
		return ErrMultiRows
	default:
		return nil
	}
}

func assertOneAffected(res *types.Result) (*types.Result, error) {
	if err := assertOne(res.Affected()); err != nil {
		return nil, err
	}
	return res, nil
}

func copyFrom(cn *pool.Conn, r io.Reader, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	if err := readCopyInResponse(cn); err != nil {
		return nil, err
	}

	for {
		if _, err := writeCopyData(cn.Wr, r); err != nil {
			if err == io.EOF {
				break
			}
			return nil, err
		}

		if err := cn.Wr.Flush(); err != nil {
			return nil, err
		}
	}

	writeCopyDone(cn.Wr)
	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	return readReadyForQueryOrError(cn)
}
<commit_msg>Release acquired DB connections in db.CopyTo()<commit_after>package pg // import "gopkg.in/pg.v4"

import (
	"io"
	"time"

	"gopkg.in/pg.v4/internal/pool"
	"gopkg.in/pg.v4/orm"
	"gopkg.in/pg.v4/types"
)

const defaultBackoff = 500 * time.Millisecond

// Connect connects to a database using provided options.
//
// The returned DB is safe for concurrent use by multiple goroutines
// and maintains its own connection pool.
func Connect(opt *Options) *DB {
	return &DB{
		opt:  opt,
		pool: newConnPool(opt),
	}
}

// DB is a database handle representing a pool of zero or more
// underlying connections. It's safe for concurrent use by multiple
// goroutines.
type DB struct {
	opt  *Options
	pool *pool.ConnPool
}

// Options returns read-only Options that were used to connect to the DB.
func (db *DB) Options() *Options {
	return db.opt
}

// WithTimeout returns a DB that uses d as the read/write timeout.
func (db *DB) WithTimeout(d time.Duration) *DB {
	newopt := *db.opt
	newopt.ReadTimeout = d
	newopt.WriteTimeout = d
	return &DB{
		opt:  &newopt,
		pool: db.pool,
	}
}

func (db *DB) conn() (*pool.Conn, error) {
	cn, err := db.pool.Get()
	if err != nil {
		return nil, err
	}

	if !cn.Inited {
		if err := db.initConn(cn); err != nil {
			_ = db.pool.Remove(cn, err)
			return nil, err
		}
	}

	cn.SetReadTimeout(db.opt.ReadTimeout)
	cn.SetWriteTimeout(db.opt.WriteTimeout)
	return cn, nil
}

func (db *DB) initConn(cn *pool.Conn) error {
	if db.opt.getSSL() {
		if err := enableSSL(cn); err != nil {
			return err
		}
	}

	err := startup(cn, db.opt.getUser(), db.opt.getPassword(), db.opt.getDatabase())
	if err != nil {
		return err
	}

	if err := setParams(cn, db.opt.Params); err != nil {
		return err
	}

	cn.Inited = true
	return nil
}

func (db *DB) freeConn(cn *pool.Conn, err error) error {
	if !isBadConn(err, false) {
		return db.pool.Put(cn)
	}
	return db.pool.Remove(cn, err)
}

// Close closes the database client, releasing any open resources.
//
// It is rare to Close a DB, as the DB handle is meant to be
// long-lived and shared between many goroutines.
func (db *DB) Close() error {
	return db.pool.Close()
}

// Exec executes a query ignoring returned rows. The params are for
// any placeholder parameters in the query.
func (db *DB) Exec(query interface{}, params ...interface{}) (res *types.Result, err error) {
	for i := 0; ; i++ {
		var cn *pool.Conn

		cn, err = db.conn()
		if err != nil {
			return nil, err
		}

		res, err = simpleQuery(cn, query, params...)
		db.freeConn(cn, err)

		if i >= db.opt.MaxRetries {
			return res, err
		}
		if !shouldRetry(err) {
			return res, err
		}

		time.Sleep(defaultBackoff << uint(i))
	}
	return
}

// ExecOne acts like Exec, but query must affect only one row. It
// returns ErrNoRows error when query returns zero rows or
// ErrMultiRows when query returns multiple rows.
func (db *DB) ExecOne(query interface{}, params ...interface{}) (*types.Result, error) {
	res, err := db.Exec(query, params...)
	if err != nil {
		return nil, err
	}
	return assertOneAffected(res)
}

// Query executes a query that returns rows, typically a SELECT.
// The params are for any placeholder parameters in the query.
func (db *DB) Query(model, query interface{}, params ...interface{}) (res *types.Result, err error) {
	for i := 0; i < 3; i++ {
		var cn *pool.Conn

		cn, err = db.conn()
		if err != nil {
			return nil, err
		}

		res, err = simpleQueryData(cn, model, query, params...)
		db.freeConn(cn, err)

		if i >= db.opt.MaxRetries {
			return res, err
		}
		if !shouldRetry(err) {
			return res, err
		}

		time.Sleep(defaultBackoff << uint(i))
	}
	return
}

// QueryOne acts like Query, but query must return only one row. It
// returns ErrNoRows error when query returns zero rows or
// ErrMultiRows when query returns multiple rows.
func (db *DB) QueryOne(model, query interface{}, params ...interface{}) (*types.Result, error) {
	mod, err := newSingleModel(model)
	if err != nil {
		return nil, err
	}
	res, err := db.Query(mod, query, params...)
	if err != nil {
		return nil, err
	}
	return assertOneAffected(res)
}

// Listen listens for notifications sent by NOTIFY statement.
func (db *DB) Listen(channels ...string) (*Listener, error) {
	l := &Listener{
		db: db,
	}
	if err := l.Listen(channels...); err != nil {
		l.Close()
		return nil, err
	}
	return l, nil
}

// CopyFrom copies data from reader to a table.
func (db *DB) CopyFrom(r io.Reader, query interface{}, params ...interface{}) (*types.Result, error) {
	cn, err := db.conn()
	if err != nil {
		return nil, err
	}
	res, err := copyFrom(cn, r, query, params...)
	if err != nil {
		db.freeConn(cn, err)
		return nil, err
	}
	db.pool.Put(cn)
	return res, nil
}

// CopyTo copies data from a table to writer.
func (db *DB) CopyTo(w io.Writer, query interface{}, params ...interface{}) (*types.Result, error) {
	cn, err := db.conn()
	if err != nil {
		return nil, err
	}

	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		db.pool.Put(cn)
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	if err := readCopyOutResponse(cn); err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	res, err := readCopyData(cn, w)
	if err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	db.pool.Put(cn)
	return res, nil
}

// Model returns new query for the model.
func (db *DB) Model(model interface{}) *orm.Query {
	return orm.NewQuery(db, model)
}

// Select selects the model by primary key.
func (db *DB) Select(model interface{}) error {
	return orm.Select(db, model)
}

// Create inserts the model updating primary keys if they are empty.
func (db *DB) Create(model interface{}) error {
	return orm.Create(db, model)
}

// Update updates the model by primary key.
func (db *DB) Update(model interface{}) error {
	return orm.Update(db, model)
}

// Delete deletes the model by primary key.
func (db *DB) Delete(model interface{}) error {
	return orm.Delete(db, model)
}

func (db *DB) FormatQuery(dst []byte, query string, params ...interface{}) []byte {
	return orm.Formatter{}.Append(dst, query, params...)
}

func setParams(cn *pool.Conn, params map[string]interface{}) error {
	for key, value := range params {
		_, err := simpleQuery(cn, "SET ? = ?", F(key), value)
		if err != nil {
			return err
		}
	}
	return nil
}

func (db *DB) cancelRequest(processId, secretKey int32) error {
	cn, err := db.pool.NewConn()
	if err != nil {
		return err
	}

	writeCancelRequestMsg(cn.Wr, processId, secretKey)
	if err = cn.Wr.Flush(); err != nil {
		return err
	}
	cn.Close()

	return nil
}

func simpleQuery(cn *pool.Conn, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	res, err := readSimpleQuery(cn)
	if err != nil {
		return nil, err
	}

	return res, nil
}

func simpleQueryData(cn *pool.Conn, model, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	res, err := readSimpleQueryData(cn, model)
	if err != nil {
		return nil, err
	}

	return res, nil
}

type singleModel struct {
	orm.Model
}

var _ orm.Collection = (*singleModel)(nil)

func newSingleModel(mod interface{}) (*singleModel, error) {
	model, ok := mod.(orm.Model)
	if !ok {
		var err error
		model, err = orm.NewModel(mod)
		if err != nil {
			return nil, err
		}
	}
	return &singleModel{
		Model: model,
	}, nil
}

func (m *singleModel) AddModel(_ orm.ColumnScanner) error {
	return nil
}

func assertOne(l int) error {
	switch {
	case l == 0:
		return ErrNoRows
	case l > 1:
		return ErrMultiRows
	default:
		return nil
	}
}

func assertOneAffected(res *types.Result) (*types.Result, error) {
	if err := assertOne(res.Affected()); err != nil {
		return nil, err
	}
	return res, nil
}

func copyFrom(cn *pool.Conn, r io.Reader, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	if err := readCopyInResponse(cn); err != nil {
		return nil, err
	}

	for {
		if _, err := writeCopyData(cn.Wr, r); err != nil {
			if err == io.EOF {
				break
			}
			return nil, err
		}

		if err := cn.Wr.Flush(); err != nil {
			return nil, err
		}
	}

	writeCopyDone(cn.Wr)
	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	return readReadyForQueryOrError(cn)
}
<|endoftext|>


<commit_before>// Every file in go is a part of some package. Since we want to create a program
// from this file we use 'package main'
package main

import (
	"encoding/hex"
	"fmt"
	"log"

	"github.com/btcsuite/btcec"
	"github.com/btcsuite/btcnet"
	"github.com/btcsuite/btcutil"
)

// generateKeyPair creates a key pair based on the eliptic curve
// secp256k1. The key pair returned by this function is two points
// on this curve. Bitcoin requires that the public and private keys
// used to generate signatures are generated using this curve.

func generateKeyPair() (*btcec.PublicKey, *btcec.PrivateKey) {

	// Generate a private key, use the curve secpc256k1 and kill the program on
	// any errors
	priv, err := btcec.NewPrivateKey(btcec.S256())
	if err != nil {
		// There was an error. Log it and bail out
		log.Fatal(err)
	}

	return priv.PubKey(), priv
}

// generateAddr computes the associated bitcon address from the provided
// public key. We compute ripemd160(sha256(b)) of the pubkey and then
// shimmy the hashed bytes into btcsuite's AddressPubKeyHash type
func generateAddr(pub *btcec.PublicKey) *btcutil.AddressPubKeyHash {

	net := &btcnet.MainNetParams

	// Serialize the public key into bytes and then run ripemd160(sha256(b)) on it
	b := btcutil.Hash160(pub.SerializeCompressed())

	// Convert the hashed public key into the btcsuite type so that the library
	// will handle the base58 encoding when we call addr.String()
	addr, err := btcutil.NewAddressPubKeyHash(b, net)
	if err != nil {
		log.Fatal(err)
	}

	return addr
}

func main() {

	// In order to recieve coins we must generate a public/private key pair.
	pub, priv := generateKeyPair()

	// To use this address we must store our private key somewhere. Everything
	// else can be recovered from the private key.
	fmt.Printf("This is a private key in hex:\t[%s]\n",
		hex.EncodeToString(priv.Serialize()))

	fmt.Printf("This is a public key in hex:\t[%s]\n",
		hex.EncodeToString(pub.SerializeCompressed()))

	addr := generateAddr(pub)

	// Output the bitcoin address derived from the public key
	fmt.Printf("This is the associated Bitcoin address:\t[%s]\n", addr.String())
}
<commit_msg>checks hex string<commit_after>// Every file in go is a part of some package. Since we want to create a program
// from this file we use 'package main'
package main

import (
	"encoding/hex"
	"fmt"
	"log"
	"strings"

	"github.com/btcsuite/btcec"
	"github.com/btcsuite/btcnet"
	"github.com/btcsuite/btcutil"
)

// generateKeyPair creates a key pair based on the eliptic curve
// secp256k1. The key pair returned by this function is two points
// on this curve. Bitcoin requires that the public and private keys
// used to generate signatures are generated using this curve.

func generateKeyPair() (*btcec.PublicKey, *btcec.PrivateKey) {

	// Generate a private key, use the curve secpc256k1 and kill the program on
	// any errors
	priv, err := btcec.NewPrivateKey(btcec.S256())
	if err != nil {
		// There was an error. Log it and bail out
		log.Fatal(err)
	}

	return priv.PubKey(), priv
}

// generateAddr computes the associated bitcon address from the provided
// public key. We compute ripemd160(sha256(b)) of the pubkey and then
// shimmy the hashed bytes into btcsuite's AddressPubKeyHash type
func generateAddr(pub *btcec.PublicKey) *btcutil.AddressPubKeyHash {

	net := &btcnet.MainNetParams

	// Serialize the public key into bytes and then run ripemd160(sha256(b)) on it
	b := btcutil.Hash160(pub.SerializeCompressed())

	// Convert the hashed public key into the btcsuite type so that the library
	// will handle the base58 encoding when we call addr.String()
	addr, err := btcutil.NewAddressPubKeyHash(b, net)
	if err != nil {
		log.Fatal(err)
	}

	return addr
}

func main() {

	//In order to recieve coins we must generate a public/private key pair.
	//pub, priv := generateKeyPair()
	generateVanityAddress("ANAT")
	//
	// fmt.Printf("THis is the vanityAddrss:\t[%s]\n", ad.String())
	//
	// // To use this address we must store our private key somewhere. Everything
	// // else can be recovered from the private key.
	// fmt.Printf("This is a private key in hex:\t[%s]\n",
	// 	hex.EncodeToString(priv.Serialize()))
	//
	// fmt.Printf("This is a public key in hex:\t[%s]\n",
	// 	hex.EncodeToString(pub.SerializeCompressed()))
	//
	// addr := generateAddr(pub)
	//
	// // Output the bitcoin address derived from the public key
	// fmt.Printf("This is the associated Bitcoin address:\t[%s]\n", addr.String())
	//

}

func generateVanityAddress(pattern string) (*btcec.PublicKey, *btcec.PrivateKey) {

	for {
		pub, priv := generateKeyPair()

		addr := generateAddr(pub)

		if strings.Contains(addr.String(), pattern) {
			fmt.Printf("This is a private key in hex:\t[%s]\n", hex.EncodeToString(priv.Serialize()))

			fmt.Printf("This is a public key in hex:\t[%s]\n", hex.EncodeToString(pub.SerializeCompressed()))
			fmt.Printf("This is the associated Bitcoin address:\t[%s]\n", addr.String())
			return pub, priv
		}

	}

}
<|endoftext|>


<commit_before>package shorturl

import (
	"crypto/sha1"

	"fmt"

	"github.com/garyburd/redigo/redis"
	log "github.com/meifamily/logrus"

	"github.com/meifamily/ptt-alertor/connections"
	"github.com/meifamily/ptt-alertor/myutil"
)

const redisPrefix = "sum:"

var url = "https://pttalertor.dinolai.com/redirect/"

func init() {
	config := myutil.Config("app")
	url = config["host"] + "/redirect/"
}

func Gen(longURL string) string {
	data := []byte(longURL)
	sum := fmt.Sprintf("%x", sha1.Sum(data))
	conn := connections.Redis()
	_, err := conn.Do("SET", redisPrefix+sum, longURL, "EX", 1800)
	if err != nil {
		log.WithField("runtime", myutil.BasicRuntimeInfo()).WithError(err).Error()
	}
	shortURL := url + sum
	return shortURL
}

func Original(sum string) string {
	conn := connections.Redis()
	key := redisPrefix + sum
	conn.Send("MULTI")
	conn.Send("GET", key)
	conn.Send("DEL", key)
	result, err := redis.Values(conn.Do("EXEC"))
	if err != nil {
		log.WithField("runtime", myutil.BasicRuntimeInfo()).WithError(err).Error()
	}
	if result[0] == nil {
		return ""
	}
	return string(result[0].([]byte))
}
<commit_msg>decrease shorturl exist time<commit_after>package shorturl

import (
	"crypto/sha1"

	"fmt"

	"github.com/garyburd/redigo/redis"
	log "github.com/meifamily/logrus"

	"github.com/meifamily/ptt-alertor/connections"
	"github.com/meifamily/ptt-alertor/myutil"
)

const redisPrefix = "sum:"

var url = "https://pttalertor.dinolai.com/redirect/"

func init() {
	config := myutil.Config("app")
	url = config["host"] + "/redirect/"
}

func Gen(longURL string) string {
	data := []byte(longURL)
	sum := fmt.Sprintf("%x", sha1.Sum(data))
	conn := connections.Redis()
	_, err := conn.Do("SET", redisPrefix+sum, longURL, "EX", 600)
	if err != nil {
		log.WithField("runtime", myutil.BasicRuntimeInfo()).WithError(err).Error()
	}
	shortURL := url + sum
	return shortURL
}

func Original(sum string) string {
	conn := connections.Redis()
	key := redisPrefix + sum
	conn.Send("MULTI")
	conn.Send("GET", key)
	conn.Send("DEL", key)
	result, err := redis.Values(conn.Do("EXEC"))
	if err != nil {
		log.WithField("runtime", myutil.BasicRuntimeInfo()).WithError(err).Error()
	}
	if result[0] == nil {
		return ""
	}
	return string(result[0].([]byte))
}
<|endoftext|>


<commit_before>// Copyright 2017, Project ArteMisc
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package sign

import (
	"go.artemisc.eu/godium"
	"go.artemisc.eu/godium/hash"
	"go.artemisc.eu/godium/internal"
	"go.artemisc.eu/godium/internal/edwards25519"
)

const (
	Ed25519_PublicKeyBytes = 32
	Ed25519_SecretKeyBytes = 64
	Ed25519_Bytes          = 64
	Ed25519_SeedBytes      = 32

	Ed25519ph_PublicKeyBytes = 32
	Ed25519ph_SecretKeyBytes = 64
	Ed25519ph_Bytes          = 64
	Ed25519ph_SeedBytes      = 32
)

type Ed25519Sign struct {
	private   godium.PrivateKey
	public    godium.PublicKey
	multipart godium.Hash
}

// NewEd25519
func NewEd25519(key godium.PrivateKey) (s godium.Sign) {
	key = internal.Copy(key, Ed25519_SecretKeyBytes)
	s = &Ed25519Sign{
		private: key,
		public:  godium.PublicKey(key[Ed25519_SeedBytes:Ed25519_SecretKeyBytes]),
	}
	return
}

// KeyPairEd25519
func KeyPairEd25519(random godium.Random) (s *Ed25519Sign, err error) {
	seed, err := random.KeyGen(Ed25519_SeedBytes)
	if err != nil {
		return
	}

	s = KeyPairSeedEd25519(seed)
	return
}

// KeyPairSeedEd25519
func KeyPairSeedEd25519(seed []byte) (s *Ed25519Sign) {
	seed = internal.Copy(seed, SeedBytes)
	defer godium.Wipe(seed)

	s = new(Ed25519Sign)
	s.private = make([]byte, Ed25519_SecretKeyBytes)
	s.public = godium.PublicKey(s.private[Ed25519_SeedBytes:])

	var hBytes [32]byte
	hash.SumSha512(hBytes[:0], s.private[:Ed25519_SeedBytes])
	hBytes[0] &= 248
	hBytes[31] &= 127
	hBytes[31] |= 64

	var A edwards25519.ExtendedGroupElement
	edwards25519.GeScalarMultBase(&A, &hBytes)
	A.ToBytes(&hBytes)
	copy(s.public[:], hBytes[:])

	return
}

// Wipe
func (s *Ed25519Sign) Wipe() {
	godium.Wipe(s.private)
}

// Write
func (s *Ed25519Sign) Write(p []byte) (n int, err error) {
	if s.multipart == nil {
		s.multipart = hash.NewSha512()
	}
	n, err = s.multipart.Write(p)
	return
}

func (s *Ed25519Sign) Sign(dst, unsigned []byte) (signed []byte) {
	mlen := uint64(len(unsigned))
	signed = internal.AllocDst(dst, mlen+Ed25519_Bytes)

	if len(unsigned) == 0 {
		signed = s.SignDetached(dst[:0], unsigned)
		return
	}

	if &dst[0] != &unsigned[Ed25519_Bytes] {
		copy(dst, unsigned)
	}

	s.SignDetached(signed[:0], signed[Ed25519_Bytes:])
	return
}

// SignDetached
func (s *Ed25519Sign) SignDetached(dst, unsigned []byte) (signature []byte) {
	signature = internal.AllocDst(dst, Ed25519_Bytes)
	edSign := edwards25519.Sign(signature[:0], unsigned, s.private, false)
	copy(signature, edSign)
	return
}

// Final
func (s *Ed25519Sign) Final(dst []byte) (signature []byte) {
	if s.multipart == nil {
		return // TODO fail/panic?
	}
	ph := make([]byte, 0, hash.Sha512_Bytes)
	ph = s.multipart.Sum(ph)
	signature = edwards25519.Sign(dst, ph, s.private, true)
	return
}

// PublicKey
func (s *Ed25519Sign) PublicKey() godium.PublicKey {
	return internal.Copy(s.public, Ed25519_PublicKeyBytes)
}

func (s *Ed25519Sign) PublicKeyBytes() (c int) { return Ed25519_PublicKeyBytes }
func (s *Ed25519Sign) SecretKeyBytes() (c int) { return Ed25519_SecretKeyBytes }
func (s *Ed25519Sign) Bytes() (c int)          { return Ed25519_Bytes }
func (s *Ed25519Sign) SeedBytes() (c int)      { return Ed25519_SeedBytes }
<commit_msg>fix: seed was not used when creating Ed25519 keypair (fixes #6)<commit_after>// Copyright 2017, Project ArteMisc
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package sign

import (
	"go.artemisc.eu/godium"
	"go.artemisc.eu/godium/hash"
	"go.artemisc.eu/godium/internal"
	"go.artemisc.eu/godium/internal/edwards25519"
)

const (
	Ed25519_PublicKeyBytes = 32
	Ed25519_SecretKeyBytes = 64
	Ed25519_Bytes          = 64
	Ed25519_SeedBytes      = 32

	Ed25519ph_PublicKeyBytes = 32
	Ed25519ph_SecretKeyBytes = 64
	Ed25519ph_Bytes          = 64
	Ed25519ph_SeedBytes      = 32
)

type Ed25519Sign struct {
	private   godium.PrivateKey
	public    godium.PublicKey
	multipart godium.Hash
}

// NewEd25519
func NewEd25519(key godium.PrivateKey) (s godium.Sign) {
	key = internal.Copy(key, Ed25519_SecretKeyBytes)
	s = &Ed25519Sign{
		private: key,
		public:  godium.PublicKey(key[Ed25519_SeedBytes:Ed25519_SecretKeyBytes]),
	}
	return
}

// KeyPairEd25519
func KeyPairEd25519(random godium.Random) (s *Ed25519Sign, err error) {
	seed, err := random.KeyGen(Ed25519_SeedBytes)
	if err != nil {
		return
	}

	s = KeyPairSeedEd25519(seed)
	return
}

// KeyPairSeedEd25519
func KeyPairSeedEd25519(seed []byte) (s *Ed25519Sign) {
	seed = internal.Copy(seed, SeedBytes)
	defer godium.Wipe(seed)

	var digest [32]byte
	hash.SumSha512(digest[:0], seed[:Ed25519_SeedBytes])
	digest[0] &= 248
	digest[31] &= 127
	digest[31] |= 64

	var A edwards25519.ExtendedGroupElement
	var hBytes [32]byte
	copy(hBytes[:], digest[:])
	edwards25519.GeScalarMultBase(&A, &hBytes)
	var publicKeyBytes [32]byte
	A.ToBytes(&publicKeyBytes)

	// initialize the struct
	s = new(Ed25519Sign)
	s.private = make([]byte, Ed25519_SecretKeyBytes)
	s.public = make([]byte, Ed25519_PublicKeyBytes)
	copy(s.private[:Ed25519_SeedBytes], seed[:Ed25519_SeedBytes])
	copy(s.private[Ed25519_SeedBytes:], publicKeyBytes[:])
	copy(s.public, publicKeyBytes[:])

	return
}

// Wipe
func (s *Ed25519Sign) Wipe() {
	godium.Wipe(s.private)
}

// Write
func (s *Ed25519Sign) Write(p []byte) (n int, err error) {
	if s.multipart == nil {
		s.multipart = hash.NewSha512()
	}
	n, err = s.multipart.Write(p)
	return
}

func (s *Ed25519Sign) Sign(dst, unsigned []byte) (signed []byte) {
	mlen := uint64(len(unsigned))
	signed = internal.AllocDst(dst, mlen+Ed25519_Bytes)

	if len(unsigned) == 0 {
		signed = s.SignDetached(dst[:0], unsigned)
		return
	}

	if &dst[0] != &unsigned[Ed25519_Bytes] {
		copy(dst, unsigned)
	}

	s.SignDetached(signed[:0], signed[Ed25519_Bytes:])
	return
}

// SignDetached
func (s *Ed25519Sign) SignDetached(dst, unsigned []byte) (signature []byte) {
	signature = internal.AllocDst(dst, Ed25519_Bytes)
	edSign := edwards25519.Sign(signature[:0], unsigned, s.private, false)
	copy(signature, edSign)
	return
}

// Final
func (s *Ed25519Sign) Final(dst []byte) (signature []byte) {
	if s.multipart == nil {
		return // TODO fail/panic?
	}
	ph := make([]byte, 0, hash.Sha512_Bytes)
	ph = s.multipart.Sum(ph)
	signature = edwards25519.Sign(dst, ph, s.private, true)
	return
}

// PublicKey
func (s *Ed25519Sign) PublicKey() godium.PublicKey {
	return internal.Copy(s.public, Ed25519_PublicKeyBytes)
}

func (s *Ed25519Sign) PublicKeyBytes() (c int) { return Ed25519_PublicKeyBytes }
func (s *Ed25519Sign) SecretKeyBytes() (c int) { return Ed25519_SecretKeyBytes }
func (s *Ed25519Sign) Bytes() (c int)          { return Ed25519_Bytes }
func (s *Ed25519Sign) SeedBytes() (c int)      { return Ed25519_SeedBytes }
<|endoftext|>


<commit_before>package simlog

// from beego

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"sync"
	"time"
)

const (
	DayDur   = time.Hour * 24   //一天的duration
	TimerDur = time.Minute * 10 //用于定时判断日期的时间间隔
)

var (
	initFlag     bool        //是否已经初始化
	splitFlag    bool        //是否根据文件大小切割
	logbasepath  string      //日志根目录，传参设定
	MAXFILESIZE  int64       //每个文件最大大小，传参设定
	MAXLOGINDEX  int         //每天最大文件个数，传参设定
	MAXLOGDAY    int         //保存文件最大天数，传参设定
	MAXLOGCNT    int         //日志判断周期，即生成MAXLOGCNT条日志后开始判断当前文件是否超过设定大小
	logdate      time.Time   //当天的日期，用来判断日期是否改变
	logfilepath  string      //日志文件路径，由logbasepath+当前日期得到
	logfileindex int         //日志文件当前序号
	logfilename  string      //日志文件名，由logfilepath+logfileindex.log得到
	logfile      *os.File    //日志文件
	logfilelock  *sync.Mutex //日志锁，在改变全局变量时需要用到
	logcnt       int         //当前日志条数，用来和日志判断周期比较，避免频繁判断文件大小
	// logLevel controls the global log level used by the logger.
)

func getdate(t time.Time) int {
	tdate, _ := strconv.Atoi(fmt.Sprintf("%04d%02d%02d", t.Year(), t.Month(), t.Day()))
	return tdate
}

func GetLogName(path string) string {
	//	fis, err := ReadDir(path)
	//	if nil != err {
	//		fmt.Printf("GetLogName|ReadDir %s|%s failed", path, err.Error())
	//		os.Exit(-1)
	//	}
	//	filename := ""
	//	if splitFlag {
	//		logfileindex = 0

	//		for _, fi := range fis {
	//			if fi.IsDir() {
	//				continue
	//			}
	//			logfileindex++
	//		}

	//		if logfileindex >= MAXLOGINDEX {
	//			logfileindex = 0
	//		}
	//		logfileindex++
	//		filename = path + fmt.Sprintf("%d.log", logfileindex)
	//	} else {
	//		filename = path + "all.log"
	//	}
	return path + "all.log"
}

func logInit(path string, maxday int, loglevel Level) {
	if path == logbasepath && maxday == MAXLOGDAY && loglevel == loglevel {
		return
	}
	logfilelock = new(sync.Mutex)
	logfilelock.Lock()
	defer logfilelock.Unlock()
	now := time.Now()

	MAXLOGDAY = maxday
	SetLogLevel(loglevel)
	logdate = now
	logbasepath = path + "/"
	logfilepath = logbasepath + MakeLogPath(now) + "/"
	err := MakeDirAll(logfilepath)
	if nil != err {
		fmt.Printf("[simlog]LogInit|MakeDirAll logpath %s|%s failed\n", logfilepath, err.Error())
		os.Exit(-1)
	}

	logfilename = GetLogName(logfilepath)

	logfile, err = OpenAndCreateFile(logfilename, os.O_APPEND)
	if nil != err {
		fmt.Printf("log Start|open log file %s|%s\n", logfilename, err.Error())
		os.Exit(-1)
	}
	SimLogger = log.New(logfile, "\n", log.Ldate|log.Ltime|log.Llongfile)
	removelogdir(MAXLOGDAY, now)
	if !initFlag {
		initFlag = true
		go changelogdate()
	}
}

func setLogSplit(maxsize, maxindex int) {
	splitFlag = true
	MAXFILESIZE = int64(maxsize * 1024 * 1024)
	MAXLOGCNT = int(MAXFILESIZE / 1024)
	MAXLOGINDEX = maxindex
}

func logClose() {
	if nil != logfile {
		logfile.Close()
	}
}

func changelogindex(addsize int) {
	if filesize, _ := GetFileSize(logfile); filesize+int64(500+addsize) >= MAXFILESIZE {
		if logfileindex >= MAXLOGINDEX {
			logfileindex = 0
		}
		logfileindex++
		changelogfile()
	}

}

func removelogdir(daynum int, now time.Time) {
	tmpdate := now.Add(-DayDur * time.Duration(daynum))
	tmpdir := logbasepath + MakeLogPath(tmpdate) + "/"
	os.RemoveAll(tmpdir)
}

func changelogdate() {
	logTimer := time.NewTicker(TimerDur)
	for {
		select {
		case <-logTimer.C:
			func() {
				logfilelock.Lock()
				defer logfilelock.Unlock()
				now := time.Now()
				if now.Day() == logdate.Day() && now.Month() == logdate.Month() && now.Year() == logdate.Year() {
					return
				}
				//如果日期改变
				//将全局信息重置
				logdate = now
				logfilepath = logbasepath + MakeLogPath(now) + "/"
				logfileindex = 0
				logfileindex++
				logfilename = logfilepath + "all.log"
				//				err := MakeDirAll(logfilepath)
				//				if nil != err {
				//					fmt.Printf("[simlog]ChangeLogPathOrFile|MakeDirAll %s|%s \n", logfilepath, err.Error())
				//					//os.Exit(-1)
				//					return
				//				}
				changelogfile()
				//删除配置指定时间的日志文件
				removelogdir(MAXLOGDAY, now)

			}()
		}
	}

}

func changelogfile() {

	//创建新文件
	//logfilename = logfilepath + "all.log"
	//	if splitFlag {
	for i := 0; i < 1; i++ {
		//关闭上一个文件
		logfile.Close()
		now := time.Now()
		logdate = now
		logfilepath = logbasepath + MakeLogPath(now) + "/"

		if err := MakeDirAll(logfilepath); err != nil {
			fmt.Printf("[simlog]ChangeLogPathOrFile|MakeDirAll %s|%s \n", logfilepath, err.Error())
			//os.Exit(-1)
			break
		}
		old := logfilepath + fmt.Sprintf("all.log.%04d%02d%02d-%02d%02d%02d.%d",
			now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), logfileindex)
		if err := os.Rename(logfilename, old); err != nil {
			fmt.Printf("Rename %s -> %s failed err=%s", logfilename, old, err.Error())
			break
		}
	}
	var err error
	logfile, err = OpenAndCreateFile(logfilename, os.O_TRUNC)
	if nil != err {
		fmt.Printf("ChangeLogPathOrFile|open log file %s|%s\n", logfilename, err.Error())
		return
	}
	SimLogger = log.New(logfile, "\n", log.Ldate|log.Ltime|log.Llongfile)
	//} else {
	//		newFile = logfilepath + "all.log"
	//}

}
<commit_msg>修改日志分割规则<commit_after>package simlog

// from beego

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"sync"
	"time"
)

const (
	DayDur   = time.Hour * 24   //一天的duration
	TimerDur = time.Minute * 10 //用于定时判断日期的时间间隔
)

var (
	LOG_BASE_NAME = "all.log"
	initFlag     bool        //是否已经初始化
	splitFlag    bool        //是否根据文件大小切割
	logbasepath  string      //日志根目录，传参设定
	MAXFILESIZE  int64       //每个文件最大大小，传参设定
	MAXLOGINDEX  int         //每天最大文件个数，传参设定
	MAXLOGDAY    int         //保存文件最大天数，传参设定
	MAXLOGCNT    int         //日志判断周期，即生成MAXLOGCNT条日志后开始判断当前文件是否超过设定大小
	logdate      time.Time   //当天的日期，用来判断日期是否改变
	logfilepath  string      //日志文件路径，由logbasepath+当前日期得到
	logfileindex int         //日志文件当前序号
	logfilename  string      //日志文件名，由logfilepath+logfileindex.log得到
	logfile      *os.File    //日志文件
	logfilelock  *sync.Mutex //日志锁，在改变全局变量时需要用到
	logcnt       int         //当前日志条数，用来和日志判断周期比较，避免频繁判断文件大小
	// logLevel controls the global log level used by the logger.
)

func getdate(t time.Time) int {
	tdate, _ := strconv.Atoi(fmt.Sprintf("%04d%02d%02d", t.Year(), t.Month(), t.Day()))
	return tdate
}

func GetLogName(path string) string {
	//	fis, err := ReadDir(path)
	//	if nil != err {
	//		fmt.Printf("GetLogName|ReadDir %s|%s failed", path, err.Error())
	//		os.Exit(-1)
	//	}
	//	filename := ""
	//	if splitFlag {
	//		logfileindex = 0

	//		for _, fi := range fis {
	//			if fi.IsDir() {
	//				continue
	//			}
	//			logfileindex++
	//		}

	//		if logfileindex >= MAXLOGINDEX {
	//			logfileindex = 0
	//		}
	//		logfileindex++
	//		filename = path + fmt.Sprintf("%d.log", logfileindex)
	//	} else {
	//		filename = path + LOG_BASE_NAME
	//	}
	return path + LOG_BASE_NAME
}

func logInit(path string, maxday int, loglevel Level) {
	if path == logbasepath && maxday == MAXLOGDAY && loglevel == loglevel {
		return
	}
	logfilelock = new(sync.Mutex)
	logfilelock.Lock()
	defer logfilelock.Unlock()
	now := time.Now()

	MAXLOGDAY = maxday
	SetLogLevel(loglevel)
	logdate = now
	logbasepath = path + "/"
	logfilepath = logbasepath + MakeLogPath(now) + "/"
	err := MakeDirAll(logfilepath)
	if nil != err {
		fmt.Printf("[simlog]LogInit|MakeDirAll logpath %s|%s failed\n", logfilepath, err.Error())
		os.Exit(-1)
	}

	logfilename = GetLogName(logfilepath)

	logfile, err = OpenAndCreateFile(logfilename, os.O_APPEND)
	if nil != err {
		fmt.Printf("log Start|open log file %s|%s\n", logfilename, err.Error())
		os.Exit(-1)
	}
	SimLogger = log.New(logfile, "\n", log.Ldate|log.Ltime|log.Llongfile)
	initlogfile()
	movelogdir()
	removelogdir(MAXLOGDAY, now)
	if !initFlag {
		initFlag = true
		go changelogdate()
	}
}

func setLogSplit(maxsize, maxindex int) {
	splitFlag = true
	MAXFILESIZE = int64(maxsize * 1024 * 1024)
	MAXLOGCNT = int(MAXFILESIZE / 1024)
	MAXLOGINDEX = maxindex
}

func logClose() {
	if nil != logfile {
		logfile.Close()
	}
}

func changelogindex(addsize int) {
	if filesize, _ := GetFileSize(logfile); filesize+int64(500+addsize) >= MAXFILESIZE {
		if logfileindex >= MAXLOGINDEX {
			logfileindex = 0
		}
		logfileindex++
		changelogfile()
	}

}

func removelogdir(daynum int, now time.Time) {
	tmpdate := now.Add(-DayDur * time.Duration(daynum))
	tmpdir := logbasepath + MakeLogPath(tmpdate) + "/"
	os.RemoveAll(tmpdir)
}

func movelogdir() {
	fis, err := ReadDir(logbasepath)
	if nil != err {
		fmt.Printf("GetLogName|ReadDir %s|%s failed", logbasepath, err.Error())
		os.Exit(-1)
	}
	var name string
	var path string
	basepos := len(LOG_BASE_NAME+".")
	for _, fi := range fis {
		if fi.IsDir() {
			continue
		}
		if fi.Name() == LOG_BASE_NAME {
			continue
		}
		name = fi.Name()
		//all.log.20160113
		if len(name) < len("all.log.20160113") {
			continue
		}
		path = logbasepath + name[basepos:basepos+8]
		if err := MakeDirAll(path); err != nil {
			Error("movelogdir failed ", err.Error())
			continue
		}
		oldname := logbasepath + name
		newname := path + name
		if err := os.Rename(oldname, newname); err != nil {
			fmt.Printf("Rename %s -> %s failed err=%s", oldname, newname, err.Error())
			continue
		}
	}

}

func initlogfile() {
	movelogdir()
	//move all.log
	fis, err := ReadDir(logbasepath)
	if nil != err {
		fmt.Printf("GetLogName|ReadDir %s|%s failed", logbasepath, err.Error())
		os.Exit(-1)
	}

	for _, fi := range fis {
		if fi.IsDir() {
			continue
		}
		if fi.Name() != LOG_BASE_NAME {
			continue
		}
		nowdate := time.Now()
		olddate := fi.ModTime()
		if nowdate.Day() == olddate.Day() && nowdate.Month() == olddate.Month() && nowdate.Year() == olddate.Year() {
			return
		}

		changelogfile()
	}
}

func changelogdate() {
	logTimer := time.NewTicker(TimerDur)
	for {
		select {
		case <-logTimer.C:
			func() {
				logfilelock.Lock()
				defer logfilelock.Unlock()
				now := time.Now()
				if now.Day() == logdate.Day() && now.Month() == logdate.Month() && now.Year() == logdate.Year() {
					return
				}
				//如果日期改变
				//将全局信息重置
				logdate = now
				//logfilepath = logbasepath + MakeLogPath(now) + "/"
				logfileindex = 0
				logfileindex++
				//logfilename = logfilepath + LOG_BASE_NAME

				changelogfile()
				//删除配置指定时间的日志文件
				movelogdir()
				removelogdir(MAXLOGDAY, now)
			}()
		}
	}

}

func changelogfile() {

	//创建新文件
	//logfilename = logfilepath + LOG_BASE_NAME
	//	if splitFlag {
	for i := 0; i < 1; i++ {
		//关闭上一个文件
		logfile.Close()
		now := time.Now()

		old := logfilepath + fmt.Sprintf("all.log.%04d%02d%02d-%02d%02d%02d.%d",
			now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), logfileindex)
		if err := os.Rename(logfilename, old); err != nil {
			fmt.Printf("Rename %s -> %s failed err=%s", logfilename, old, err.Error())
			break
		}
	}
	var err error
	logfile, err = OpenAndCreateFile(logfilename, os.O_TRUNC)
	if nil != err {
		fmt.Printf("ChangeLogPathOrFile|open log file %s|%s\n", logfilename, err.Error())
		return
	}
	SimLogger = log.New(logfile, "\n", log.Ldate|log.Ltime|log.Llongfile)
}
<|endoftext|>


<commit_before>package controller

import (
	"github.com/eaciit/colony-core/v0"
	"github.com/eaciit/colony-manager/helper"
	"github.com/eaciit/knot/knot.v1"
	"github.com/eaciit/toolkit"
	// "io/ioutil"
	// "path/filepath"
	// "fmt"
)

type PageDesignerController struct {
	App
}

func CreatePageDesignerController(s *knot.Server) *PageDesignerController {
	var controller = new(PageDesignerController)
	controller.Server = s
	return controller
}

// func (p *PageDesignerController) FetchDataSource(ids []string) (toolkit.Ms, error) {
// 	widgetData := toolkit.Ms{}
// 	for _, _id := range ids {
// 		data, err := helper.FetchDataFromDS(_id, 0)
// 		if err != nil {
// 			return nil, err
// 		}
// 		datasourcewidget := toolkit.M{}
// 		datasourcewidget.Set("Data", data)
// 		widgetData = append(widgetData, datasourcewidget)
// 	}

// 	return widgetData, nil
// }

// func (p *PageDesignerController) GetAllFields(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson
// 	type DSMap struct {
// 		ID     string   `json:"_id"`
// 		Fields []string `json:"fields"`
// 	}
// 	payload := toolkit.M{}
// 	if err := r.GetPayload(&payload); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	var data = []DSMap{}
// 	var _data = DSMap{}
// 	for _, ds := range payload.Get("datasource", "").([]interface{}) {
// 		tm, err := toolkit.ToM(ds)
// 		if err != nil {
// 			return helper.CreateResult(false, nil, err.Error())
// 		}
// 		_data.ID = tm.Get("dsWidget", "").(string)
// 		_data.Fields, err = helper.GetFieldsFromDS(tm.Get("dsColony", "").(string))
// 		if err != nil {
// 			return helper.CreateResult(false, nil, err.Error())
// 		}
// 		data = append(data, _data)
// 	}
// 	widgetSource := filepath.Join(EC_DATA_PATH, "widget", payload.Get("widgetId", "").(string))
// 	getFileIndex, err := colonycore.GetWidgetPath(widgetSource)
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	widgetPath := filepath.Join(getFileIndex, "config-widget.html")
// 	content, err := ioutil.ReadFile(widgetPath)
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	contentstring := string(content)
// 	/*get widget data*/
// 	dataWidget := new(colonycore.Widget)
// 	dataWidget.ID = payload.Get("widgetId", "").(string)
// 	err = dataWidget.GetById()
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	newData := toolkit.M{}
// 	newData.Set("fieldDs", data)
// 	newData.Set("container", contentstring)
// 	newData.Set("pageId", payload.Get("pageId", "").(string))
// 	newData.Set("url", dataWidget.URL)
// 	return helper.CreateResult(true, newData, "")
// }

// func (p *PageDesignerController) GetDataSource(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	data, err := helper.GetDataSourceQuery()
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, data, "")
// }

func (p *PageDesignerController) GetPages(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := map[string]string{}
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	data := new(colonycore.Page).GetPages(payload["search"])
	return helper.CreateResult(true, data, "")
}

func (p *PageDesignerController) SelectPage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := new(colonycore.Page)
	if err := r.GetPayload(payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	page := new(colonycore.Page)
	if err := colonycore.Get(page, payload.ID); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	pageDetail := new(colonycore.PageDetail)
	pageDetail.ID = payload.ID
	pageDetailRes, err := pageDetail.Get()
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	data := toolkit.M{"page": page, "pageDetail": pageDetailRes}
	return helper.CreateResult(true, data, "")
}

func (p *PageDesignerController) SavePage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := new(colonycore.PageDetail)
	if err := r.GetPayload(payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	if err := payload.Save(); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, payload, "")
}

// func (p *PageDesignerController) EditPage(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	data := colonycore.MapPage{}
// 	if err := r.GetPayload(&data); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	if err := data.GetById(); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, data, "")
// }

func (p *PageDesignerController) RemovePage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := struct {
		IDs []string `json:"ids"`
	}{}
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	for _, id := range payload.IDs {
		o := new(colonycore.PageDetail)
		o.ID = id

		if err := o.Remove(); err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
	}

	return helper.CreateResult(true, nil, "")
}

func (p *PageDesignerController) GetWidgetSetting(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := new(colonycore.Widget)
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	config, err := payload.GetConfigWidget()
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, config, "")
}

// func (p *PageDesignerController) SaveConfigPage(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	payload := toolkit.M{}
// 	err := r.GetPayload(&payload)
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	if err := new(colonycore.Page).Save(payload, true, ""); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, payload, "")
// }

// func (p *PageDesignerController) SaveDesigner(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	payload := toolkit.M{}
// 	err := r.GetPayload(&payload)
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	payload.Set("mode", "save widget")
// 	if err := new(colonycore.Page).Save(payload, true, ""); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, payload, "")
// }

// func (p *PageDesignerController) EditPageDesigner(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	payload := toolkit.M{}
// 	data := colonycore.Page{}
// 	if err := r.GetPayload(&payload); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	data.ID = payload.Get("_id", "").(string)

// 	if payload.Get("mode", "").(string) != "" {
// 		data.Save(payload, true, filepath.Join(EC_DATA_PATH, "widget"))
// 	}
// 	if err := data.GetById(); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, data, "")
// }

/*func (p *PageDesignerController) PreviewExample(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	data := toolkit.M{}
	if err := r.GetPayload(&data); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	widgetSource := filepath.Join(EC_DATA_PATH, "widget", data.Get("_id", "").(string))

	getFileIndex, err := colonycore.GetPath(widgetSource)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	widgetPath := filepath.Join(getFileIndex, "index.html")

	content, err := ioutil.ReadFile(widgetPath)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	contentstring := string(content)

	var datasource []string
	for _, val := range data.Get("dataSource").([]interface{}) {
		datasource = append(datasource, val.(string))
	}

	dataSourceArry := strings.Join(datasource, ",")
	widgetData, err := new(WidgetController).FetchDataSources(dataSourceArry)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	previewData := toolkit.M{}
	previewData.Set("container", contentstring)
	previewData.Set("dataSource", widgetData)

	if data.Get("mode", "").(string) == "save" {
		dataWidget := colonycore.Widget{}
		dataWidget.ID = data.Get("_id", "").(string)
		if err := dataWidget.GetById(); err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
		dataWidget.DataSourceId = datasource

		configs := toolkit.Ms{}
		for _, val := range data.Get("config", "").([]interface{}) {
			configs = append(configs, val.(map[string]interface{}))
		}
		dataWidget.Config = configs

		if err := dataWidget.Save(); err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
	}

	return helper.CreateResult(true, previewData, "")
}*/
<commit_msg>read file config-widget.html<commit_after>package controller

import (
	"fmt"
	"github.com/eaciit/colony-core/v0"
	"github.com/eaciit/colony-manager/helper"
	"github.com/eaciit/knot/knot.v1"
	"github.com/eaciit/toolkit"
	"io/ioutil"
	"os"
	"path/filepath"
	// "io/ioutil"
	// "path/filepath"
	// "fmt"
)

type PageDesignerController struct {
	App
}

func CreatePageDesignerController(s *knot.Server) *PageDesignerController {
	var controller = new(PageDesignerController)
	controller.Server = s
	return controller
}

// func (p *PageDesignerController) FetchDataSource(ids []string) (toolkit.Ms, error) {
// 	widgetData := toolkit.Ms{}
// 	for _, _id := range ids {
// 		data, err := helper.FetchDataFromDS(_id, 0)
// 		if err != nil {
// 			return nil, err
// 		}
// 		datasourcewidget := toolkit.M{}
// 		datasourcewidget.Set("Data", data)
// 		widgetData = append(widgetData, datasourcewidget)
// 	}

// 	return widgetData, nil
// }

// func (p *PageDesignerController) GetAllFields(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson
// 	type DSMap struct {
// 		ID     string   `json:"_id"`
// 		Fields []string `json:"fields"`
// 	}
// 	payload := toolkit.M{}
// 	if err := r.GetPayload(&payload); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	var data = []DSMap{}
// 	var _data = DSMap{}
// 	for _, ds := range payload.Get("datasource", "").([]interface{}) {
// 		tm, err := toolkit.ToM(ds)
// 		if err != nil {
// 			return helper.CreateResult(false, nil, err.Error())
// 		}
// 		_data.ID = tm.Get("dsWidget", "").(string)
// 		_data.Fields, err = helper.GetFieldsFromDS(tm.Get("dsColony", "").(string))
// 		if err != nil {
// 			return helper.CreateResult(false, nil, err.Error())
// 		}
// 		data = append(data, _data)
// 	}
// 	widgetSource := filepath.Join(EC_DATA_PATH, "widget", payload.Get("widgetId", "").(string))
// 	getFileIndex, err := colonycore.GetWidgetPath(widgetSource)
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	widgetPath := filepath.Join(getFileIndex, "config-widget.html")
// 	content, err := ioutil.ReadFile(widgetPath)
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	contentstring := string(content)
// 	/*get widget data*/
// 	dataWidget := new(colonycore.Widget)
// 	dataWidget.ID = payload.Get("widgetId", "").(string)
// 	err = dataWidget.GetById()
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	newData := toolkit.M{}
// 	newData.Set("fieldDs", data)
// 	newData.Set("container", contentstring)
// 	newData.Set("pageId", payload.Get("pageId", "").(string))
// 	newData.Set("url", dataWidget.URL)
// 	return helper.CreateResult(true, newData, "")
// }

// func (p *PageDesignerController) GetDataSource(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	data, err := helper.GetDataSourceQuery()
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, data, "")
// }

func (p *PageDesignerController) GetPages(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := map[string]string{}
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	data := new(colonycore.Page).GetPages(payload["search"])
	return helper.CreateResult(true, data, "")
}

func (p *PageDesignerController) SelectPage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := new(colonycore.Page)
	if err := r.GetPayload(payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	page := new(colonycore.Page)
	if err := colonycore.Get(page, payload.ID); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	pageDetail := new(colonycore.PageDetail)
	pageDetail.ID = payload.ID
	pageDetailRes, err := pageDetail.Get()
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	data := toolkit.M{"page": page, "pageDetail": pageDetailRes}
	return helper.CreateResult(true, data, "")
}

func (p *PageDesignerController) SavePage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := new(colonycore.PageDetail)
	if err := r.GetPayload(payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	if err := payload.Save(); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, payload, "")
}

// func (p *PageDesignerController) EditPage(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	data := colonycore.MapPage{}
// 	if err := r.GetPayload(&data); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	if err := data.GetById(); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, data, "")
// }

func (p *PageDesignerController) RemovePage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := struct {
		IDs []string `json:"ids"`
	}{}
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	for _, id := range payload.IDs {
		o := new(colonycore.PageDetail)
		o.ID = id

		if err := o.Remove(); err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
	}

	return helper.CreateResult(true, nil, "")
}

func (p *PageDesignerController) GetWidgetSetting(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := new(colonycore.Widget)
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	config, err := payload.GetConfigWidget()
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, config, "")
}
func (p *PageDesignerController) WidgetPreview(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	data := toolkit.M{}
	if err := r.GetPayload(&data); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	var result string

	widgetBasePath := filepath.Join(os.Getenv("EC_DATA_PATH"), "widget", data.Get("widgetId", "").(string))
	err := filepath.Walk(widgetBasePath, func(path string, info os.FileInfo, err error) error {

		if err != nil {
			return err
		}
		if info.Name() == "config-widget.html" {
			bytes, err := ioutil.ReadFile(path)
			if err != nil {
				return err
			}
			result = string(bytes)
		}
		return nil
	})

	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, result, "")
}

// func (p *PageDesignerController) SaveConfigPage(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	payload := toolkit.M{}
// 	err := r.GetPayload(&payload)
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	if err := new(colonycore.Page).Save(payload, true, ""); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, payload, "")
// }

// func (p *PageDesignerController) SaveDesigner(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	payload := toolkit.M{}
// 	err := r.GetPayload(&payload)
// 	if err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	payload.Set("mode", "save widget")
// 	if err := new(colonycore.Page).Save(payload, true, ""); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, payload, "")
// }

// func (p *PageDesignerController) EditPageDesigner(r *knot.WebContext) interface{} {
// 	r.Config.OutputType = knot.OutputJson

// 	payload := toolkit.M{}
// 	data := colonycore.Page{}
// 	if err := r.GetPayload(&payload); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}
// 	data.ID = payload.Get("_id", "").(string)

// 	if payload.Get("mode", "").(string) != "" {
// 		data.Save(payload, true, filepath.Join(EC_DATA_PATH, "widget"))
// 	}
// 	if err := data.GetById(); err != nil {
// 		return helper.CreateResult(false, nil, err.Error())
// 	}

// 	return helper.CreateResult(true, data, "")
// }

/*func (p *PageDesignerController) PreviewExample(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	data := toolkit.M{}
	if err := r.GetPayload(&data); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	widgetSource := filepath.Join(EC_DATA_PATH, "widget", data.Get("_id", "").(string))

	getFileIndex, err := colonycore.GetPath(widgetSource)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	widgetPath := filepath.Join(getFileIndex, "index.html")

	content, err := ioutil.ReadFile(widgetPath)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	contentstring := string(content)

	var datasource []string
	for _, val := range data.Get("dataSource").([]interface{}) {
		datasource = append(datasource, val.(string))
	}

	dataSourceArry := strings.Join(datasource, ",")
	widgetData, err := new(WidgetController).FetchDataSources(dataSourceArry)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	previewData := toolkit.M{}
	previewData.Set("container", contentstring)
	previewData.Set("dataSource", widgetData)

	if data.Get("mode", "").(string) == "save" {
		dataWidget := colonycore.Widget{}
		dataWidget.ID = data.Get("_id", "").(string)
		if err := dataWidget.GetById(); err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
		dataWidget.DataSourceId = datasource

		configs := toolkit.Ms{}
		for _, val := range data.Get("config", "").([]interface{}) {
			configs = append(configs, val.(map[string]interface{}))
		}
		dataWidget.Config = configs

		if err := dataWidget.Save(); err != nil {
			return helper.CreateResult(false, nil, err.Error())
		}
	}

	return helper.CreateResult(true, previewData, "")
}*/
<|endoftext|>


<commit_before>package video

import (
	"fmt"
	"net/url"
	"time"

	"bitbucket.org/ikeikeikeike/antenna/models/image"
	"bitbucket.org/ikeikeikeike/antenna/ormapper"
	"bitbucket.org/ikeikeikeike/antenna/ormapper/blog"

	"github.com/gorilla/feeds"
	"github.com/ikeikeikeike/gopkg/convert"
)

type FeedsController struct {
	BaseController
}

func (c *FeedsController) Rdf() {}

func (c *FeedsController) Atom() {}

func (c *FeedsController) Rss() {
	c.Ctx.Output.Header("Access-Control-Allow-Origin", "*")
	c.Ctx.Output.Header("Access-Control-Allow-Headers", "*")
	c.Ctx.Output.Header("Access-Control-Allow-Credentials", "true")
	c.Ctx.Output.Header("Access-Control-Allow-Methods", "POST,GET,OPTIONS")

	now := time.Now()
	meta := c.Meta
	feed := &feeds.Feed{
		Title:       meta.Title,
		Link:        &feeds.Link{Href: meta.Host},
		Description: meta.Description,
		Author:      &feeds.Author{meta.Author, meta.Email},
		Created:     now,
	}

	var (
		src       string
		summaries []*ormapper.Summary
	)

	ormapper.VideoSummaries().
		Scopes(blog.FilterMediatype("movie")).
		Limit(10).
		Order("summary.sort ASC").
		Find(&summaries)

	for _, summary := range summaries {
		summary.NewsLoader()
		e := summary.Entry

		path := c.UrlFor("EntriesController.Show",
			":id", convert.ToStr(e.Id),
			":title", url.QueryEscape(e.SeoTitle),
		)
		href := c.BuildRequestUrl(path)

		src = image.CachedRandomSrc("large")
		if len(e.Images) > 0 {
			src = e.Images[0].Src
		}

		feed.Items = append(feed.Items, &feeds.Item{
			Title: e.Title,
			Link:  &feeds.Link{Href: href},
			Description: fmt.Sprintf(`<![CDATA[

%s

%s

続きを読む

				]]>`,
				href, src, e.Blog.Name, e.Blog.Name, e.Title,
			),
			Author:  &feeds.Author{e.Creator, ""},
			Created: e.PublishedAt,
		})
	}

	rss, _ := feed.ToRss()
	c.Ctx.Output.Body([]byte(rss))
	c.ServeXml()
}
<commit_msg>ignore blank record in hots entreis<commit_after>package video

import (
	"fmt"
	"net/url"
	"time"

	"bitbucket.org/ikeikeikeike/antenna/models/image"
	"bitbucket.org/ikeikeikeike/antenna/ormapper"
	"bitbucket.org/ikeikeikeike/antenna/ormapper/blog"

	"github.com/gorilla/feeds"
	"github.com/ikeikeikeike/gopkg/convert"
)

type FeedsController struct {
	BaseController
}

func (c *FeedsController) Rdf() {}

func (c *FeedsController) Atom() {}

func (c *FeedsController) Rss() {
	c.Ctx.Output.Header("Access-Control-Allow-Origin", "*")
	c.Ctx.Output.Header("Access-Control-Allow-Headers", "*")
	c.Ctx.Output.Header("Access-Control-Allow-Credentials", "true")
	c.Ctx.Output.Header("Access-Control-Allow-Methods", "POST,GET,OPTIONS")

	now := time.Now()
	meta := c.Meta
	feed := &feeds.Feed{
		Title:       meta.Title,
		Link:        &feeds.Link{Href: meta.Host},
		Description: meta.Description,
		Author:      &feeds.Author{meta.Author, meta.Email},
		Created:     now,
	}

	var (
		src       string
		summaries []*ormapper.Summary
	)

	ormapper.VideoSummaries().
		Scopes(blog.FilterMediatype("movie")).
		Where(`video.url != ? OR video.code != ?`, "", "").
		Limit(10).
		Order("summary.sort ASC").
		Find(&summaries)

	for _, summary := range summaries {
		summary.NewsLoader()
		e := summary.Entry

		path := c.UrlFor("EntriesController.Show",
			":id", convert.ToStr(e.Id),
			":title", url.QueryEscape(e.SeoTitle),
		)
		href := c.BuildRequestUrl(path)

		src = image.CachedRandomSrc("large")
		if len(e.Images) > 0 {
			src = e.Images[0].Src
		}

		feed.Items = append(feed.Items, &feeds.Item{
			Title: e.Title,
			Link:  &feeds.Link{Href: href},
			Description: fmt.Sprintf(`<![CDATA[

%s

%s

続きを読む

				]]>`,
				href, src, e.Blog.Name, e.Blog.Name, e.Title,
			),
			Author:  &feeds.Author{e.Creator, ""},
			Created: e.PublishedAt,
		})
	}

	rss, _ := feed.ToRss()
	c.Ctx.Output.Body([]byte(rss))
	c.ServeXml()
}
<|endoftext|>


<commit_before>package slackboard

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

type SlackPayload struct {
	Channel   string `json:"channel"`
	Username  string `json:"username,omitempty"`
	IconEmoji string `json:"icon_emoji,omitempty"`
	Text      string `json:"text"`
	Parse     string `json:"parse,omitempty"`
}

type SlackboardPayload struct {
	Tag  string `json:"tag"`
	Host string `json:"host,omitempty"`
	Text string `json:"text"`
	Sync bool   `json:"sync,omitempty"`
}

func sendNotification2Slack(payload *SlackPayload) error {
	body, err := json.Marshal(payload)
	if err != nil {
		return err
	}

	client := &http.Client{}

	resp, err := client.Post(
		ConfSlackboard.Core.SlackURL,
		"application/json",
		strings.NewReader(string(body)))

	if resp.StatusCode != 200 {
		return errors.New(fmt.Sprintf("Slack is not available:%s", resp.Status))
	}

	if err != nil {
		return err
	}

	defer resp.Body.Close()

	return nil
}

func NotifyHandler(w http.ResponseWriter, r *http.Request) {
	LogError.Debug("notify-request is Accepted")

	LogError.Debug("parse request body")
	var req SlackboardPayload
	reqBody, _ := ioutil.ReadAll(r.Body)
	err := json.Unmarshal(reqBody, &req)
	if err != nil {
		LogAcceptedRequest("/notify", r.Method, r.Proto, r.ContentLength, "")
		sendResponse(w, "Request-body is malformed", http.StatusBadRequest)
		return
	}

	LogAcceptedRequest("/notify", r.Method, r.Proto, r.ContentLength, req.Tag)

	LogError.Debug("method check")
	if r.Method != "POST" {
		sendResponse(w, "invalid method", http.StatusBadRequest)
		return
	}

	LogError.Debug("find tag")
	sent := false
	for i, tag := range ConfSlackboard.Tags {
		if tag.Tag == req.Tag {
			atomic.AddUint64(&Topics[i].Count, 1)
			payload := &SlackPayload{
				Channel:   tag.Channel,
				Username:  tag.Username,
				IconEmoji: tag.IconEmoji,
				Text:      req.Text,
				Parse:     tag.Parse,
			}

			if req.Sync {
				err := sendNotification2Slack(payload)
				if err != nil {
					sendResponse(w, "failed to post message to slack", http.StatusBadGateway)
					return
				}
				sent = true
			} else {
				go func() {
					err := sendNotification2Slack(payload)
					if err != nil {
						LogError.Error(fmt.Sprintf("failed to post message to slack:%s", err.Error()))
					}
				}()
			}
		}

	}

	LogError.Debug("response to client")

	if req.Sync {
		if sent {
			sendResponse(w, "ok", http.StatusOK)
		} else {
			msg := fmt.Sprintf("tag:%s is not found", req.Tag)
			sendResponse(w, msg, http.StatusBadRequest)
		}

	} else {
		sendResponse(w, "ok", http.StatusOK)
	}
}
<commit_msg>slackboard: use constant instead of magick-number.<commit_after>package slackboard

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

type SlackPayload struct {
	Channel   string `json:"channel"`
	Username  string `json:"username,omitempty"`
	IconEmoji string `json:"icon_emoji,omitempty"`
	Text      string `json:"text"`
	Parse     string `json:"parse,omitempty"`
}

type SlackboardPayload struct {
	Tag  string `json:"tag"`
	Host string `json:"host,omitempty"`
	Text string `json:"text"`
	Sync bool   `json:"sync,omitempty"`
}

func sendNotification2Slack(payload *SlackPayload) error {
	body, err := json.Marshal(payload)
	if err != nil {
		return err
	}

	client := &http.Client{}

	resp, err := client.Post(
		ConfSlackboard.Core.SlackURL,
		"application/json",
		strings.NewReader(string(body)))

	if resp.StatusCode != http.StatusOK {
		return errors.New(fmt.Sprintf("Slack is not available:%s", resp.Status))
	}

	if err != nil {
		return err
	}

	defer resp.Body.Close()

	return nil
}

func NotifyHandler(w http.ResponseWriter, r *http.Request) {
	LogError.Debug("notify-request is Accepted")

	LogError.Debug("parse request body")
	var req SlackboardPayload
	reqBody, _ := ioutil.ReadAll(r.Body)
	err := json.Unmarshal(reqBody, &req)
	if err != nil {
		LogAcceptedRequest("/notify", r.Method, r.Proto, r.ContentLength, "")
		sendResponse(w, "Request-body is malformed", http.StatusBadRequest)
		return
	}

	LogAcceptedRequest("/notify", r.Method, r.Proto, r.ContentLength, req.Tag)

	LogError.Debug("method check")
	if r.Method != "POST" {
		sendResponse(w, "invalid method", http.StatusBadRequest)
		return
	}

	LogError.Debug("find tag")
	sent := false
	for i, tag := range ConfSlackboard.Tags {
		if tag.Tag == req.Tag {
			atomic.AddUint64(&Topics[i].Count, 1)
			payload := &SlackPayload{
				Channel:   tag.Channel,
				Username:  tag.Username,
				IconEmoji: tag.IconEmoji,
				Text:      req.Text,
				Parse:     tag.Parse,
			}

			if req.Sync {
				err := sendNotification2Slack(payload)
				if err != nil {
					sendResponse(w, "failed to post message to slack", http.StatusBadGateway)
					return
				}
				sent = true
			} else {
				go func() {
					err := sendNotification2Slack(payload)
					if err != nil {
						LogError.Error(fmt.Sprintf("failed to post message to slack:%s", err.Error()))
					}
				}()
			}
		}

	}

	LogError.Debug("response to client")

	if req.Sync {
		if sent {
			sendResponse(w, "ok", http.StatusOK)
		} else {
			msg := fmt.Sprintf("tag:%s is not found", req.Tag)
			sendResponse(w, msg, http.StatusBadRequest)
		}

	} else {
		sendResponse(w, "ok", http.StatusOK)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"io/ioutil"
	"math/rand"
	"net"
	"os"

	"github.com/lightningnetwork/lnd/chainntnfs"
	"github.com/lightningnetwork/lnd/channeldb"
	"github.com/lightningnetwork/lnd/contractcourt"
	"github.com/lightningnetwork/lnd/htlcswitch"
	"github.com/lightningnetwork/lnd/keychain"
	"github.com/lightningnetwork/lnd/lnwallet"
	"github.com/lightningnetwork/lnd/lnwire"
	"github.com/lightningnetwork/lnd/shachain"
	"github.com/roasbeef/btcd/btcec"
	"github.com/roasbeef/btcd/chaincfg/chainhash"
	"github.com/roasbeef/btcd/wire"
	"github.com/roasbeef/btcutil"
)

var (
	alicesPrivKey = []byte{
		0x2b, 0xd8, 0x06, 0xc9, 0x7f, 0x0e, 0x00, 0xaf,
		0x1a, 0x1f, 0xc3, 0x32, 0x8f, 0xa7, 0x63, 0xa9,
		0x26, 0x97, 0x23, 0xc8, 0xdb, 0x8f, 0xac, 0x4f,
		0x93, 0xaf, 0x71, 0xdb, 0x18, 0x6d, 0x6e, 0x90,
	}

	bobsPrivKey = []byte{
		0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
		0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
		0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
		0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9,
	}

	// Use a hard-coded HD seed.
	testHdSeed = [32]byte{
		0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab,
		0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4,
		0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9,
		0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53,
	}

	// Just use some arbitrary bytes as delivery script.
	dummyDeliveryScript = alicesPrivKey[:]
)

// createTestPeer creates a channel between two nodes, and returns a peer for
// one of the nodes, together with the channel seen from both nodes.
func createTestPeer(notifier chainntnfs.ChainNotifier,
	publTx chan *wire.MsgTx) (*peer, *lnwallet.LightningChannel,
	*lnwallet.LightningChannel, func(), error) {

	aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
		alicesPrivKey)
	bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
		bobsPrivKey)

	channelCapacity := btcutil.Amount(10 * 1e8)
	channelBal := channelCapacity / 2
	aliceDustLimit := btcutil.Amount(200)
	bobDustLimit := btcutil.Amount(1300)
	csvTimeoutAlice := uint32(5)
	csvTimeoutBob := uint32(4)

	prevOut := &wire.OutPoint{
		Hash:  chainhash.Hash(testHdSeed),
		Index: 0,
	}
	fundingTxIn := wire.NewTxIn(prevOut, nil, nil)

	aliceCfg := channeldb.ChannelConfig{
		ChannelConstraints: channeldb.ChannelConstraints{
			DustLimit:        aliceDustLimit,
			MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()),
			ChanReserve:      btcutil.Amount(rand.Int63()),
			MinHTLC:          lnwire.MilliSatoshi(rand.Int63()),
			MaxAcceptedHtlcs: uint16(rand.Int31()),
		},
		CsvDelay: uint16(csvTimeoutAlice),
		MultiSigKey: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
		RevocationBasePoint: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
		PaymentBasePoint: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
		DelayBasePoint: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
		HtlcBasePoint: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
	}
	bobCfg := channeldb.ChannelConfig{
		ChannelConstraints: channeldb.ChannelConstraints{
			DustLimit:        bobDustLimit,
			MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()),
			ChanReserve:      btcutil.Amount(rand.Int63()),
			MinHTLC:          lnwire.MilliSatoshi(rand.Int63()),
			MaxAcceptedHtlcs: uint16(rand.Int31()),
		},
		CsvDelay: uint16(csvTimeoutBob),
		MultiSigKey: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
		RevocationBasePoint: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
		PaymentBasePoint: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
		DelayBasePoint: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
		HtlcBasePoint: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
	}

	bobRoot, err := chainhash.NewHash(bobKeyPriv.Serialize())
	if err != nil {
		return nil, nil, nil, nil, err
	}
	bobPreimageProducer := shachain.NewRevocationProducer(*bobRoot)
	bobFirstRevoke, err := bobPreimageProducer.AtIndex(0)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	bobCommitPoint := lnwallet.ComputeCommitmentPoint(bobFirstRevoke[:])

	aliceRoot, err := chainhash.NewHash(aliceKeyPriv.Serialize())
	if err != nil {
		return nil, nil, nil, nil, err
	}
	alicePreimageProducer := shachain.NewRevocationProducer(*aliceRoot)
	aliceFirstRevoke, err := alicePreimageProducer.AtIndex(0)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	aliceCommitPoint := lnwallet.ComputeCommitmentPoint(aliceFirstRevoke[:])

	aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns(channelBal,
		channelBal, &aliceCfg, &bobCfg, aliceCommitPoint, bobCommitPoint,
		*fundingTxIn)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	alicePath, err := ioutil.TempDir("", "alicedb")
	dbAlice, err := channeldb.Open(alicePath)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	bobPath, err := ioutil.TempDir("", "bobdb")
	dbBob, err := channeldb.Open(bobPath)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	estimator := &lnwallet.StaticFeeEstimator{FeeRate: 50}
	feePerVSize, err := estimator.EstimateFeePerVSize(1)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	feePerKw := feePerVSize.FeePerKWeight()

	// TODO(roasbeef): need to factor in commit fee?
	aliceCommit := channeldb.ChannelCommitment{
		CommitHeight:  0,
		LocalBalance:  lnwire.NewMSatFromSatoshis(channelBal),
		RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal),
		FeePerKw:      btcutil.Amount(feePerKw),
		CommitFee:     feePerKw.FeeForWeight(lnwallet.CommitWeight),
		CommitTx:      aliceCommitTx,
		CommitSig:     bytes.Repeat([]byte{1}, 71),
	}
	bobCommit := channeldb.ChannelCommitment{
		CommitHeight:  0,
		LocalBalance:  lnwire.NewMSatFromSatoshis(channelBal),
		RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal),
		FeePerKw:      btcutil.Amount(feePerKw),
		CommitFee:     feePerKw.FeeForWeight(lnwallet.CommitWeight),
		CommitTx:      bobCommitTx,
		CommitSig:     bytes.Repeat([]byte{1}, 71),
	}

	aliceChannelState := &channeldb.OpenChannel{
		LocalChanCfg:            aliceCfg,
		RemoteChanCfg:           bobCfg,
		IdentityPub:             aliceKeyPub,
		FundingOutpoint:         *prevOut,
		ChanType:                channeldb.SingleFunder,
		IsInitiator:             true,
		Capacity:                channelCapacity,
		RemoteCurrentRevocation: bobCommitPoint,
		RevocationProducer:      alicePreimageProducer,
		RevocationStore:         shachain.NewRevocationStore(),
		LocalCommitment:         aliceCommit,
		RemoteCommitment:        aliceCommit,
		Db:                      dbAlice,
	}
	bobChannelState := &channeldb.OpenChannel{
		LocalChanCfg:            bobCfg,
		RemoteChanCfg:           aliceCfg,
		IdentityPub:             bobKeyPub,
		FundingOutpoint:         *prevOut,
		ChanType:                channeldb.SingleFunder,
		IsInitiator:             false,
		Capacity:                channelCapacity,
		RemoteCurrentRevocation: aliceCommitPoint,
		RevocationProducer:      bobPreimageProducer,
		RevocationStore:         shachain.NewRevocationStore(),
		LocalCommitment:         bobCommit,
		RemoteCommitment:        bobCommit,
		Db:                      dbBob,
	}

	addr := &net.TCPAddr{
		IP:   net.ParseIP("127.0.0.1"),
		Port: 18555,
	}

	if err := aliceChannelState.SyncPending(addr, 0); err != nil {
		return nil, nil, nil, nil, err
	}

	addr = &net.TCPAddr{
		IP:   net.ParseIP("127.0.0.1"),
		Port: 18556,
	}

	if err := bobChannelState.SyncPending(addr, 0); err != nil {
		return nil, nil, nil, nil, err
	}

	cleanUpFunc := func() {
		os.RemoveAll(bobPath)
		os.RemoveAll(alicePath)
	}

	aliceSigner := &mockSigner{aliceKeyPriv}
	bobSigner := &mockSigner{bobKeyPriv}

	channelAlice, err := lnwallet.NewLightningChannel(
		aliceSigner, nil, aliceChannelState,
	)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	channelBob, err := lnwallet.NewLightningChannel(
		bobSigner, nil, bobChannelState,
	)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	chainIO := &mockChainIO{}
	wallet := &lnwallet.LightningWallet{
		WalletController: &mockWalletController{
			rootKey:               aliceKeyPriv,
			publishedTransactions: publTx,
		},
	}
	cc := &chainControl{
		feeEstimator:  estimator,
		chainIO:       chainIO,
		chainNotifier: notifier,
		wallet:        wallet,
	}

	breachArbiter := &breachArbiter{}

	chainArb := contractcourt.NewChainArbitrator(
		contractcourt.ChainArbitratorConfig{
			Notifier: notifier,
			ChainIO:  chainIO,
		}, dbAlice,
	)
	chainArb.WatchNewChannel(aliceChannelState)

	s := &server{
		chanDB:        dbAlice,
		cc:            cc,
		breachArbiter: breachArbiter,
		chainArb:      chainArb,
	}
	s.htlcSwitch = htlcswitch.New(htlcswitch.Config{})
	s.htlcSwitch.Start()

	alicePeer := &peer{
		server:        s,
		sendQueue:     make(chan outgoingMsg, 1),
		outgoingQueue: make(chan outgoingMsg, outgoingQueueLen),

		activeChannels: make(map[lnwire.ChannelID]*lnwallet.LightningChannel),
		newChannels:    make(chan *newChannelMsg, 1),

		activeChanCloses:   make(map[lnwire.ChannelID]*channelCloser),
		localCloseChanReqs: make(chan *htlcswitch.ChanClose),
		chanCloseMsgs:      make(chan *closeMsg),

		queueQuit: make(chan struct{}),
		quit:      make(chan struct{}),
	}

	chanID := lnwire.NewChanIDFromOutPoint(channelAlice.ChannelPoint())
	alicePeer.activeChannels[chanID] = channelAlice

	go alicePeer.channelManager()

	return alicePeer, channelAlice, channelBob, cleanUpFunc, nil
}
<commit_msg>test_utils: init switch with channeldb<commit_after>package main

import (
	"bytes"
	"io/ioutil"
	"math/rand"
	"net"
	"os"

	"github.com/lightningnetwork/lnd/chainntnfs"
	"github.com/lightningnetwork/lnd/channeldb"
	"github.com/lightningnetwork/lnd/contractcourt"
	"github.com/lightningnetwork/lnd/htlcswitch"
	"github.com/lightningnetwork/lnd/keychain"
	"github.com/lightningnetwork/lnd/lnwallet"
	"github.com/lightningnetwork/lnd/lnwire"
	"github.com/lightningnetwork/lnd/shachain"
	"github.com/roasbeef/btcd/btcec"
	"github.com/roasbeef/btcd/chaincfg/chainhash"
	"github.com/roasbeef/btcd/wire"
	"github.com/roasbeef/btcutil"
)

var (
	alicesPrivKey = []byte{
		0x2b, 0xd8, 0x06, 0xc9, 0x7f, 0x0e, 0x00, 0xaf,
		0x1a, 0x1f, 0xc3, 0x32, 0x8f, 0xa7, 0x63, 0xa9,
		0x26, 0x97, 0x23, 0xc8, 0xdb, 0x8f, 0xac, 0x4f,
		0x93, 0xaf, 0x71, 0xdb, 0x18, 0x6d, 0x6e, 0x90,
	}

	bobsPrivKey = []byte{
		0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
		0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
		0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
		0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9,
	}

	// Use a hard-coded HD seed.
	testHdSeed = [32]byte{
		0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab,
		0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4,
		0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9,
		0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53,
	}

	// Just use some arbitrary bytes as delivery script.
	dummyDeliveryScript = alicesPrivKey[:]
)

// createTestPeer creates a channel between two nodes, and returns a peer for
// one of the nodes, together with the channel seen from both nodes.
func createTestPeer(notifier chainntnfs.ChainNotifier,
	publTx chan *wire.MsgTx) (*peer, *lnwallet.LightningChannel,
	*lnwallet.LightningChannel, func(), error) {

	aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
		alicesPrivKey)
	bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes(btcec.S256(),
		bobsPrivKey)

	channelCapacity := btcutil.Amount(10 * 1e8)
	channelBal := channelCapacity / 2
	aliceDustLimit := btcutil.Amount(200)
	bobDustLimit := btcutil.Amount(1300)
	csvTimeoutAlice := uint32(5)
	csvTimeoutBob := uint32(4)

	prevOut := &wire.OutPoint{
		Hash:  chainhash.Hash(testHdSeed),
		Index: 0,
	}
	fundingTxIn := wire.NewTxIn(prevOut, nil, nil)

	aliceCfg := channeldb.ChannelConfig{
		ChannelConstraints: channeldb.ChannelConstraints{
			DustLimit:        aliceDustLimit,
			MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()),
			ChanReserve:      btcutil.Amount(rand.Int63()),
			MinHTLC:          lnwire.MilliSatoshi(rand.Int63()),
			MaxAcceptedHtlcs: uint16(rand.Int31()),
		},
		CsvDelay: uint16(csvTimeoutAlice),
		MultiSigKey: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
		RevocationBasePoint: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
		PaymentBasePoint: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
		DelayBasePoint: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
		HtlcBasePoint: keychain.KeyDescriptor{
			PubKey: aliceKeyPub,
		},
	}
	bobCfg := channeldb.ChannelConfig{
		ChannelConstraints: channeldb.ChannelConstraints{
			DustLimit:        bobDustLimit,
			MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()),
			ChanReserve:      btcutil.Amount(rand.Int63()),
			MinHTLC:          lnwire.MilliSatoshi(rand.Int63()),
			MaxAcceptedHtlcs: uint16(rand.Int31()),
		},
		CsvDelay: uint16(csvTimeoutBob),
		MultiSigKey: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
		RevocationBasePoint: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
		PaymentBasePoint: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
		DelayBasePoint: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
		HtlcBasePoint: keychain.KeyDescriptor{
			PubKey: bobKeyPub,
		},
	}

	bobRoot, err := chainhash.NewHash(bobKeyPriv.Serialize())
	if err != nil {
		return nil, nil, nil, nil, err
	}
	bobPreimageProducer := shachain.NewRevocationProducer(*bobRoot)
	bobFirstRevoke, err := bobPreimageProducer.AtIndex(0)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	bobCommitPoint := lnwallet.ComputeCommitmentPoint(bobFirstRevoke[:])

	aliceRoot, err := chainhash.NewHash(aliceKeyPriv.Serialize())
	if err != nil {
		return nil, nil, nil, nil, err
	}
	alicePreimageProducer := shachain.NewRevocationProducer(*aliceRoot)
	aliceFirstRevoke, err := alicePreimageProducer.AtIndex(0)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	aliceCommitPoint := lnwallet.ComputeCommitmentPoint(aliceFirstRevoke[:])

	aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns(channelBal,
		channelBal, &aliceCfg, &bobCfg, aliceCommitPoint, bobCommitPoint,
		*fundingTxIn)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	alicePath, err := ioutil.TempDir("", "alicedb")
	dbAlice, err := channeldb.Open(alicePath)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	bobPath, err := ioutil.TempDir("", "bobdb")
	dbBob, err := channeldb.Open(bobPath)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	estimator := &lnwallet.StaticFeeEstimator{FeeRate: 50}
	feePerVSize, err := estimator.EstimateFeePerVSize(1)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	feePerKw := feePerVSize.FeePerKWeight()

	// TODO(roasbeef): need to factor in commit fee?
	aliceCommit := channeldb.ChannelCommitment{
		CommitHeight:  0,
		LocalBalance:  lnwire.NewMSatFromSatoshis(channelBal),
		RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal),
		FeePerKw:      btcutil.Amount(feePerKw),
		CommitFee:     feePerKw.FeeForWeight(lnwallet.CommitWeight),
		CommitTx:      aliceCommitTx,
		CommitSig:     bytes.Repeat([]byte{1}, 71),
	}
	bobCommit := channeldb.ChannelCommitment{
		CommitHeight:  0,
		LocalBalance:  lnwire.NewMSatFromSatoshis(channelBal),
		RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal),
		FeePerKw:      btcutil.Amount(feePerKw),
		CommitFee:     feePerKw.FeeForWeight(lnwallet.CommitWeight),
		CommitTx:      bobCommitTx,
		CommitSig:     bytes.Repeat([]byte{1}, 71),
	}

	aliceChannelState := &channeldb.OpenChannel{
		LocalChanCfg:            aliceCfg,
		RemoteChanCfg:           bobCfg,
		IdentityPub:             aliceKeyPub,
		FundingOutpoint:         *prevOut,
		ChanType:                channeldb.SingleFunder,
		IsInitiator:             true,
		Capacity:                channelCapacity,
		RemoteCurrentRevocation: bobCommitPoint,
		RevocationProducer:      alicePreimageProducer,
		RevocationStore:         shachain.NewRevocationStore(),
		LocalCommitment:         aliceCommit,
		RemoteCommitment:        aliceCommit,
		Db:                      dbAlice,
	}
	bobChannelState := &channeldb.OpenChannel{
		LocalChanCfg:            bobCfg,
		RemoteChanCfg:           aliceCfg,
		IdentityPub:             bobKeyPub,
		FundingOutpoint:         *prevOut,
		ChanType:                channeldb.SingleFunder,
		IsInitiator:             false,
		Capacity:                channelCapacity,
		RemoteCurrentRevocation: aliceCommitPoint,
		RevocationProducer:      bobPreimageProducer,
		RevocationStore:         shachain.NewRevocationStore(),
		LocalCommitment:         bobCommit,
		RemoteCommitment:        bobCommit,
		Db:                      dbBob,
	}

	addr := &net.TCPAddr{
		IP:   net.ParseIP("127.0.0.1"),
		Port: 18555,
	}

	if err := aliceChannelState.SyncPending(addr, 0); err != nil {
		return nil, nil, nil, nil, err
	}

	addr = &net.TCPAddr{
		IP:   net.ParseIP("127.0.0.1"),
		Port: 18556,
	}

	if err := bobChannelState.SyncPending(addr, 0); err != nil {
		return nil, nil, nil, nil, err
	}

	cleanUpFunc := func() {
		os.RemoveAll(bobPath)
		os.RemoveAll(alicePath)
	}

	aliceSigner := &mockSigner{aliceKeyPriv}
	bobSigner := &mockSigner{bobKeyPriv}

	channelAlice, err := lnwallet.NewLightningChannel(
		aliceSigner, nil, aliceChannelState,
	)
	if err != nil {
		return nil, nil, nil, nil, err
	}
	channelBob, err := lnwallet.NewLightningChannel(
		bobSigner, nil, bobChannelState,
	)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	chainIO := &mockChainIO{}
	wallet := &lnwallet.LightningWallet{
		WalletController: &mockWalletController{
			rootKey:               aliceKeyPriv,
			publishedTransactions: publTx,
		},
	}
	cc := &chainControl{
		feeEstimator:  estimator,
		chainIO:       chainIO,
		chainNotifier: notifier,
		wallet:        wallet,
	}

	breachArbiter := &breachArbiter{}

	chainArb := contractcourt.NewChainArbitrator(
		contractcourt.ChainArbitratorConfig{
			Notifier: notifier,
			ChainIO:  chainIO,
		}, dbAlice,
	)
	chainArb.WatchNewChannel(aliceChannelState)

	s := &server{
		chanDB:        dbAlice,
		cc:            cc,
		breachArbiter: breachArbiter,
		chainArb:      chainArb,
	}
	htlcSwitch, err := htlcswitch.New(htlcswitch.Config{
		DB: dbAlice,
	})
	if err != nil {
		return nil, nil, nil, nil, err
	}
	s.htlcSwitch = htlcSwitch
	s.htlcSwitch.Start()

	alicePeer := &peer{
		server:        s,
		sendQueue:     make(chan outgoingMsg, 1),
		outgoingQueue: make(chan outgoingMsg, outgoingQueueLen),

		activeChannels: make(map[lnwire.ChannelID]*lnwallet.LightningChannel),
		newChannels:    make(chan *newChannelMsg, 1),

		activeChanCloses:   make(map[lnwire.ChannelID]*channelCloser),
		localCloseChanReqs: make(chan *htlcswitch.ChanClose),
		chanCloseMsgs:      make(chan *closeMsg),

		queueQuit: make(chan struct{}),
		quit:      make(chan struct{}),
	}

	chanID := lnwire.NewChanIDFromOutPoint(channelAlice.ChannelPoint())
	alicePeer.activeChannels[chanID] = channelAlice

	go alicePeer.channelManager()

	return alicePeer, channelAlice, channelBob, cleanUpFunc, nil
}
<|endoftext|>


<commit_before>package market

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/nzai/stockrecorder/config"
	"github.com/nzai/stockrecorder/io"
)

type Peroid60 struct {
	Market string
	Code   string
	Time   string
	Open   float32
	Close  float32
	High   float32
	Low    float32
	Volume int64
}

const (
	rawSuffix     = "raw"
	preSuffix     = "pre"
	regularSuffix = "regular"
	postSuffix    = "post"
	errorSuffix   = "error"
	invalidSuffix = "invalid"
)

//	判断不同结尾的文件是否存在
func isExists(market Market, code string, date time.Time, suffix string) bool {

	fileName := fmt.Sprintf("%s_%s.txt", date.Format("20060102"), suffix)
	filePath := filepath.Join(config.Get().DataDir, market.Name(), code, fileName)

	return io.IsExists(filePath)
}

//	是否已下载
func isDownloaded(market Market, code string, date time.Time) bool {
	return isExists(market, code, date, rawSuffix)
}

//	是否已处理
func isProcessed(rawPath string) bool {

	//	是否有error或regular文件
	return io.IsExists(strings.Replace(rawPath, rawSuffix, errorSuffix, -1)) ||
		io.IsExists(strings.Replace(rawPath, rawSuffix, regularSuffix, -1))
}

//	是否有异常数据
func isInvalid(market Market, code string, date time.Time) bool {
	return isExists(market, code, date, invalidSuffix)
}

//	将文件标为异常
func invalidate(market Market, code string, date time.Time) error {

	fileDir := filepath.Join(config.Get().DataDir, market.Name(), code)
	dateString := date.Format("20060102")

	rawFilePath := filepath.Join(fileDir, fmt.Sprintf("%s_%s.txt", dateString, rawSuffix))
	invalidFilePath := filepath.Join(fileDir, fmt.Sprintf("%s_%s.txt", dateString, invalidSuffix))

	//	将文件改名，以便重新下载分析
	return os.Rename(rawFilePath, invalidFilePath)
}

//	记录异常
func saveError(market Market, code string, date time.Time, err error) error {

	fileName := fmt.Sprintf("%s_%s.txt", date.Format("20060102"), errorSuffix)
	filePath := filepath.Join(config.Get().DataDir, market.Name(), code, fileName)

	return io.WriteString(filePath, err.Error())
}

//	保存原始数据
func saveRaw(market Market, code string, date time.Time, buffer []byte) (string, error) {

	fileName := fmt.Sprintf("%s_%s.txt", date.Format("20060102"), rawSuffix)
	filePath := filepath.Join(config.Get().DataDir, market.Name(), code, fileName)

	return filePath, io.WriteBytes(filePath, buffer)
}

//	从文件名中获取信息
func retrieveRawParams(rawFilePath string) (Market, string, time.Time, error) {

	other := strings.Replace(rawFilePath, config.Get().DataDir, "", -1)

	//	路径处理
	if os.IsPathSeparator(other[0]) {
		other = other[1:]
	}

	parts := strings.Split(other, string(os.PathSeparator))
	if len(parts) != 3 {
		return nil, "", time.Now(), fmt.Errorf("[ProcessQueue]\t不规则的文件名:%s", rawFilePath)
	}

	market, found := markets[parts[0]]
	if !found {
		return nil, "", time.Now(), fmt.Errorf("[ProcessQueue]\t错误的市场定义:%s", parts[0])
	}

	dateString := parts[2][:8]
	day, err := time.Parse("20060102", dateString)
	if err != nil {
		return nil, "", time.Now(), fmt.Errorf("[ProcessQueue]\t不规则的文件名日期:%s", dateString)
	}

	return market, parts[1], day, nil
}

//	保存分时数据到文件
func savePeroid60(market Market, code, suffix string, date time.Time, peroids []Peroid60) error {

	if len(peroids) == 0 {
		return nil
	}

	fileName := fmt.Sprintf("%s_%s.txt", date.Format("20060102"), suffix)
	filePath := filepath.Join(config.Get().DataDir, market.Name(), code, fileName)

	lines := make([]string, 0)
	for _, p := range peroids {
		lines = append(lines, fmt.Sprintf("%s\t%.3f\t%.3f\t%.3f\t%.3f\t%d", p.Time, p.Open, p.Close, p.High, p.Low, p.Volume))
	}

	return io.WriteLines(filePath, lines)
}

//	从文件读取分时数据
func loadPeroid60(market Market, code string, date time.Time) ([]Peroid60, error) {

	//	检查分时数据是否存在
	if !isExists(market, code, date, regularSuffix) {
		return nil, fmt.Errorf("[%s]\t[%s]在%s的分时数据不存在", market.Name(), code, date.Format("20060102"))
	}

	fileName := fmt.Sprintf("%s_%s.txt", date.Format("20060102"), regularSuffix)
	filePath := filepath.Join(config.Get().DataDir, market.Name(), code, fileName)

	lines, err := io.ReadLines(filePath)
	if err != nil {
		return nil, err
	}

	var timeString string
	var open, _close, high, low float32
	var volume int64

	dateString := date.Format("20060102")
	peroids := make([]Peroid60, 0)
	for _, line := range lines {

		_, err = fmt.Sscanf(line, "%s\t%f\t%f\t%f\t%f\t%d", &timeString, &open, &_close, &high, &low, &volume)
		if err != nil {
			return nil, err
		}

		peroids = append(peroids, Peroid60{
			Market: market.Name(),
			Code:   strings.ToUpper(code),
			Time:   dateString + timeString,
			Open:   open,
			Close:  _close,
			High:   high,
			Low:    low,
			Volume: volume})
	}

	return peroids, nil
}
<commit_msg>调整数据保存方式，增加日期一级目录，一方面可以用目录是否存在来检测是否操作过，另一方面可以降低单个目录中的文件数量<commit_after>package market

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/nzai/stockrecorder/config"
	"github.com/nzai/stockrecorder/io"
)

type Peroid60 struct {
	Market string
	Code   string
	Time   string
	Open   float32
	Close  float32
	High   float32
	Low    float32
	Volume int64
}

const (
	rawSuffix     = "raw.txt"
	preSuffix     = "pre.txt"
	regularSuffix = "regular.txt"
	postSuffix    = "post.txt"
	errorSuffix   = "error.txt"
	invalidSuffix = "invalid.txt"
)

//	判断不同结尾的文件是否存在
func isExists(market Market, code string, date time.Time, suffix string) bool {

	filePath := filepath.Join(config.Get().DataDir,
		market.Name(),
		code,
		date.Format("20060102"),
		suffix)

	return io.IsExists(filePath)
}

//	是否已下载
func isDownloaded(market Market, code string, date time.Time) bool {

	//	判断目录是否存在
	filePath := filepath.Join(config.Get().DataDir,
		market.Name(),
		code,
		date.Format("20060102"))

	return io.IsExists(filePath)
}

//	是否已处理
func isProcessed(rawPath string) bool {

	//	是否有error或regular文件
	return io.IsExists(strings.Replace(rawPath, rawSuffix, errorSuffix, -1)) ||
		io.IsExists(strings.Replace(rawPath, rawSuffix, regularSuffix, -1))
}

//	是否有异常数据
func isInvalid(market Market, code string, date time.Time) bool {
	return isExists(market, code, date, invalidSuffix)
}

//	将文件标为异常
func invalidate(market Market, code string, date time.Time) error {

	fileDir := filepath.Join(config.Get().DataDir, market.Name(), code, date.Format("20060102"))
	rawFilePath := filepath.Join(fileDir, rawSuffix)
	invalidFilePath := filepath.Join(fileDir, invalidSuffix)

	//	将文件改名，以便重新下载分析
	return os.Rename(rawFilePath, invalidFilePath)
}

//	记录异常
func saveError(market Market, code string, date time.Time) error {

	fileDir := filepath.Join(config.Get().DataDir, market.Name(), code, date.Format("20060102"))
	rawFilePath := filepath.Join(fileDir, rawSuffix)
	errorFilePath := filepath.Join(fileDir, errorSuffix)

	//	将文件改名，以便分析
	return os.Rename(rawFilePath, errorFilePath)
}

//	保存原始数据
func saveRaw(market Market, code string, date time.Time, buffer []byte) (string, error) {

	filePath := filepath.Join(config.Get().DataDir,
		market.Name(),
		code,
		date.Format("20060102"),
		rawSuffix)

	return filePath, io.WriteBytes(filePath, buffer)
}

//	删除原始数据
func removeRaw(market Market, code string, date time.Time) error {

	filePath := filepath.Join(config.Get().DataDir,
		market.Name(),
		code,
		date.Format("20060102"),
		rawSuffix)

	return os.Remove(filePath)
}

//	从文件名中获取信息
func retrieveRawParams(rawFilePath string) (Market, string, time.Time, error) {

	other := strings.Replace(rawFilePath, config.Get().DataDir, "", -1)

	//	路径处理
	if os.IsPathSeparator(other[0]) {
		other = other[1:]
	}

	parts := strings.Split(other, string(os.PathSeparator))
	if len(parts) != 4 {
		return nil, "", time.Now(), fmt.Errorf("[ProcessQueue]\t不规则的文件名:%s", rawFilePath)
	}

	market, found := markets[parts[0]]
	if !found {
		return nil, "", time.Now(), fmt.Errorf("[ProcessQueue]\t错误的市场定义:%s", parts[0])
	}

	code := parts[1]
	dateString := parts[2]
	day, err := time.Parse("20060102", dateString)
	if err != nil {
		return nil, "", time.Now(), fmt.Errorf("[ProcessQueue]\t不规则的文件名日期:%s", dateString)
	}

	return market, code, day, nil
}

//	保存分时数据到文件
func savePeroid60(market Market, code, suffix string, date time.Time, peroids []Peroid60) error {

	if len(peroids) == 0 {
		return nil
	}

	filePath := filepath.Join(config.Get().DataDir, market.Name(), code, date.Format("20060102"), suffix)

	lines := make([]string, 0)
	for _, p := range peroids {

		//	如果全为0就忽略
		if p.Open == 0 && p.Close == 0 && p.High == 0 && p.Low == 0 && p.Volume == 0 {
			continue
		}

		lines = append(lines, fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t%d", p.Time, f2s(p.Open), f2s(p.Close), f2s(p.High), f2s(p.Low), p.Volume))
	}

	return io.WriteLines(filePath, lines)
}

func f2s(value float32) string {
	return strings.TrimRight(strings.TrimRight(fmt.Sprintf("%.3f", value), "0"), ".")
}

//	从文件读取分时数据
func loadPeroid60(market Market, code string, date time.Time) ([]Peroid60, error) {

	//	检查分时数据是否存在
	if !isExists(market, code, date, regularSuffix) {
		return nil, fmt.Errorf("[%s]\t[%s]在%s的分时数据不存在", market.Name(), code, date.Format("20060102"))
	}

	dateString := date.Format("20060102")
	filePath := filepath.Join(config.Get().DataDir,
		market.Name(),
		code,
		dateString,
		regularSuffix)

	lines, err := io.ReadLines(filePath)
	if err != nil {
		return nil, err
	}

	var timeString string
	var open, _close, high, low float32
	var volume int64

	peroids := make([]Peroid60, 0)
	for _, line := range lines {

		_, err = fmt.Sscanf(line, "%s\t%f\t%f\t%f\t%f\t%d", &timeString, &open, &_close, &high, &low, &volume)
		if err != nil {
			return nil, err
		}

		peroids = append(peroids, Peroid60{
			Market: market.Name(),
			Code:   strings.ToUpper(code),
			Time:   dateString + timeString,
			Open:   open,
			Close:  _close,
			High:   high,
			Low:    low,
			Volume: volume})
	}

	return peroids, nil
}
<|endoftext|>