<commit_before>package main

import (
    "log"
    "net"
    "time"
    "container/list"
    "huabot-sched/db"
    "github.com/docker/libchan/unix"
)

type Sched struct {
    new_worker chan *Worker
    ask_worker chan *Worker
    die_worker chan *Worker
    started bool
    worker_count int
    timer *time.Timer
    queue *list.List
    jobQueue *list.List
    sockFile string
}

func NewSched(sockFile string) *Sched {
    sched = new(Sched)
    sched.started = false
    sched.new_worker = make(chan *Worker, 1)
    sched.ask_worker = make(chan *Worker, 1)
    sched.die_worker = make(chan *Worker, 1)
    sched.worker_count = 0
    sched.timer = time.NewTimer(1 * time.Hour)
    sched.queue = list.New()
    sched.jobQueue = list.New()
    sched.sockFile = sockFile
    return sched
}

func (sched *Sched) Serve() {
    sched.started = true
    sockCheck(sched.sockFile)
    go sched.run()
    go sched.handle()
    listen, err := net.Listen("unix", sched.sockFile)
    if err != nil {
        log.Fatal(err)
    }
    defer listen.Close()
    log.Printf("huabot-sched started on %s\n", sched.sockFile)
    for {
        conn, err := listen.Accept()
        if err != nil {
            log.Fatal(err)
        }
        sched.NewConnectioin(conn)
    }
}

func (sched *Sched) Notify() {
    sched.timer.Reset(time.Millisecond)
}

func (sched *Sched) run() {
    var worker *Worker
    for {
        select {
        case worker = <-sched.new_worker:
            sched.worker_count += 1
            log.Printf("worker_count: %d\n", sched.worker_count)
            go worker.HandeNewConnection()
            break
        case worker =<-sched.ask_worker:
            sched.queue.PushBack(worker)
            sched.Notify()
            break
        case worker =<-sched.die_worker:
            sched.worker_count -= 1
            log.Printf("worker_count: %d\n", sched.worker_count)
            sched.removeQueue(worker)
            sched.Notify()
            worker.Close()
            break
        }
    }
    sched.started = false
}

func (sched *Sched) NewConnectioin(conn net.Conn) {
    uconn := conn.(*net.UnixConn)
    worker := NewWorker(sched, &unix.UnixConn{UnixConn: uconn})
    sched.new_worker <- worker
}

func (sched *Sched) Done(jobId int) {
    removeListJob(sched.jobQueue, jobId)
    return
}

func (sched *Sched) isDoJob(job db.Job) bool {
    for e := sched.jobQueue.Front(); e != nil; e = e.Next() {
        if e.Value.(db.Job).Id == job.Id {
            old := e.Value.(db.Job)
            now := time.Now()
            if old.SchedAt + old.Timeout < int(now.Unix()) {
                return true
            }
        }
    }
    return false
}

func (sched *Sched) SubmitJob(worker *Worker, job db.Job) {
    job.Status = "doing"
    job.Save()
    if sched.isDoJob(job) {
        return
    }
    sched.removeQueue(worker)
    go worker.HandleDo(job)
}

func (sched *Sched) handle() {
    var current time.Time
    var timestamp int
    for {
        for e := sched.queue.Front(); e != nil; e = e.Next() {
            worker := e.Value.(*Worker)
            jobs, err := db.RangeSchedJob("ready", 0, 0)
            if err != nil {
                sched.queue.Remove(e)
                go worker.HandleNoJob()
            }
            if len(jobs) == 0 {
                sched.timer.Reset(time.Minute)
                current =<-sched.timer.C
                continue
            }
            timestamp = int(time.Now().Unix())
            if jobs[0].SchedAt < timestamp {
                sched.SubmitJob(worker, jobs[0])
            } else {
                sched.timer.Reset(time.Second * time.Duration(jobs[0].SchedAt - timestamp))
                current =<-sched.timer.C
                timestamp = int(current.Unix())
                if jobs[0].SchedAt <= timestamp {
                    sched.SubmitJob(worker, jobs[0])
                }
            }
        }
        if sched.queue.Len() == 0 {
            current =<-sched.timer.C
        }
    }
}

func (sched *Sched) Fail(jobId int) {
    removeListJob(sched.jobQueue, jobId)
    job, _ := db.GetJob(jobId)
    job.Status = "ready"
    job.Save()
    return
}

func (sched *Sched) SchedLater(jobId int, delay int) {
    removeListJob(sched.jobQueue, jobId)
    job, _ := db.GetJob(jobId)
    job.Status = "ready"
    var now = time.Now()
    job.SchedAt = int(now.Unix()) + delay
    job.Save()
    return
}

func (sched *Sched) removeQueue(worker *Worker) {
    for e := sched.queue.Front(); e != nil; e = e.Next() {
        if e.Value.(*Worker) == worker {
            sched.queue.Remove(e)
        }
    }
}

func (sched *Sched) Close() {
}
<commit_msg>update check doing job<commit_after>package main

import (
    "log"
    "net"
    "time"
    "container/list"
    "huabot-sched/db"
    "github.com/docker/libchan/unix"
)

type Sched struct {
    new_worker chan *Worker
    ask_worker chan *Worker
    die_worker chan *Worker
    started bool
    worker_count int
    timer *time.Timer
    queue *list.List
    jobQueue *list.List
    sockFile string
}

func NewSched(sockFile string) *Sched {
    sched = new(Sched)
    sched.started = false
    sched.new_worker = make(chan *Worker, 1)
    sched.ask_worker = make(chan *Worker, 1)
    sched.die_worker = make(chan *Worker, 1)
    sched.worker_count = 0
    sched.timer = time.NewTimer(1 * time.Hour)
    sched.queue = list.New()
    sched.jobQueue = list.New()
    sched.sockFile = sockFile
    return sched
}

func (sched *Sched) Serve() {
    sched.started = true
    sockCheck(sched.sockFile)
    go sched.run()
    go sched.handle()
    listen, err := net.Listen("unix", sched.sockFile)
    if err != nil {
        log.Fatal(err)
    }
    defer listen.Close()
    log.Printf("huabot-sched started on %s\n", sched.sockFile)
    for {
        conn, err := listen.Accept()
        if err != nil {
            log.Fatal(err)
        }
        sched.NewConnectioin(conn)
    }
}

func (sched *Sched) Notify() {
    sched.timer.Reset(time.Millisecond)
}

func (sched *Sched) run() {
    var worker *Worker
    for {
        select {
        case worker = <-sched.new_worker:
            sched.worker_count += 1
            log.Printf("worker_count: %d\n", sched.worker_count)
            go worker.HandeNewConnection()
            break
        case worker =<-sched.ask_worker:
            sched.queue.PushBack(worker)
            sched.Notify()
            break
        case worker =<-sched.die_worker:
            sched.worker_count -= 1
            log.Printf("worker_count: %d\n", sched.worker_count)
            sched.removeQueue(worker)
            sched.Notify()
            worker.Close()
            break
        }
    }
    sched.started = false
}

func (sched *Sched) NewConnectioin(conn net.Conn) {
    uconn := conn.(*net.UnixConn)
    worker := NewWorker(sched, &unix.UnixConn{UnixConn: uconn})
    sched.new_worker <- worker
}

func (sched *Sched) Done(jobId int) {
    removeListJob(sched.jobQueue, jobId)
    return
}

func (sched *Sched) isDoJob(job db.Job) bool {
    for e := sched.jobQueue.Front(); e != nil; e = e.Next() {
        if e.Value.(db.Job).Id == job.Id {
            old := e.Value.(db.Job)
            now := time.Now()
            if old.Timeout > 0 && old.SchedAt + old.Timeout < int(now.Unix()) {
                return false
            } else {
                return true
            }
        }
    }
    return false
}

func (sched *Sched) SubmitJob(worker *Worker, job db.Job) {
    job.Status = "doing"
    job.Save()
    if sched.isDoJob(job) {
        return
    }
    sched.removeQueue(worker)
    sched.jobQueue.PushBack(job)
    go worker.HandleDo(job)
}

func (sched *Sched) handle() {
    var current time.Time
    var timestamp int
    for {
        for e := sched.queue.Front(); e != nil; e = e.Next() {
            worker := e.Value.(*Worker)
            jobs, err := db.RangeSchedJob("ready", 0, 0)
            if err != nil {
                sched.queue.Remove(e)
                go worker.HandleNoJob()
            }
            if len(jobs) == 0 {
                sched.timer.Reset(time.Minute)
                current =<-sched.timer.C
                continue
            }
            timestamp = int(time.Now().Unix())
            if jobs[0].SchedAt < timestamp {
                sched.SubmitJob(worker, jobs[0])
            } else {
                sched.timer.Reset(time.Second * time.Duration(jobs[0].SchedAt - timestamp))
                current =<-sched.timer.C
                timestamp = int(current.Unix())
                if jobs[0].SchedAt <= timestamp {
                    sched.SubmitJob(worker, jobs[0])
                }
            }
        }
        if sched.queue.Len() == 0 {
            current =<-sched.timer.C
        }
    }
}

func (sched *Sched) Fail(jobId int) {
    removeListJob(sched.jobQueue, jobId)
    job, _ := db.GetJob(jobId)
    job.Status = "ready"
    job.Save()
    return
}

func (sched *Sched) SchedLater(jobId int, delay int) {
    removeListJob(sched.jobQueue, jobId)
    job, _ := db.GetJob(jobId)
    job.Status = "ready"
    var now = time.Now()
    job.SchedAt = int(now.Unix()) + delay
    job.Save()
    return
}

func (sched *Sched) removeQueue(worker *Worker) {
    for e := sched.queue.Front(); e != nil; e = e.Next() {
        if e.Value.(*Worker) == worker {
            sched.queue.Remove(e)
        }
    }
}

func (sched *Sched) Close() {
}
<|endoftext|>


<commit_before>package main

import (
    "log"
    "net"
    "time"
    "container/list"
    "github.com/docker/libchan/unix"
)

type Sched struct {
    new_worker chan *Worker
    ask_worker chan *Worker
    die_worker chan *Worker
    started bool
    worker_count int
    timer *time.Timer
    queue *list.List
}

func NewSched() *Sched {
    sched = new(Sched)
    sched.started = false
    sched.new_worker = make(chan *Worker, 1)
    sched.ask_worker = make(chan *Worker, 1)
    sched.die_worker = make(chan *Worker, 1)
    sched.worker_count = 0
    sched.timer = time.NewTimer(1 * time.Hour)
    sched.queue = list.New()
    return sched
}

func (sched *Sched) Start() {
    sched.started = true
    go sched.run()
    go sched.handle()
}

func (sched *Sched) Notify() {
    sched.timer.Reset(time.Millisecond)
}

func (sched *Sched) run() {
    var worker *Worker
    for {
        select {
        case worker = <-sched.new_worker:
            sched.worker_count += 1
            log.Printf("worker_count: %d\n", sched.worker_count)
            go worker.HandeNewConnection()
            break
        case worker =<-sched.ask_worker:
            sched.queue.PushBack(worker)
            sched.Notify()
            break
        case worker =<-sched.die_worker:
            log.Printf("%v close\n", worker)
            sched.worker_count -= 1
            log.Printf("worker_count: %d\n", sched.worker_count)
            sched.removeQueue(worker)
            worker.Close()
            break
        }
    }
    sched.started = false
}

func (sched *Sched) NewConnectioin(conn net.Conn) {
    uconn := conn.(*net.UnixConn)
    worker := NewWorker(sched, &unix.UnixConn{UnixConn: uconn})
    sched.new_worker <- worker
    sched.Notify()
}

