<commit_before>package inject_test

import (
	"testing"

	"github.com/daaku/go.inject"
)

type LevelA struct {
	B *LevelB `inject:""`
	C *LevelC `inject:""`
}

type LevelB struct {
	C *LevelC `inject:""`
	D *LevelD `inject:""`
}

type LevelE struct {
	F *LevelF `inject:""`
}

type LevelC struct {
	F int
}

type LevelD struct {
	C *LevelC `inject:""`
}

type LevelF struct {
	F int
}

func TestLevels(t *testing.T) {
	var a LevelA
	var b LevelB
	var e LevelE

	var g inject.Graph
	err := g.Provide(
		&inject.Object{Value: &a},
		&inject.Object{Value: &b},
		&inject.Object{Value: &e},
	)
	if err != nil {
		t.Fatal(err)
	}

	if err := g.Populate(); err != nil {
		t.Fatal(err)
	}

	levels := g.Levels()
	if len(levels) != 4 {
		t.Fatalf("expecting 4 levels got %d", len(levels))
	}

	if levels[0][0].Value != &a {
		t.Fatal("did not find LevelA")
	}
	if levels[0][1].Value != &e {
		t.Fatal("did not find LevelE")
	}
	if levels[1][0].Value != &b {
		t.Fatal("did not find LevelB")
	}
	if levels[1][1].Value != e.F {
		t.Fatal("did not find LevelF")
	}
	if levels[2][0].Value != b.D {
		t.Fatal("did not find LevelD")
	}
	if levels[3][0].Value != b.C {
		t.Fatal("did not find LevelC")
	}
	t.Log(levels)
}
<commit_msg>remove unnecessary test log<commit_after>package inject_test

import (
	"testing"

	"github.com/daaku/go.inject"
)

type LevelA struct {
	B *LevelB `inject:""`
	C *LevelC `inject:""`
}

type LevelB struct {
	C *LevelC `inject:""`
	D *LevelD `inject:""`
}

type LevelE struct {
	F *LevelF `inject:""`
}

type LevelC struct {
	F int
}

type LevelD struct {
	C *LevelC `inject:""`
}

type LevelF struct {
	F int
}

func TestLevels(t *testing.T) {
	var a LevelA
	var b LevelB
	var e LevelE

	var g inject.Graph
	err := g.Provide(
		&inject.Object{Value: &a},
		&inject.Object{Value: &b},
		&inject.Object{Value: &e},
	)
	if err != nil {
		t.Fatal(err)
	}

	if err := g.Populate(); err != nil {
		t.Fatal(err)
	}

	levels := g.Levels()
	if len(levels) != 4 {
		t.Fatalf("expecting 4 levels got %d", len(levels))
	}

	if levels[0][0].Value != &a {
		t.Fatal("did not find LevelA")
	}
	if levels[0][1].Value != &e {
		t.Fatal("did not find LevelE")
	}
	if levels[1][0].Value != &b {
		t.Fatal("did not find LevelB")
	}
	if levels[1][1].Value != e.F {
		t.Fatal("did not find LevelF")
	}
	if levels[2][0].Value != b.D {
		t.Fatal("did not find LevelD")
	}
	if levels[3][0].Value != b.C {
		t.Fatal("did not find LevelC")
	}
}
<|endoftext|>


<commit_before>package lfsapi

import (
	"encoding/base64"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"strings"

	"github.com/git-lfs/git-lfs/errors"
	"github.com/rubyist/tracerx"
)

var (
	defaultCredentialHelper = &CommandCredentialHelper{}
	defaultNetrcFinder      = &noFinder{}
	defaultEndpointFinder   = NewEndpointFinder(nil)
)

func (c *Client) DoWithAuth(remote string, req *http.Request) (*http.Response, error) {
	credHelper := c.Credentials
	if credHelper == nil {
		credHelper = defaultCredentialHelper
	}

	netrcFinder := c.Netrc
	if netrcFinder == nil {
		netrcFinder = defaultNetrcFinder
	}

	ef := c.Endpoints
	if ef == nil {
		ef = defaultEndpointFinder
	}

	creds, credsURL, access, err := getCreds(credHelper, netrcFinder, ef, remote, req)
	if err != nil {
		return nil, err
	}

	res, err := c.Do(req)
	if err != nil {
		if errors.IsAuthError(err) {
			newAccess := getAuthAccess(res)
			if credsURL != nil && newAccess != access {
				c.Endpoints.SetAccess(credsURL.String(), newAccess)
			}

			if access == NoneAccess || creds != nil {
				tracerx.Printf("api: http response indicates %q authentication. Resubmitting...", newAccess)
				req.Header.Del("Authorization")
				if creds != nil {
					credHelper.Reject(creds)
				}
				return c.DoWithAuth(remote, req)
			}
		}

		err = errors.Wrap(err, "http")
	}

	if res == nil {
		return nil, err
	}

	switch res.StatusCode {
	case 401, 403:
		credHelper.Reject(creds)
	default:
		if res.StatusCode < 300 && res.StatusCode > 199 {
			credHelper.Approve(creds)
		}
	}

	return res, err
}

func getCreds(credHelper CredentialHelper, netrcFinder NetrcFinder, ef EndpointFinder, remote string, req *http.Request) (Creds, *url.URL, Access, error) {
	if skipCreds(ef, req) {
		return nil, nil, emptyAccess, nil
	}

	operation := getReqOperation(req)
	apiEndpoint := ef.Endpoint(operation, remote)
	access := ef.AccessFor(apiEndpoint.Url)
	credsUrl, err := getCredURLForAPI(ef, operation, remote, access, apiEndpoint, req)
	if err != nil {
		return nil, nil, access, errors.Wrap(err, "creds")
	}

	if credsUrl == nil {
		return nil, nil, access, nil
	}

	if setAuthFromNetrc(netrcFinder, req) {
		return nil, credsUrl, access, nil
	}
	if ef.AccessFor(credsUrl.String()) == NoneAccess {
		return nil, credsUrl, access, nil
	}

	creds, err := fillCredentials(credHelper, ef, req, credsUrl)
	return creds, credsUrl, access, err
}

func fillCredentials(credHelper CredentialHelper, ef EndpointFinder, req *http.Request, u *url.URL) (Creds, error) {
	path := strings.TrimPrefix(u.Path, "/")
	input := Creds{"protocol": u.Scheme, "host": u.Host, "path": path}
	if u.User != nil && u.User.Username() != "" {
		input["username"] = u.User.Username()
	}

	creds, err := credHelper.Fill(input)
	if creds == nil || len(creds) < 1 {
		errmsg := fmt.Sprintf("Git credentials for %s not found", u)
		if err != nil {
			errmsg = errmsg + ":\n" + err.Error()
		} else {
			errmsg = errmsg + "."
		}
		err = errors.New(errmsg)
	}

	if err != nil {
		return nil, err
	}

	tracerx.Printf("Filled credentials for %s", u)
	setRequestAuth(req, creds["username"], creds["password"])

	return creds, err
}

func setAuthFromNetrc(netrcFinder NetrcFinder, req *http.Request) bool {
	hostname := req.URL.Host
	var host string

	if strings.Contains(hostname, ":") {
		var err error
		host, _, err = net.SplitHostPort(hostname)
		if err != nil {
			tracerx.Printf("netrc: error parsing %q: %s", hostname, err)
			return false
		}
	} else {
		host = hostname
	}

	if machine := netrcFinder.FindMachine(host); machine != nil {
		setRequestAuth(req, machine.Login, machine.Password)
		return true
	}

	return false
}

func getCredURLForAPI(ef EndpointFinder, operation, remote string, access Access, e Endpoint, req *http.Request) (*url.URL, error) {
	apiUrl, err := url.Parse(e.Url)
	if err != nil {
		return nil, err
	}

	// if the LFS request doesn't match the current LFS url, don't bother
	// attempting to set the Authorization header from the LFS or Git remote URLs.
	if req.URL.Scheme != apiUrl.Scheme ||
		req.URL.Host != apiUrl.Host {
		return req.URL, nil
	}

	if setRequestAuthFromUrl(req, access, apiUrl) {
		return nil, nil
	}

	credsUrl := apiUrl
	if len(remote) > 0 {
		if u := ef.GitRemoteURL(remote, operation == "upload"); u != "" {
			gitRemoteUrl, err := url.Parse(u)
			if err != nil {
				return nil, err
			}

			if gitRemoteUrl.Scheme == apiUrl.Scheme &&
				gitRemoteUrl.Host == apiUrl.Host {

				if setRequestAuthFromUrl(req, access, gitRemoteUrl) {
					return nil, nil
				}

				credsUrl = gitRemoteUrl
			}
		}
	}

	return credsUrl, nil
}

func skipCreds(ef EndpointFinder, req *http.Request) bool {
	if ef.AccessFor(req.URL.String()) == NTLMAccess {
		return false
	}

	if len(req.Header.Get("Authorization")) > 0 {
		return true
	}

	return len(req.URL.Query().Get("token")) > 0
}

func setRequestAuthFromUrl(req *http.Request, access Access, u *url.URL) bool {
	if access == NTLMAccess || u.User == nil {
		return false
	}

	if pass, ok := u.User.Password(); ok {
		fmt.Fprintln(os.Stderr, "warning: current Git remote contains credentials")
		setRequestAuth(req, u.User.Username(), pass)
		return true
	}

	return false
}

func setRequestAuth(req *http.Request, user, pass string) {
	// better not be NTLM!
	if len(user) == 0 && len(pass) == 0 {
		return
	}

	token := fmt.Sprintf("%s:%s", user, pass)
	auth := "Basic " + strings.TrimSpace(base64.StdEncoding.EncodeToString([]byte(token)))
	req.Header.Set("Authorization", auth)
}

func getReqOperation(req *http.Request) string {
	operation := "download"
	if req.Method == "POST" || req.Method == "PUT" {
		operation = "upload"
	}
	return operation
}

var (
	authenticateHeaders = []string{"Lfs-Authenticate", "Www-Authenticate"}
)

func getAuthAccess(res *http.Response) Access {
	for _, headerName := range authenticateHeaders {
		for _, auth := range res.Header[headerName] {
			pieces := strings.SplitN(strings.ToLower(auth), " ", 2)
			if len(pieces) == 0 {
				continue
			}

			switch Access(pieces[0]) {
			case NegotiateAccess, NTLMAccess:
				// When server sends Www-Authentication: Negotiate, it supports both Kerberos and NTLM.
				// Since git-lfs current does not support Kerberos, we will return NTLM in this case.
				return NTLMAccess
			}
		}
	}

	return BasicAccess
}
<commit_msg>add a spot for future ntlm support<commit_after>package lfsapi

import (
	"encoding/base64"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"strings"

	"github.com/git-lfs/git-lfs/errors"
	"github.com/rubyist/tracerx"
)

var (
	defaultCredentialHelper = &CommandCredentialHelper{}
	defaultNetrcFinder      = &noFinder{}
	defaultEndpointFinder   = NewEndpointFinder(nil)
)

func (c *Client) DoWithAuth(remote string, req *http.Request) (*http.Response, error) {
	credHelper := c.Credentials
	if credHelper == nil {
		credHelper = defaultCredentialHelper
	}

	netrcFinder := c.Netrc
	if netrcFinder == nil {
		netrcFinder = defaultNetrcFinder
	}

	ef := c.Endpoints
	if ef == nil {
		ef = defaultEndpointFinder
	}

	creds, credsURL, access, err := getCreds(credHelper, netrcFinder, ef, remote, req)
	if err != nil {
		return nil, err
	}

	res, err := c.doWithCreds(req, creds, credsURL, access)
	if err != nil {
		if errors.IsAuthError(err) {
			newAccess := getAuthAccess(res)
			if credsURL != nil && newAccess != access {
				c.Endpoints.SetAccess(credsURL.String(), newAccess)
			}

			if access == NoneAccess || creds != nil {
				tracerx.Printf("api: http response indicates %q authentication. Resubmitting...", newAccess)
				req.Header.Del("Authorization")
				if creds != nil {
					credHelper.Reject(creds)
				}
				return c.DoWithAuth(remote, req)
			}
		}

		err = errors.Wrap(err, "http")
	}

	if res == nil {
		return nil, err
	}

	switch res.StatusCode {
	case 401, 403:
		credHelper.Reject(creds)
	default:
		if res.StatusCode < 300 && res.StatusCode > 199 {
			credHelper.Approve(creds)
		}
	}

	return res, err
}