func (sched *Sched) Done(job string) {
    return
}

func (sched *Sched) SubmitJob(worker *Worker, job string) {
    delay := RandomDelay()
    SchedLater(job, delay)
    go worker.HandleDo(job)
}

func (sched *Sched) handle() {
    var current time.Time
    var timestamp int
    for {
        for e := sched.queue.Front(); e != nil; e = e.Next() {
            worker := e.Value.(*Worker)
            job, err := NextSchedJob(0, 0)
            if err != nil {
                sched.queue.Remove(e)
                go worker.HandleNoJob()
            }
            timestamp = int(time.Now().Unix())
            if job[0].SchedAt < timestamp {
                sched.queue.Remove(e)
                sched.SubmitJob(worker, job[0].JobId)
            } else {
                sched.timer.Reset(time.Second * time.Duration(job[0].SchedAt - timestamp))
                current =<-sched.timer.C
                timestamp = int(current.Unix())
                if job[0].SchedAt <= timestamp {
                    sched.queue.Remove(e)
                    sched.SubmitJob(worker, job[0].JobId)
                }
            }
        }
        if sched.queue.Len() == 0 {
            current =<-sched.timer.C
        }
    }
}

func (sched *Sched) Fail(job string) {
    return
}

func (sched *Sched) removeQueue(worker *Worker) {
    for e := sched.queue.Front(); e != nil; e = e.Next() {
        if e.Value.(*Worker) == worker {
            sched.queue.Remove(e)
        }
    }
}

func (sched *Sched) Close() {
}
<commit_msg>notify when new remove queue<commit_after>package main

import (
    "log"
    "net"
    "time"
    "container/list"
    "github.com/docker/libchan/unix"
)

type Sched struct {
    new_worker chan *Worker
    ask_worker chan *Worker
    die_worker chan *Worker
    started bool
    worker_count int
    timer *time.Timer
    queue *list.List
}

func NewSched() *Sched {
    sched = new(Sched)
    sched.started = false
    sched.new_worker = make(chan *Worker, 1)
    sched.ask_worker = make(chan *Worker, 1)
    sched.die_worker = make(chan *Worker, 1)
    sched.worker_count = 0
    sched.timer = time.NewTimer(1 * time.Hour)
    sched.queue = list.New()
    return sched
}

func (sched *Sched) Start() {
    sched.started = true
    go sched.run()
    go sched.handle()
}

func (sched *Sched) Notify() {
    sched.timer.Reset(time.Millisecond)
}

func (sched *Sched) run() {
    var worker *Worker
    for {
        select {
        case worker = <-sched.new_worker:
            sched.worker_count += 1
            log.Printf("worker_count: %d\n", sched.worker_count)
            go worker.HandeNewConnection()
            break
        case worker =<-sched.ask_worker:
            sched.queue.PushBack(worker)
            sched.Notify()
            break
        case worker =<-sched.die_worker:
            log.Printf("%v close\n", worker)
            sched.worker_count -= 1
            log.Printf("worker_count: %d\n", sched.worker_count)
            sched.removeQueue(worker)
            sched.Notify()
            worker.Close()
            break
        }
    }
    sched.started = false
}

func (sched *Sched) NewConnectioin(conn net.Conn) {
    uconn := conn.(*net.UnixConn)
    worker := NewWorker(sched, &unix.UnixConn{UnixConn: uconn})
    sched.new_worker <- worker
    sched.Notify()
}

func (sched *Sched) Done(job string) {
    return
}

func (sched *Sched) SubmitJob(worker *Worker, job string) {
    delay := RandomDelay()
    SchedLater(job, delay)
    go worker.HandleDo(job)
}

func (sched *Sched) handle() {
    var current time.Time
    var timestamp int
    for {
        for e := sched.queue.Front(); e != nil; e = e.Next() {
            worker := e.Value.(*Worker)
            job, err := NextSchedJob(0, 0)
            if err != nil {
                sched.queue.Remove(e)
                go worker.HandleNoJob()
            }
            timestamp = int(time.Now().Unix())
            if job[0].SchedAt < timestamp {
                sched.queue.Remove(e)
                sched.SubmitJob(worker, job[0].JobId)
            } else {
                sched.timer.Reset(time.Second * time.Duration(job[0].SchedAt - timestamp))
                current =<-sched.timer.C
                timestamp = int(current.Unix())
                if job[0].SchedAt <= timestamp {
                    sched.queue.Remove(e)
                    sched.SubmitJob(worker, job[0].JobId)
                }
            }
        }
        if sched.queue.Len() == 0 {
            current =<-sched.timer.C
        }
    }
}

func (sched *Sched) Fail(job string) {
    return
}

func (sched *Sched) removeQueue(worker *Worker) {
    for e := sched.queue.Front(); e != nil; e = e.Next() {
        if e.Value.(*Worker) == worker {
            sched.queue.Remove(e)
        }
    }
}

func (sched *Sched) Close() {
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

type Score struct {
	midgame int
	endgame int
}

func (s *Score) clear() *Score {
	s.midgame, s.endgame = 0, 0

	return s
}

func (s *Score) add(score Score) *Score {
	s.midgame += score.midgame
	s.endgame += score.endgame

	return s
}

func (s *Score) subtract(score Score) *Score {
	s.midgame -= score.midgame
	s.endgame -= score.endgame

	return s
}

func (s *Score) adjust(n int) *Score {
	s.midgame += n
	s.endgame += n

	return s
}

func (s Score) times(n int) Score {
	s.midgame *= n
	s.endgame *= n

	return s
}

// Calculates normalized score based on the game phase.
func (s Score) blended(phase int) int {
	return (s.midgame * phase + s.endgame * (256-phase)) / 256
}
<commit_msg>plus() and minus() methods for score<commit_after>// Copyright (c) 2013-2014 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

type Score struct {
	midgame int
	endgame int
}

// Pointer methods that change the receiver in place and return its pointer.
func (s *Score) clear() *Score {
	s.midgame, s.endgame = 0, 0

	return s
}

func (s *Score) add(score Score) *Score {
	s.midgame += score.midgame
	s.endgame += score.endgame

	return s
}

func (s *Score) subtract(score Score) *Score {
	s.midgame -= score.midgame
	s.endgame -= score.endgame

	return s
}

func (s *Score) adjust(n int) *Score {
	s.midgame += n
	s.endgame += n

	return s
}

// Value methods returning new updated receiver.
func (s Score) plus(score Score) Score {
	s.midgame += score.midgame
	s.endgame += score.endgame

	return s
}

func (s Score) minus(score Score) Score {
	s.midgame -= score.midgame
	s.endgame -= score.endgame

	return s
}

func (s Score) times(n int) Score {
	s.midgame *= n
	s.endgame *= n

	return s
}

// Calculates normalized score based on the game phase.
func (s Score) blended(phase int) int {
	return (s.midgame * phase + s.endgame * (256-phase)) / 256
}
<|endoftext|>


<commit_before>package handler
import (
	"net/http"
	"github.com/akaspin/bar/bard/storage"
	"strings"
	"github.com/tamtam-im/logx"
	"encoding/json"
)

type FrontHandler struct {

}

func (h *FrontHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("works"))
}

//
type BatHandler struct {

}

func (h *BatHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("works"))
}

type SpecHandler struct {
	Storage *storage.StoragePool
}

func (h *SpecHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	store, err := h.Storage.Take()
	if err != nil {
		return
	}
	defer h.Storage.Release(store)

	id := strings.TrimPrefix(r.URL.Path, "/v1/spec/")

	logx.Debugf("serving spec %s", id)

	spec, err := store.ReadSpec(id)
	if err != nil {
		logx.Errorf("bad spec id %s", id)
		w.WriteHeader(404)
		return
	}

	w.Header().Set("Content-Type", "application/javascript")

	if err = json.NewEncoder(w).Encode(&spec); err != nil {
		logx.Error(err)
		w.WriteHeader(500)
		return
	}
}
<commit_msg>fix content-type for fuckin' IE<commit_after>package handler
import (
	"net/http"
	"github.com/akaspin/bar/bard/storage"
	"strings"
	"github.com/tamtam-im/logx"
	"encoding/json"
)

type FrontHandler struct {

}

func (h *FrontHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("works"))
}

//
type BatHandler struct {

}

func (h *BatHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("works"))
}

type SpecHandler struct {
	Storage *storage.StoragePool
}

func (h *SpecHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	store, err := h.Storage.Take()
	if err != nil {
		return
	}
	defer h.Storage.Release(store)

	id := strings.TrimPrefix(r.URL.Path, "/v1/spec/")

	logx.Debugf("serving spec %s", id)

	spec, err := store.ReadSpec(id)
	if err != nil {
		logx.Errorf("bad spec id %s", id)
		w.WriteHeader(404)
		return
	}

	w.Header().Set("Content-Type", "text/html")

	if err = json.NewEncoder(w).Encode(&spec); err != nil {
		logx.Error(err)
		w.WriteHeader(500)
		return
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Benoit Caron and contributors
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

/*
Package sensu implements simple methods to interact with Sensu API.

Usage:
	sensu := New("Sensu test API", "", "http://your.SENSU_SERVER_URL.tld"), 15, "username", "secret")
	events = sensu.GetEvents()

The sensu object expose methods that corresponds to the Sensu API:
 http://sensuapp.org/docs/0.13/api_overview

The package follow the form GetApiName() or GetApiName(args, args) where the api
 call wants arguments.

Eg:
	// match http://sensu/clients/
	clients, err := sensu.GetClients()
	// match http://sensu/clients/my_hostname
	a_client,err  := sensu.GetClient("my_hostname")
	// match http://sensu/clients/my_hostname/history
	a_history,err := sensu.GetClientHistory("my_hostname")

Methods returns a data structure and an error object that is nil on successfull query.

API methods that returns an array of results will return a []interface{}.
Methods that return a JSON object will return a map[string]interface{}.
Methods that returns no results on success will return nil, or non-nil (an error object) on errors

No distinction is made yet between server errors (HTTP Status 500) and missing
objects (HTTP status 404)

*/
package sensu

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
	//"bytes"
)

// Sensu struct contains the API details
type Sensu struct {
	Name     string
	Path     string
	URL      string
	Timeout  int
	User     string
	Pass     string
	Client   http.Client
}

// NoLimit do not specify a limit parameter
const NoLimit int = -1

// NoOffset do not specify an offset parameter
const NoOffset int = -1

// New Initialize a new Sensu API
func New(name string, path string, url string, timeout int, username string, password string, insecure bool) *Sensu {
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure},
	}

	client := http.Client{Timeout: time.Duration(s.Timeout) * time.Second, Transport: tr}

	return &Sensu{name, path, url, timeout, username, password, client}
}

// Health The health endpoint checks to see if the api can connect to redis and rabbitmq. It takes parameters for minimum consumers and maximum messages and checks rabbitmq.
func (s *Sensu) Health(consumers int, messages int) (map[string]interface{}, error) {
	return s.get(fmt.Sprintf("health/%d/%d", consumers, messages))
}

// Info Will return the Sensu version along with rabbitmq and redis information.
func (s *Sensu) Info() (map[string]interface{}, error) {
	return s.get("info")
}

// get ...
func (s *Sensu) get(endpoint string) (map[string]interface{}, error) {
	url := fmt.Sprintf("%s/%s", s.URL, endpoint)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("Parsing error: %q returned: %v", err, err)
	}
	res, err := s.doHTTP(req)
	if err != nil {
		return nil, fmt.Errorf("API call to %q returned: %v", url, err)
	}
	return s.doJSON(res)
}

// getList Construct an API call and return the list of results
//  LIMITATION: the limit/offset is currently ignored and all results are sent back
func (s *Sensu) getList(endpoint string, limit int, offset int) ([]interface{}, error) {

	/*
		args := ""
		//ERROR GET LIST TODO deal with limit %d and offset %d", limit, offset
		if limit != NOLIMIT {
			args = fmt.Sprintf("%slimit=%d", args, limit)
		}
		if offset != NOOFFSET {
			args = fmt.Sprintf("%soffset=%d", args, limit)
		}
	*/
	url := fmt.Sprintf("%s/%s", s.URL, endpoint)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("URL Parsing error: %q returned: %v", url, err)
	}
	res, err := s.doHTTP(req)
	if err != nil {
		return nil, fmt.Errorf("API call to %q returned: %v", url, err)
	}
	return s.doJSONArray(res)
}

func (s *Sensu) doHTTP(req *http.Request) ([]byte, error) {

	if s.User != "" && s.Pass != "" {
		req.SetBasicAuth(s.User, s.Pass)
	}

	res, err := s.Client.Do(req)

	if err != nil {
		return nil, fmt.Errorf("%v", err)
	}

	defer res.Body.Close()

	if res.StatusCode >= 400 {
		return nil, fmt.Errorf("%v", res.Status)
	}

	body, err := ioutil.ReadAll(res.Body)

	if err != nil {
		return nil, fmt.Errorf("Parsing response body returned: %v", err)
	}
	return body, nil
}

// doJsonArray Unmarshall JSON expecting an array
func (s *Sensu) doJSONArray(body []byte) ([]interface{}, error) {
	var results []interface{}
	if err := json.Unmarshal(body, &results); err != nil {
		return nil, fmt.Errorf("Parsing JSON-encoded response body: %v", err)
	}
	return results, nil
}

// doJsonArray Unmarshall JSON expecting a map
func (s *Sensu) doJSON(body []byte) (map[string]interface{}, error) {
	var results map[string]interface{}
	if err := json.Unmarshal(body, &results); err != nil {
		return nil, fmt.Errorf("Parsing JSON-encoded response body: %v", err)
	}
	return results, nil
}

// Post to endpoint
func (s *Sensu) post(endpoint string) (map[string]interface{}, error) {
	// Call a List with magic value of limit 0 and offset 0

	//ERROR GET LIST TODO deal with limit %d and offset %d", limit, offset

	url := fmt.Sprintf("%s/%s", s.URL, endpoint)
	req, err := http.NewRequest("POST", url, nil)
	if err != nil {
		return nil, fmt.Errorf("Parsing error: %q returned: %v", url, err)
	}

	res, err := s.doHTTP(req)
	if err != nil {
		return nil, fmt.Errorf("API call to %q returned: %v", url, err)
	}
	return s.doJSON(res)
}

// postPayload to endpoint
func (s *Sensu) postPayload(endpoint string, payload string) (map[string]interface{}, error) {
	url := fmt.Sprintf("%s/%s", s.URL, endpoint)

	req, err := http.NewRequest("POST", url, strings.NewReader(fmt.Sprintf("%s\n\n", payload)))

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Content-Length", fmt.Sprintf("%d", len(payload)))

	if err != nil {
		return nil, fmt.Errorf("Parsing error: %q returned: %v", url, err)
	}
	res, err := s.doHTTP(req)
	if err != nil {
		return nil, fmt.Errorf("API call to %q returned: %v", url, err)
	}
	return s.doJSON(res)
}

// Delete resource
func (s *Sensu) delete(endpoint string) error {
	url := fmt.Sprintf("%s/%s", s.URL, endpoint)
	req, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return fmt.Errorf("Parsing error: %q returned: %v", err, err)
	}

	if s.User != "" && s.Pass != "" {
		req.SetBasicAuth(s.User, s.Pass)
	}

	http.DefaultClient.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: s.Insecure}}

	res, err := http.DefaultClient.Do(req)

	if err != nil {
		return fmt.Errorf("API call to %q returned: %v", url, err)
	}
	defer res.Body.Close()

	if err != nil {
		return fmt.Errorf("%v", err)
	}
	if res.StatusCode >= 400 {
		return fmt.Errorf("%v", res.Status)
	}
	return nil
}
<commit_msg>Fixed timeout in New and changed the delete method to use the http.Client from the Sensu struct<commit_after>// Copyright 2014 Benoit Caron and contributors
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

/*
Package sensu implements simple methods to interact with Sensu API.

Usage:
	sensu := New("Sensu test API", "", "http://your.SENSU_SERVER_URL.tld"), 15, "username", "secret")
	events = sensu.GetEvents()

The sensu object expose methods that corresponds to the Sensu API:
 http://sensuapp.org/docs/0.13/api_overview

The package follow the form GetApiName() or GetApiName(args, args) where the api
 call wants arguments.

Eg:
	// match http://sensu/clients/
	clients, err := sensu.GetClients()
	// match http://sensu/clients/my_hostname
	a_client,err  := sensu.GetClient("my_hostname")
	// match http://sensu/clients/my_hostname/history
	a_history,err := sensu.GetClientHistory("my_hostname")

Methods returns a data structure and an error object that is nil on successfull query.

API methods that returns an array of results will return a []interface{}.
Methods that return a JSON object will return a map[string]interface{}.
Methods that returns no results on success will return nil, or non-nil (an error object) on errors

No distinction is made yet between server errors (HTTP Status 500) and missing
objects (HTTP status 404)

*/
package sensu

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
	//"bytes"
)

// Sensu struct contains the API details
type Sensu struct {
	Name     string
	Path     string
	URL      string
	Timeout  int
	User     string
	Pass     string
	Client   http.Client
}

// NoLimit do not specify a limit parameter
const NoLimit int = -1

// NoOffset do not specify an offset parameter
const NoOffset int = -1

// New Initialize a new Sensu API
func New(name string, path string, url string, timeout int, username string, password string, insecure bool) *Sensu {
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure},
	}

	client := http.Client{Timeout: time.Duration(timeout) * time.Second, Transport: tr}

	return &Sensu{name, path, url, timeout, username, password, client}
}

// Health The health endpoint checks to see if the api can connect to redis and rabbitmq. It takes parameters for minimum consumers and maximum messages and checks rabbitmq.
func (s *Sensu) Health(consumers int, messages int) (map[string]interface{}, error) {
	return s.get(fmt.Sprintf("health/%d/%d", consumers, messages))
}

// Info Will return the Sensu version along with rabbitmq and redis information.
func (s *Sensu) Info() (map[string]interface{}, error) {
	return s.get("info")
}

// get ...
func (s *Sensu) get(endpoint string) (map[string]interface{}, error) {
	url := fmt.Sprintf("%s/%s", s.URL, endpoint)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("Parsing error: %q returned: %v", err, err)
	}
	res, err := s.doHTTP(req)
	if err != nil {
		return nil, fmt.Errorf("API call to %q returned: %v", url, err)
	}
	return s.doJSON(res)
}

// getList Construct an API call and return the list of results
//  LIMITATION: the limit/offset is currently ignored and all results are sent back
func (s *Sensu) getList(endpoint string, limit int, offset int) ([]interface{}, error) {

	/*
		args := ""
		//ERROR GET LIST TODO deal with limit %d and offset %d", limit, offset
		if limit != NOLIMIT {
			args = fmt.Sprintf("%slimit=%d", args, limit)
		}
		if offset != NOOFFSET {
			args = fmt.Sprintf("%soffset=%d", args, limit)
		}
	*/
	url := fmt.Sprintf("%s/%s", s.URL, endpoint)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("URL Parsing error: %q returned: %v", url, err)
	}
	res, err := s.doHTTP(req)
	if err != nil {
		return nil, fmt.Errorf("API call to %q returned: %v", url, err)
	}
	return s.doJSONArray(res)
}

func (s *Sensu) doHTTP(req *http.Request) ([]byte, error) {

	if s.User != "" && s.Pass != "" {
		req.SetBasicAuth(s.User, s.Pass)
	}

	res, err := s.Client.Do(req)

	if err != nil {
		return nil, fmt.Errorf("%v", err)
	}

	defer res.Body.Close()

	if res.StatusCode >= 400 {
		return nil, fmt.Errorf("%v", res.Status)
	}

	body, err := ioutil.ReadAll(res.Body)

	if err != nil {
		return nil, fmt.Errorf("Parsing response body returned: %v", err)
	}
	return body, nil
}

// doJsonArray Unmarshall JSON expecting an array
func (s *Sensu) doJSONArray(body []byte) ([]interface{}, error) {
	var results []interface{}
	if err := json.Unmarshal(body, &results); err != nil {
		return nil, fmt.Errorf("Parsing JSON-encoded response body: %v", err)
	}
	return results, nil
}

// doJsonArray Unmarshall JSON expecting a map
func (s *Sensu) doJSON(body []byte) (map[string]interface{}, error) {
	var results map[string]interface{}
	if err := json.Unmarshal(body, &results); err != nil {
		return nil, fmt.Errorf("Parsing JSON-encoded response body: %v", err)
	}
	return results, nil
}

// Post to endpoint
func (s *Sensu) post(endpoint string) (map[string]interface{}, error) {
	// Call a List with magic value of limit 0 and offset 0

	//ERROR GET LIST TODO deal with limit %d and offset %d", limit, offset

	url := fmt.Sprintf("%s/%s", s.URL, endpoint)
	req, err := http.NewRequest("POST", url, nil)
	if err != nil {
		return nil, fmt.Errorf("Parsing error: %q returned: %v", url, err)
	}

	res, err := s.doHTTP(req)
	if err != nil {
		return nil, fmt.Errorf("API call to %q returned: %v", url, err)
	}
	return s.doJSON(res)
}

// postPayload to endpoint
func (s *Sensu) postPayload(endpoint string, payload string) (map[string]interface{}, error) {
	url := fmt.Sprintf("%s/%s", s.URL, endpoint)

	req, err := http.NewRequest("POST", url, strings.NewReader(fmt.Sprintf("%s\n\n", payload)))

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Content-Length", fmt.Sprintf("%d", len(payload)))

	if err != nil {
		return nil, fmt.Errorf("Parsing error: %q returned: %v", url, err)
	}
	res, err := s.doHTTP(req)
	if err != nil {
		return nil, fmt.Errorf("API call to %q returned: %v", url, err)
	}
	return s.doJSON(res)
}

// Delete resource
func (s *Sensu) delete(endpoint string) error {
	url := fmt.Sprintf("%s/%s", s.URL, endpoint)
	req, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return fmt.Errorf("Parsing error: %q returned: %v", err, err)
	}

	if s.User != "" && s.Pass != "" {
		req.SetBasicAuth(s.User, s.Pass)
	}

	res, err := s.Client.Do(req)

	if err != nil {
		return fmt.Errorf("API call to %q returned: %v", url, err)
	}
	defer res.Body.Close()

	if err != nil {
		return fmt.Errorf("%v", err)
	}
	if res.StatusCode >= 400 {
		return fmt.Errorf("%v", res.Status)
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"io"
	"log"
	"net"
	"net/http"
	"time"
)

type Server struct {
	http.Server
	config Config
}

type FlushyResponseWriter struct {
	http.ResponseWriter
}

func (writer *FlushyResponseWriter) Write(data []byte) (int, error) {
	defer func() {
		if flusher, ok := writer.ResponseWriter.(http.Flusher); ok {
			flusher.Flush()
		} else {
			log.Fatalf("ResponseWriter is not a flusher")
		}
	}()
	return writer.Write(data)
}