func (c *Client) doWithCreds(req *http.Request, creds Creds, credsURL *url.URL, access Access) (*http.Response, error) {
	if access == NTLMAccess {
		return c.doWithNTLM(req, creds, credsURL)
	}
	return c.Do(req)
}

func getCreds(credHelper CredentialHelper, netrcFinder NetrcFinder, ef EndpointFinder, remote string, req *http.Request) (Creds, *url.URL, Access, error) {
	if skipCreds(ef, req) {
		return nil, nil, emptyAccess, nil
	}

	operation := getReqOperation(req)
	apiEndpoint := ef.Endpoint(operation, remote)
	access := ef.AccessFor(apiEndpoint.Url)
	credsUrl, err := getCredURLForAPI(ef, operation, remote, access, apiEndpoint, req)
	if err != nil {
		return nil, nil, access, errors.Wrap(err, "creds")
	}

	if credsUrl == nil {
		return nil, nil, access, nil
	}

	if setAuthFromNetrc(netrcFinder, req) {
		return nil, credsUrl, access, nil
	}
	if ef.AccessFor(credsUrl.String()) == NoneAccess {
		return nil, credsUrl, access, nil
	}

	creds, err := fillCredentials(credHelper, ef, req, credsUrl)
	return creds, credsUrl, access, err
}

func fillCredentials(credHelper CredentialHelper, ef EndpointFinder, req *http.Request, u *url.URL) (Creds, error) {
	path := strings.TrimPrefix(u.Path, "/")
	input := Creds{"protocol": u.Scheme, "host": u.Host, "path": path}
	if u.User != nil && u.User.Username() != "" {
		input["username"] = u.User.Username()
	}

	creds, err := credHelper.Fill(input)
	if creds == nil || len(creds) < 1 {
		errmsg := fmt.Sprintf("Git credentials for %s not found", u)
		if err != nil {
			errmsg = errmsg + ":\n" + err.Error()
		} else {
			errmsg = errmsg + "."
		}
		err = errors.New(errmsg)
	}

	if err != nil {
		return nil, err
	}

	tracerx.Printf("Filled credentials for %s", u)
	setRequestAuth(req, creds["username"], creds["password"])

	return creds, err
}

func setAuthFromNetrc(netrcFinder NetrcFinder, req *http.Request) bool {
	hostname := req.URL.Host
	var host string

	if strings.Contains(hostname, ":") {
		var err error
		host, _, err = net.SplitHostPort(hostname)
		if err != nil {
			tracerx.Printf("netrc: error parsing %q: %s", hostname, err)
			return false
		}
	} else {
		host = hostname
	}

	if machine := netrcFinder.FindMachine(host); machine != nil {
		setRequestAuth(req, machine.Login, machine.Password)
		return true
	}

	return false
}

func getCredURLForAPI(ef EndpointFinder, operation, remote string, access Access, e Endpoint, req *http.Request) (*url.URL, error) {
	apiUrl, err := url.Parse(e.Url)
	if err != nil {
		return nil, err
	}

	// if the LFS request doesn't match the current LFS url, don't bother
	// attempting to set the Authorization header from the LFS or Git remote URLs.
	if req.URL.Scheme != apiUrl.Scheme ||
		req.URL.Host != apiUrl.Host {
		return req.URL, nil
	}

	if setRequestAuthFromUrl(req, access, apiUrl) {
		return nil, nil
	}

	credsUrl := apiUrl
	if len(remote) > 0 {
		if u := ef.GitRemoteURL(remote, operation == "upload"); u != "" {
			gitRemoteUrl, err := url.Parse(u)
			if err != nil {
				return nil, err
			}

			if gitRemoteUrl.Scheme == apiUrl.Scheme &&
				gitRemoteUrl.Host == apiUrl.Host {

				if setRequestAuthFromUrl(req, access, gitRemoteUrl) {
					return nil, nil
				}

				credsUrl = gitRemoteUrl
			}
		}
	}

	return credsUrl, nil
}

func skipCreds(ef EndpointFinder, req *http.Request) bool {
	if ef.AccessFor(req.URL.String()) == NTLMAccess {
		return false
	}

	if len(req.Header.Get("Authorization")) > 0 {
		return true
	}

	return len(req.URL.Query().Get("token")) > 0
}

func setRequestAuthFromUrl(req *http.Request, access Access, u *url.URL) bool {
	if access == NTLMAccess || u.User == nil {
		return false
	}

	if pass, ok := u.User.Password(); ok {
		fmt.Fprintln(os.Stderr, "warning: current Git remote contains credentials")
		setRequestAuth(req, u.User.Username(), pass)
		return true
	}

	return false
}

func setRequestAuth(req *http.Request, user, pass string) {
	// better not be NTLM!
	if len(user) == 0 && len(pass) == 0 {
		return
	}

	token := fmt.Sprintf("%s:%s", user, pass)
	auth := "Basic " + strings.TrimSpace(base64.StdEncoding.EncodeToString([]byte(token)))
	req.Header.Set("Authorization", auth)
}

func getReqOperation(req *http.Request) string {
	operation := "download"
	if req.Method == "POST" || req.Method == "PUT" {
		operation = "upload"
	}
	return operation
}

var (
	authenticateHeaders = []string{"Lfs-Authenticate", "Www-Authenticate"}
)

func getAuthAccess(res *http.Response) Access {
	for _, headerName := range authenticateHeaders {
		for _, auth := range res.Header[headerName] {
			pieces := strings.SplitN(strings.ToLower(auth), " ", 2)
			if len(pieces) == 0 {
				continue
			}

			switch Access(pieces[0]) {
			case NegotiateAccess, NTLMAccess:
				// When server sends Www-Authentication: Negotiate, it supports both Kerberos and NTLM.
				// Since git-lfs current does not support Kerberos, we will return NTLM in this case.
				return NTLMAccess
			}
		}
	}

	return BasicAccess
}
<|endoftext|>


<commit_before>package lib

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
)

type Action interface {
	getName() string
	getHint() string
	firstUp() Action
	getQuestions() Questions
	nextQuestion() *Question
	askQuestion()
}

const (
	start_action, help_action = "/start", "/help"

	say_action      = "/say"
	say_action_hint = "/say <message>"

	ask_action      = "/ask"
	ask_action_hint = "/ask <message>"

	chat_action = "/chat"

	review_action      = "/review"
	review_action_hint = "/review <days>"

	default_script = "default"
)

func NewAction(s *session, actionName string) Action {

	if s != nil {
		s.User = s.getSender()
	}

	cmd := actionName

	if s.sentAsCommand() {
		cmd = s.getSentCommand()
	}

	log.Println("incoming sticker?", s.sentAsSticker())
	log.Println("txt", s.getIncoming().msg.Text)
	log.Println("sticker", s.getIncoming().msg.Sticker.FileID)

	if cmd == say_action {
		return SayAction{session: s}
	} else if cmd == ask_action {
		return AskAction{session: s}
	} else if cmd == review_action {
		return &ReviewAction{session: s}
	} else if cmd == chat_action {
		return &ChatAction{session: s}
	} else if s.sentAsSticker() {
		return &StickerChatAction{session: s}
	}
	return &HelpAction{session: s}
}

func load(name string, q interface{}) {

	if strings.Contains(name, "/") {
		name = strings.Split(name, "/")[1]
	}

	absPath, _ := filepath.Abs(fmt.Sprintf("config/%s.json", name))
	file, err := os.Open(absPath)

	if err != nil {
		absPath, _ = filepath.Abs(fmt.Sprintf("lib/config/%s.json", name))
		log.Println("QandA path ", absPath)

		file, err = os.Open(absPath)
	}

	err = json.NewDecoder(file).Decode(&q)
	if err != nil {
		log.Panic("could not decode QandA ", err.Error())
	}

	return
}

type SayAction struct {
	*session
}

func (a SayAction) getName() string {
	return say_action
}
func (a SayAction) getHint() string {
	return say_action_hint
}
func (a SayAction) firstUp() Action {
	if a.sentAsSubmission() {
		a.session.save()
	}
	return a
}