func RunNewServer(c Config, listening chan<- string) error {
	defer func() { listening <- "" }()
	srv := &Server{}
	addr, err := net.ResolveTCPAddr("tcp", c.Addr)
	if err != nil {
		return err
	}
	ln, err := net.ListenTCP("tcp", addr)
	if err != nil {
		return err
	}
	if listening != nil {
		listening <- ln.Addr().String()
	}
	http.Handle("/", http.HandlerFunc(func (writer http.ResponseWriter, req *http.Request) {
		fwriter := &FlushyResponseWriter{writer}
		label := "client#TODO"
		err := NewSink(label, fwriter, c.Path, c).Run()
		log.Printf("Handler: %s %s", label, err)
	}))
	return srv.Serve(tcpKeepAliveListener{ln})
}

// Copied from net/http because not exported.
//
type tcpKeepAliveListener struct {
	*net.TCPListener
}

func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
	tc, err := ln.AcceptTCP()
	if err != nil {
		return
	}
	tc.SetKeepAlive(true)
	tc.SetKeepAlivePeriod(3 * time.Minute)
	return tc, nil
}
<commit_msg>Fix write-flushing.<commit_after>package main

import (
	"log"
	"net"
	"net/http"
	"time"
)

type Server struct {
	http.Server
	config Config
}

type FlushyResponseWriter struct {
	http.ResponseWriter
}

func (writer *FlushyResponseWriter) Write(data []byte) (int, error) {
	defer func() {
		flusher, ok := writer.ResponseWriter.(http.Flusher)
		if !ok {
			log.Fatal("ResponseWriter is not a flusher")
		}
		flusher.Flush()
	}()
	return writer.ResponseWriter.Write(data)
}

func RunNewServer(c Config, listening chan<- string) error {
	defer func() { listening <- "" }()
	srv := &Server{}
	addr, err := net.ResolveTCPAddr("tcp", c.Addr)
	if err != nil {
		return err
	}
	ln, err := net.ListenTCP("tcp", addr)
	if err != nil {
		return err
	}
	if listening != nil {
		listening <- ln.Addr().String()
	}
	http.Handle("/", http.HandlerFunc(func (writer http.ResponseWriter, req *http.Request) {
		fwriter := &FlushyResponseWriter{writer}
		label := "client#TODO"
		err := NewSink(label, fwriter, c.Path, c).Run()
		log.Printf("Handler: %s %s", label, err)
	}))
	return srv.Serve(tcpKeepAliveListener{ln})
}

// Copied from net/http because not exported.
//
type tcpKeepAliveListener struct {
	*net.TCPListener
}

func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
	tc, err := ln.AcceptTCP()
	if err != nil {
		return
	}
	tc.SetKeepAlive(true)
	tc.SetKeepAlivePeriod(3 * time.Minute)
	return tc, nil
}
<|endoftext|>


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

package main

import (
	"bytes"
	"container/list"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/codegangsta/cli"
	"github.com/gogits/gogs/modules/log"

	"github.com/gogits/git"
	"github.com/gogits/gogs/models"
	"github.com/gogits/gogs/modules/base"
)

var (
	COMMANDS_READONLY = map[string]int{
		"git-upload-pack":    models.AU_WRITABLE,
		"git upload-pack":    models.AU_WRITABLE,
		"git-upload-archive": models.AU_WRITABLE,
	}

	COMMANDS_WRITE = map[string]int{
		"git-receive-pack": models.AU_READABLE,
		"git receive-pack": models.AU_READABLE,
	}
)

var CmdServ = cli.Command{
	Name:  "serv",
	Usage: "This command just should be called by ssh shell",
	Description: `
gogs serv provide access auth for repositories`,
	Action: runServ,
	Flags:  []cli.Flag{},
}

func init() {
	level := "0"
	os.MkdirAll("log", os.ModePerm)
	log.NewLogger(10000, "file", fmt.Sprintf(`{"level":%s,"filename":"%s"}`, level, "log/serv.log"))
	log.Trace("start logging...")
}

func parseCmd(cmd string) (string, string) {
	ss := strings.SplitN(cmd, " ", 2)
	if len(ss) != 2 {
		return "", ""
	}

	verb, args := ss[0], ss[1]
	if verb == "git" {
		ss = strings.SplitN(args, " ", 2)
		args = ss[1]
		verb = fmt.Sprintf("%s %s", verb, ss[0])
	}
	return verb, args
}

func In(b string, sl map[string]int) bool {
	_, e := sl[b]
	return e
}

func runServ(k *cli.Context) {
	base.NewConfigContext()
	models.LoadModelsConfig()
	models.NewEngine()

	keys := strings.Split(os.Args[2], "-")
	if len(keys) != 2 {
		fmt.Println("auth file format error")
		log.Error("auth file format error")
		return
	}

	keyId, err := strconv.ParseInt(keys[1], 10, 64)
	if err != nil {
		fmt.Println("auth file format error")
		log.Error("auth file format error")
		return
	}
	user, err := models.GetUserByKeyId(keyId)
	if err != nil {
		fmt.Println("You have no right to access")
		log.Error("You have no right to access")
		return
	}

	cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
	if cmd == "" {
		println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.")
		return
	}

	verb, args := parseCmd(cmd)
	rRepo := strings.Trim(args, "'")
	rr := strings.SplitN(rRepo, "/", 2)
	if len(rr) != 2 {
		println("Unavilable repository", args)
		log.Error("Unavilable repository %v", args)
		return
	}
	repoName := rr[1]
	if strings.HasSuffix(repoName, ".git") {
		repoName = repoName[:len(repoName)-4]
	}

	isWrite := In(verb, COMMANDS_WRITE)
	isRead := In(verb, COMMANDS_READONLY)

	repo, err := models.GetRepositoryByName(user.Id, repoName)
	var isExist bool = true
	if err != nil {
		if err == models.ErrRepoNotExist {
			isExist = false
			if isRead {
				println("Repository", user.Name+"/"+repoName, "is not exist")
				log.Error("Repository " + user.Name + "/" + repoName + " is not exist")
				return
			}
		} else {
			println("Get repository error:", err)
			log.Error("Get repository error: " + err.Error())
			return
		}
	}

	// access check
	switch {
	case isWrite:
		has, err := models.HasAccess(user.Name, repoName, models.AU_WRITABLE)
		if err != nil {
			println("Inernel error:", err)
			log.Error(err.Error())
			return
		}
		if !has {
			println("You have no right to write this repository")
			log.Error("You have no right to access this repository")
			return
		}
	case isRead:
		has, err := models.HasAccess(user.Name, repoName, models.AU_READABLE)
		if err != nil {
			println("Inernel error")
			log.Error(err.Error())
			return
		}
		if !has {
			has, err = models.HasAccess(user.Name, repoName, models.AU_WRITABLE)
			if err != nil {
				println("Inernel error")
				log.Error(err.Error())
				return
			}
		}
		if !has {
			println("You have no right to access this repository")
			log.Error("You have no right to access this repository")
			return
		}
	default:
		println("Unknown command")
		log.Error("Unknown command")
		return
	}

	var rep *git.Repository
	repoPath := models.RepoPath(user.Name, repoName)
	if !isExist {
		if isWrite {
			_, err = models.CreateRepository(user, repoName, "", "", "", false, true)
			if err != nil {
				println("Create repository failed")
				log.Error("Create repository failed: " + err.Error())
				return
			}
		}
	}

	rep, err = git.OpenRepository(repoPath)
	if err != nil {
		println("OpenRepository failed:", err.Error())
		log.Error("OpenRepository failed: " + err.Error())
		return
	}

	refs, err := rep.AllReferencesMap()
	if err != nil {
		println("Get All References failed:", err.Error())
		log.Error("Get All References failed: " + err.Error())
		return
	}

	gitcmd := exec.Command(verb, rRepo)
	gitcmd.Dir = base.RepoRootPath

	var s string
	b := bytes.NewBufferString(s)

	gitcmd.Stdout = io.MultiWriter(os.Stdout, b)
	//gitcmd.Stdin = io.MultiReader(os.Stdin, b)
	gitcmd.Stdin = os.Stdin
	gitcmd.Stderr = os.Stderr

	if err = gitcmd.Run(); err != nil {
		println("execute command error:", err.Error())
		log.Error("execute command error: " + err.Error())
		return
	}

	if isRead {
		return
	}

	time.Sleep(time.Second)

	// find push reference name
	var t = "ok refs/heads/"
	var i int
	var refname string
	for {
		l, err := b.ReadString('\n')
		if err != nil {
			break
		}
		i = i + 1
		l = l[:len(l)-1]
		idx := strings.Index(l, t)
		if idx > 0 {
			refname = l[idx+len(t):]
		}
	}
	if refname == "" {
		println("No find any reference name:", b.String())
		log.Error("No find any reference name: " + b.String())
		return
	}

	var ref *git.Reference
	var ok bool
	var l *list.List
	//log.Info("----", refname, "-----")
	if ref, ok = refs[refname]; !ok {
		// for new branch
		refs, err = rep.AllReferencesMap()
		if err != nil {
			println("Get All References failed:", err.Error())
			log.Error("Get All References failed: " + err.Error())
			return
		}
		if ref, ok = refs[refname]; !ok {
			log.Error("unknow reference name -", refname, "-", b.String())
			log.Error("unknow reference name -", refname, "-", b.String())
			return
		}
		l, err = ref.AllCommits()
		if err != nil {
			println("Get All Commits failed:", err.Error())
			log.Error("Get All Commits failed: " + err.Error())
			return
		}
	} else {
		//log.Info("----", ref, "-----")
		var last *git.Commit
		//log.Info("00000", ref.Oid.String())
		last, err = ref.LastCommit()
		if err != nil {
			println("Get last commit failed:", err.Error())
			log.Error("Get last commit failed: " + err.Error())
			return
		}

		ref2, err := rep.LookupReference(ref.Name)
		if err != nil {
			println("look up reference failed:", err.Error())
			log.Error("look up reference failed: " + err.Error())
			return
		}

		//log.Info("11111", ref2.Oid.String())
		before, err := ref2.LastCommit()
		if err != nil {
			println("Get last commit failed:", err.Error())
			log.Error("Get last commit failed: " + err.Error())
			return
		}
		//log.Info("----", before.Id(), "-----", last.Id())
		l = ref.CommitsBetween(before, last)
	}

	commits := make([][]string, 0)
	var maxCommits = 3
	for e := l.Front(); e != nil; e = e.Next() {
		commit := e.Value.(*git.Commit)
		commits = append(commits, []string{commit.Id().String(), commit.Message()})
		if len(commits) >= maxCommits {
			break
		}
	}

	if err = models.CommitRepoAction(user.Id, user.Name,
		repo.Id, repoName, refname, &base.PushCommits{l.Len(), commits}); err != nil {
		log.Error("runUpdate.models.CommitRepoAction: %v", err, commits)
	} else {
		c := exec.Command("git", "update-server-info")
		c.Dir = repoPath
		err := c.Run()
		if err != nil {
			log.Error("update-server-info: %v", err)
		}
	}
}
<commit_msg>Add more log to locate issue<commit_after>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"container/list"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/codegangsta/cli"
	"github.com/gogits/gogs/modules/log"

	"github.com/gogits/git"
	"github.com/gogits/gogs/models"
	"github.com/gogits/gogs/modules/base"
)

var (
	COMMANDS_READONLY = map[string]int{
		"git-upload-pack":    models.AU_WRITABLE,
		"git upload-pack":    models.AU_WRITABLE,
		"git-upload-archive": models.AU_WRITABLE,
	}

	COMMANDS_WRITE = map[string]int{
		"git-receive-pack": models.AU_READABLE,
		"git receive-pack": models.AU_READABLE,
	}
)

var CmdServ = cli.Command{
	Name:  "serv",
	Usage: "This command just should be called by ssh shell",
	Description: `
gogs serv provide access auth for repositories`,
	Action: runServ,
	Flags:  []cli.Flag{},
}

func init() {
	level := "0"
	os.MkdirAll("log", os.ModePerm)
	log.NewLogger(10000, "file", fmt.Sprintf(`{"level":%s,"filename":"%s"}`, level, "log/serv.log"))
	log.Trace("start logging...")
}

func parseCmd(cmd string) (string, string) {
	ss := strings.SplitN(cmd, " ", 2)
	if len(ss) != 2 {
		return "", ""
	}

	verb, args := ss[0], ss[1]
	if verb == "git" {
		ss = strings.SplitN(args, " ", 2)
		args = ss[1]
		verb = fmt.Sprintf("%s %s", verb, ss[0])
	}
	return verb, args
}

func In(b string, sl map[string]int) bool {
	_, e := sl[b]
	return e
}