func (a SayAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsCommand() {
		return q.First()
	}

	next, save := q.next(a.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a SayAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
}

func (a SayAction) getQuestions() Questions {

	var q struct {
		Questions `json:"QandA"`
	}
	load(a.getName(), &q)
	return q.Questions
}

type AskAction struct {
	*session
}

func (a AskAction) getName() string {
	return ask_action
}
func (a AskAction) getHint() string {
	return ask_action_hint
}
func (a AskAction) firstUp() Action {
	if a.sentAsSubmission() {
		a.session.save(help_tag)
	}
	return a
}

func (a AskAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsCommand() {
		return q.First()
	}

	next, save := q.next(a.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a AskAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
}

func (a AskAction) getQuestions() Questions {

	var q struct {
		Questions `json:"QandA"`
	}
	load(a.getName(), &q)
	return q.Questions
}

type HelpAction struct {
	*session
	q struct {
		Questions `json:"QandA"`
	}
}

func (a HelpAction) getName() string {
	return say_action
}
func (a HelpAction) getHint() string {
	return say_action_hint
}
func (a HelpAction) firstUp() Action {
	log.Println("help first up")
	helpInfo := fmt.Sprintf("%s %s %s %s %s ",
		fmt.Sprintf("Hey %s! We can't do it all but we can:\n\n", a.session.getSentUsername()),
		chat_action+" - to have a *quick chat* about what your up-to \n\n",
		say_action_hint+" - to say *anything* thats on your mind \n\n",
		//TODO: ask_action_hint+" - to ask *anything* thats on your mind \n\n",
		review_action_hint+" - to review what has been happening \n\n",
		"Stickers - we have those to help express yourself!! \n\n [Get them here](https://telegram.me/addstickers/betes)",
	)
	a.session.send(helpInfo)
	return a
}

func (a HelpAction) nextQuestion() *Question {
	return nil
}

func (a HelpAction) getQuestions() Questions {
	return nil
}

func (a HelpAction) askQuestion() {
	return
}

type ChatAction struct {
	*session
}

func (a ChatAction) getName() string {
	return chat_action
}
func (a ChatAction) getHint() string {
	return ""
}
func (a ChatAction) firstUp() Action {
	//nothing to doFirst
	return a
}

func (a ChatAction) getQuestions() Questions {

	var q struct {
		Questions `json:"QandA"`
	}

	load(a.getName(), &q)
	return q.Questions
}

func (a ChatAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsCommand() {
		return q.First()
	}
	next, save := q.next(a.session.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a ChatAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
	return
}

type ReviewAction struct {
	*session
	q struct {
		Questions `json:"QandA"`
	}
}

func (a ReviewAction) getName() string {
	return review_action
}
func (a ReviewAction) getHint() string {
	return review_action_hint
}
func (a ReviewAction) firstUp() Action {
	log.Println("doFirsting review ...")
	n := a.session.getNotes()

	saidTxt := fmt.Sprintf("%s you said: \n\n %s", a.session.getSentUsername(), n.FilterOnTag(said_tag).ToString())
	a.session.send(saidTxt)
	talkedTxt := fmt.Sprintf("%s we talked about: \n\n %s", a.session.getSentUsername(), n.FilterOnTag(chat_tag).ToString())
	a.session.send(talkedTxt)
	return a
}

func (a ReviewAction) getQuestions() Questions {

	var q struct {
		Questions `json:"QandA"`
	}

	load(a.getName(), &q)

	return q.Questions
}

func (a ReviewAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsCommand() {
		return q.First()
	}
	next, save := q.next(a.session.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a ReviewAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
	return
}

type StickerChatAction struct {
	*session
	stickers Stickers
}

func (a StickerChatAction) getName() string {
	return chat_action
}
func (a StickerChatAction) getHint() string {
	return ""
}

func (a StickerChatAction) firstUp() Action {
	a.stickers = LoadKnownStickers()
	return a
}

func (a StickerChatAction) getQuestions() Questions {
	var q struct {
		Questions `json:"QandA"`
	}
	load(a.getName(), &q)
	return q.Questions
}

func (a StickerChatAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsSticker() {

		sticker := a.stickers.FindSticker(a.session.getSentStickerId())
		a.session.setSentMsgText(sticker.Meaning)
		next, save := q.nextFrom(sticker.Ids...)
		if save {
			a.session.save(a.getName(), next.RelatesTo.SaveTag)
		}
		return next
	}
	next, save := q.next(a.session.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a StickerChatAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
	return
}
<commit_msg>only deal with what we know<commit_after>package lib

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
)

type Action interface {
	getName() string
	getHint() string
	firstUp() Action
	getQuestions() Questions
	nextQuestion() *Question
	askQuestion()
}

const (
	start_action, help_action = "/start", "/help"

	say_action      = "/say"
	say_action_hint = "/say <message>"

	ask_action      = "/ask"
	ask_action_hint = "/ask <message>"

	chat_action = "/chat"

	review_action      = "/review"
	review_action_hint = "/review <days>"

	default_script = "default"
)

func NewAction(s *session, actionName string) Action {

	if s != nil {
		s.User = s.getSender()
	}

	cmd := actionName

	if s.sentAsCommand() {
		cmd = s.getSentCommand()
	}

	log.Println("incoming sticker?", s.sentAsSticker())
	log.Println("cmd", cmd)
	log.Println("txt", s.getIncoming().msg.Text)
	log.Println("sticker", s.getIncoming().msg.Sticker.FileID)

	if cmd == say_action {
		return SayAction{session: s}
	} else if cmd == ask_action {
		return AskAction{session: s}
	} else if cmd == review_action {
		return &ReviewAction{session: s}
	} else if cmd == chat_action {
		return &ChatAction{session: s}
	} else if s.sentAsSticker() {
		return &StickerChatAction{session: s}
	} else if cmd == help_action || cmd == start_action {
		return &HelpAction{session: s}
	}
	return nil
}

func load(name string, q interface{}) {

	if strings.Contains(name, "/") {
		name = strings.Split(name, "/")[1]
	}

	absPath, _ := filepath.Abs(fmt.Sprintf("config/%s.json", name))
	file, err := os.Open(absPath)

	if err != nil {
		absPath, _ = filepath.Abs(fmt.Sprintf("lib/config/%s.json", name))
		log.Println("QandA path ", absPath)

		file, err = os.Open(absPath)
	}

	err = json.NewDecoder(file).Decode(&q)
	if err != nil {
		log.Panic("could not decode QandA ", err.Error())
	}

	return
}

type SayAction struct {
	*session
}

func (a SayAction) getName() string {
	return say_action
}
func (a SayAction) getHint() string {
	return say_action_hint
}
func (a SayAction) firstUp() Action {
	if a.sentAsSubmission() {
		a.session.save()
	}
	return a
}

func (a SayAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsCommand() {
		return q.First()
	}

	next, save := q.next(a.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a SayAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
}

func (a SayAction) getQuestions() Questions {

	var q struct {
		Questions `json:"QandA"`
	}
	load(a.getName(), &q)
	return q.Questions
}

type AskAction struct {
	*session
}

func (a AskAction) getName() string {
	return ask_action
}
func (a AskAction) getHint() string {
	return ask_action_hint
}
func (a AskAction) firstUp() Action {
	if a.sentAsSubmission() {
		a.session.save(help_tag)
	}
	return a
}

func (a AskAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsCommand() {
		return q.First()
	}

	next, save := q.next(a.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a AskAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
}

func (a AskAction) getQuestions() Questions {

	var q struct {
		Questions `json:"QandA"`
	}
	load(a.getName(), &q)
	return q.Questions
}

type HelpAction struct {
	*session
	q struct {
		Questions `json:"QandA"`
	}
}

func (a HelpAction) getName() string {
	return say_action
}
func (a HelpAction) getHint() string {
	return say_action_hint
}
func (a HelpAction) firstUp() Action {
	log.Println("help first up")
	helpInfo := fmt.Sprintf("%s %s %s %s %s ",
		fmt.Sprintf("Hey %s! We can't do it all but we can:\n\n", a.session.getSentUsername()),
		chat_action+" - to have a *quick chat* about what your up-to \n\n",
		say_action_hint+" - to say *anything* thats on your mind \n\n",
		//TODO: ask_action_hint+" - to ask *anything* thats on your mind \n\n",
		review_action_hint+" - to review what has been happening \n\n",
		"Stickers - we have those to help express yourself!! \n\n [Get them here](https://telegram.me/addstickers/betes)",
	)
	a.session.send(helpInfo)
	return a
}

func (a HelpAction) nextQuestion() *Question {
	return nil
}

func (a HelpAction) getQuestions() Questions {
	return nil
}

func (a HelpAction) askQuestion() {
	return
}

type ChatAction struct {
	*session
}

func (a ChatAction) getName() string {
	return chat_action
}
func (a ChatAction) getHint() string {
	return ""
}
func (a ChatAction) firstUp() Action {
	//nothing to doFirst
	return a
}

func (a ChatAction) getQuestions() Questions {

	var q struct {
		Questions `json:"QandA"`
	}

	load(a.getName(), &q)
	return q.Questions
}

func (a ChatAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsCommand() {
		return q.First()
	}
	next, save := q.next(a.session.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a ChatAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
	return
}

type ReviewAction struct {
	*session
	q struct {
		Questions `json:"QandA"`
	}
}

func (a ReviewAction) getName() string {
	return review_action
}
func (a ReviewAction) getHint() string {
	return review_action_hint
}
func (a ReviewAction) firstUp() Action {
	log.Println("doFirsting review ...")
	n := a.session.getNotes()

	saidTxt := fmt.Sprintf("%s you said: \n\n %s", a.session.getSentUsername(), n.FilterOnTag(said_tag).ToString())
	a.session.send(saidTxt)
	talkedTxt := fmt.Sprintf("%s we talked about: \n\n %s", a.session.getSentUsername(), n.FilterOnTag(chat_tag).ToString())
	a.session.send(talkedTxt)
	return a
}

func (a ReviewAction) getQuestions() Questions {

	var q struct {
		Questions `json:"QandA"`
	}

	load(a.getName(), &q)

	return q.Questions
}

func (a ReviewAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsCommand() {
		return q.First()
	}
	next, save := q.next(a.session.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a ReviewAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
	return
}

type StickerChatAction struct {
	*session
	stickers Stickers
}

func (a StickerChatAction) getName() string {
	return chat_action
}
func (a StickerChatAction) getHint() string {
	return ""
}

func (a StickerChatAction) firstUp() Action {
	a.stickers = LoadKnownStickers()
	return a
}

func (a StickerChatAction) getQuestions() Questions {
	var q struct {
		Questions `json:"QandA"`
	}
	load(a.getName(), &q)
	return q.Questions
}

func (a StickerChatAction) nextQuestion() *Question {

	q := a.getQuestions()

	if a.session.sentAsSticker() {

		sticker := a.stickers.FindSticker(a.session.getSentStickerId())
		a.session.setSentMsgText(sticker.Meaning)
		next, save := q.nextFrom(sticker.Ids...)
		if save {
			a.session.save(a.getName(), next.RelatesTo.SaveTag)
		}
		return next
	}
	next, save := q.next(a.session.getSentMsgText())
	if save {
		a.session.save(a.getName(), next.RelatesTo.SaveTag)
	}
	return next
}

func (a StickerChatAction) askQuestion() {
	if q := a.nextQuestion(); q != nil {
		a.session.send(q.Context...)
		a.session.sendWithKeyboard(q.QuestionText, q.makeKeyboard())
	}
	return
}
<|endoftext|>


<commit_before>package medtronic

const (
	LastHistoryPage Command = 0x9D
	HistoryPage     Command = 0x80
)

func (pump *Pump) LastHistoryPage() int {
	data := pump.Execute(LastHistoryPage)
	if pump.Error() != nil {
		return 0
	}
	if len(data) < 5 || data[0] != 4 {
		pump.BadResponse(LastHistoryPage, data)
		return 0
	}
	page := fourByteInt(data[1:5])
	if page < 0 || page > 36 {
		page = 36
	}
	return page
}

func (pump *Pump) HistoryPage(page int) []byte {
	return pump.Download(HistoryPage, page)
}
<commit_msg>Use unsigned history page number<commit_after>package medtronic

const (
	LastHistoryPage Command = 0x9D
	HistoryPage     Command = 0x80
)

func (pump *Pump) LastHistoryPage() int {
	data := pump.Execute(LastHistoryPage)
	if pump.Error() != nil {
		return 0
	}
	if len(data) < 5 || data[0] != 4 {
		pump.BadResponse(LastHistoryPage, data)
		return 0
	}
	page := fourByteUint(data[1:5])
	if page > 35 {
		page = 35
	}
	return int(page)
}

func (pump *Pump) HistoryPage(page int) []byte {
	return pump.Download(HistoryPage, page)
}
<|endoftext|>


<commit_before>package vegeta

import (
	"strconv"
	"time"

	"github.com/influxdata/tdigest"
)

// Metrics holds metrics computed out of a slice of Results which are used
// in some of the Reporters
type Metrics struct {
	// Latencies holds computed request latency metrics.
	Latencies LatencyMetrics `json:"latencies"`
	// BytesIn holds computed incoming byte metrics.
	BytesIn ByteMetrics `json:"bytes_in"`
	// BytesOut holds computed outgoing byte metrics.
	BytesOut ByteMetrics `json:"bytes_out"`
	// First is the earliest timestamp in a Result set.
	Earliest time.Time `json:"earliest"`
	// Latest is the latest timestamp in a Result set.
	Latest time.Time `json:"latest"`
	// End is the latest timestamp in a Result set plus its latency.
	End time.Time `json:"end"`
	// Duration is the duration of the attack.
	Duration time.Duration `json:"duration"`
	// Wait is the extra time waiting for responses from targets.
	Wait time.Duration `json:"wait"`
	// Requests is the total number of requests executed.
	Requests uint64 `json:"requests"`
	// Rate is the rate of requests per second.
	Rate float64 `json:"rate"`
	// Success is the percentage of non-error responses.
	Success float64 `json:"success"`
	// StatusCodes is a histogram of the responses' status codes.
	StatusCodes map[string]int `json:"status_codes"`
	// Errors is a set of unique errors returned by the targets during the attack.
	Errors []string `json:"errors"`

	errors    map[string]struct{}
	success   uint64
	latencies estimator
}

// LatencyMetrics holds computed request latency metrics.
type LatencyMetrics struct {
	// Total is the total latency sum of all requests in an attack.
	Total time.Duration `json:"total"`
	// Mean is the mean request latency.
	Mean time.Duration `json:"mean"`
	// P50 is the 50th percentile request latency.
	P50 time.Duration `json:"50th"`
	// P95 is the 95th percentile request latency.
	P95 time.Duration `json:"95th"`
	// P99 is the 99th percentile request latency.
	P99 time.Duration `json:"99th"`
	// Max is the maximum observed request latency.
	Max time.Duration `json:"max"`
}

// ByteMetrics holds computed byte flow metrics.
type ByteMetrics struct {
	// Total is the total number of flowing bytes in an attack.
	Total uint64 `json:"total"`
	// Mean is the mean number of flowing bytes per hit.
	Mean float64 `json:"mean"`
}

// Add implements the Add method of the Report interface by adding the given
// Result to Metrics.
func (m *Metrics) Add(r *Result) {
	m.init()

	m.Requests++
	m.StatusCodes[strconv.Itoa(int(r.Code))]++
	m.Latencies.Total += r.Latency
	m.BytesOut.Total += r.BytesOut
	m.BytesIn.Total += r.BytesIn

	m.latencies.Add(float64(r.Latency))

	if m.Earliest.IsZero() || m.Earliest.After(r.Timestamp) {
		m.Earliest = r.Timestamp
	}

	if r.Timestamp.After(m.Latest) {
		m.Latest = r.Timestamp
	}

	if end := r.End(); end.After(m.End) {
		m.End = end
	}

	if r.Latency > m.Latencies.Max {
		m.Latencies.Max = r.Latency
	}

	if r.Code >= 200 && r.Code < 400 {
		m.success++
	}

	if r.Error != "" {
		if _, ok := m.errors[r.Error]; !ok {
			m.errors[r.Error] = struct{}{}
			m.Errors = append(m.Errors, r.Error)
		}
	}
}

// Close implements the Close method of the Report interface by computing
// derived summary metrics which don't need to be run on every Add call.
func (m *Metrics) Close() {
	m.init()
	m.Rate = float64(m.Requests)
	m.Duration = m.Latest.Sub(m.Earliest)
	if secs := m.Duration.Seconds(); secs > 0 {
		m.Rate /= secs
	}
	m.Wait = m.End.Sub(m.Latest)
	m.BytesIn.Mean = float64(m.BytesIn.Total) / float64(m.Requests)
	m.BytesOut.Mean = float64(m.BytesOut.Total) / float64(m.Requests)
	m.Success = float64(m.success) / float64(m.Requests)
	m.Latencies.Mean = time.Duration(float64(m.Latencies.Total) / float64(m.Requests))
	m.Latencies.P50 = time.Duration(m.latencies.Get(0.50))
	m.Latencies.P95 = time.Duration(m.latencies.Get(0.95))
	m.Latencies.P99 = time.Duration(m.latencies.Get(0.99))
}

func (m *Metrics) init() {
	if m.StatusCodes == nil {
		m.StatusCodes = map[string]int{}
	}

	if m.errors == nil {
		m.errors = map[string]struct{}{}
	}

	if m.latencies == nil {
		m.latencies = newTdigestEstimator(100)
	}

	if m.Errors == nil {
		m.Errors = make([]string, 0)
	}
}

type estimator interface {
	Add(sample float64)
	Get(quantile float64) float64
}

type tdigestEstimator struct{ *tdigest.TDigest }

func newTdigestEstimator(compression float64) *tdigestEstimator {
	return &tdigestEstimator{tdigest.NewWithCompression(compression)}
}

func (e *tdigestEstimator) Add(s float64) { e.TDigest.Add(s, 1) }
func (e *tdigestEstimator) Get(q float64) float64 {
	return e.TDigest.Quantile(q)
}
<commit_msg>metrics: Explain choice of TDigest compression parameter<commit_after>package vegeta

import (
	"strconv"
	"time"

	"github.com/influxdata/tdigest"
)

// Metrics holds metrics computed out of a slice of Results which are used
// in some of the Reporters
type Metrics struct {
	// Latencies holds computed request latency metrics.
	Latencies LatencyMetrics `json:"latencies"`
	// BytesIn holds computed incoming byte metrics.
	BytesIn ByteMetrics `json:"bytes_in"`
	// BytesOut holds computed outgoing byte metrics.
	BytesOut ByteMetrics `json:"bytes_out"`
	// First is the earliest timestamp in a Result set.
	Earliest time.Time `json:"earliest"`
	// Latest is the latest timestamp in a Result set.
	Latest time.Time `json:"latest"`
	// End is the latest timestamp in a Result set plus its latency.
	End time.Time `json:"end"`
	// Duration is the duration of the attack.
	Duration time.Duration `json:"duration"`
	// Wait is the extra time waiting for responses from targets.
	Wait time.Duration `json:"wait"`
	// Requests is the total number of requests executed.
	Requests uint64 `json:"requests"`
	// Rate is the rate of requests per second.
	Rate float64 `json:"rate"`
	// Success is the percentage of non-error responses.
	Success float64 `json:"success"`
	// StatusCodes is a histogram of the responses' status codes.
	StatusCodes map[string]int `json:"status_codes"`
	// Errors is a set of unique errors returned by the targets during the attack.
	Errors []string `json:"errors"`

	errors    map[string]struct{}
	success   uint64
	latencies estimator
}

// LatencyMetrics holds computed request latency metrics.
type LatencyMetrics struct {
	// Total is the total latency sum of all requests in an attack.
	Total time.Duration `json:"total"`
	// Mean is the mean request latency.
	Mean time.Duration `json:"mean"`
	// P50 is the 50th percentile request latency.
	P50 time.Duration `json:"50th"`
	// P95 is the 95th percentile request latency.
	P95 time.Duration `json:"95th"`
	// P99 is the 99th percentile request latency.
	P99 time.Duration `json:"99th"`
	// Max is the maximum observed request latency.
	Max time.Duration `json:"max"`
}

// ByteMetrics holds computed byte flow metrics.
type ByteMetrics struct {
	// Total is the total number of flowing bytes in an attack.
	Total uint64 `json:"total"`
	// Mean is the mean number of flowing bytes per hit.
	Mean float64 `json:"mean"`
}

// Add implements the Add method of the Report interface by adding the given
// Result to Metrics.
func (m *Metrics) Add(r *Result) {
	m.init()

	m.Requests++
	m.StatusCodes[strconv.Itoa(int(r.Code))]++
	m.Latencies.Total += r.Latency
	m.BytesOut.Total += r.BytesOut
	m.BytesIn.Total += r.BytesIn

	m.latencies.Add(float64(r.Latency))

	if m.Earliest.IsZero() || m.Earliest.After(r.Timestamp) {
		m.Earliest = r.Timestamp
	}

	if r.Timestamp.After(m.Latest) {
		m.Latest = r.Timestamp
	}

	if end := r.End(); end.After(m.End) {
		m.End = end
	}

	if r.Latency > m.Latencies.Max {
		m.Latencies.Max = r.Latency
	}

	if r.Code >= 200 && r.Code < 400 {
		m.success++
	}

	if r.Error != "" {
		if _, ok := m.errors[r.Error]; !ok {
			m.errors[r.Error] = struct{}{}
			m.Errors = append(m.Errors, r.Error)
		}
	}
}

// Close implements the Close method of the Report interface by computing
// derived summary metrics which don't need to be run on every Add call.
func (m *Metrics) Close() {
	m.init()
	m.Rate = float64(m.Requests)
	m.Duration = m.Latest.Sub(m.Earliest)
	if secs := m.Duration.Seconds(); secs > 0 {
		m.Rate /= secs
	}
	m.Wait = m.End.Sub(m.Latest)
	m.BytesIn.Mean = float64(m.BytesIn.Total) / float64(m.Requests)
	m.BytesOut.Mean = float64(m.BytesOut.Total) / float64(m.Requests)
	m.Success = float64(m.success) / float64(m.Requests)
	m.Latencies.Mean = time.Duration(float64(m.Latencies.Total) / float64(m.Requests))
	m.Latencies.P50 = time.Duration(m.latencies.Get(0.50))
	m.Latencies.P95 = time.Duration(m.latencies.Get(0.95))
	m.Latencies.P99 = time.Duration(m.latencies.Get(0.99))
}

func (m *Metrics) init() {
	if m.StatusCodes == nil {
		m.StatusCodes = map[string]int{}
	}

	if m.errors == nil {
		m.errors = map[string]struct{}{}
	}

	if m.latencies == nil {
		// This compression parameter value is the recommended value
		// for normal uses as per http://javadox.com/com.tdunning/t-digest/3.0/com/tdunning/math/stats/TDigest.html
		m.latencies = newTdigestEstimator(100)
	}

	if m.Errors == nil {
		m.Errors = make([]string, 0)
	}
}

type estimator interface {
	Add(sample float64)
	Get(quantile float64) float64
}

type tdigestEstimator struct{ *tdigest.TDigest }

func newTdigestEstimator(compression float64) *tdigestEstimator {
	return &tdigestEstimator{tdigest.NewWithCompression(compression)}
}

func (e *tdigestEstimator) Add(s float64) { e.TDigest.Add(s, 1) }
func (e *tdigestEstimator) Get(q float64) float64 {
	return e.TDigest.Quantile(q)
}
<|endoftext|>


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

package docker2aci

import "github.com/appc/spec/schema"

var Version = "0.11.1"
var AppcVersion = schema.AppContainerVersion
<commit_msg>version: bump to v0.11.1+git<commit_after>// Copyright 2016 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package docker2aci

import "github.com/appc/spec/schema"

var Version = "0.11.1+git"
var AppcVersion = schema.AppContainerVersion
<|endoftext|>


<commit_before>package gostatic

const (
	VERSION = "2.2"
)
<commit_msg>Version up to 2.3<commit_after>package gostatic

const (
	VERSION = "2.3"
)
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"

	"github.com/Zac-Garby/pluto/bytecode"
	"github.com/Zac-Garby/pluto/compiler"
	"github.com/Zac-Garby/pluto/object"
	"github.com/Zac-Garby/pluto/parser"
	"github.com/Zac-Garby/pluto/vm"
)

func main() {
	store := vm.NewStore()

	for {
		reader := bufio.NewReader(os.Stdin)
		fmt.Print(">> ")
		text, _ := reader.ReadString('\n')
		text = strings.TrimRight(text, "\n")

		if obj, err := execute(text, store); err != nil {
			fmt.Println("   ", err)
		} else if obj != nil {
			fmt.Println("   ", obj)
		}
	}
}

func execute(text string, store *vm.Store) (object.Object, error) {
	var (
		cmp   = compiler.New()
		parse = parser.New(text)
		prog  = parse.Parse()
	)

	if len(parse.Errors) > 0 {
		parse.PrintErrors()
		os.Exit(1)
	}

	err := cmp.CompileProgram(prog)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	code, err := bytecode.Read(cmp.Bytes)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	store.Names = cmp.Names
	store.Functions.Functions = cmp.Functions
	store.Patterns = cmp.Patterns

	machine := vm.New()
	machine.Run(code, store, cmp.Constants)

	if machine.Error != nil {
		return nil, machine.Error
	}

	return machine.ExtractValue(), nil
}
<commit_msg>Colour REPL output<commit_after>package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"

	"github.com/Zac-Garby/pluto/bytecode"
	"github.com/Zac-Garby/pluto/compiler"
	"github.com/Zac-Garby/pluto/object"
	"github.com/Zac-Garby/pluto/parser"
	"github.com/Zac-Garby/pluto/vm"

	"github.com/fatih/color"
)

func main() {
	store := vm.NewStore()

	for {
		reader := bufio.NewReader(os.Stdin)
		fmt.Print(">> ")
		text, _ := reader.ReadString('\n')
		text = strings.TrimRight(text, "\n")

		if obj, err := execute(text, store); err != nil {
			color.Red("  %s", err)
		} else if obj != nil {
			color.Cyan("  %s", obj)
		}
	}
}

func execute(text string, store *vm.Store) (object.Object, error) {
	var (
		cmp   = compiler.New()
		parse = parser.New(text)
		prog  = parse.Parse()
	)

	if len(parse.Errors) > 0 {
		parse.PrintErrors()
		os.Exit(1)
	}

	err := cmp.CompileProgram(prog)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	code, err := bytecode.Read(cmp.Bytes)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	store.Names = cmp.Names
	store.Functions.Functions = cmp.Functions
	store.Patterns = cmp.Patterns

	machine := vm.New()
	machine.Run(code, store, cmp.Constants)

	if machine.Error != nil {
		return nil, machine.Error
	}

	return machine.ExtractValue(), nil
}
<|endoftext|>


<commit_before>package libstns

import (
	"fmt"
	"log"
	"sort"
	"strconv"

	"github.com/STNS/STNS/stns"
	"github.com/STNS/libnss_stns/cache"
)

// http://www.gnu.org/software/libc/manual/html_node/NSS-Modules-Interface.html
const (
	NSS_STATUS_SUCCESS  = 1
	NSS_STATUS_NOTFOUND = 0
	NSS_STATUS_UNAVAIL  = -1
	NSS_STATUS_TRYGAIN  = -2
)

const (
	NSS_LIST_PRESET = 0
	NSS_LIST_PURGE  = 1
)

type SetNss func(stns.Attributes, interface{}, interface{}) int

type Nss struct {
	config  *Config
	request *Request
	rtype   string
	column  string
	value   string
}

func NewNss(r, c, v string) (*Nss, error) {
	config, err := LoadConfig("/etc/stns/libnss_stns.conf")
	if err != nil {
		return nil, err
	}

	req, err := NewRequest(config, r, c, v)
	if err != nil {
		return nil, err
	}

	return &Nss{
		config:  config,
		request: req,
		rtype:   r,
		column:  c,
		value:   v,
	}, nil
}
func (n *Nss) Get() (stns.Attributes, error) {
	u, err := cache.Read(n.request.ApiPath)
	if u != nil || err != nil {
		return u, err
	}

	res, err := n.request.GetByWrapperCmd()

	if err != nil {
		return nil, err
	}

	if n.column == "id" {
		cache.WriteMinId(n.rtype, res.MetaData.MinId)
	}

	if res.Items == nil {
		return nil, fmt.Errorf("resource notfound %s/%s/%s", n.rtype, n.column, n.value)
	}

	cache.Write(n.request.ApiPath, *res.Items, nil)
	return *res.Items, nil
}

func (n *Nss) Set(s SetNss, entry, presult interface{}) int {
	id, _ := strconv.Atoi(n.column)
	if n.column != "id" || (n.column == "id" && cache.ReadMinId(n.rtype) <= id) {
		resource, err := n.Get()
		if err != nil {
			log.Print(err)
			return NSS_STATUS_UNAVAIL
		}

		if len(resource) > 0 {
			return s(resource, entry, presult)
		}
	}
	return NSS_STATUS_NOTFOUND
}

func (n *Nss) SetByList(s SetNss, entry, presult interface{}, list stns.Attributes, position *int) int {
	keys := n.keys(list)
L:
	if len(keys) > *position && keys[*position] != "" {
		name := keys[*position]
		resource := stns.Attributes{
			name: list[name],
		}

		*position++
		result := s(resource, entry, presult)

		// lack of data
		if result == NSS_STATUS_NOTFOUND {
			goto L
		}

		return result
	}
	return NSS_STATUS_NOTFOUND
}

func (n *Nss) PresetList(list stns.Attributes, position *int) int {
	var attr stns.Attributes
	var err error
	// reset value
	n.PurgeList(list, position)

	attr, err = n.Get()

	if err != nil {
		log.Print(err)
		// When the error refers to the last result.
		// This is supposed to when the server is restarted
		attr = *cache.LastResultList(n.rtype)
		if attr != nil {
			goto C
		}
		return NSS_STATUS_UNAVAIL
	}
	cache.SaveResultList(n.rtype, attr)
C:
	if len(attr) > 0 {
		for k, v := range attr {
			list[k] = v
		}
		return NSS_STATUS_SUCCESS
	}
	return NSS_STATUS_NOTFOUND
}

func (n *Nss) PurgeList(list stns.Attributes, position *int) {
	*position = 0
	for k, _ := range list {
		delete(list, k)
	}
}

func (n *Nss) keys(list stns.Attributes) []string {
	ks := []string{}
	for k, _ := range list {
		ks = append(ks, k)

	}
	sort.Strings(ks)
	return ks
}
<commit_msg>returns immediately value<commit_after>package libstns

import (
	"fmt"
	"log"
	"sort"
	"strconv"

	"github.com/STNS/STNS/stns"
	"github.com/STNS/libnss_stns/cache"
)

// http://www.gnu.org/software/libc/manual/html_node/NSS-Modules-Interface.html
const (
	NSS_STATUS_SUCCESS  = 1
	NSS_STATUS_NOTFOUND = 0
	NSS_STATUS_UNAVAIL  = -1
	NSS_STATUS_TRYGAIN  = -2
)

const (
	NSS_LIST_PRESET = 0
	NSS_LIST_PURGE  = 1
)

type SetNss func(stns.Attributes, interface{}, interface{}) int

type Nss struct {
	config  *Config
	request *Request
	rtype   string
	column  string
	value   string
}

func NewNss(r, c, v string) (*Nss, error) {
	config, err := LoadConfig("/etc/stns/libnss_stns.conf")
	if err != nil {
		return nil, err
	}

	req, err := NewRequest(config, r, c, v)
	if err != nil {
		return nil, err
	}

	return &Nss{
		config:  config,
		request: req,
		rtype:   r,
		column:  c,
		value:   v,
	}, nil
}
func (n *Nss) Get() (stns.Attributes, error) {
	u, err := cache.Read(n.request.ApiPath)
	if u != nil || err != nil {
		return u, err
	}

	res, err := n.request.GetByWrapperCmd()

	if err != nil {
		return nil, err
	}

	if n.column == "id" {
		cache.WriteMinId(n.rtype, res.MetaData.MinId)
	}

	if res.Items == nil {
		return nil, fmt.Errorf("resource notfound %s/%s/%s", n.rtype, n.column, n.value)
	}

	cache.Write(n.request.ApiPath, *res.Items, nil)
	return *res.Items, nil
}

func (n *Nss) Set(s SetNss, entry, presult interface{}) int {
	id, _ := strconv.Atoi(n.column)
	if n.column != "id" || (n.column == "id" && cache.ReadMinId(n.rtype) <= id) {
		resource, err := n.Get()
		if err != nil {
			log.Print(err)
			return NSS_STATUS_UNAVAIL
		}

		if len(resource) > 0 {
			return s(resource, entry, presult)
		}
	}
	return NSS_STATUS_NOTFOUND
}

func (n *Nss) SetByList(s SetNss, entry, presult interface{}, list stns.Attributes, position *int) int {
	keys := n.keys(list)

	if len(keys) > *position && keys[*position] != "" {
		name := keys[*position]
		resource := stns.Attributes{
			name: list[name],
		}

		*position++
		result := s(resource, entry, presult)

		if result == NSS_STATUS_NOTFOUND {
			return NSS_STATUS_NOTFOUND
		}

		return result
	}
	return NSS_STATUS_NOTFOUND
}

func (n *Nss) PresetList(list stns.Attributes, position *int) int {
	var attr stns.Attributes
	var err error
	// reset value
	n.PurgeList(list, position)

	attr, err = n.Get()

	if err != nil {
		log.Print(err)
		// When the error refers to the last result.
		// This is supposed to when the server is restarted
		attr = *cache.LastResultList(n.rtype)
		if attr != nil {
			goto C
		}
		return NSS_STATUS_UNAVAIL
	}
	cache.SaveResultList(n.rtype, attr)
C:
	if len(attr) > 0 {
		for k, v := range attr {
			list[k] = v
		}
		return NSS_STATUS_SUCCESS
	}
	return NSS_STATUS_NOTFOUND
}

func (n *Nss) PurgeList(list stns.Attributes, position *int) {
	*position = 0
	for k, _ := range list {
		delete(list, k)
	}
}

func (n *Nss) keys(list stns.Attributes) []string {
	ks := []string{}
	for k, _ := range list {
		ks = append(ks, k)

	}
	sort.Strings(ks)
	return ks
}
<|endoftext|>


<commit_before>package modelhelper

import (
	"errors"
	"koding/db/models"

	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type Bongo struct {
	ConstructorName string `json:"constructorName"`
	InstanceId      string `json:"instanceId"`
}

type MachineContainer struct {
	Bongo Bongo           `json:"bongo_"`
	Data  *models.Machine `json:"data"`
	*models.Machine
}

var (
	MachineColl            = "jMachines"
	MachineConstructorName = "JMachine"
)

func GetMachines(userId bson.ObjectId) ([]*MachineContainer, error) {
	machines := []*models.Machine{}

	query := func(c *mgo.Collection) error {
		return c.Find(bson.M{"users.id": userId}).All(&machines)
	}

	err := Mongo.Run(MachineColl, query)
	if err != nil {
		return nil, err
	}

	containers := []*MachineContainer{}

	for _, machine := range machines {
		bongo := Bongo{
			ConstructorName: MachineConstructorName,
			InstanceId:      "1", // TODO: what should go here?
		}
		container := &MachineContainer{bongo, machine, machine}

		containers = append(containers, container)
	}

	return containers, nil
}

var (
	MachineStateRunning = "Running"
)

func GetRunningVms() ([]models.Machine, error) {
	machines := []models.Machine{}

	query := func(c *mgo.Collection) error {
		iter := c.Find(bson.M{"status.state": MachineStateRunning}).Iter()

		var machine models.Machine
		for iter.Next(&machine) {
			machines = append(machines, machine)
		}

		return nil
	}

	err := Mongo.Run(MachineColl, query)
	if err != nil {
		return nil, err
	}

	return machines, nil
}

// GetMachineByUid returns the machine by its uid field
func GetMachineByUid(uid string) (*models.Machine, error) {
	machine := &models.Machine{}

	query := func(c *mgo.Collection) error {
		return c.Find(bson.M{"uid": uid}).One(machine)
	}

	err := Mongo.Run(MachineColl, query)
	if err != nil {
		return nil, err
	}

	return machine, nil
}

// UnshareMachineByUid unshares the machine from all other users except the
// owner
func UnshareMachineByUid(uid string) error {
	machine, err := GetMachineByUid(uid)
	if err != nil {
		return err
	}

	owner := make([]models.MachineUser, 1)
	for _, user := range machine.Users {
		// this is the correct way to remove all users but the owner from a
		// machine
		if user.Sudo && user.Owner {
			owner[0] = user
			break
		}
	}

	if len(owner) == 0 {
		return errors.New("owner couldnt found")
	}

	s := Selector{"_id": machine.ObjectId}
	o := Selector{"$set": Selector{
		"users": owner,
	}}

	query := func(c *mgo.Collection) error {
		return c.Update(s, o)
	}

	return Mongo.Run(MachineColl, query)
}

func GetMachinesByUsername(username string) ([]*models.Machine, error) {
	user, err := GetUser(username)
	if err != nil {
		return nil, err
	}

	machines := []*models.Machine{}

	query := func(c *mgo.Collection) error {
		return c.Find(
			bson.M{"provider": "koding", "users.id": user.ObjectId, "users.sudo": true},
		).All(&machines)
	}

	err = Mongo.Run(MachineColl, query)
	if err != nil {
		return nil, err
	}

	return machines, nil
}

func CreateMachine(m *models.Machine) error {
	query := func(c *mgo.Collection) error {
		return c.Insert(m)
	}

	return Mongo.Run(MachineColl, query)
}

// DeleteMachine deletes the machine from mongodb, it is here just for cleaning
// purposes(after tests), machines should not be removed from database  unless
// you are kloud
func DeleteMachine(id bson.ObjectId) error {
	selector := bson.M{"_id": id}

	query := func(c *mgo.Collection) error {
		return c.Remove(selector)
	}

	return Mongo.Run(MachineColl, query)
}

func UpdateMachineAlwaysOn(machineId bson.ObjectId, alwaysOn bool) error {
	query := func(c *mgo.Collection) error {
		return c.Update(
			bson.M{"_id": machineId},
			bson.M{"$set": bson.M{"meta.alwaysOn": alwaysOn}},
		)
	}

	return Mongo.Run(MachineColl, query)
}
<commit_msg>Go: use the helper function for finding the owner<commit_after>package modelhelper

import (
	"errors"
	"koding/db/models"

	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type Bongo struct {
	ConstructorName string `json:"constructorName"`
	InstanceId      string `json:"instanceId"`
}

type MachineContainer struct {
	Bongo Bongo           `json:"bongo_"`
	Data  *models.Machine `json:"data"`
	*models.Machine
}

var (
	MachineColl            = "jMachines"
	MachineConstructorName = "JMachine"
)

func GetMachines(userId bson.ObjectId) ([]*MachineContainer, error) {
	machines := []*models.Machine{}

	query := func(c *mgo.Collection) error {
		return c.Find(bson.M{"users.id": userId}).All(&machines)
	}

	err := Mongo.Run(MachineColl, query)
	if err != nil {
		return nil, err
	}

	containers := []*MachineContainer{}

	for _, machine := range machines {
		bongo := Bongo{
			ConstructorName: MachineConstructorName,
			InstanceId:      "1", // TODO: what should go here?
		}
		container := &MachineContainer{bongo, machine, machine}

		containers = append(containers, container)
	}

	return containers, nil
}

var (
	MachineStateRunning = "Running"
)

func GetRunningVms() ([]models.Machine, error) {
	machines := []models.Machine{}

	query := func(c *mgo.Collection) error {
		iter := c.Find(bson.M{"status.state": MachineStateRunning}).Iter()

		var machine models.Machine
		for iter.Next(&machine) {
			machines = append(machines, machine)
		}

		return nil
	}

	err := Mongo.Run(MachineColl, query)
	if err != nil {
		return nil, err
	}

	return machines, nil
}

// GetMachineByUid returns the machine by its uid field
func GetMachineByUid(uid string) (*models.Machine, error) {
	machine := &models.Machine{}

	query := func(c *mgo.Collection) error {
		return c.Find(bson.M{"uid": uid}).One(machine)
	}

	err := Mongo.Run(MachineColl, query)
	if err != nil {
		return nil, err
	}

	return machine, nil
}

// UnshareMachineByUid unshares the machine from all other users except the
// owner
func UnshareMachineByUid(uid string) error {
	machine, err := GetMachineByUid(uid)
	if err != nil {
		return err
	}

	machineOwner := machine.Owner()
	if machineOwner == nil {
		return errors.New("owner couldnt found")
	}

	owner := []models.MachineUser{*machineOwner}

	s := Selector{"_id": machine.ObjectId}
	o := Selector{"$set": Selector{
		"users": owner,
	}}

	query := func(c *mgo.Collection) error {
		return c.Update(s, o)
	}

	return Mongo.Run(MachineColl, query)
}

func GetMachinesByUsername(username string) ([]*models.Machine, error) {
	user, err := GetUser(username)
	if err != nil {
		return nil, err
	}

	machines := []*models.Machine{}

	query := func(c *mgo.Collection) error {
		return c.Find(
			bson.M{"provider": "koding", "users.id": user.ObjectId, "users.sudo": true},
		).All(&machines)
	}

	err = Mongo.Run(MachineColl, query)
	if err != nil {
		return nil, err
	}

	return machines, nil
}

func CreateMachine(m *models.Machine) error {
	query := func(c *mgo.Collection) error {
		return c.Insert(m)
	}

	return Mongo.Run(MachineColl, query)
}

// DeleteMachine deletes the machine from mongodb, it is here just for cleaning
// purposes(after tests), machines should not be removed from database  unless
// you are kloud
func DeleteMachine(id bson.ObjectId) error {
	selector := bson.M{"_id": id}

	query := func(c *mgo.Collection) error {
		return c.Remove(selector)
	}

	return Mongo.Run(MachineColl, query)
}

func UpdateMachineAlwaysOn(machineId bson.ObjectId, alwaysOn bool) error {
	query := func(c *mgo.Collection) error {
		return c.Update(
			bson.M{"_id": machineId},
			bson.M{"$set": bson.M{"meta.alwaysOn": alwaysOn}},
		)
	}

	return Mongo.Run(MachineColl, query)
}
<|endoftext|>


<commit_before>// Package terminal provides a tty emulation and session handlings that is
// supported via Screen
package terminal

import (
	"bytes"
	"errors"
	"fmt"
	"koding/tools/pty"
	"os"
	"os/exec"
	"os/user"
	"sync"
	"syscall"
	"time"
	"unicode/utf8"

	"github.com/koding/kite"
)

type Terminal struct {
	InputHook func()
	Log       kite.Logger

	Users      map[string]*User
	sync.Mutex // protects Users
}

func New(log kite.Logger) *Terminal {
	return &Terminal{
		Users: make(map[string]*User),
		Log:   log,
	}
}

// AddUserSession adds the given username and session
func (t *Terminal) AddUserSession(username, session string, server *Server) {
	t.Lock()
	defer t.Unlock()

	// check if it's exists, if not go and lazy initialize a new user instance
	var user *User
	var ok bool
	user, ok = t.Users[username]
	if !ok {
		user = NewUser(username)
	}

	user.AddSession(session, server)
	t.Users[username] = user
}

// DeleteUserSession deletes the given session from the Users map
func (t *Terminal) DeleteUserSession(username, session string) {
	t.Lock()
	defer t.Unlock()

	user := t.Users[username]
	user.DeleteSession(session)

	if len(user.Sessions) == 0 {
		delete(t.Users, username)
	}
}

// KillSession kills the given screen session
func (t *Terminal) KillSession(r *kite.Request) (interface{}, error) {
	var params struct {
		Session string
	}

	if r.Args.One().Unmarshal(&params) != nil {
		return nil, errors.New("{ session: [string] }")
	}

	if params.Session == "" {
		return nil, errors.New("session is empty")
	}

	if err := killSession(params.Session); err != nil {
		return nil, err
	}

	t.DeleteUserSession(r.Username, params.Session)

	return true, nil
}

// KillSessions kills all available screen sessions
func (t *Terminal) KillSessions(r *kite.Request) (interface{}, error) {
	if err := killSessions(r.Username); err != nil {
		return nil, err
	}

	return true, nil
}

// GetSessions return a list of curren active screen sessions
func (t *Terminal) GetSessions(r *kite.Request) (interface{}, error) {
	user, err := user.Current()
	if err != nil {
		return nil, fmt.Errorf("Could not get home dir: %s", err)
	}

	sessions := screenSessions(user.Username)
	if len(sessions) == 0 {
		return nil, errors.New("no sessions available")
	}

	return sessions, nil
}

// Connect creates and open a new TTY instance. It returns a *Server instance
// so every caller can send and receive from the connected TTY end.
func (t *Terminal) Connect(r *kite.Request) (interface{}, error) {
	var params struct {
		Remote       Remote
		Session      string
		SizeX, SizeY int
		Mode         string
	}

	if err := r.Args.One().Unmarshal(&params); err != nil {
		return nil, fmt.Errorf("{ remote: [object], session: %s, noScreen: [bool] }, err: %s",
			params.Session, err)
	}

	if params.SizeX <= 0 || params.SizeY <= 0 {
		return nil, fmt.Errorf("{ sizeX: %d, sizeY: %d } { raw JSON : %v }", params.SizeX, params.SizeY, r.Args.One())
	}

	user, err := user.Current()
	if err != nil {
		return nil, fmt.Errorf("Could not get home dir: %s", err)
	}

	command, err := newCommand(params.Mode, params.Session, user.Username)
	if err != nil {
		return nil, err
	}

	// get pty and tty descriptors
	p, err := pty.NewPTY()
	if err != nil {
		return nil, err
	}

	// We will return this object to the client.
	server := &Server{
		Session:   command.Session,
		remote:    params.Remote,
		pty:       p,
		inputHook: t.InputHook,
	}
	server.setSize(float64(params.SizeX), float64(params.SizeY))

	t.AddUserSession(r.Username, command.Session, server)

	// wrap the command with sudo -i for initiation login shell. This is needed
	// in order to have Environments and other to be initialized correctly.
	// check also if klient was started in root mode or not.
	var args []string
	if os.Geteuid() == 0 {
		args = []string{"-i", command.Name}
	} else {
		args = []string{"-i", "-u", "#" + user.Uid, "--", command.Name}
	}

	args = append(args, command.Args...)
	cmd := exec.Command("/usr/bin/sudo", args...)

	// For test use this, sudo is not going to work
	// cmd := exec.Command(command.Name, command.Args...)

	cmd.Env = []string{"TERM=xterm-256color", "HOME=" + user.HomeDir}
	cmd.Stdin = server.pty.Slave
	cmd.Stdout = server.pty.Slave
	cmd.Dir = user.HomeDir
	// cmd.Stderr = server.pty.Slave

	// Open in background, this is needed otherwise the process will be killed
	// if you hit close on the client side.
	cmd.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true}
	err = cmd.Start()
	if err != nil {
		fmt.Println("could not start", err)
	}

	// Wait until the shell process is closed and notify the client.
	go func() {
		err := cmd.Wait()
		if err != nil {
			fmt.Println("cmd.wait err", err)
		}

		server.pty.Slave.Close()
		server.pty.Master.Close()
		server.remote.SessionEnded.Call()

		t.DeleteUserSession(r.Username, command.Session)
	}()

	// Read the STDOUT from shell process and send to the connected client.
	go func() {
		buf := make([]byte, (1<<12)-utf8.UTFMax, 1<<12)
		for {
			n, err := server.pty.Master.Read(buf)
			for n < cap(buf)-1 {
				r, _ := utf8.DecodeLastRune(buf[:n])
				if r != utf8.RuneError {
					break
				}
				server.pty.Master.Read(buf[n : n+1])
				n++
			}

			// Rate limiting...
			if server.throttling {
				s := time.Now().Unix()
				if server.currentSecond != s {
					server.currentSecond = s
					server.messageCounter = 0
					server.byteCounter = 0
					server.lineFeeedCounter = 0
				}
				server.messageCounter += 1
				server.byteCounter += n
				server.lineFeeedCounter += bytes.Count(buf[:n], []byte{'\n'})
				if server.messageCounter > 100 || server.byteCounter > 1<<18 || server.lineFeeedCounter > 300 {
					time.Sleep(time.Second)
				}
			}

			server.remote.Output.Call(string(filterInvalidUTF8(buf[:n])))
			if err != nil {
				break
			}
		}
	}()

	return server, nil
}

// CloseSessions closes all active session for the given username and deletes
// it from the internal user map
func (t *Terminal) CloseSessions(username string) {
	t.Log.Info("Closing terminal sessions of user '%s'", username)

	t.Lock()
	user, ok := t.Users[username]
	t.Unlock()

	if !ok {
		return
	}

	user.CloseSessions()

	t.Lock()
	delete(t.Users, username)
	t.Unlock()
}

func filterInvalidUTF8(buf []byte) []byte {
	i := 0
	j := 0
	for {
		r, l := utf8.DecodeRune(buf[i:])
		if l == 0 {
			break
		}
		if r < 0xD800 {
			if i != j {
				copy(buf[j:], buf[i:i+l])
			}
			j += l
		}
		i += l
	}
	return buf[:j]
}
<commit_msg>terminal: check before we call something on user<commit_after>// Package terminal provides a tty emulation and session handlings that is
// supported via Screen
package terminal

import (
	"bytes"
	"errors"
	"fmt"
	"koding/tools/pty"
	"os"
	"os/exec"
	"os/user"
	"sync"
	"syscall"
	"time"
	"unicode/utf8"

	"github.com/koding/kite"
)

type Terminal struct {
	InputHook func()
	Log       kite.Logger

	Users      map[string]*User
	sync.Mutex // protects Users
}

func New(log kite.Logger) *Terminal {
	return &Terminal{
		Users: make(map[string]*User),
		Log:   log,
	}
}

// AddUserSession adds the given username and session
func (t *Terminal) AddUserSession(username, session string, server *Server) {
	t.Lock()
	defer t.Unlock()

	// check if it's exists, if not go and lazy initialize a new user instance
	var user *User
	var ok bool
	user, ok = t.Users[username]
	if !ok {
		user = NewUser(username)
	}

	user.AddSession(session, server)
	t.Users[username] = user
}

// DeleteUserSession deletes the given session from the Users map
func (t *Terminal) DeleteUserSession(username, session string) {
	t.Lock()
	defer t.Unlock()

	user, ok := t.Users[username]
	if !ok {
		return // nothing to do
	}

	user.DeleteSession(session)

	if len(user.Sessions) == 0 {
		delete(t.Users, username)
	}
}

// KillSession kills the given screen session
func (t *Terminal) KillSession(r *kite.Request) (interface{}, error) {
	var params struct {
		Session string
	}

	if r.Args.One().Unmarshal(&params) != nil {
		return nil, errors.New("{ session: [string] }")
	}

	if params.Session == "" {
		return nil, errors.New("session is empty")
	}

	if err := killSession(params.Session); err != nil {
		return nil, err
	}

	t.DeleteUserSession(r.Username, params.Session)

	return true, nil
}

// KillSessions kills all available screen sessions
func (t *Terminal) KillSessions(r *kite.Request) (interface{}, error) {
	if err := killSessions(r.Username); err != nil {
		return nil, err
	}

	return true, nil
}

// GetSessions return a list of curren active screen sessions
func (t *Terminal) GetSessions(r *kite.Request) (interface{}, error) {
	user, err := user.Current()
	if err != nil {
		return nil, fmt.Errorf("Could not get home dir: %s", err)
	}

	sessions := screenSessions(user.Username)
	if len(sessions) == 0 {
		return nil, errors.New("no sessions available")
	}

	return sessions, nil
}

// Connect creates and open a new TTY instance. It returns a *Server instance
// so every caller can send and receive from the connected TTY end.
func (t *Terminal) Connect(r *kite.Request) (interface{}, error) {
	var params struct {
		Remote       Remote
		Session      string
		SizeX, SizeY int
		Mode         string
	}

	if err := r.Args.One().Unmarshal(&params); err != nil {
		return nil, fmt.Errorf("{ remote: [object], session: %s, noScreen: [bool] }, err: %s",
			params.Session, err)
	}

	if params.SizeX <= 0 || params.SizeY <= 0 {
		return nil, fmt.Errorf("{ sizeX: %d, sizeY: %d } { raw JSON : %v }", params.SizeX, params.SizeY, r.Args.One())
	}

	user, err := user.Current()
	if err != nil {
		return nil, fmt.Errorf("Could not get home dir: %s", err)
	}

	command, err := newCommand(params.Mode, params.Session, user.Username)
	if err != nil {
		return nil, err
	}

	// get pty and tty descriptors
	p, err := pty.NewPTY()
	if err != nil {
		return nil, err
	}

	// We will return this object to the client.
	server := &Server{
		Session:   command.Session,
		remote:    params.Remote,
		pty:       p,
		inputHook: t.InputHook,
	}
	server.setSize(float64(params.SizeX), float64(params.SizeY))

	t.AddUserSession(r.Username, command.Session, server)

	// wrap the command with sudo -i for initiation login shell. This is needed
	// in order to have Environments and other to be initialized correctly.
	// check also if klient was started in root mode or not.
	var args []string
	if os.Geteuid() == 0 {
		args = []string{"-i", command.Name}
	} else {
		args = []string{"-i", "-u", "#" + user.Uid, "--", command.Name}
	}

	args = append(args, command.Args...)
	cmd := exec.Command("/usr/bin/sudo", args...)

	// For test use this, sudo is not going to work
	// cmd := exec.Command(command.Name, command.Args...)

	cmd.Env = []string{"TERM=xterm-256color", "HOME=" + user.HomeDir}
	cmd.Stdin = server.pty.Slave
	cmd.Stdout = server.pty.Slave
	cmd.Dir = user.HomeDir
	// cmd.Stderr = server.pty.Slave

	// Open in background, this is needed otherwise the process will be killed
	// if you hit close on the client side.
	cmd.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true}
	err = cmd.Start()
	if err != nil {
		fmt.Println("could not start", err)
	}

	// Wait until the shell process is closed and notify the client.
	go func() {
		err := cmd.Wait()
		if err != nil {
			fmt.Println("cmd.wait err", err)
		}

		server.pty.Slave.Close()
		server.pty.Master.Close()
		server.remote.SessionEnded.Call()

		t.DeleteUserSession(r.Username, command.Session)
	}()

	// Read the STDOUT from shell process and send to the connected client.
	go func() {
		buf := make([]byte, (1<<12)-utf8.UTFMax, 1<<12)
		for {
			n, err := server.pty.Master.Read(buf)
			for n < cap(buf)-1 {
				r, _ := utf8.DecodeLastRune(buf[:n])
				if r != utf8.RuneError {
					break
				}
				server.pty.Master.Read(buf[n : n+1])
				n++
			}

			// Rate limiting...
			if server.throttling {
				s := time.Now().Unix()
				if server.currentSecond != s {
					server.currentSecond = s
					server.messageCounter = 0
					server.byteCounter = 0
					server.lineFeeedCounter = 0
				}
				server.messageCounter += 1
				server.byteCounter += n
				server.lineFeeedCounter += bytes.Count(buf[:n], []byte{'\n'})
				if server.messageCounter > 100 || server.byteCounter > 1<<18 || server.lineFeeedCounter > 300 {
					time.Sleep(time.Second)
				}
			}

			server.remote.Output.Call(string(filterInvalidUTF8(buf[:n])))
			if err != nil {
				break
			}
		}
	}()

	return server, nil
}

// CloseSessions closes all active session for the given username and deletes
// it from the internal user map
func (t *Terminal) CloseSessions(username string) {
	t.Log.Info("Closing terminal sessions of user '%s'", username)

	t.Lock()
	user, ok := t.Users[username]
	t.Unlock()

	if !ok {
		return
	}

	user.CloseSessions()

	t.Lock()
	delete(t.Users, username)
	t.Unlock()
}

func filterInvalidUTF8(buf []byte) []byte {
	i := 0
	j := 0
	for {
		r, l := utf8.DecodeRune(buf[i:])
		if l == 0 {
			break
		}
		if r < 0xD800 {
			if i != j {
				copy(buf[j:], buf[i:i+l])
			}
			j += l
		}
		i += l
	}
	return buf[:j]
}
<|endoftext|>


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

package inode_test

import (
	"testing"
	"time"

	"golang.org/x/net/context"

	"github.com/googlecloudplatform/gcsfuse/fs/inode"
	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsfake"
	. "github.com/jacobsa/ogletest"
)

func TestDir(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

const inodeID = 17
const inodeName = "foo/bar/"
const typeCacheTTL = time.Second

type DirTest struct {
	ctx    context.Context
	bucket gcs.Bucket
	clock  timeutil.SimulatedClock

	in *inode.DirInode
}

var _ SetUpInterface = &DirTest{}
var _ TearDownInterface = &DirTest{}

func init() { RegisterTestSuite(&DirTest{}) }

func (t *DirTest) SetUp(ti *TestInfo) {
	t.ctx = ti.Ctx
	t.clock.SetTime(time.Date(2015, 4, 5, 2, 15, 0, 0, time.Local))
	t.bucket = gcsfake.NewFakeBucket(&t.clock, "some_bucket")

	// Create the inode. No implicit dirs by default.
	t.resetInode(false)
}

func (t *DirTest) TearDown() {
	t.in.Unlock()
}

func (t *DirTest) resetInode(implicitDirs bool) {
	if t.in != nil {
		t.in.Unlock()
	}

	t.in = inode.NewDirInode(
		inodeID,
		inodeName,
		implicitDirs,
		typeCacheTTL,
		t.bucket,
		&t.clock)

	t.in.Lock()
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *DirTest) ID() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) Name() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookupCount() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) Attributes() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_NonExistent() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_FileOnly() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_DirOnly() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_ImplicitDirOnly_Disabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_ImplicitDirOnly_Enabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_FileAndDir() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_FileAndDirAndImplicitDir_Disabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_FileAndDirAndImplicitDir_Enabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_Empty() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_NonEmpty_ImplicitDirsDisabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_NonEmpty_ImplicitDirsEnabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_LotsOfEntries() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildFile_DoesntExist() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildFile_Exists() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildFile_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildDir_DoesntExist() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildDir_Exists() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildDir_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildFile_DoesntExist() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildFile_Exists() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildFile_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildDir_DoesntExist() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildDir_Exists() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildDir_TypeCaching() {
	AssertTrue(false, "TODO")
}
<commit_msg>DirTest.ID<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package inode_test

import (
	"testing"
	"time"

	"golang.org/x/net/context"

	"github.com/googlecloudplatform/gcsfuse/fs/inode"
	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsfake"
	. "github.com/jacobsa/ogletest"
)

func TestDir(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

const inodeID = 17
const inodeName = "foo/bar/"
const typeCacheTTL = time.Second

type DirTest struct {
	ctx    context.Context
	bucket gcs.Bucket
	clock  timeutil.SimulatedClock

	in *inode.DirInode
}

var _ SetUpInterface = &DirTest{}
var _ TearDownInterface = &DirTest{}

func init() { RegisterTestSuite(&DirTest{}) }

func (t *DirTest) SetUp(ti *TestInfo) {
	t.ctx = ti.Ctx
	t.clock.SetTime(time.Date(2015, 4, 5, 2, 15, 0, 0, time.Local))
	t.bucket = gcsfake.NewFakeBucket(&t.clock, "some_bucket")

	// Create the inode. No implicit dirs by default.
	t.resetInode(false)
}

func (t *DirTest) TearDown() {
	t.in.Unlock()
}

func (t *DirTest) resetInode(implicitDirs bool) {
	if t.in != nil {
		t.in.Unlock()
	}

	t.in = inode.NewDirInode(
		inodeID,
		inodeName,
		implicitDirs,
		typeCacheTTL,
		t.bucket,
		&t.clock)

	t.in.Lock()
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *DirTest) ID() {
	ExpectEq(inodeID, t.in.ID())
}

func (t *DirTest) Name() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookupCount() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) Attributes() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_NonExistent() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_FileOnly() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_DirOnly() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_ImplicitDirOnly_Disabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_ImplicitDirOnly_Enabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_FileAndDir() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_FileAndDirAndImplicitDir_Disabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_FileAndDirAndImplicitDir_Enabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) LookUpChild_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_Empty() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_NonEmpty_ImplicitDirsDisabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_NonEmpty_ImplicitDirsEnabled() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_LotsOfEntries() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) ReadEntries_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildFile_DoesntExist() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildFile_Exists() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildFile_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildDir_DoesntExist() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildDir_Exists() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) CreateChildDir_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildFile_DoesntExist() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildFile_Exists() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildFile_TypeCaching() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildDir_DoesntExist() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildDir_Exists() {
	AssertTrue(false, "TODO")
}

func (t *DirTest) DeleteChildDir_TypeCaching() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
)

type item struct {
	name string
}

type character struct {
	name     string
	leftHand *item
}

func (c *character) pickup(i *item) {
	if c == nil || i == nil {
		return
	}
	fmt.Printf("%v picks up a %v\n", c.name, i.name)
	c.leftHand = i
}

func (c *character) give(to *character) {
	if c == nil || to == nil {
		return
	}
	if c.leftHand == nil {
		fmt.Printf("%v has nothing to give\n", c.name)
		return
	}
	if to.leftHand != nil {
		fmt.Printf("%v's hands are full\n", to.name)
		return
	}
	to.leftHand = c.leftHand
	c.leftHand = nil
	fmt.Printf("%v's gives %v a %v\n", c.name, to.name, to.leftHand.name)
}

func (c character) String() string {
	if c.leftHand == nil {
		return fmt.Sprintf("%v is carrying nothing", c.name)
	}
	return fmt.Sprintf("%v is carrying a %v", c.name, c.leftHand.name)
}

func main() {
	arthur := &character{name: "Arthur"}

	shrubbery := &item{name: "shrubbery"}
	arthur.pickup(shrubbery)

	knight := &character{name: "Knight"}
	arthur.give(knight)

	fmt.Println(arthur)
	fmt.Println(knight)
}
<commit_msg>appendix: fix grammar in lesson 27 solution<commit_after>package main

import (
	"fmt"
)

type item struct {
	name string
}

type character struct {
	name     string
	leftHand *item
}

func (c *character) pickup(i *item) {
	if c == nil || i == nil {
		return
	}
	fmt.Printf("%v picks up a %v\n", c.name, i.name)
	c.leftHand = i
}

func (c *character) give(to *character) {
	if c == nil || to == nil {
		return
	}
	if c.leftHand == nil {
		fmt.Printf("%v has nothing to give\n", c.name)
		return
	}
	if to.leftHand != nil {
		fmt.Printf("%v's hands are full\n", to.name)
		return
	}
	to.leftHand = c.leftHand
	c.leftHand = nil
	fmt.Printf("%v gives %v a %v\n", c.name, to.name, to.leftHand.name)
}

func (c character) String() string {
	if c.leftHand == nil {
		return fmt.Sprintf("%v is carrying nothing", c.name)
	}
	return fmt.Sprintf("%v is carrying a %v", c.name, c.leftHand.name)
}

func main() {
	arthur := &character{name: "Arthur"}

	shrubbery := &item{name: "shrubbery"}
	arthur.pickup(shrubbery)

	knight := &character{name: "Knight"}
	arthur.give(knight)

	fmt.Println(arthur)
	fmt.Println(knight)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/gin-gonic/gin"
)

func pmdaServer() (result string) {
	result = os.Getenv("PMDA")
	if result == "" {
		result = "www.pmda.go.jp"
	}
	return
}

func pmdaPath(yjcode string) (path string, err error) {
	f := fmt.Sprintf("/asset/bin/yj/%s", yjcode)
	if _, err = os.Stat(f); err != nil {
		return
	}
	r, err := os.OpenFile(f, os.O_RDONLY, 0666)
	if err != nil {
		return
	}
	buf := bytes.NewBuffer([]byte{})
	_, err = io.Copy(buf, r)
	if err != nil {
		return
	}
	line := buf.String()
	path = strings.Trim(line, "\r\n ")
	return
}

func redirectToPMDA(c *gin.Context) {
	yjcode := c.Param("yjcode")
	path, err := pmdaPath(yjcode)
	if err != nil {
		message := fmt.Sprintf("NOT FOUND: %s \n error:%s", yjcode, err)
		fmt.Println(message)
		c.String(http.StatusNotFound, message)
		return
	}
	var pmda = pmdaServer()
	var url = fmt.Sprintf("//%s/PmdaSearch/iyakuDetail/%s", pmda, path)

	c.Redirect(http.StatusTemporaryRedirect, url)
}

func guessPmdaPath(yjcode string) (path_list []string, err error) {
	pattern := fmt.Sprintf("/asset/bin/html/??????_%s*_?_??.html", yjcode)
	path_list, err = filepath.Glob(pattern)
	return
}

//TODO 実装中
func guessRedirectToPMDA(c *gin.Context) {
	yjcode := c.Param("yjcode")
	path_list, err := guessPmdaPath(yjcode)
	if err != nil {
		message := fmt.Sprintf(
			"pattern search error: yj:%s \nerror:%s\n", yjcode, err)
		fmt.Println(message)
		c.String(http.StatusNotFound, message)
		return
	}

	var url = ""
	c.Redirect(http.StatusTemporaryRedirect, url)
}

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.String(200, "Converter(YJcode to PMDA path) works.")
	})

	//redirect to PMDA
	r.GET("/redirect/:yjcode/", redirectToPMDA)
	r.GET("/redirect_guess/:yjcode/", guessRedirectToPMDA)

	fmt.Println("listen: 80")
	r.Run(":80")
}
<commit_msg>server err fix<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/gin-gonic/gin"
)

func pmdaServer() (result string) {
	result = os.Getenv("PMDA")
	if result == "" {
		result = "www.pmda.go.jp"
	}
	return
}

func pmdaPath(yjcode string) (path string, err error) {
	f := fmt.Sprintf("/asset/bin/yj/%s", yjcode)
	if _, err = os.Stat(f); err != nil {
		return
	}
	r, err := os.OpenFile(f, os.O_RDONLY, 0666)
	if err != nil {
		return
	}
	buf := bytes.NewBuffer([]byte{})
	_, err = io.Copy(buf, r)
	if err != nil {
		return
	}
	line := buf.String()
	path = strings.Trim(line, "\r\n ")
	return
}

func redirectToPMDA(c *gin.Context) {
	yjcode := c.Param("yjcode")
	path, err := pmdaPath(yjcode)
	if err != nil {
		message := fmt.Sprintf("NOT FOUND: %s \n error:%s", yjcode, err)
		fmt.Println(message)
		c.String(http.StatusNotFound, message)
		return
	}
	var pmda = pmdaServer()
	var url = fmt.Sprintf("//%s/PmdaSearch/iyakuDetail/%s", pmda, path)

	c.Redirect(http.StatusTemporaryRedirect, url)
}

func guessPmdaPath(yjcode string) (path_list []string, err error) {
	pattern := fmt.Sprintf("/asset/bin/html/??????_%s*_?_??.html", yjcode)
	path_list, err = filepath.Glob(pattern)
	return
}