func runServ(k *cli.Context) {
	log.Trace("new serv request")

	base.NewConfigContext()
	models.LoadModelsConfig()
	models.NewEngine()

	keys := strings.Split(os.Args[2], "-")
	if len(keys) != 2 {
		fmt.Println("auth file format error")
		log.Error("auth file format error")
		return
	}

	keyId, err := strconv.ParseInt(keys[1], 10, 64)
	if err != nil {
		fmt.Println("auth file format error")
		log.Error("auth file format error")
		return
	}
	user, err := models.GetUserByKeyId(keyId)
	if err != nil {
		fmt.Println("You have no right to access")
		log.Error("You have no right to access")
		return
	}

	cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
	if cmd == "" {
		println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.")
		return
	}

	verb, args := parseCmd(cmd)
	rRepo := strings.Trim(args, "'")
	rr := strings.SplitN(rRepo, "/", 2)
	if len(rr) != 2 {
		println("Unavilable repository", args)
		log.Error("Unavilable repository %v", args)
		return
	}
	repoName := rr[1]
	if strings.HasSuffix(repoName, ".git") {
		repoName = repoName[:len(repoName)-4]
	}

	isWrite := In(verb, COMMANDS_WRITE)
	isRead := In(verb, COMMANDS_READONLY)

	repo, err := models.GetRepositoryByName(user.Id, repoName)
	var isExist bool = true
	if err != nil {
		if err == models.ErrRepoNotExist {
			isExist = false
			if isRead {
				println("Repository", user.Name+"/"+repoName, "is not exist")
				log.Error("Repository " + user.Name + "/" + repoName + " is not exist")
				return
			}
		} else {
			println("Get repository error:", err)
			log.Error("Get repository error: " + err.Error())
			return
		}
	}

	// access check
	switch {
	case isWrite:
		has, err := models.HasAccess(user.Name, repoName, models.AU_WRITABLE)
		if err != nil {
			println("Inernel error:", err)
			log.Error(err.Error())
			return
		}
		if !has {
			println("You have no right to write this repository")
			log.Error("You have no right to access this repository")
			return
		}
	case isRead:
		has, err := models.HasAccess(user.Name, repoName, models.AU_READABLE)
		if err != nil {
			println("Inernel error")
			log.Error(err.Error())
			return
		}
		if !has {
			has, err = models.HasAccess(user.Name, repoName, models.AU_WRITABLE)
			if err != nil {
				println("Inernel error")
				log.Error(err.Error())
				return
			}
		}
		if !has {
			println("You have no right to access this repository")
			log.Error("You have no right to access this repository")
			return
		}
	default:
		println("Unknown command")
		log.Error("Unknown command")
		return
	}

	var rep *git.Repository
	repoPath := models.RepoPath(user.Name, repoName)
	if !isExist {
		if isWrite {
			_, err = models.CreateRepository(user, repoName, "", "", "", false, true)
			if err != nil {
				println("Create repository failed")
				log.Error("Create repository failed: " + err.Error())
				return
			}
		}
	}

	rep, err = git.OpenRepository(repoPath)
	if err != nil {
		println("OpenRepository failed:", err.Error())
		log.Error("OpenRepository failed: " + err.Error())
		return
	}

	refs, err := rep.AllReferencesMap()
	if err != nil {
		println("Get All References failed:", err.Error())
		log.Error("Get All References failed: " + err.Error())
		return
	}

	gitcmd := exec.Command(verb, rRepo)
	gitcmd.Dir = base.RepoRootPath

	var s string
	b := bytes.NewBufferString(s)

	gitcmd.Stdout = io.MultiWriter(os.Stdout, b)
	//gitcmd.Stdin = io.MultiReader(os.Stdin, b)
	gitcmd.Stdin = os.Stdin
	gitcmd.Stderr = os.Stderr

	if err = gitcmd.Run(); err != nil {
		println("execute command error:", err.Error())
		log.Error("execute command error: " + err.Error())
		return
	}

	if isRead {
		return
	}

	time.Sleep(time.Second)

	// find push reference name
	var t = "ok refs/heads/"
	var i int
	var refname string
	for {
		l, err := b.ReadString('\n')
		if err != nil {
			break
		}
		i = i + 1
		l = l[:len(l)-1]
		idx := strings.Index(l, t)
		if idx > 0 {
			refname = l[idx+len(t):]
		}
	}
	if refname == "" {
		println("No find any reference name:", b.String())
		log.Error("No find any reference name: " + b.String())
		return
	}

	var ref *git.Reference
	var ok bool
	var l *list.List
	//log.Info("----", refname, "-----")
	if ref, ok = refs[refname]; !ok {
		// for new branch
		refs, err = rep.AllReferencesMap()
		if err != nil {
			println("Get All References failed:", err.Error())
			log.Error("Get All References failed: " + err.Error())
			return
		}
		if ref, ok = refs[refname]; !ok {
			log.Error("unknow reference name -", refname, "-", b.String())
			log.Error("unknow reference name -", refname, "-", b.String())
			return
		}
		l, err = ref.AllCommits()
		if err != nil {
			println("Get All Commits failed:", err.Error())
			log.Error("Get All Commits failed: " + err.Error())
			return
		}
	} else {
		//log.Info("----", ref, "-----")
		var last *git.Commit
		//log.Info("00000", ref.Oid.String())
		last, err = ref.LastCommit()
		if err != nil {
			println("Get last commit failed:", err.Error())
			log.Error("Get last commit failed: " + err.Error())
			return
		}

		ref2, err := rep.LookupReference(ref.Name)
		if err != nil {
			println("look up reference failed:", err.Error())
			log.Error("look up reference failed: " + err.Error())
			return
		}

		//log.Info("11111", ref2.Oid.String())
		before, err := ref2.LastCommit()
		if err != nil {
			println("Get last commit failed:", err.Error())
			log.Error("Get last commit failed: " + err.Error())
			return
		}
		//log.Info("----", before.Id(), "-----", last.Id())
		l = ref.CommitsBetween(before, last)
	}

	commits := make([][]string, 0)
	var maxCommits = 3
	for e := l.Front(); e != nil; e = e.Next() {
		commit := e.Value.(*git.Commit)
		commits = append(commits, []string{commit.Id().String(), commit.Message()})
		if len(commits) >= maxCommits {
			break
		}
	}

	if err = models.CommitRepoAction(user.Id, user.Name,
		repo.Id, repoName, refname, &base.PushCommits{l.Len(), commits}); err != nil {
		log.Error("runUpdate.models.CommitRepoAction: %v", err, commits)
	} else {
		c := exec.Command("git", "update-server-info")
		c.Dir = repoPath
		err := c.Run()
		if err != nil {
			log.Error("update-server-info: %v", err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"github.com/miekg/dns"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

func getQuestionName(z *Zone, req *dns.Msg) string {
	lx := dns.SplitLabels(req.Question[0].Name)
	ql := lx[0 : len(lx)-z.LenLabels]
	return strings.ToLower(strings.Join(ql, "."))
}

var geoIP = setupGeoIP()

func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {

	qtype := req.Question[0].Qtype

	logPrintf("[zone %s] incoming %s %s %d from %s\n", z.Origin, req.Question[0].Name,
		dns.Rr_str[qtype], req.MsgHdr.Id, w.RemoteAddr())

	// is this safe/atomic or does it need to go through a channel?
	qCounter++

	logPrintln("Got request", req)

	label := getQuestionName(z, req)

	var country string
	if geoIP != nil {
		country = geoIP.GetCountry(w.RemoteAddr().String())
		logPrintln("Country:", country)
	}

	m := new(dns.Msg)
	m.SetReply(req)
	if e := m.IsEdns0(); e != nil {
		m.SetEdns0(4096, e.Do())
	}
	m.Authoritative = true

	// TODO(ask) Fix the findLabels API to make this work better
	if alias := z.findLabels(label, "", dns.TypeMF); alias != nil &&
		alias.Records[dns.TypeMF] != nil {
		// We found an alias record, so pretend the question was for that name instead
		label = alias.firstRR(dns.TypeMF).(*dns.RR_MF).Mf
	}

	labels := z.findLabels(label, country, qtype)
	if labels == nil {

		if label == "_status" && (qtype == dns.TypeANY || qtype == dns.TypeTXT) {
			m.Answer = statusRR(z)
			m.Authoritative = true
			w.Write(m)
			return
		}

		// return NXDOMAIN
		m.SetRcode(req, dns.RcodeNameError)
		m.Authoritative = true

		m.Ns = []dns.RR{z.SoaRR()}

		w.Write(m)
		return
	}

	if servers := labels.Picker(qtype, 4); servers != nil {
		var rrs []dns.RR
		for _, record := range servers {
			rr := record.RR
			rr.Header().Name = req.Question[0].Name
			rrs = append(rrs, rr)
		}
		m.Answer = rrs
	}

	if len(m.Answer) == 0 {
		if labels := z.Labels[label]; labels != nil {
			if _, ok := labels.Records[dns.TypeCNAME]; ok {
				cname := labels.firstRR(dns.TypeCNAME)
				m.Answer = append(m.Answer, cname)
			}
		} else {
			m.Ns = append(m.Ns, z.SoaRR())
		}
	}

	logPrintln(m)

	err := w.Write(m)
	if err != nil {
		// if Pack'ing fails the Write fails. Return SERVFAIL.
		log.Println("Error writing packet", m)
		dns.HandleFailed(w, req)
	}
	return
}

func statusRR(z *Zone) []dns.RR {
	h := dns.RR_Header{Ttl: 1, Class: dns.ClassINET, Rrtype: dns.TypeTXT}
	h.Name = "_status." + z.Origin + "."

	status := map[string]string{"v": VERSION, "id": serverId}

	var hostname, err = os.Hostname()
	if err == nil {
		status["h"] = hostname
	}
	status["up"] = strconv.Itoa(int(time.Since(timeStarted).Seconds()))
	status["qs"] = strconv.FormatUint(qCounter, 10)

	js, err := json.Marshal(status)

	return []dns.RR{&dns.RR_TXT{Hdr: h, Txt: []string{string(js)}}}
}

func setupServerFunc(Zone *Zone) func(dns.ResponseWriter, *dns.Msg) {
	return func(w dns.ResponseWriter, r *dns.Msg) {
		serve(w, r, Zone)
	}
}

func listenAndServe(ip string, Zones *Zones) {

	prots := []string{"udp", "tcp"}

	for _, prot := range prots {
		go func(p string) {
			server := &dns.Server{Addr: ip, Net: p}

			log.Printf("Opening on %s %s", ip, p)
			if err := server.ListenAndServe(); err != nil {
				log.Fatalf("geodns: failed to setup %s %s: %s", ip, p, err)
			}
			log.Fatalf("geodns: ListenAndServe unexpectedly returned")
		}(prot)
	}

}
<commit_msg>Add _country.pgeodns debug query<commit_after>package main

import (
	"encoding/json"
	"geodns/countries"
	"github.com/miekg/dns"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

func getQuestionName(z *Zone, req *dns.Msg) string {
	lx := dns.SplitLabels(req.Question[0].Name)
	ql := lx[0 : len(lx)-z.LenLabels]
	return strings.ToLower(strings.Join(ql, "."))
}

var geoIP = setupGeoIP()

func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {

	qtype := req.Question[0].Qtype

	logPrintf("[zone %s] incoming %s %s %d from %s\n", z.Origin, req.Question[0].Name,
		dns.Rr_str[qtype], req.MsgHdr.Id, w.RemoteAddr())

	// is this safe/atomic or does it need to go through a channel?
	qCounter++

	logPrintln("Got request", req)

	label := getQuestionName(z, req)

	var country string
	if geoIP != nil {
		country = geoIP.GetCountry(w.RemoteAddr().String())
		logPrintln("Country:", country)
	}

	m := new(dns.Msg)
	m.SetReply(req)
	if e := m.IsEdns0(); e != nil {
		m.SetEdns0(4096, e.Do())
	}
	m.Authoritative = true

	// TODO(ask) Fix the findLabels API to make this work better
	if alias := z.findLabels(label, "", dns.TypeMF); alias != nil &&
		alias.Records[dns.TypeMF] != nil {
		// We found an alias record, so pretend the question was for that name instead
		label = alias.firstRR(dns.TypeMF).(*dns.RR_MF).Mf
	}

	labels := z.findLabels(label, country, qtype)
	if labels == nil {

		if label == "_status" && (qtype == dns.TypeANY || qtype == dns.TypeTXT) {
			m.Answer = statusRR(z)
			m.Authoritative = true
			w.Write(m)
			return
		}

		if label == "_country" && (qtype == dns.TypeANY || qtype == dns.TypeTXT) {
			h := dns.RR_Header{Ttl: 1, Class: dns.ClassINET, Rrtype: dns.TypeTXT}
			h.Name = "_country." + z.Origin + "."

			m.Answer = []dns.RR{&dns.RR_TXT{Hdr: h,
				Txt: []string{
					string(country),
					string(countries.CountryContinent[country]),
				},
			}}

			m.Authoritative = true
			w.Write(m)
			return
		}

		// return NXDOMAIN
		m.SetRcode(req, dns.RcodeNameError)
		m.Authoritative = true

		m.Ns = []dns.RR{z.SoaRR()}

		w.Write(m)
		return
	}

	if servers := labels.Picker(qtype, 4); servers != nil {
		var rrs []dns.RR
		for _, record := range servers {
			rr := record.RR
			rr.Header().Name = req.Question[0].Name
			rrs = append(rrs, rr)
		}
		m.Answer = rrs
	}

	if len(m.Answer) == 0 {
		if labels := z.Labels[label]; labels != nil {
			if _, ok := labels.Records[dns.TypeCNAME]; ok {
				cname := labels.firstRR(dns.TypeCNAME)
				m.Answer = append(m.Answer, cname)
			}
		} else {
			m.Ns = append(m.Ns, z.SoaRR())
		}
	}

	logPrintln(m)

	err := w.Write(m)
	if err != nil {
		// if Pack'ing fails the Write fails. Return SERVFAIL.
		log.Println("Error writing packet", m)
		dns.HandleFailed(w, req)
	}
	return
}

func statusRR(z *Zone) []dns.RR {
	h := dns.RR_Header{Ttl: 1, Class: dns.ClassINET, Rrtype: dns.TypeTXT}
	h.Name = "_status." + z.Origin + "."

	status := map[string]string{"v": VERSION, "id": serverId}

	var hostname, err = os.Hostname()
	if err == nil {
		status["h"] = hostname
	}
	status["up"] = strconv.Itoa(int(time.Since(timeStarted).Seconds()))
	status["qs"] = strconv.FormatUint(qCounter, 10)

	js, err := json.Marshal(status)

	return []dns.RR{&dns.RR_TXT{Hdr: h, Txt: []string{string(js)}}}
}

func setupServerFunc(Zone *Zone) func(dns.ResponseWriter, *dns.Msg) {
	return func(w dns.ResponseWriter, r *dns.Msg) {
		serve(w, r, Zone)
	}
}

func listenAndServe(ip string, Zones *Zones) {

	prots := []string{"udp", "tcp"}

	for _, prot := range prots {
		go func(p string) {
			server := &dns.Server{Addr: ip, Net: p}

			log.Printf("Opening on %s %s", ip, p)
			if err := server.ListenAndServe(); err != nil {
				log.Fatalf("geodns: failed to setup %s %s: %s", ip, p, err)
			}
			log.Fatalf("geodns: ListenAndServe unexpectedly returned")
		}(prot)
	}

}
<|endoftext|>


<commit_before>package dynamixel

import (
	"errors"
	"fmt"
	"math"
)

const (

	// Control Table Addresses (EEPROM)
	addrID                byte = 0x03 // 1
	addrStatusReturnLevel byte = 0x10 // 1

	// Control Table Addresses (RAM, Read/Write)
	addrTorqueEnable      byte = 0x18 // 1
	addrLed               byte = 0x19 // 1
	addrGoalPosition      byte = 0x1E // 2
	addrMovingSpeed       byte = 0x20 // 2
	addrTorqueLimit       byte = 0x22 // 2

	// Control Table Addresses (RAM, Read Only)
	addrCurrentPosition byte = 0x24 // 2

	// Limits (from dxl_ax_actuator.htm)
	maxPos   uint16  = 1023
	maxSpeed uint16  = 1023
	maxAngle float64 = 300

	// Unit conversions
	positionToAngle float64 = maxAngle / float64(maxPos) // 0.293255132
	angleToPosition float64 = 1 / positionToAngle        // 3.41
)

type DynamixelServo struct {
	Network   *DynamixelNetwork
	Ident     uint8
	zeroAngle float64

	// Cache of control table values
	statusReturnLevel int
}

// http://support.robotis.com/en/product/dynamixel/ax_series/dxl_ax_actuator.htm
func NewServo(network *DynamixelNetwork, ident uint8) *DynamixelServo {
	s := &DynamixelServo{
		Network:           network,
		Ident:             ident,
		zeroAngle:         150,
		statusReturnLevel: 2,
	}

	return s
}

// Ping sends the PING instruction to servo, and waits for the response. Returns
// nil if the ping succeeds, otherwise an error. It's optional, but a very good
// idea, to call this before sending any other instructions to the servo.
func (servo *DynamixelServo) Ping() error {
	return servo.Network.Ping(servo.Ident)
}

// Converts a bool to an int.
func btoi(b bool) uint8 {
	if b {
		return 1
	}
	return 0
}

func low(i int) byte {
	return byte(i & 0xFF)
}

func high(i int) byte {
	return low(i >> 8)
}

func (servo *DynamixelServo) readData(startAddress byte, length int) (uint16, error) {
	if servo.statusReturnLevel == 0 {
		return 0, errors.New("can't READ while Status Return Level is zero")
	}

	return servo.Network.ReadData(servo.Ident, startAddress, length)
}

func (servo *DynamixelServo) writeData(params ...byte) error {
	return servo.Network.WriteData(servo.Ident, (servo.statusReturnLevel == 2), params...)
}

func posDistance(a uint16, b uint16) uint16 {
	return uint16(math.Abs(float64(a) - float64(b)))
}

//
func normalizeAngle(d float64) float64 {
	if d > 180 {
		return normalizeAngle(d - 360)

	} else if d < -180 {
		return normalizeAngle(d + 360)

	} else {
		return d
	}
}

//
// -- High-level interface
//
//    These methods should provide as useful and friendly of an interface to the
//    servo as possible.

func (servo *DynamixelServo) posToAngle(pos uint16) float64 {
	return (positionToAngle * float64(pos)) - servo.zeroAngle
}

func (servo *DynamixelServo) angleToPos(angle float64) uint16 {
	pos := uint16((servo.zeroAngle + angle) * angleToPosition)
	return pos
}

// Sets the origin angle (in degrees).
func (servo *DynamixelServo) SetZero(offset float64) {
	servo.zeroAngle = offset
}

//
// Returns the current position of the servo, relative to the zero angle.
//
func (servo *DynamixelServo) Angle() (float64, error) {
	pos, err := servo.Position()

	if err != nil {
		return 0, err

	} else {
		return servo.posToAngle(pos), nil
	}
}

// MoveTo sets the goal position of the servo by angle (in degrees), where zero
// is the midpoint, 150 deg is max left (clockwise), and -150 deg is max right
// (counter-clockwise). This is generally preferable to calling SetGoalPosition,
// which uses the internal uint16 representation.
//
// If the angle is out of bounds
//
func (servo *DynamixelServo) MoveTo(angle float64) error {
	pos := int(servo.angleToPos(normalizeAngle(angle)))
	return servo.SetGoalPosition(pos)
}

//
// -- Low-level interface
//
//    These methods should follow the Dynamixel protocol docs as closely as
//    possible, with no fancy stuff.
//

// Enables or disables torque.
func (servo *DynamixelServo) SetTorqueEnable(state bool) error {
	servo.logMethod("SetTorqueEnable(%t)", state)
	return servo.writeData(addrTorqueEnable, btoi(state))
}

// Enables or disables the LED.
func (servo *DynamixelServo) SetLed(state bool) error {
	servo.logMethod("SetLed(%t)", state)
	return servo.writeData(addrLed, btoi(state))
}

// Sets the goal position.
// See: http://support.robotis.com/en/product/dynamixel/ax_series/dxl_ax_actuator.htm#Actuator_Address_1E
func (servo *DynamixelServo) SetGoalPosition(pos int) error {
	if pos < 0 || pos > int(maxPos) {
		return errors.New("goal position out of range")
	}
	return servo.writeData(addrGoalPosition, low(pos), high(pos))
}

// Sets the moving speed.
func (servo *DynamixelServo) SetMovingSpeed(speed int) error {
	if speed < 0 || speed > int(maxSpeed) {
		return errors.New("moving speed out of range")
	}
	return servo.writeData(addrMovingSpeed, low(speed), high(speed))
}

// Sets the torque limit.
func (servo *DynamixelServo) SetTorqueLimit(limit int) error {
	servo.logMethod("SetTorqueLimit(%d)", limit)

	if limit < 0 || limit > 1023 {
		return errors.New("torque limit out of range")
	}
	return servo.writeData(addrTorqueLimit, low(limit), high(limit))
}

// Sets the status return level. Possible values are:
//
// 0 = Only respond to PING commands
// 1 = Only respond to PING and READ commands
// 2 = Respond to all commands
//
// Servos default to 2, but retain the value so long as they're powered up. This
// makes it a very good idea to explicitly set the value after connecting, to
// avoid waiting for status packets which will never arrive.
//
// See: dxl_ax_actuator.htm#Actuator_Address_10
func (servo *DynamixelServo) SetStatusReturnLevel(value int) error {
	servo.logMethod("SetStatusReturnLevel(%d)", value)

	if value < 0 || value > 2 {
		return fmt.Errorf("invalid Status Return Level value: %d", value)
	}

	// Call Network.WriteData directly, rather than via servo.writeData, because
	// the return status level will depend upon the new level, rather than the
	// current level cache. We don't want to update that until we're sure that
	// the write was successful.
	err := servo.Network.WriteData(servo.Ident, (value == 2), addrStatusReturnLevel, low(value))
	if err != nil {
		return err
	}

	servo.statusReturnLevel = value
	return nil
}

// Returns the current position.
func (servo *DynamixelServo) Position() (uint16, error) {
	return servo.readData(addrCurrentPosition, 2)
}

// Changes the identity of the servo.
// This is stored in EEPROM, so will persist between reboots.
func (servo *DynamixelServo) SetIdent(ident int) error {
	servo.logMethod("SetIdent(%d, %d)", ident)
	i := low(ident)

	if i < 0 || i > 252 {
		return fmt.Errorf("invalid ID (must be 0-252): %d", i)
	}

	err := servo.writeData(addrID, i)
	if err != nil {
		return err
	}

	servo.Ident = i
	return nil
}

func (servo *DynamixelServo) logMethod(format string, v ...interface{}) {
	prefix := fmt.Sprintf("servo[%d].", servo.Ident)
	servo.Network.Log(prefix + format, v...)
}
<commit_msg>go fmt<commit_after>package dynamixel

import (
	"errors"
	"fmt"
	"math"
)

const (

	// Control Table Addresses (EEPROM)
	addrID                byte = 0x03 // 1
	addrStatusReturnLevel byte = 0x10 // 1

	// Control Table Addresses (RAM, Read/Write)
	addrTorqueEnable byte = 0x18 // 1
	addrLed          byte = 0x19 // 1
	addrGoalPosition byte = 0x1E // 2
	addrMovingSpeed  byte = 0x20 // 2
	addrTorqueLimit  byte = 0x22 // 2

	// Control Table Addresses (RAM, Read Only)
	addrCurrentPosition byte = 0x24 // 2

	// Limits (from dxl_ax_actuator.htm)
	maxPos   uint16  = 1023
	maxSpeed uint16  = 1023
	maxAngle float64 = 300

	// Unit conversions
	positionToAngle float64 = maxAngle / float64(maxPos) // 0.293255132
	angleToPosition float64 = 1 / positionToAngle        // 3.41
)

type DynamixelServo struct {
	Network   *DynamixelNetwork
	Ident     uint8
	zeroAngle float64

	// Cache of control table values
	statusReturnLevel int
}

// http://support.robotis.com/en/product/dynamixel/ax_series/dxl_ax_actuator.htm
func NewServo(network *DynamixelNetwork, ident uint8) *DynamixelServo {
	s := &DynamixelServo{
		Network:           network,
		Ident:             ident,
		zeroAngle:         150,
		statusReturnLevel: 2,
	}

	return s
}

// Ping sends the PING instruction to servo, and waits for the response. Returns
// nil if the ping succeeds, otherwise an error. It's optional, but a very good
// idea, to call this before sending any other instructions to the servo.
func (servo *DynamixelServo) Ping() error {
	return servo.Network.Ping(servo.Ident)
}

// Converts a bool to an int.
func btoi(b bool) uint8 {
	if b {
		return 1
	}
	return 0
}

func low(i int) byte {
	return byte(i & 0xFF)
}

func high(i int) byte {
	return low(i >> 8)
}

func (servo *DynamixelServo) readData(startAddress byte, length int) (uint16, error) {
	if servo.statusReturnLevel == 0 {
		return 0, errors.New("can't READ while Status Return Level is zero")
	}

	return servo.Network.ReadData(servo.Ident, startAddress, length)
}

func (servo *DynamixelServo) writeData(params ...byte) error {
	return servo.Network.WriteData(servo.Ident, (servo.statusReturnLevel == 2), params...)
}

func posDistance(a uint16, b uint16) uint16 {
	return uint16(math.Abs(float64(a) - float64(b)))
}

//
func normalizeAngle(d float64) float64 {
	if d > 180 {
		return normalizeAngle(d - 360)

	} else if d < -180 {
		return normalizeAngle(d + 360)

	} else {
		return d
	}
}

//
// -- High-level interface
//
//    These methods should provide as useful and friendly of an interface to the
//    servo as possible.

func (servo *DynamixelServo) posToAngle(pos uint16) float64 {
	return (positionToAngle * float64(pos)) - servo.zeroAngle
}

func (servo *DynamixelServo) angleToPos(angle float64) uint16 {
	pos := uint16((servo.zeroAngle + angle) * angleToPosition)
	return pos
}

// Sets the origin angle (in degrees).
func (servo *DynamixelServo) SetZero(offset float64) {
	servo.zeroAngle = offset
}

//
// Returns the current position of the servo, relative to the zero angle.
//
func (servo *DynamixelServo) Angle() (float64, error) {
	pos, err := servo.Position()

	if err != nil {
		return 0, err

	} else {
		return servo.posToAngle(pos), nil
	}
}

// MoveTo sets the goal position of the servo by angle (in degrees), where zero
// is the midpoint, 150 deg is max left (clockwise), and -150 deg is max right
// (counter-clockwise). This is generally preferable to calling SetGoalPosition,
// which uses the internal uint16 representation.
//
// If the angle is out of bounds
//
func (servo *DynamixelServo) MoveTo(angle float64) error {
	pos := int(servo.angleToPos(normalizeAngle(angle)))
	return servo.SetGoalPosition(pos)
}

//
// -- Low-level interface
//
//    These methods should follow the Dynamixel protocol docs as closely as
//    possible, with no fancy stuff.
//

// Enables or disables torque.
func (servo *DynamixelServo) SetTorqueEnable(state bool) error {
	servo.logMethod("SetTorqueEnable(%t)", state)
	return servo.writeData(addrTorqueEnable, btoi(state))
}

// Enables or disables the LED.
func (servo *DynamixelServo) SetLed(state bool) error {
	servo.logMethod("SetLed(%t)", state)
	return servo.writeData(addrLed, btoi(state))
}

// Sets the goal position.
// See: http://support.robotis.com/en/product/dynamixel/ax_series/dxl_ax_actuator.htm#Actuator_Address_1E
func (servo *DynamixelServo) SetGoalPosition(pos int) error {
	if pos < 0 || pos > int(maxPos) {
		return errors.New("goal position out of range")
	}
	return servo.writeData(addrGoalPosition, low(pos), high(pos))
}

// Sets the moving speed.
func (servo *DynamixelServo) SetMovingSpeed(speed int) error {
	if speed < 0 || speed > int(maxSpeed) {
		return errors.New("moving speed out of range")
	}
	return servo.writeData(addrMovingSpeed, low(speed), high(speed))
}

// Sets the torque limit.
func (servo *DynamixelServo) SetTorqueLimit(limit int) error {
	servo.logMethod("SetTorqueLimit(%d)", limit)

	if limit < 0 || limit > 1023 {
		return errors.New("torque limit out of range")
	}
	return servo.writeData(addrTorqueLimit, low(limit), high(limit))
}

// Sets the status return level. Possible values are:
//
// 0 = Only respond to PING commands
// 1 = Only respond to PING and READ commands
// 2 = Respond to all commands
//
// Servos default to 2, but retain the value so long as they're powered up. This
// makes it a very good idea to explicitly set the value after connecting, to
// avoid waiting for status packets which will never arrive.
//
// See: dxl_ax_actuator.htm#Actuator_Address_10
func (servo *DynamixelServo) SetStatusReturnLevel(value int) error {
	servo.logMethod("SetStatusReturnLevel(%d)", value)

	if value < 0 || value > 2 {
		return fmt.Errorf("invalid Status Return Level value: %d", value)
	}

	// Call Network.WriteData directly, rather than via servo.writeData, because
	// the return status level will depend upon the new level, rather than the
	// current level cache. We don't want to update that until we're sure that
	// the write was successful.
	err := servo.Network.WriteData(servo.Ident, (value == 2), addrStatusReturnLevel, low(value))
	if err != nil {
		return err
	}

	servo.statusReturnLevel = value
	return nil
}

// Returns the current position.
func (servo *DynamixelServo) Position() (uint16, error) {
	return servo.readData(addrCurrentPosition, 2)
}

// Changes the identity of the servo.
// This is stored in EEPROM, so will persist between reboots.
func (servo *DynamixelServo) SetIdent(ident int) error {
	servo.logMethod("SetIdent(%d, %d)", ident)
	i := low(ident)

	if i < 0 || i > 252 {
		return fmt.Errorf("invalid ID (must be 0-252): %d", i)
	}

	err := servo.writeData(addrID, i)
	if err != nil {
		return err
	}

	servo.Ident = i
	return nil
}

func (servo *DynamixelServo) logMethod(format string, v ...interface{}) {
	prefix := fmt.Sprintf("servo[%d].", servo.Ident)
	servo.Network.Log(prefix+format, v...)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"github.com/darkhelmet/env"
	"github.com/stretchr/testify/assert"
	"github.com/zenazn/goji"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"
)

func init() {
	log.SetOutput(ioutil.Discard)
	if !strings.HasSuffix(env.String("DATABASE_URL"), "-test") {
		panic("Doesn't look like a test database")
	}
	dataStart()
	webBuild()
}

func clear() {
	_, err := dataConn.Exec("DELETE from dbs")
	must(err)
	_, err = dataConn.Exec("DELETE from pins")
	must(err)
}

func TestStatus(t *testing.T) {
	req, err := http.NewRequest("GET", "/status", nil)
	must(err)
	res := httptest.NewRecorder()
	goji.DefaultMux.ServeHTTP(res, req)
	webStatus(res, req)
	assert.Equal(t, 200, res.Code)
	status := &status{}
	must(json.NewDecoder(res.Body).Decode(status))
	assert.Equal(t, "ok", status.Message)
}

func TestDbAdd(t *testing.T) {
	defer clear()
	in := `{"name": "pins-1", "url": "postgres://u:p@h:1234/d-1"}`
	req, err := http.NewRequest("POST", "/dbs", bytes.NewReader([]byte(in)))
	must(err)
	res := httptest.NewRecorder()
	goji.DefaultMux.ServeHTTP(res, req)
	assert.Equal(t, 201, res.Code)
	db := &db{}
	must(json.NewDecoder(res.Body).Decode(db))
	assert.Equal(t, "pins-1", db.Name)
	assert.Equal(t, "postgres://u:p@h:1234/d-1", db.Url)
	assert.NotEmpty(t, db.Id)
	assert.WithinDuration(t, time.Now(), db.AddedAt, 3*time.Second)
}

func TestDbGet(t *testing.T) {
	defer clear()
}

func TestDbRemove(t *testing.T) {
	defer clear()
}

func TestDbList(t *testing.T) {
	defer clear()
}
<commit_msg>Clean up test a bit<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"github.com/darkhelmet/env"
	"github.com/stretchr/testify/assert"
	"github.com/zenazn/goji"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"
)

func init() {
	log.SetOutput(ioutil.Discard)
	if !strings.HasSuffix(env.String("DATABASE_URL"), "-test") {
		panic("Doesn't look like a test database")
	}
	dataStart()
	webBuild()
}

func clear() {
	_, err := dataConn.Exec("DELETE from dbs")
	must(err)
	_, err = dataConn.Exec("DELETE from pins")
	must(err)
}

func mustRequest(method, url string, body io.Reader) *httptest.ResponseRecorder {
	req, err := http.NewRequest(method, url, body)
	must(err)
	res := httptest.NewRecorder()
	goji.DefaultMux.ServeHTTP(res, req)
	return res
}

func TestStatus(t *testing.T) {
	res := mustRequest("GET", "/status", nil)
	assert.Equal(t, 200, res.Code)
	status := &status{}
	must(json.NewDecoder(res.Body).Decode(status))
	assert.Equal(t, "ok", status.Message)
}

func TestDbAdd(t *testing.T) {
	defer clear()
	b := bytes.NewReader([]byte(`{"name": "pins-1", "url": "postgres://u:p@h:1234/d-1"}`))
	res := mustRequest("POST", "/dbs", b)
	assert.Equal(t, 201, res.Code)
	db := &db{}
	must(json.NewDecoder(res.Body).Decode(db))
	assert.Equal(t, "pins-1", db.Name)
	assert.Equal(t, "postgres://u:p@h:1234/d-1", db.Url)
	assert.NotEmpty(t, db.Id)
	assert.WithinDuration(t, time.Now(), db.AddedAt, 3*time.Second)
}

func TestDbGet(t *testing.T) {
	defer clear()
}

func TestDbRemove(t *testing.T) {
	defer clear()
}

func TestDbList(t *testing.T) {
	defer clear()
}
<|endoftext|>


<commit_before>package fpm

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"testing"

	"github.com/goreleaser/goreleaser/config"
	"github.com/goreleaser/goreleaser/context"
	"github.com/goreleaser/goreleaser/internal/testlib"
	"github.com/stretchr/testify/assert"
)

func TestDescription(t *testing.T) {
	assert.NotEmpty(t, Pipe{}.Description())
}

func TestRunPipeNoFormats(t *testing.T) {
	var ctx = &context.Context{
		Version:     "1.0.0",
		Config:      config.Project{},
		Parallelism: runtime.NumCPU(),
	}
	testlib.AssertSkipped(t, Pipe{}.Run(ctx))
}

func TestRunPipe(t *testing.T) {
	folder, err := ioutil.TempDir("", "archivetest")
	assert.NoError(t, err)
	var dist = filepath.Join(folder, "dist")
	assert.NoError(t, os.Mkdir(dist, 0755))
	assert.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
	var binPath = filepath.Join(dist, "mybin", "mybin")
	_, err = os.Create(binPath)
	assert.NoError(t, err)
	var ctx = &context.Context{
		Version:     "1.0.0",
		Parallelism: runtime.NumCPU(),
		Config: config.Project{
			ProjectName: "mybin",
			Dist:        dist,
			FPM: config.FPM{
				Formats:      []string{"deb", "rpm"},
				Dependencies: []string{"make"},
				Conflicts:    []string{"git"},
				Description:  "Some description",
				License:      "MIT",
				Maintainer:   "me@me",
				Vendor:       "asdf",
				Homepage:     "https://goreleaser.github.io",
			},
		},
	}
	for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} {
		ctx.AddBinary(plat, "mybin", "mybin", binPath)
	}
	assert.NoError(t, Pipe{}.Run(ctx))
}

func TestNoFPMInPath(t *testing.T) {
	var path = os.Getenv("PATH")
	defer func() {
		assert.NoError(t, os.Setenv("PATH", path))
	}()
	assert.NoError(t, os.Setenv("PATH", ""))
	var ctx = &context.Context{
		Version:     "1.0.0",
		Parallelism: runtime.NumCPU(),
		Config: config.Project{
			FPM: config.FPM{
				Formats: []string{"deb", "rpm"},
			},
		},
	}
	assert.EqualError(t, Pipe{}.Run(ctx), ErrNoFPM.Error())
}

func TestCreateFileDoesntExist(t *testing.T) {
	folder, err := ioutil.TempDir("", "archivetest")
	assert.NoError(t, err)
	var dist = filepath.Join(folder, "dist")
	assert.NoError(t, os.Mkdir(dist, 0755))
	assert.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
	var ctx = &context.Context{
		Version:     "1.0.0",
		Parallelism: runtime.NumCPU(),
		Config: config.Project{
			Dist: dist,
			FPM: config.FPM{
				Formats: []string{"deb", "rpm"},
				Files: map[string]string{
					"testdata/testfile.txt": "/var/lib/test/testfile.txt",
				},
			},
		},
	}
	ctx.AddBinary("linuxamd64", "mybin", "mybin", filepath.Join(dist, "mybin", "mybin"))
	assert.Error(t, Pipe{}.Run(ctx))
}

func TestRunPipeWithExtraFiles(t *testing.T) {
	var ctx = &context.Context{
		Version:     "1.0.0",
		Parallelism: runtime.NumCPU(),
		Config: config.Project{
			FPM: config.FPM{
				Formats: []string{"deb", "rpm"},
			},
		},
	}
	assert.NoError(t, Pipe{}.Run(ctx))
}
<commit_msg>chore: enable debug in fpm TestRunPipe<commit_after>package fpm

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"testing"

	"github.com/goreleaser/goreleaser/config"
	"github.com/goreleaser/goreleaser/context"
	"github.com/goreleaser/goreleaser/internal/testlib"
	"github.com/stretchr/testify/assert"
)

func TestDescription(t *testing.T) {
	assert.NotEmpty(t, Pipe{}.Description())
}

func TestRunPipeNoFormats(t *testing.T) {
	var ctx = &context.Context{
		Version:     "1.0.0",
		Config:      config.Project{},
		Parallelism: runtime.NumCPU(),
	}
	testlib.AssertSkipped(t, Pipe{}.Run(ctx))
}

func TestRunPipe(t *testing.T) {
	folder, err := ioutil.TempDir("", "archivetest")
	assert.NoError(t, err)
	var dist = filepath.Join(folder, "dist")
	assert.NoError(t, os.Mkdir(dist, 0755))
	assert.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
	var binPath = filepath.Join(dist, "mybin", "mybin")
	_, err = os.Create(binPath)
	assert.NoError(t, err)
	var ctx = &context.Context{
		Version:     "1.0.0",
		Parallelism: runtime.NumCPU(),
		Debug:       true,
		Config: config.Project{
			ProjectName: "mybin",
			Dist:        dist,
			FPM: config.FPM{
				Formats:      []string{"deb", "rpm"},
				Dependencies: []string{"make"},
				Conflicts:    []string{"git"},
				Description:  "Some description",
				License:      "MIT",
				Maintainer:   "me@me",
				Vendor:       "asdf",
				Homepage:     "https://goreleaser.github.io",
			},
		},
	}
	for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} {
		ctx.AddBinary(plat, "mybin", "mybin", binPath)
	}
	assert.NoError(t, Pipe{}.Run(ctx))
}