//TODO 実装中
func guessRedirectToPMDA(c *gin.Context) {
	yjcode := c.Param("yjcode")
	path_list, err := guessPmdaPath(yjcode)
	fmt.Printf("path_list: %s\n", path_list)
	if err != nil {
		message := fmt.Sprintf(
			"pattern search error: yj:%s \nerror:%s\n", yjcode, err)
		fmt.Println(message)
		c.String(http.StatusNotFound, message)
		return
	}

	var url = ""
	c.Redirect(http.StatusTemporaryRedirect, url)
}

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.String(200, "Converter(YJcode to PMDA path) works.")
	})

	//redirect to PMDA
	r.GET("/redirect/:yjcode/", redirectToPMDA)
	r.GET("/redirect_guess/:yjcode/", guessRedirectToPMDA)

	fmt.Println("listen: 80")
	r.Run(":80")
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"

	"github.com/gin-gonic/gin"
)

func pmdaServer() (result string) {
	result = os.Getenv("PMDA")
	if result == "" {
		result = "www.pmda.go.jp"
	}
	return
}

func pmdaPath(yjcode string) (path string, err error) {
	f := fmt.Sprintf("/asset/bin/data/yj/%s", yjcode)
	if _, err = os.Stat(f); err != nil {
		return
	}
	r, err := os.OpenFile(f, os.O_RDONLY, 0666)
	if err != nil {
		return
	}
	buf := bytes.NewBuffer([]byte{})
	_, err = io.Copy(buf, r)
	if err != nil {
		return
	}
	line := buf.String()
	path = strings.Trim(line, "\r\n ")
	return
}