func TestNoFPMInPath(t *testing.T) {
	var path = os.Getenv("PATH")
	defer func() {
		assert.NoError(t, os.Setenv("PATH", path))
	}()
	assert.NoError(t, os.Setenv("PATH", ""))
	var ctx = &context.Context{
		Version:     "1.0.0",
		Parallelism: runtime.NumCPU(),
		Config: config.Project{
			FPM: config.FPM{
				Formats: []string{"deb", "rpm"},
			},
		},
	}
	assert.EqualError(t, Pipe{}.Run(ctx), ErrNoFPM.Error())
}

func TestCreateFileDoesntExist(t *testing.T) {
	folder, err := ioutil.TempDir("", "archivetest")
	assert.NoError(t, err)
	var dist = filepath.Join(folder, "dist")
	assert.NoError(t, os.Mkdir(dist, 0755))
	assert.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
	var ctx = &context.Context{
		Version:     "1.0.0",
		Parallelism: runtime.NumCPU(),
		Config: config.Project{
			Dist: dist,
			FPM: config.FPM{
				Formats: []string{"deb", "rpm"},
				Files: map[string]string{
					"testdata/testfile.txt": "/var/lib/test/testfile.txt",
				},
			},
		},
	}
	ctx.AddBinary("linuxamd64", "mybin", "mybin", filepath.Join(dist, "mybin", "mybin"))
	assert.Error(t, Pipe{}.Run(ctx))
}