func redirectToPMDA(c *gin.Context) {
	yjcode := c.Param("yjcode")
	path, err := pmdaPath(yjcode)
	if err != nil {
		message := fmt.Sprintf("NOT FOUND: %s \n error:%s", yjcode, err)
		c.String(http.StatusNotFound, message)
		return
	}
	var pmda = pmdaServer()
	var url = fmt.Sprintf("//%s/PmdaSearch/iyakuSearch/%s", pmda, path)

	c.Redirect(http.StatusMovedPermanently, url)
}

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.String(200, "Converter(YJcode to PMDA path) works.")
	})

	//redirect to PMDA
	r.GET("/redirect/:yjcode/", redirectToPMDA)

	fmt.Println("listen: 80")
	r.Run(":80")
}
<commit_msg>fix YJ path<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"

	"github.com/gin-gonic/gin"
)

func pmdaServer() (result string) {
	result = os.Getenv("PMDA")
	if result == "" {
		result = "www.pmda.go.jp"
	}
	return
}

func pmdaPath(yjcode string) (path string, err error) {
	f := fmt.Sprintf("/asset/bin/yj/%s", yjcode)
	if _, err = os.Stat(f); err != nil {
		return
	}
	r, err := os.OpenFile(f, os.O_RDONLY, 0666)
	if err != nil {
		return
	}
	buf := bytes.NewBuffer([]byte{})
	_, err = io.Copy(buf, r)
	if err != nil {
		return
	}
	line := buf.String()
	path = strings.Trim(line, "\r\n ")
	return
}

func redirectToPMDA(c *gin.Context) {
	yjcode := c.Param("yjcode")
	path, err := pmdaPath(yjcode)
	if err != nil {
		message := fmt.Sprintf("NOT FOUND: %s \n error:%s", yjcode, err)
		c.String(http.StatusNotFound, message)
		return
	}
	var pmda = pmdaServer()
	var url = fmt.Sprintf("//%s/PmdaSearch/iyakuSearch/%s", pmda, path)

	c.Redirect(http.StatusMovedPermanently, url)
}

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.String(200, "Converter(YJcode to PMDA path) works.")
	})

	//redirect to PMDA
	r.GET("/redirect/:yjcode/", redirectToPMDA)

	fmt.Println("listen: 80")
	r.Run(":80")
}
<|endoftext|>


<commit_before>package gochecks

import (
	"fmt"
	"time"

	"io/ioutil"
	"net/http"
)

// ValidateHTTPResponseFunction function type that should validate a http response and return the state (ok, critical, warning) and error description for a check. (Used with NewGenericHTTPChecker)
type ValidateHTTPResponseFunction func(resp *http.Response) (state, description string)

// BodyGreaterThan return a function that given a http response return true if the body is greater than a given number of bytes
func BodyGreaterThan(minLength int) ValidateHTTPResponseFunction {
	return func(httpResp *http.Response) (state, description string) {
		if httpResp.StatusCode != 200 {
			return "critical", fmt.Sprintf("Response %d", httpResp.StatusCode)
		}
		if httpResp.Body == nil {
			return "critical", fmt.Sprintf("Empty body")
		}
		body, err := ioutil.ReadAll(httpResp.Body)
		if err != nil {
			return "critical", fmt.Sprintf("Error geting body")
		}
		if len(body) < minLength {
			return "critical", fmt.Sprintf("Obtained %d bytes, expected more than %d", len(body), minLength)
		}
		return "ok", ""
	}
}