func TestRunPipeWithExtraFiles(t *testing.T) {
	var ctx = &context.Context{
		Version:     "1.0.0",
		Parallelism: runtime.NumCPU(),
		Config: config.Project{
			FPM: config.FPM{
				Formats: []string{"deb", "rpm"},
			},
		},
	}
	assert.NoError(t, Pipe{}.Run(ctx))
}
<|endoftext|>


<commit_before>//
// Last.Backend LLC CONFIDENTIAL
// __________________
//
// [2014] - [2018] Last.Backend LLC
// All Rights Reserved.
//
// NOTICE:  All information contained herein is, and remains
// the property of Last.Backend LLC and its suppliers,
// if any.  The intellectual and technical concepts contained
// herein are proprietary to Last.Backend LLC
// and its suppliers and may be covered by Russian Federation and Foreign Patents,
// patents in process, and are protected by trade secret or copyright law.
// Dissemination of this information or reproduction of this material
// is strictly forbidden unless prior written permission is obtained
// from Last.Backend LLC.
//

package client

import (
	"github.com/lastbackend/lastbackend/pkg/api/client/http"
	"github.com/lastbackend/lastbackend/pkg/api/client/v1"
	"net/url"
)

func NewHTTP(endpoint string, config *Config) (*Client, error) {
	c := new(Client)

	u, err := url.Parse(endpoint)
	if err != nil {
		return nil, err
	}

	cfg := new(http.Config)
	if config != nil {
		cfg.BearerToken = config.BearerToken
		cfg.Timeout = config.Timeout
	} else {
		cfg.SetDefault()
	}

	client, err := http.NewRESTClient(u, cfg)
	if err != nil {
		return nil, err
	}
	c.client = client
	return c, nil
}

type Client struct {
	client http.Interface
}

func (c Client) V1() IClientV1 {
	return v1.New(c.client)
}
<commit_msg>Client insecure flag hotfix<commit_after>//
// Last.Backend LLC CONFIDENTIAL
// __________________
//
// [2014] - [2018] Last.Backend LLC
// All Rights Reserved.
//
// NOTICE:  All information contained herein is, and remains
// the property of Last.Backend LLC and its suppliers,
// if any.  The intellectual and technical concepts contained
// herein are proprietary to Last.Backend LLC
// and its suppliers and may be covered by Russian Federation and Foreign Patents,
// patents in process, and are protected by trade secret or copyright law.
// Dissemination of this information or reproduction of this material
// is strictly forbidden unless prior written permission is obtained
// from Last.Backend LLC.
//

package client

import (
	"github.com/lastbackend/lastbackend/pkg/api/client/http"
	"github.com/lastbackend/lastbackend/pkg/api/client/v1"
	"net/url"
)

func NewHTTP(endpoint string, config *Config) (*Client, error) {
	c := new(Client)

	u, err := url.Parse(endpoint)
	if err != nil {
		return nil, err
	}

	cfg := new(http.Config)
	if config != nil {
		cfg.BearerToken = config.BearerToken
		cfg.Timeout = config.Timeout
		cfg.Insecure = config.Insecure
	} else {
		cfg.SetDefault()
	}

	client, err := http.NewRESTClient(u, cfg)
	if err != nil {
		return nil, err
	}
	c.client = client
	return c, nil
}

type Client struct {
	client http.Interface
}

func (c Client) V1() IClientV1 {
	return v1.New(c.client)
}
<|endoftext|>