// NewGenericHTTPChecker returns a check function that can check the returned http response of a http get with a given validation function
func NewGenericHTTPChecker(host, service, url string, validationFunc ValidateHTTPResponseFunction) CheckFunction {
	return func() Event {
		var t1 = time.Now()

		response, err := http.Get(url)
		milliseconds := float32((time.Now().Sub(t1)).Nanoseconds() / 1e6)
		result := Event{Host: host, Service: service, State: "critical", Metric: milliseconds}
		if err != nil {
			result.Description = err.Error()
		} else {
			if response.Body != nil {
				defer response.Body.Close()
			}
			result.State, result.Description = validationFunc(response)
		}
		return result
	}
}

// NewHTTPChecker returns a check function that get a given url and validate if the return code is the expected one
func NewHTTPChecker(host, service, url string, expectedStatusCode int) CheckFunction {
	return NewGenericHTTPChecker(host, service, url,
		func(httpResp *http.Response) (string, string) {
			if httpResp.StatusCode == expectedStatusCode {
				return "ok", ""
			}
			return "critical", fmt.Sprintf("Response %d", httpResp.StatusCode)
		})
}
<commit_msg>Helper funcion to validate the content of a request<commit_after>package gochecks

import (
	"fmt"
	"time"

	"io/ioutil"
	"net/http"
)

// ValidateHTTPResponseFunction function type that should validate a http response and return the state (ok, critical, warning) and error description for a check. (Used with NewGenericHTTPChecker)
type ValidateHTTPResponseFunction func(resp *http.Response) (state, description string)

// BodyGreaterThan return a function that given a http response return true if the body is greater than a given number of bytes
func BodyGreaterThan(minLength int) ValidateHTTPResponseFunction {
	return func(httpResp *http.Response) (state, description string) {
		if httpResp.StatusCode != 200 {
			return "critical", fmt.Sprintf("Response %d", httpResp.StatusCode)
		}
		if httpResp.Body == nil {
			return "critical", fmt.Sprintf("Empty body")
		}
		body, err := ioutil.ReadAll(httpResp.Body)
		if err != nil {
			return "critical", fmt.Sprintf("Error geting body")
		}
		if len(body) < minLength {
			return "critical", fmt.Sprintf("Obtained %d bytes, expected more than %d", len(body), minLength)
		}
		return "ok", ""
	}
}

// ValidateContentFunctio function type that should validate a content (usualy a http body) and return the state (ok, critical, warning) and error description for a check.
type ValidateContentFunction func(content string) (state, description string)

func BodyValidation(bodyValidationFunc ValidateContentFunction) ValidateHTTPResponseFunction {
	return func(httpResp *http.Response) (state, description string) {
		if httpResp.StatusCode != 200 {
			return "critical", fmt.Sprintf("Response %d", httpResp.StatusCode)
		}
		if httpResp.Body == nil {
			return "critical", fmt.Sprintf("Empty body")
		}
		body, err := ioutil.ReadAll(httpResp.Body)
		if err != nil {
			return "critical", fmt.Sprintf("Error geting body")
		}
		return bodyValidationFunc(string(body))
	}
}

// NewGenericHTTPChecker returns a check function that can check the returned http response of a http get with a given validation function
func NewGenericHTTPChecker(host, service, url string, validationFunc ValidateHTTPResponseFunction) CheckFunction {
	return func() Event {
		var t1 = time.Now()

		response, err := http.Get(url)
		milliseconds := float32((time.Now().Sub(t1)).Nanoseconds() / 1e6)
		result := Event{Host: host, Service: service, State: "critical", Metric: milliseconds}
		if err != nil {
			result.Description = err.Error()
		} else {
			if response.Body != nil {
				defer response.Body.Close()
			}
			result.State, result.Description = validationFunc(response)
		}
		return result
	}
}

// NewHTTPChecker returns a check function that get a given url and validate if the return code is the expected one
func NewHTTPChecker(host, service, url string, expectedStatusCode int) CheckFunction {
	return NewGenericHTTPChecker(host, service, url,
		func(httpResp *http.Response) (string, string) {
			if httpResp.StatusCode == expectedStatusCode {
				return "ok", ""
			}
			return "critical", fmt.Sprintf("Response %d", httpResp.StatusCode)
		})
}
<|endoftext|>