<commit_before>package gordon

import (
	"bufio"
	"bytes"
	"fmt"
	"github.com/codegangsta/cli"
	gh "github.com/crosbymichael/octokat"
	"io"
	"os"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"
)

const (
	defaultTimeFormat = time.RFC822
	truncSize         = 80
)

func newTabwriter() *tabwriter.Writer {
	return tabwriter.NewWriter(os.Stdout, 8, 1, 3, ' ', 0)
}

func truncate(s string) string {
	if len(s) > truncSize {
		s = s[:truncSize] + "..."
	}
	return s
}

func DisplayPullRequests(c *cli.Context, pulls []*gh.PullRequest, notrunc bool) {
	w := newTabwriter()
	fmt.Fprintf(w, "NUMBER\tLAST UPDATED\tASSIGNEE\tTITLE")
	if c.Bool("lgtm") {
		fmt.Fprintf(w, "\tLGTM")
	}
	fmt.Fprintf(w, "\n")
	for _, p := range pulls {
		if !notrunc {
			p.Title = truncate(p.Title)
		}
		var assignee string
		if p.Assignee != nil {
			assignee = p.Assignee.Login
		}
		fmt.Fprintf(w, "%d\t%s\t%s\t%s", p.Number, HumanDuration(time.Since(p.UpdatedAt)), assignee, p.Title)
		if c.Bool("lgtm") {
			lgtm := strconv.Itoa(p.ReviewComments)
			if p.ReviewComments >= 2 {
				lgtm = Green(lgtm)
			} else if p.ReviewComments == 0 {
				lgtm = DarkRed(lgtm)
			} else {
				lgtm = DarkYellow(lgtm)
			}
			fmt.Fprintf(w, "\t%s", lgtm)
		}
		fmt.Fprintf(w, "\n")
	}

	if err := w.Flush(); err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
}

func DisplayReviewers(c *cli.Context, reviewers map[string][]string) {
	w := newTabwriter()
	fmt.Fprintf(w, "FILE\tREVIEWERS")
	fmt.Fprintf(w, "\n")
	for file, fileReviewers := range reviewers {
		var usernames bytes.Buffer
		for _, reviewer := range fileReviewers {
			usernames.WriteString(reviewer)
			usernames.WriteString(", ")
		}
		usernames.Truncate(usernames.Len() - 2)
		fmt.Fprintf(w, "%s\t%s\n", file, usernames.String())
	}
	if err := w.Flush(); err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
}

func DisplayContributors(c *cli.Context, contributors []*gh.Contributor) {
	var (
		w                 = newTabwriter()
		contributorsStats []ContributorStats
	)

	for _, contrib := range contributors {
		contribStats := ContributorStats{}
		contribStats.Name = contrib.Author.Login
		for _, week := range contrib.Weeks {
			contribStats.Additions += week.Additions
			contribStats.Deletions += week.Deletions
			contribStats.Commits += week.Commits
		}
		contributorsStats = append(contributorsStats, []ContributorStats{contribStats}...)
	}
	if c.Bool("additions") {
		sort.Sort(ByAdditions(contributorsStats))
	} else if c.Bool("deletions") {
		sort.Sort(ByDeletions(contributorsStats))
	} else if c.Bool("commits") {
		sort.Sort(ByCommits(contributorsStats))
	} else {
		// Sort by default by Commits
		sort.Sort(ByCommits(contributorsStats))
	}
	topN := c.Int("top")
	fmt.Fprintf(w, "CONTRIBUTOR\tADDITIONS\tDELETIONS\tCOMMITS")
	fmt.Fprintf(w, "\n")
	for i := 0; i < len(contributorsStats) && i < topN; i++ {
		fmt.Fprintf(w, "%s\t%d\t%d\t%d", contributorsStats[i].Name,
			contributorsStats[i].Additions,
			contributorsStats[i].Deletions,
			contributorsStats[i].Commits)
		fmt.Fprintf(w, "\n")
	}

	if err := w.Flush(); err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
}

func DisplayPullRequest(pr *gh.PullRequest, comments []gh.Comment) {
	fmt.Fprint(os.Stdout, fmt.Sprintf("Pull Request from: %s", Green("@"+pr.User.Login)), "\n")
	fmt.Printf("No: %d\nTitle: %s\n", pr.Number, pr.Title)

	if pr.Merged {
		fmt.Fprintf(os.Stdout, "\nMerged by: %s\nMerged at: %s\nMerge Commit: %s\n\n", Yellow("@"+pr.MergedBy.Login), Yellow(pr.MergedAt.Format(time.RubyDate)), Yellow(pr.MergeCommitSha))
	} else {
		m := fmt.Sprintf("%t", pr.Mergeable)
		if pr.Mergeable {
			fmt.Fprintf(os.Stdout, "Mergeable: %s", Green(m))
		} else {
			fmt.Fprintf(os.Stdout, "Mergeable: %s", Red(m))
		}
	}
	fmt.Fprint(os.Stdout, "\n")

	lines := strings.Split(pr.Body, "\n")
	for i, l := range lines {
		lines[i] = "\t" + l
	}
	fmt.Printf("Description:\n\n%s\n\n", strings.Join(lines, "\n"))
	fmt.Printf("\n\n")

	DisplayComments(comments)
}

func DisplayComments(comments []gh.Comment) {
	fmt.Fprintln(os.Stdout, "Comments:")
	for _, c := range comments {
		fmt.Printf("<%s\n@%s %s\n%s\n%s>", strings.Repeat("=", 79), Red(c.User.Login), c.CreatedAt.Format(defaultTimeFormat), strings.Replace(c.Body, "LGTM", fmt.Sprintf("%s", Green("LGTM")), -1), strings.Repeat("=", 79))
		fmt.Fprint(os.Stdout, "\n\n")
	}
}

func DisplayCommentAdded(cmt gh.Comment) {
	fmt.Printf("Comment added at %s\n", cmt.CreatedAt.Format(defaultTimeFormat))
}

func printIssue(c *cli.Context, w *tabwriter.Writer, number int, updatedAt time.Time, login string, title string, comments int) {
	fmt.Fprintf(w, "%d\t%s\t%s\t%s", number, HumanDuration(time.Since(updatedAt)), login, title)
	if c.Int("votes") > 0 {
		votes := strconv.Itoa(comments)
		if comments >= 2 {
			votes = Green(votes)
		}
		fmt.Fprintf(w, "\t%s", votes)
	}
	fmt.Fprintf(w, "\n")
}

// Display Issues prints `issues` to standard output in a human-friendly tabulated format.
func DisplayIssues(c *cli.Context, v interface{}, notrunc bool) {
	w := newTabwriter()
	fmt.Fprintf(w, "NUMBER\tLAST UPDATED\tASSIGNEE\tTITLE")
	if c.Int("votes") > 0 {
		fmt.Fprintf(w, "\tVOTES")
	}
	fmt.Fprintf(w, "\n")

	switch issues := v.(type) {
	case []*gh.Issue:
		for _, p := range issues {
			printIssue(c, w, p.Number, p.UpdatedAt, p.Assignee.Login, p.Title, p.Comments)
		}
	case []*gh.SearchItem:
		for _, p := range issues {
			printIssue(c, w, p.Number, p.UpdatedAt, p.Assignee.Login, p.Title, p.Comments)
		}
	}
	if err := w.Flush(); err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
}

func DisplayIssue(issue *gh.Issue, comments []gh.Comment) {
	fmt.Fprint(os.Stdout, Green("Issue:"), "\n")
	fmt.Printf("No: %d\nTitle: %s\n\n", issue.Number, issue.Title)

	lines := strings.Split(issue.Body, "\n")
	for i, l := range lines {
		lines[i] = "\t" + l
	}
	fmt.Printf("Description:\n\n%s\n\n", strings.Join(lines, "\n"))
	fmt.Printf("\n\n")

	DisplayComments(comments)
}

// HumanDuration returns a human-readable approximation of a duration
// This function is taken from the Docker project, and slightly modified
// to cap units at days.
// (eg. "About a minute", "4 hours ago", etc.)
// (c) 2013 Docker, inc. and the Docker authors (http://docker.io)
func HumanDuration(d time.Duration) string {
	if seconds := int(d.Seconds()); seconds < 1 {
		return "Less than a second"
	} else if seconds < 60 {
		return fmt.Sprintf("%d seconds", seconds)
	} else if minutes := int(d.Minutes()); minutes == 1 {
		return "About a minute"
	} else if minutes < 60 {
		return fmt.Sprintf("%d minutes", minutes)
	} else if hours := int(d.Hours()); hours == 1 {
		return "About an hour"
	} else if hours < 48 {
		return fmt.Sprintf("%d hours", hours)
	}
	return fmt.Sprintf("%d days", int(d.Hours()/24))
}

func DisplayPatch(r io.Reader) error {
	s := bufio.NewScanner(r)
	for s.Scan() {
		if err := s.Err(); err != nil {
			return err
		}
		t := s.Text()

		switch t[0] {
		case '-':
			fmt.Fprintln(os.Stdout, Red(t))
		case '+':
			fmt.Fprintln(os.Stdout, Green(t))
		default:
			fmt.Fprintln(os.Stdout, t)
		}
	}
	return nil
}
<commit_msg>Show contributors next to assignee when listing all PRs<commit_after>package gordon

import (
	"bufio"
	"bytes"
	"fmt"
	"github.com/codegangsta/cli"
	gh "github.com/crosbymichael/octokat"
	"io"
	"os"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"
)

const (
	defaultTimeFormat = time.RFC822
	truncSize         = 80
)

func newTabwriter() *tabwriter.Writer {
	return tabwriter.NewWriter(os.Stdout, 8, 1, 3, ' ', 0)
}

func truncate(s string) string {
	if len(s) > truncSize {
		s = s[:truncSize] + "..."
	}
	return s
}

func DisplayPullRequests(c *cli.Context, pulls []*gh.PullRequest, notrunc bool) {
	w := newTabwriter()
	fmt.Fprintf(w, "NUMBER\tLAST UPDATED\tCONTRIBUTOR\tASSIGNEE\tTITLE")
	if c.Bool("lgtm") {
		fmt.Fprintf(w, "\tLGTM")
	}
	fmt.Fprintf(w, "\n")
	for _, p := range pulls {
		if !notrunc {
			p.Title = truncate(p.Title)
		}
		var assignee string
		if p.Assignee != nil {
			assignee = p.Assignee.Login
		}
		fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s", p.Number, HumanDuration(time.Since(p.UpdatedAt)), p.User.Login, assignee, p.Title)
		if c.Bool("lgtm") {
			lgtm := strconv.Itoa(p.ReviewComments)
			if p.ReviewComments >= 2 {
				lgtm = Green(lgtm)
			} else if p.ReviewComments == 0 {
				lgtm = DarkRed(lgtm)
			} else {
				lgtm = DarkYellow(lgtm)
			}
			fmt.Fprintf(w, "\t%s", lgtm)
		}
		fmt.Fprintf(w, "\n")
	}

	if err := w.Flush(); err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
}

func DisplayReviewers(c *cli.Context, reviewers map[string][]string) {
	w := newTabwriter()
	fmt.Fprintf(w, "FILE\tREVIEWERS")
	fmt.Fprintf(w, "\n")
	for file, fileReviewers := range reviewers {
		var usernames bytes.Buffer
		for _, reviewer := range fileReviewers {
			usernames.WriteString(reviewer)
			usernames.WriteString(", ")
		}
		usernames.Truncate(usernames.Len() - 2)
		fmt.Fprintf(w, "%s\t%s\n", file, usernames.String())
	}
	if err := w.Flush(); err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
}

func DisplayContributors(c *cli.Context, contributors []*gh.Contributor) {
	var (
		w                 = newTabwriter()
		contributorsStats []ContributorStats
	)

	for _, contrib := range contributors {
		contribStats := ContributorStats{}
		contribStats.Name = contrib.Author.Login
		for _, week := range contrib.Weeks {
			contribStats.Additions += week.Additions
			contribStats.Deletions += week.Deletions
			contribStats.Commits += week.Commits
		}
		contributorsStats = append(contributorsStats, []ContributorStats{contribStats}...)
	}
	if c.Bool("additions") {
		sort.Sort(ByAdditions(contributorsStats))
	} else if c.Bool("deletions") {
		sort.Sort(ByDeletions(contributorsStats))
	} else if c.Bool("commits") {
		sort.Sort(ByCommits(contributorsStats))
	} else {
		// Sort by default by Commits
		sort.Sort(ByCommits(contributorsStats))
	}
	topN := c.Int("top")
	fmt.Fprintf(w, "CONTRIBUTOR\tADDITIONS\tDELETIONS\tCOMMITS")
	fmt.Fprintf(w, "\n")
	for i := 0; i < len(contributorsStats) && i < topN; i++ {
		fmt.Fprintf(w, "%s\t%d\t%d\t%d", contributorsStats[i].Name,
			contributorsStats[i].Additions,
			contributorsStats[i].Deletions,
			contributorsStats[i].Commits)
		fmt.Fprintf(w, "\n")
	}

	if err := w.Flush(); err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
}

func DisplayPullRequest(pr *gh.PullRequest, comments []gh.Comment) {
	fmt.Fprint(os.Stdout, fmt.Sprintf("Pull Request from: %s", Green("@"+pr.User.Login)), "\n")
	fmt.Printf("No: %d\nTitle: %s\n", pr.Number, pr.Title)

	if pr.Merged {
		fmt.Fprintf(os.Stdout, "\nMerged by: %s\nMerged at: %s\nMerge Commit: %s\n\n", Yellow("@"+pr.MergedBy.Login), Yellow(pr.MergedAt.Format(time.RubyDate)), Yellow(pr.MergeCommitSha))
	} else {
		m := fmt.Sprintf("%t", pr.Mergeable)
		if pr.Mergeable {
			fmt.Fprintf(os.Stdout, "Mergeable: %s", Green(m))
		} else {
			fmt.Fprintf(os.Stdout, "Mergeable: %s", Red(m))
		}
	}
	fmt.Fprint(os.Stdout, "\n")

	lines := strings.Split(pr.Body, "\n")
	for i, l := range lines {
		lines[i] = "\t" + l
	}
	fmt.Printf("Description:\n\n%s\n\n", strings.Join(lines, "\n"))
	fmt.Printf("\n\n")

	DisplayComments(comments)
}

func DisplayComments(comments []gh.Comment) {
	fmt.Fprintln(os.Stdout, "Comments:")
	for _, c := range comments {
		fmt.Printf("<%s\n@%s %s\n%s\n%s>", strings.Repeat("=", 79), Red(c.User.Login), c.CreatedAt.Format(defaultTimeFormat), strings.Replace(c.Body, "LGTM", fmt.Sprintf("%s", Green("LGTM")), -1), strings.Repeat("=", 79))
		fmt.Fprint(os.Stdout, "\n\n")
	}
}

func DisplayCommentAdded(cmt gh.Comment) {
	fmt.Printf("Comment added at %s\n", cmt.CreatedAt.Format(defaultTimeFormat))
}

func printIssue(c *cli.Context, w *tabwriter.Writer, number int, updatedAt time.Time, login string, title string, comments int) {
	fmt.Fprintf(w, "%d\t%s\t%s\t%s", number, HumanDuration(time.Since(updatedAt)), login, title)
	if c.Int("votes") > 0 {
		votes := strconv.Itoa(comments)
		if comments >= 2 {
			votes = Green(votes)
		}
		fmt.Fprintf(w, "\t%s", votes)
	}
	fmt.Fprintf(w, "\n")
}

// Display Issues prints `issues` to standard output in a human-friendly tabulated format.
func DisplayIssues(c *cli.Context, v interface{}, notrunc bool) {
	w := newTabwriter()
	fmt.Fprintf(w, "NUMBER\tLAST UPDATED\tASSIGNEE\tTITLE")
	if c.Int("votes") > 0 {
		fmt.Fprintf(w, "\tVOTES")
	}
	fmt.Fprintf(w, "\n")

	switch issues := v.(type) {
	case []*gh.Issue:
		for _, p := range issues {
			printIssue(c, w, p.Number, p.UpdatedAt, p.Assignee.Login, p.Title, p.Comments)
		}
	case []*gh.SearchItem:
		for _, p := range issues {
			printIssue(c, w, p.Number, p.UpdatedAt, p.Assignee.Login, p.Title, p.Comments)
		}
	}
	if err := w.Flush(); err != nil {
		fmt.Fprintf(os.Stderr, "%s", err)
	}
}

func DisplayIssue(issue *gh.Issue, comments []gh.Comment) {
	fmt.Fprint(os.Stdout, Green("Issue:"), "\n")
	fmt.Printf("No: %d\nTitle: %s\n\n", issue.Number, issue.Title)

	lines := strings.Split(issue.Body, "\n")
	for i, l := range lines {
		lines[i] = "\t" + l
	}
	fmt.Printf("Description:\n\n%s\n\n", strings.Join(lines, "\n"))
	fmt.Printf("\n\n")

	DisplayComments(comments)
}

// HumanDuration returns a human-readable approximation of a duration
// This function is taken from the Docker project, and slightly modified
// to cap units at days.
// (eg. "About a minute", "4 hours ago", etc.)
// (c) 2013 Docker, inc. and the Docker authors (http://docker.io)
func HumanDuration(d time.Duration) string {
	if seconds := int(d.Seconds()); seconds < 1 {
		return "Less than a second"
	} else if seconds < 60 {
		return fmt.Sprintf("%d seconds", seconds)
	} else if minutes := int(d.Minutes()); minutes == 1 {
		return "About a minute"
	} else if minutes < 60 {
		return fmt.Sprintf("%d minutes", minutes)
	} else if hours := int(d.Hours()); hours == 1 {
		return "About an hour"
	} else if hours < 48 {
		return fmt.Sprintf("%d hours", hours)
	}
	return fmt.Sprintf("%d days", int(d.Hours()/24))
}

func DisplayPatch(r io.Reader) error {
	s := bufio.NewScanner(r)
	for s.Scan() {
		if err := s.Err(); err != nil {
			return err
		}
		t := s.Text()

		switch t[0] {
		case '-':
			fmt.Fprintln(os.Stdout, Red(t))
		case '+':
			fmt.Fprintln(os.Stdout, Green(t))
		default:
			fmt.Fprintln(os.Stdout, t)
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package controller

import (
	// "archive/zip"
	"encoding/json"
	// "errors"
	"fmt"
	"path/filepath"
	"strings"
	// "time"

	"github.com/eaciit/colony-core/v0"
	"github.com/eaciit/colony-manager/helper"
	"github.com/eaciit/dbox"
	_ "github.com/eaciit/dbox/dbc/jsons"
	// "github.com/eaciit/hdc/hdfs"
	"github.com/eaciit/knot/knot.v1"
	// "github.com/eaciit/live"
	// "github.com/eaciit/sshclient"
	// "github.com/eaciit/toolkit"
	// "golang.org/x/crypto/ssh"
)

var (
	leSourcePath = filepath.Join(EC_DATA_PATH, "langenvironment", "installer")
)

const (
	DESTINSTALL_PATH = "/usr/local/"
	SERVER_WIN       = "windows"
	SERVER_LINUX     = "linux"
	SERVER_OSX       = "osx"

	LANG_GO    = "go"
	LANG_JAVA  = "java"
	LANG_SCALA = "scala"
)

type LangenvironmentController struct {
	App
}

func getArch(serverOS string, lang string, arch string) string {
	var result string
	if serverOS == SERVER_LINUX {
		if lang == LANG_GO {
			result = fmt.Sprintf("%s1.6.%s-%s.%s", LANG_GO, SERVER_LINUX, strings.TrimSpace(arch), "tar.gz")
		}
	} else if serverOS == SERVER_WIN {
		if lang == LANG_GO {
			result = fmt.Sprintf("%s1.6.%s-%s.%s", LANG_GO, SERVER_WIN, strings.TrimSpace(arch), "zip")
		}
	}

	return result
}

func CreateLangenvironmentController(l *knot.Server) *LangenvironmentController {
	var controller = new(LangenvironmentController)
	controller.Server = l
	return controller
}

func (l *LangenvironmentController) GetSampleDataForSetupLang() colonycore.LanguageEnvironmentPayload {
	// s := `[{ "ServerId": "vagrant-test1", "Lang": [ "go" ] }, { "ServerId": "vagrant-test2", "Lang": [ "go", "java" ] }]`
	s := `{ "ServerId": "localhost", "Lang": "go" }`

	r := colonycore.LanguageEnvironmentPayload{}
	err := json.Unmarshal([]byte(s), &r)
	if err != nil {
		fmt.Println(err)
	}

	return r
}

func (le *LangenvironmentController) GetLanguage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	cursor, err := colonycore.Find(new(colonycore.LanguageEnviroment), nil)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	data := []colonycore.LanguageEnviroment{}
	err = cursor.Fetch(&data, 0, false)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	// fmt.Println(data)
	defer cursor.Close()

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

func (le *LangenvironmentController) GetServerLanguage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	cursorServer, err := colonycore.Find(new(colonycore.Server), dbox.Eq("serverType", "node"))
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	dataServer := []colonycore.Server{}
	err = cursorServer.Fetch(&dataServer, 0, false)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer cursorServer.Close()

	cursorLangEnc, err := colonycore.Find(new(colonycore.LanguageEnviroment), nil)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	dataLangEnv := []colonycore.LanguageEnviroment{}
	err = cursorLangEnc.Fetch(&dataLangEnv, 0, false)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer cursorLangEnc.Close()

	result := []*colonycore.ServerLanguage{}
	// result := []ServerLanguage{}

	for _, each := range dataServer {
		serverLang := new(colonycore.ServerLanguage)
		serverLang.ServerID = each.ID
		serverLang.ServerOS = each.OS
		serverLang.ServerHost = each.Host
		serverLang.Languages = []*colonycore.InstalledLang{}

		if each.InstalledLang == nil {
			each.InstalledLang = []*colonycore.InstalledLang{}
		}

		for _, eachLang := range dataLangEnv {
			var lang *colonycore.InstalledLang = nil
			for _, eachInstalledLang := range each.InstalledLang {
				if eachInstalledLang.Lang == eachLang.Language {
					lang = eachInstalledLang
					break
				}
			}

			if lang == nil {
				lang = new(colonycore.InstalledLang)
				lang.Lang = eachLang.Language
				lang.Version = ""
				lang.IsInstalled = false
			}

			serverLang.Languages = append(serverLang.Languages, lang)
		}

		result = append(result, serverLang)
	}

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

func (l *LangenvironmentController) SetupFromSH(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	// payload := l.GetSampleDataForSetupLang()

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

	dataServers := new(colonycore.Server)
	err = colonycore.Get(dataServers, payload.ServerId)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	serverPathSeparator := CreateApplicationController(l.Server).GetServerPathSeparator(dataServers)
	// fmt.Println(" ::: ", dataServers)

	sshSetting, sshClient, err := dataServers.Connect()
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer sshClient.Close()

	dataLanguage := []colonycore.LanguageEnviroment{}
	cursor, err := colonycore.Find(new(colonycore.LanguageEnviroment), dbox.Eq("language", payload.Lang))
	cursor.Fetch(&dataLanguage, 0, false)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer cursor.Close()
	if cursor.Count() > 0 {
		for _, eachLang := range dataLanguage {
			for _, dataInstaller := range eachLang.Installer {
				var sourcePath string
				var destinationPath string
				pathstring := []string{dataServers.DataPath, "langenvironment", "installer"}

				var installShPath string

				if strings.ToLower(dataServers.OS) == strings.ToLower(dataInstaller.OS) {
					targetLang := new(colonycore.InstalledLang)
					targetLang.IsInstalled = true
					targetLang.Lang = eachLang.Language

					if eachLang.Language == LANG_GO {
						pathstring = append(pathstring, LANG_GO)
						pathstring = append(pathstring, dataServers.OS)
						sourcePath = filepath.Join(leSourcePath, LANG_GO, dataServers.OS, dataInstaller.InstallerSource)
						destinationPath = strings.Join(pathstring, serverPathSeparator)
						installShPath = filepath.Join(leSourcePath, LANG_GO, dataServers.OS, "install.sh")
					} else if eachLang.Language == LANG_JAVA {
						pathstring = append(pathstring, LANG_JAVA)
						pathstring = append(pathstring, dataServers.OS)
						sourcePath = filepath.Join(leSourcePath, LANG_JAVA, dataServers.OS, dataInstaller.InstallerSource)
						destinationPath = strings.Join(pathstring, serverPathSeparator)
						installShPath = filepath.Join(leSourcePath, LANG_JAVA, dataServers.OS, "install.sh")
					} else if eachLang.Language == LANG_SCALA {
						pathstring = append(pathstring, LANG_SCALA)
						pathstring = append(pathstring, dataServers.OS)
						sourcePath = filepath.Join(leSourcePath, LANG_SCALA, dataServers.OS, dataInstaller.InstallerSource)
						destinationPath = strings.Join(pathstring, serverPathSeparator)
						installShPath = filepath.Join(leSourcePath, LANG_SCALA, dataServers.OS, "install.sh")
					}
					installShdestPath := strings.Join(append(pathstring, "install.sh"), serverPathSeparator)
					installFilePath := strings.Join(append(pathstring, dataInstaller.InstallerSource), serverPathSeparator)

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

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

					//sed -i 's/^M//' install.sh
					cmdSedInstall := fmt.Sprintf("sed -i 's/\r//g' %s", installShdestPath)
					_, err = sshSetting.GetOutputCommandSsh(cmdSedInstall)
					if err != nil {
						return helper.CreateResult(false, nil, err.Error())
					}

					// // chmod +x install.sh
					cmdChmodCli := fmt.Sprintf("chmod -x %s", installShdestPath)
					_, err = sshSetting.GetOutputCommandSsh(cmdChmodCli)
					if err != nil {
						return helper.CreateResult(false, nil, err.Error())
					}

					// // sh install.sh installFilePath DESTINSTALL_PATH projectpath
					cmdShCli := fmt.Sprintf("bash %s %s %s", installShdestPath, installFilePath, DESTINSTALL_PATH)
					outputCmd, err := sshSetting.RunCommandSshAsMap(cmdShCli)
					if err != nil {
						return helper.CreateResult(false, nil, err.Error())
					}
					// fmt.Println(" --- > ", outputCmd)
					// fmt.Println("go run : ", outputCmd[0].CMD)
					fmt.Println(" :: : ", outputCmd[0].Output)

					dataServers.InstalledLang = append(dataServers.InstalledLang, targetLang)
					colonycore.Save(dataServers)
				}
			}
		}
	}

	return helper.CreateResult(true, payload, "")
}
<commit_msg>no message<commit_after>package controller

import (
	// "archive/zip"
	"encoding/json"
	// "errors"
	"fmt"
	"path/filepath"
	"strings"
	// "time"

	"github.com/eaciit/colony-core/v0"
	"github.com/eaciit/colony-manager/helper"
	"github.com/eaciit/dbox"
	_ "github.com/eaciit/dbox/dbc/jsons"
	// "github.com/eaciit/hdc/hdfs"
	"github.com/eaciit/knot/knot.v1"
	// "github.com/eaciit/live"
	// "github.com/eaciit/sshclient"
	// "github.com/eaciit/toolkit"
	// "golang.org/x/crypto/ssh"
)

var (
	leSourcePath = filepath.Join(EC_DATA_PATH, "langenvironment", "installer")
)

const (
	DESTINSTALL_PATH = "/usr/local/"
	SERVER_WIN       = "windows"
	SERVER_LINUX     = "linux"
	SERVER_OSX       = "osx"

	LANG_GO    = "go"
	LANG_JAVA  = "java"
	LANG_SCALA = "scala"
)

type LangenvironmentController struct {
	App
}

func getArch(serverOS string, lang string, arch string) string {
	var result string
	if serverOS == SERVER_LINUX {
		if lang == LANG_GO {
			result = fmt.Sprintf("%s1.6.%s-%s.%s", LANG_GO, SERVER_LINUX, strings.TrimSpace(arch), "tar.gz")
		}
	} else if serverOS == SERVER_WIN {
		if lang == LANG_GO {
			result = fmt.Sprintf("%s1.6.%s-%s.%s", LANG_GO, SERVER_WIN, strings.TrimSpace(arch), "zip")
		}
	}

	return result
}

func CreateLangenvironmentController(l *knot.Server) *LangenvironmentController {
	var controller = new(LangenvironmentController)
	controller.Server = l
	return controller
}

func (l *LangenvironmentController) GetSampleDataForSetupLang() colonycore.LanguageEnvironmentPayload {
	// s := `[{ "ServerId": "vagrant-test1", "Lang": [ "go" ] }, { "ServerId": "vagrant-test2", "Lang": [ "go", "java" ] }]`
	s := `{ "ServerId": "localhost", "Lang": "go" }`

	r := colonycore.LanguageEnvironmentPayload{}
	err := json.Unmarshal([]byte(s), &r)
	if err != nil {
		fmt.Println(err)
	}

	return r
}

func (le *LangenvironmentController) GetLanguage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	cursor, err := colonycore.Find(new(colonycore.LanguageEnviroment), nil)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	data := []colonycore.LanguageEnviroment{}
	err = cursor.Fetch(&data, 0, false)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	// fmt.Println(data)
	defer cursor.Close()

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

func (le *LangenvironmentController) GetServerLanguage(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	cursorServer, err := colonycore.Find(new(colonycore.Server), dbox.Eq("serverType", "node"))
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	dataServer := []colonycore.Server{}
	err = cursorServer.Fetch(&dataServer, 0, false)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer cursorServer.Close()

	cursorLangEnc, err := colonycore.Find(new(colonycore.LanguageEnviroment), nil)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	dataLangEnv := []colonycore.LanguageEnviroment{}
	err = cursorLangEnc.Fetch(&dataLangEnv, 0, false)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer cursorLangEnc.Close()

	result := []*colonycore.ServerLanguage{}
	// result := []ServerLanguage{}

	for _, each := range dataServer {
		serverLang := new(colonycore.ServerLanguage)
		serverLang.ServerID = each.ID
		serverLang.ServerOS = each.OS
		serverLang.ServerHost = each.Host
		serverLang.Languages = []*colonycore.InstalledLang{}

		if each.InstalledLang == nil {
			each.InstalledLang = []*colonycore.InstalledLang{}
		}

		for _, eachLang := range dataLangEnv {
			var lang *colonycore.InstalledLang = nil
			for _, eachInstalledLang := range each.InstalledLang {
				if eachInstalledLang.Lang == eachLang.Language {
					lang = eachInstalledLang
					break
				}
			}

			if lang == nil {
				lang = new(colonycore.InstalledLang)
				lang.Lang = eachLang.Language
				lang.Version = ""
				lang.IsInstalled = false
			}

			serverLang.Languages = append(serverLang.Languages, lang)
		}

		result = append(result, serverLang)
	}

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

func (l *LangenvironmentController) SetupFromSH(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	// payload := l.GetSampleDataForSetupLang()

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

	dataServers := new(colonycore.Server)
	err = colonycore.Get(dataServers, payload.ServerId)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	serverPathSeparator := CreateApplicationController(l.Server).GetServerPathSeparator(dataServers)
	// fmt.Println(" ::: ", dataServers)

	sshSetting, sshClient, err := dataServers.Connect()
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer sshClient.Close()

	dataLanguage := []colonycore.LanguageEnviroment{}
	cursor, err := colonycore.Find(new(colonycore.LanguageEnviroment), dbox.Eq("language", payload.Lang))
	cursor.Fetch(&dataLanguage, 0, false)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	defer cursor.Close()
	if cursor.Count() > 0 {
		for _, eachLang := range dataLanguage {
			for _, dataInstaller := range eachLang.Installer {
				var sourcePath string
				var destinationPath string
				pathstring := []string{dataServers.DataPath, "langenvironment", "installer"}

				var installShPath string

				if strings.ToLower(dataServers.OS) == strings.ToLower(dataInstaller.OS) {
					targetLang := new(colonycore.InstalledLang)
					targetLang.Lang = eachLang.Language

					for _, eachLang := range dataServers.InstalledLang {
						if eachLang.Lang == targetLang.Lang {
							targetLang = eachLang
							break
						}
					}

					if eachLang.Language == LANG_GO {
						pathstring = append(pathstring, LANG_GO)
						pathstring = append(pathstring, dataServers.OS)
						sourcePath = filepath.Join(leSourcePath, LANG_GO, dataServers.OS, dataInstaller.InstallerSource)
						destinationPath = strings.Join(pathstring, serverPathSeparator)
						installShPath = filepath.Join(leSourcePath, LANG_GO, dataServers.OS, "install.sh")
					} else if eachLang.Language == LANG_JAVA {
						pathstring = append(pathstring, LANG_JAVA)
						pathstring = append(pathstring, dataServers.OS)
						sourcePath = filepath.Join(leSourcePath, LANG_JAVA, dataServers.OS, dataInstaller.InstallerSource)
						destinationPath = strings.Join(pathstring, serverPathSeparator)
						installShPath = filepath.Join(leSourcePath, LANG_JAVA, dataServers.OS, "install.sh")
					} else if eachLang.Language == LANG_SCALA {
						pathstring = append(pathstring, LANG_SCALA)
						pathstring = append(pathstring, dataServers.OS)
						sourcePath = filepath.Join(leSourcePath, LANG_SCALA, dataServers.OS, dataInstaller.InstallerSource)
						destinationPath = strings.Join(pathstring, serverPathSeparator)
						installShPath = filepath.Join(leSourcePath, LANG_SCALA, dataServers.OS, "install.sh")
					}
					installShdestPath := strings.Join(append(pathstring, "install.sh"), serverPathSeparator)
					installFilePath := strings.Join(append(pathstring, dataInstaller.InstallerSource), serverPathSeparator)

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

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

					//sed -i 's/^M//' install.sh
					cmdSedInstall := fmt.Sprintf("sed -i 's/\r//g' %s", installShdestPath)
					_, err = sshSetting.GetOutputCommandSsh(cmdSedInstall)
					if err != nil {
						return helper.CreateResult(false, nil, err.Error())
					}

					// // chmod +x install.sh
					cmdChmodCli := fmt.Sprintf("chmod -x %s", installShdestPath)
					_, err = sshSetting.GetOutputCommandSsh(cmdChmodCli)
					if err != nil {
						return helper.CreateResult(false, nil, err.Error())
					}

					// // sh install.sh installFilePath DESTINSTALL_PATH projectpath
					cmdShCli := fmt.Sprintf("bash %s %s %s", installShdestPath, installFilePath, DESTINSTALL_PATH)
					outputCmd, err := sshSetting.RunCommandSshAsMap(cmdShCli)
					if err != nil {
						return helper.CreateResult(false, nil, err.Error())
					}
					// fmt.Println(" --- > ", outputCmd)
					// fmt.Println("go run : ", outputCmd[0].CMD)
					fmt.Println(" :: : ", outputCmd[0].Output)

					targetLang.IsInstalled = true
					dataServers.InstalledLang = append(dataServers.InstalledLang, targetLang)
					colonycore.Save(dataServers)
				}
			}
		}
	}

	return helper.CreateResult(true, payload, "")
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"flag"
	"log"
	"net/http"

	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

var (
	dbConn *sql.DB = nil
	db             = flag.String("db", "", "the db")
	user           = flag.String("user", "", "the db user")
	pwd            = flag.String("pwd", "", "the db password")
)

func Handler(w http.ResponseWriter, r *http.Request) {
	shorturl := mux.Vars(r)["shorturl"]

	// lookup shorturl
	var longurl string
	var access_count int
	err := dbConn.QueryRow("select long,access_count from url where short=?", shorturl).Scan(&longurl, &access_count)

	// TODO: update accessed and access_count

	switch {
	case err == sql.ErrNoRows:
		http.NotFound(w, r)

	case err != nil:
		log.Fatal(err)

	default:
		access_count++
		http.Redirect(w, r, longurl, 200)
	}
}

func main() {
	dbConn, err := sql.Open("mysql", *user+":"+*pwd+"@/"+*db)
	if err != nil {
		log.Fatal("Failed to open sql dbConnection")
	}
	defer dbConn.Close()

	r := mux.NewRouter()
	// TODO: dashboard with metrics
	r.HandleFunc("/{shorturl}", Handler).Methods("GET")
	http.Handle("/", r)
}
<commit_msg>Actually listen and set the port by flag<commit_after>package main

import (
	"database/sql"
	"flag"
	"log"
	"net/http"

	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

var (
	dbConn *sql.DB = nil
	db             = flag.String("db", "", "the db")
	user           = flag.String("user", "", "the db user")
	pwd            = flag.String("pwd", "", "the db password")
	port	       = flag.String("port", "http", "the port to listen on")
)

func Handler(w http.ResponseWriter, r *http.Request) {
	shorturl := mux.Vars(r)["shorturl"]

	// lookup shorturl
	var longurl string
	var access_count int
	err := dbConn.QueryRow("select long,access_count from url where short=?", shorturl).Scan(&longurl, &access_count)

	// TODO: update accessed and access_count

	switch {
	case err == sql.ErrNoRows:
		http.NotFound(w, r)

	case err != nil:
		log.Fatal(err)

	default:
		access_count++
		http.Redirect(w, r, longurl, 200)
	}
}

func main() {
	flag.Parse()

	dbConn, err := sql.Open("mysql", *user+":"+*pwd+"@/"+*db)
	if err != nil {
		log.Fatal("Failed to open sql dbConnection")
	}
	defer dbConn.Close()

	r := mux.NewRouter()
	// TODO: dashboard with metrics
	r.HandleFunc("/{shorturl}", Handler).Methods("GET")
	http.Handle("/", r)

	log.Fatal(http.ListenAndServe(":"+*port, nil))
}
<|endoftext|>


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

// Package sequtils provides generic functions for manipulation of biogo/seq/... types.
package sequtils

import (
	"code.google.com/p/biogo/alphabet"
	"code.google.com/p/biogo/feat"
	"code.google.com/p/biogo/seq"

	"errors"
	"sort"
)

// A Joinable can be joined to another of the same concrete type using the Join function.
type Joinable interface {
	SetOffset(int) error
	Slice() alphabet.Slice
	SetSlice(alphabet.Slice)
}

// Join joins a and be with the target location of b specified by where. The offset of dst
// will be updated if src is prepended. Join will panic if dst and src do not hold the same
// concrete Slice type. Circular sequences cannot be joined.
func Join(dst, src Joinable, where int) error {
	dstC, dstOk := dst.(seq.Conformationer)
	srcC, srcOk := src.(seq.Conformationer)
	switch {
	case dstOk && dstC.Conformation() > feat.Linear, srcOk && srcC.Conformation() > feat.Linear:
		return errors.New("sequtils: cannot join circular sequence")
	}

	o := dst
	if where == seq.End {
		src, dst = dst, src
	}
	dstSl, srcSl := dst.Slice(), src.Slice()
	srcLen := srcSl.Len()
	if where == seq.Start {
		dst.SetOffset(-srcLen)
	}
	t := dst.Slice().Make(srcLen, srcLen+dstSl.Len())
	t.Copy(srcSl)
	o.SetSlice(t.Append(dstSl))
	return nil
}

// A Sliceable can be truncated, stitched and composed.
type Sliceable interface {
	Start() int
	End() int
	SetOffset(int) error
	Slice() alphabet.Slice
	SetSlice(alphabet.Slice)
}

// Truncate performs a truncation on src from start to end and places the result in dst.
// The conformation of dst is set to linear and the offset is set to start. If dst and src
// are not equal, a copy of the truncation is allocated. Only circular sequences can be
// truncated with start > end.
func Truncate(dst, src Sliceable, start, end int) error {
	var (
		sl     = src.Slice()
		offset = src.Start()
	)
	if start < offset || end > src.End() {
		return errors.New("sequtils: index out of range")
	}
	if start <= end {
		if dst == src {
			dst.SetSlice(sl.Slice(start-offset, end-offset))
		} else {
			dst.SetSlice(sl.Make(0, sl.Len()).Append(sl.Slice(start-offset, end-offset)))
		}
		dst.SetOffset(start)
		if dst, ok := dst.(seq.ConformationSetter); ok {
			dst.SetConformation(feat.Linear)
		}
		return nil
	}

	if src, ok := src.(seq.Conformationer); !ok || src.Conformation() == feat.Linear {
		return errors.New("sequtils: start position greater than end position for linear sequence")
	}
	if end < offset || start > src.End() {
		return errors.New("sequtils: index out of range")
	}
	t := sl.Make(sl.Len()-start+offset, sl.Len()+end-start)
	t.Copy(sl.Slice(start-offset, sl.Len()))
	dst.SetSlice(t.Append(sl.Slice(0, end-offset)))
	dst.SetOffset(start)
	if dst, ok := dst.(seq.ConformationSetter); ok {
		dst.SetConformation(feat.Linear)
	}

	return nil
}

type feats []feat.Feature

func (f feats) Len() int           { return len(f) }
func (f feats) Less(i, j int) bool { return f[i].Start() < f[j].Start() }
func (f feats) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// Stitch produces a subsequence of src defined by fs and places the the result in dst.
// The subsequences are guaranteed to be in order and non-overlapping even if not provided as such.
// Stitching a circular sequence returns a linear sequence.
func Stitch(dst, src Sliceable, fs feat.Set) error {
	var (
		sl     = src.Slice()
		offset = src.Start()
		ff     = feats(fs.Features())
	)
	for _, f := range ff {
		if f.End() < f.Start() {
			return errors.New("sequtils: feature end < feature start")
		}
	}
	ff = append(feats(nil), ff...)
	sort.Sort(ff)
	// FIXME Does not correctly deal with circular sequences and feature sets.
	// Range over ff if src is circular and  and trunc at start and end, do checks to
	// see if feature splits on origin and rearrange tail to front.

	pLen := sl.Len()
	end := pLen + offset

	type fi struct{ s, e int }
	var (
		fsp = make([]*fi, 0, len(ff))
		csp *fi
	)
	for i, f := range ff {
		if s := f.Start(); i == 0 || s > csp.e {
			csp = &fi{s: s, e: f.End()}
			fsp = append(fsp, csp)
		} else {
			csp.e = max(csp.e, f.End())
		}
	}

	var l int
	for _, f := range fsp {
		l += max(0, min(f.e, end)-max(f.s, offset))
	}
	t := sl.Make(0, l)

	for _, f := range fsp {
		fs, fe := max(f.s-offset, 0), min(f.e-offset, pLen)
		if fs >= fe {
			continue
		}
		t = t.Append(sl.Slice(fs, fe))
	}

	dst.SetSlice(t)
	if dst, ok := dst.(seq.ConformationSetter); ok {
		dst.SetConformation(feat.Linear)
	}
	dst.SetOffset(0)

	return nil
}

type SliceReverser interface {
	Sliceable
	New() seq.Sequence
	Alphabet() alphabet.Alphabet
	SetAlphabet(alphabet.Alphabet) error
	RevComp()
	Reverse()
}

// Compose produces a composition of src defined by the features in fs. The subparts of
// the composition may be out of order and if features in fs specify orientation may be
// reversed or reverse complemented depending on the src - if src is a SliceReverser and
// its alphabet is a Complementor the segment will be reverse complemented, if the alphabte
// is not a Complementor these segments will only be reversed. If src is not a SliceREverser
// and a reverse segment is specified an error is returned.
// Composing a circular sequence returns a linear sequence.
func Compose(dst, src Sliceable, fs feat.Set) error {
	var (
		sl     = src.Slice()
		offset = src.Start()
		ff     = feats(fs.Features())
	)

	pLen := sl.Len()
	end := pLen + offset

	t := make([]alphabet.Slice, len(ff))
	var tl int
	for i, f := range ff {
		if f.End() < f.Start() {
			return errors.New("sequtils: feature end < feature start")
		}
		l := min(f.End(), end) - max(f.Start(), offset)
		tl += l
		t[i] = sl.Make(l, l)
		t[i].Copy(sl.Slice(max(f.Start()-offset, 0), min(f.End()-offset, pLen)))
	}

	c := sl.Make(0, tl)
	var r SliceReverser
	for i, ts := range t {
		if f, ok := ff[i].(feat.Orienter); ok && f.Orientation() == feat.Reverse {
			switch src := src.(type) {
			case SliceReverser:
				if r == nil {
					r = src.New().(SliceReverser)
					if _, ok := src.Alphabet().(alphabet.Complementor); ok {
						r.SetAlphabet(src.Alphabet())
						r.SetSlice(ts)
						r.RevComp()
					} else {
						r.SetSlice(ts)
						r.Reverse()
					}
				}
			default:
				return errors.New("sequtils: unable to reverse segment during compose")
			}
			c = c.Append(r.Slice())
		} else {
			c = c.Append(ts)
		}
	}

	dst.SetSlice(c)
	if dst, ok := dst.(seq.ConformationSetter); ok {
		dst.SetConformation(feat.Linear)
	}
	dst.SetOffset(0)

	return nil
}

// A QualityFeature describes a segment of sequence quality information. EAt() called with
// column values within Start() and End() is expected to return valid error probabilities for
// the zero'th row position.
type QualityFeature interface {
	feat.Feature
	EAt(int) float64
}

// Trim uses the modified-Mott trimming function to determine the start and end positions
// of good sequence. http://www.phrap.org/phredphrap/phred.html
func Trim(q QualityFeature, limit float64) (start, end int) {
	var sum, max float64
	for i := q.Start(); i < q.End(); i++ {
		sum += limit - q.EAt(i)
		if sum < 0 {
			sum, start = 0, i+1
		}
		if sum >= max {
			max, end = sum, i+1
		}
	}
	return
}
<commit_msg>Do not overallocate when truncating<commit_after>// Copyright ©2011-2013 The bíogo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package sequtils provides generic functions for manipulation of biogo/seq/... types.
package sequtils

import (
	"code.google.com/p/biogo/alphabet"
	"code.google.com/p/biogo/feat"
	"code.google.com/p/biogo/seq"

	"errors"
	"sort"
)

// A Joinable can be joined to another of the same concrete type using the Join function.
type Joinable interface {
	SetOffset(int) error
	Slice() alphabet.Slice
	SetSlice(alphabet.Slice)
}

// Join joins a and be with the target location of b specified by where. The offset of dst
// will be updated if src is prepended. Join will panic if dst and src do not hold the same
// concrete Slice type. Circular sequences cannot be joined.
func Join(dst, src Joinable, where int) error {
	dstC, dstOk := dst.(seq.Conformationer)
	srcC, srcOk := src.(seq.Conformationer)
	switch {
	case dstOk && dstC.Conformation() > feat.Linear, srcOk && srcC.Conformation() > feat.Linear:
		return errors.New("sequtils: cannot join circular sequence")
	}

	o := dst
	if where == seq.End {
		src, dst = dst, src
	}
	dstSl, srcSl := dst.Slice(), src.Slice()
	srcLen := srcSl.Len()
	if where == seq.Start {
		dst.SetOffset(-srcLen)
	}
	t := dst.Slice().Make(srcLen, srcLen+dstSl.Len())
	t.Copy(srcSl)
	o.SetSlice(t.Append(dstSl))
	return nil
}

// A Sliceable can be truncated, stitched and composed.
type Sliceable interface {
	Start() int
	End() int
	SetOffset(int) error
	Slice() alphabet.Slice
	SetSlice(alphabet.Slice)
}

// Truncate performs a truncation on src from start to end and places the result in dst.
// The conformation of dst is set to linear and the offset is set to start. If dst and src
// are not equal, a copy of the truncation is allocated. Only circular sequences can be
// truncated with start > end.
func Truncate(dst, src Sliceable, start, end int) error {
	var (
		sl     = src.Slice()
		offset = src.Start()
	)
	if start < offset || end > src.End() {
		return errors.New("sequtils: index out of range")
	}
	if start <= end {
		if dst == src {
			dst.SetSlice(sl.Slice(start-offset, end-offset))
		} else {
			dst.SetSlice(sl.Make(0, end-start).Append(sl.Slice(start-offset, end-offset)))
		}
		dst.SetOffset(start)
		if dst, ok := dst.(seq.ConformationSetter); ok {
			dst.SetConformation(feat.Linear)
		}
		return nil
	}

	if src, ok := src.(seq.Conformationer); !ok || src.Conformation() == feat.Linear {
		return errors.New("sequtils: start position greater than end position for linear sequence")
	}
	if end < offset || start > src.End() {
		return errors.New("sequtils: index out of range")
	}
	t := sl.Make(sl.Len()-start+offset, sl.Len()+end-start)
	t.Copy(sl.Slice(start-offset, sl.Len()))
	dst.SetSlice(t.Append(sl.Slice(0, end-offset)))
	dst.SetOffset(start)
	if dst, ok := dst.(seq.ConformationSetter); ok {
		dst.SetConformation(feat.Linear)
	}

	return nil
}

type feats []feat.Feature

func (f feats) Len() int           { return len(f) }
func (f feats) Less(i, j int) bool { return f[i].Start() < f[j].Start() }
func (f feats) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// Stitch produces a subsequence of src defined by fs and places the the result in dst.
// The subsequences are guaranteed to be in order and non-overlapping even if not provided as such.
// Stitching a circular sequence returns a linear sequence.
func Stitch(dst, src Sliceable, fs feat.Set) error {
	var (
		sl     = src.Slice()
		offset = src.Start()
		ff     = feats(fs.Features())
	)
	for _, f := range ff {
		if f.End() < f.Start() {
			return errors.New("sequtils: feature end < feature start")
		}
	}
	ff = append(feats(nil), ff...)
	sort.Sort(ff)
	// FIXME Does not correctly deal with circular sequences and feature sets.
	// Range over ff if src is circular and  and trunc at start and end, do checks to
	// see if feature splits on origin and rearrange tail to front.

	pLen := sl.Len()
	end := pLen + offset

	type fi struct{ s, e int }
	var (
		fsp = make([]*fi, 0, len(ff))
		csp *fi
	)
	for i, f := range ff {
		if s := f.Start(); i == 0 || s > csp.e {
			csp = &fi{s: s, e: f.End()}
			fsp = append(fsp, csp)
		} else {
			csp.e = max(csp.e, f.End())
		}
	}

	var l int
	for _, f := range fsp {
		l += max(0, min(f.e, end)-max(f.s, offset))
	}
	t := sl.Make(0, l)

	for _, f := range fsp {
		fs, fe := max(f.s-offset, 0), min(f.e-offset, pLen)
		if fs >= fe {
			continue
		}
		t = t.Append(sl.Slice(fs, fe))
	}

	dst.SetSlice(t)
	if dst, ok := dst.(seq.ConformationSetter); ok {
		dst.SetConformation(feat.Linear)
	}
	dst.SetOffset(0)

	return nil
}

type SliceReverser interface {
	Sliceable
	New() seq.Sequence
	Alphabet() alphabet.Alphabet
	SetAlphabet(alphabet.Alphabet) error
	RevComp()
	Reverse()
}

// Compose produces a composition of src defined by the features in fs. The subparts of
// the composition may be out of order and if features in fs specify orientation may be
// reversed or reverse complemented depending on the src - if src is a SliceReverser and
// its alphabet is a Complementor the segment will be reverse complemented, if the alphabte
// is not a Complementor these segments will only be reversed. If src is not a SliceREverser
// and a reverse segment is specified an error is returned.
// Composing a circular sequence returns a linear sequence.
func Compose(dst, src Sliceable, fs feat.Set) error {
	var (
		sl     = src.Slice()
		offset = src.Start()
		ff     = feats(fs.Features())
	)

	pLen := sl.Len()
	end := pLen + offset

	t := make([]alphabet.Slice, len(ff))
	var tl int
	for i, f := range ff {
		if f.End() < f.Start() {
			return errors.New("sequtils: feature end < feature start")
		}
		l := min(f.End(), end) - max(f.Start(), offset)
		tl += l
		t[i] = sl.Make(l, l)
		t[i].Copy(sl.Slice(max(f.Start()-offset, 0), min(f.End()-offset, pLen)))
	}

	c := sl.Make(0, tl)
	var r SliceReverser
	for i, ts := range t {
		if f, ok := ff[i].(feat.Orienter); ok && f.Orientation() == feat.Reverse {
			switch src := src.(type) {
			case SliceReverser:
				if r == nil {
					r = src.New().(SliceReverser)
					if _, ok := src.Alphabet().(alphabet.Complementor); ok {
						r.SetAlphabet(src.Alphabet())
						r.SetSlice(ts)
						r.RevComp()
					} else {
						r.SetSlice(ts)
						r.Reverse()
					}
				}
			default:
				return errors.New("sequtils: unable to reverse segment during compose")
			}
			c = c.Append(r.Slice())
		} else {
			c = c.Append(ts)
		}
	}

	dst.SetSlice(c)
	if dst, ok := dst.(seq.ConformationSetter); ok {
		dst.SetConformation(feat.Linear)
	}
	dst.SetOffset(0)

	return nil
}

// A QualityFeature describes a segment of sequence quality information. EAt() called with
// column values within Start() and End() is expected to return valid error probabilities for
// the zero'th row position.
type QualityFeature interface {
	feat.Feature
	EAt(int) float64
}

// Trim uses the modified-Mott trimming function to determine the start and end positions
// of good sequence. http://www.phrap.org/phredphrap/phred.html
func Trim(q QualityFeature, limit float64) (start, end int) {
	var sum, max float64
	for i := q.Start(); i < q.End(); i++ {
		sum += limit - q.EAt(i)
		if sum < 0 {
			sum, start = 0, i+1
		}
		if sum >= max {
			max, end = sum, i+1
		}
	}
	return
}
<|endoftext|>


<commit_before>// Package regserv implements a registration server kite. Users can register
// to a kite infrastructure by running "kite register" command.
package regserv

import (
	"errors"
	"github.com/dgrijalva/jwt-go"
	"github.com/nu7hatch/gouuid"
	"kite"
	"kite/kitekey"
	"os"
	"time"
)

const version = "0.0.1"

// RegServ is a registration kite. Users can register their machines by
// running "kite register" command.
type RegServ struct {
	Environment string
	Region      string
	PublicIP    string
	Port        string
	backend     Backend
	kite        *kite.Kite
}

func New(backend Backend) *RegServ {
	return &RegServ{
		Environment: "production",
		Region:      "localhost",
		backend:     backend,
	}
}

func (s *RegServ) Run() {
	if s.Environment == "" || s.Region == "" || s.PublicIP == "" || s.Port == "" {
		panic("RegServ is not initialized properly")
	}

	_, err := kitekey.Parse()
	if err != nil {
		s.RegisterSelf() // Need to do this before creating new kite
	}

	// Create a kite and run it.
	opts := &kite.Options{
		Kitename:    "regserv",
		Version:     version,
		Environment: s.Environment,
		Region:      s.Region,
		PublicIP:    s.PublicIP,
		Port:        s.Port,
		Path:        "/regserv",
		DisableAuthentication: true,
	}
	s.kite = kite.New(opts)
	s.kite.HandleFunc("register", s.handleRegister)
	s.kite.Run()
}

// RegisterSelf registers this host and writes a key to ~/.kite/kite.key
func (s *RegServ) RegisterSelf() error {
	hostname, err := os.Hostname()
	if err != nil {
		return err
	}
	key, err := s.register(s.backend.Username(), hostname)
	if err != nil {
		return err
	}
	return kitekey.Write(key)
}

// Backend is the interface that is passed to New() function.
type Backend interface {
	Username() string
	KontrolURL() string
	PublicKey() string
	PrivateKey() string

	// Authenticate the user and return username.
	Authenticate(r *kite.Request) (string, error)
}

func (s *RegServ) handleRegister(r *kite.Request) (interface{}, error) {
	var args struct {
		Hostname string
	}
	r.Args.One().MustUnmarshal(&args)

	username, err := s.backend.Authenticate(r)
	if err != nil {
		return nil, errors.New("cannot authenticate user")
	}

	return s.register(username, args.Hostname)
}

func (s *RegServ) register(username, hostname string) (kiteKey string, err error) {
	tknID, err := uuid.NewV4()
	if err != nil {
		return "", errors.New("cannot generate a token")
	}

	token := jwt.New(jwt.GetSigningMethod("RS256"))

	token.Claims = map[string]interface{}{
		"iss":        s.backend.Username(),    // Issuer
		"sub":        username,                // Subject
		"iat":        time.Now().UTC().Unix(), // Issued At
		"hostname":   hostname,                // Hostname of registered machine
		"kontrolURL": s.backend.KontrolURL(),  // Kontrol URL
		"kontrolKey": s.backend.PublicKey(),   // Public key of kontrol
		"jti":        tknID.String(),          // JWT ID
	}

	return token.SignedString([]byte(s.backend.PrivateKey()))
}
<commit_msg>regserv prints the register command<commit_after>// Package regserv implements a registration server kite. Users can register
// to a kite infrastructure by running "kite register" command.
package regserv

import (
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/nu7hatch/gouuid"
	"kite"
	"kite/kitekey"
	"os"
	"time"
)

const version = "0.0.1"

// RegServ is a registration kite. Users can register their machines by
// running "kite register" command.
type RegServ struct {
	Environment string
	Region      string
	PublicIP    string
	Port        string
	backend     Backend
	kite        *kite.Kite
}

func New(backend Backend) *RegServ {
	return &RegServ{
		Environment: "production",
		Region:      "localhost",
		backend:     backend,
	}
}

func (s *RegServ) Run() {
	if s.Environment == "" || s.Region == "" || s.PublicIP == "" || s.Port == "" {
		panic("RegServ is not initialized properly")
	}

	_, err := kitekey.Parse()
	if err != nil {
		s.RegisterSelf() // Need to do this before creating new kite
	}

	// Create a kite and run it.
	opts := &kite.Options{
		Kitename:    "regserv",
		Version:     version,
		Environment: s.Environment,
		Region:      s.Region,
		PublicIP:    s.PublicIP,
		Port:        s.Port,
		Path:        "/regserv",
		DisableAuthentication: true,
	}
	s.kite = kite.New(opts)
	s.kite.HandleFunc("register", s.handleRegister)

	ready := s.kite.ReadyNotify()
	go func() {
		<-ready
		fmt.Println("Users can register with the following command:")
		fmt.Printf("kite register -to '%s'\n", s.kite.URL.String())
	}()

	s.kite.Run()
}

// RegisterSelf registers this host and writes a key to ~/.kite/kite.key
func (s *RegServ) RegisterSelf() error {
	hostname, err := os.Hostname()
	if err != nil {
		return err
	}
	key, err := s.register(s.backend.Username(), hostname)
	if err != nil {
		return err
	}
	return kitekey.Write(key)
}

// Backend is the interface that is passed to New() function.
type Backend interface {
	Username() string
	KontrolURL() string
	PublicKey() string
	PrivateKey() string

	// Authenticate the user and return username.
	Authenticate(r *kite.Request) (string, error)
}

func (s *RegServ) handleRegister(r *kite.Request) (interface{}, error) {
	var args struct {
		Hostname string
	}
	r.Args.One().MustUnmarshal(&args)

	username, err := s.backend.Authenticate(r)
	if err != nil {
		return nil, errors.New("cannot authenticate user")
	}

	return s.register(username, args.Hostname)
}

func (s *RegServ) register(username, hostname string) (kiteKey string, err error) {
	tknID, err := uuid.NewV4()
	if err != nil {
		return "", errors.New("cannot generate a token")
	}

	token := jwt.New(jwt.GetSigningMethod("RS256"))

	token.Claims = map[string]interface{}{
		"iss":        s.backend.Username(),    // Issuer
		"sub":        username,                // Subject
		"iat":        time.Now().UTC().Unix(), // Issued At
		"hostname":   hostname,                // Hostname of registered machine
		"kontrolURL": s.backend.KontrolURL(),  // Kontrol URL
		"kontrolKey": s.backend.PublicKey(),   // Public key of kontrol
		"jti":        tknID.String(),          // JWT ID
	}

	return token.SignedString([]byte(s.backend.PrivateKey()))
}
<|endoftext|>


<commit_before>package dbus

import (
	"container/list"
	"sync"
)

// NewSequentialSignalHandler returns an instance of a new
// signal handler that guarantees sequential processing of signals. It is a
// guarantee of this signal handler that signals will be written to
// channels in the order they are received on the DBus connection.
func NewSequentialSignalHandler() SignalHandler {
	return &sequentialSignalHandler{}
}

type sequentialSignalHandler struct {
	mu      sync.RWMutex
	closed  bool
	signals []*sequentialSignalChannelData
}

func (sh *sequentialSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
	sh.mu.RLock()
	defer sh.mu.RUnlock()
	if sh.closed {
		return
	}
	for _, scd := range sh.signals {
		scd.deliver(signal)
	}
}

func (sh *sequentialSignalHandler) Terminate() {
	sh.mu.Lock()
	defer sh.mu.Unlock()
	if sh.closed {
		return
	}

	for _, scd := range sh.signals {
		scd.close()
		close(scd.ch)
	}
	sh.closed = true
	sh.signals = nil
}

func (sh *sequentialSignalHandler) AddSignal(ch chan<- *Signal) {
	sh.mu.Lock()
	defer sh.mu.Unlock()
	if sh.closed {
		return
	}
	sh.signals = append(sh.signals, newSequentialSignalChannelData(ch))
}

func (sh *sequentialSignalHandler) RemoveSignal(ch chan<- *Signal) {
	sh.mu.Lock()
	defer sh.mu.Unlock()
	if sh.closed {
		return
	}
	for i := len(sh.signals) - 1; i >= 0; i-- {
		if ch == sh.signals[i].ch {
			sh.signals[i].close()
			copy(sh.signals[i:], sh.signals[i+1:])
			sh.signals[len(sh.signals)-1] = nil
			sh.signals = sh.signals[:len(sh.signals)-1]
		}
	}
}

type sequentialSignalChannelData struct {
	ch   chan<- *Signal
	in   chan *Signal
	done chan struct{}
}

func newSequentialSignalChannelData(ch chan<- *Signal) *sequentialSignalChannelData {
	scd := &sequentialSignalChannelData{
		ch:   ch,
		in:   make(chan *Signal),
		done: make(chan struct{}),
	}
	go scd.bufferSignals()
	return scd
}

func (scd *sequentialSignalChannelData) bufferSignals() {
	var (
		queue list.List
		next  *Signal
	)
	defer close(scd.done)

	for {
		if next == nil {
			if queue.Len() != 0 {
				elem := queue.Front()
				queue.Remove(elem)
				next = elem.Value.(*Signal)
			} else {
				var ok bool
				next, ok = <-scd.in
				if !ok {
					return
				}
			}
		}
		select {
		case scd.ch <- next:
			// Signal delivered: the next signal will be
			// picked next iteration.
			next = nil
		case signal, ok := <-scd.in:
			if ok {
				queue.PushBack(signal)
			} else {
				return
			}
		}
	}
}

func (scd *sequentialSignalChannelData) deliver(signal *Signal) {
	scd.in <- signal
}

func (scd *sequentialSignalChannelData) close() {
	close(scd.in)
	// Ensure that bufferSignals() has exited and won't attempt
	// any future sends on scd.ch
	<-scd.done
}
<commit_msg>sequential_handler: convert queue to from a list to a slice<commit_after>package dbus

import (
	"sync"
)

// NewSequentialSignalHandler returns an instance of a new
// signal handler that guarantees sequential processing of signals. It is a
// guarantee of this signal handler that signals will be written to
// channels in the order they are received on the DBus connection.
func NewSequentialSignalHandler() SignalHandler {
	return &sequentialSignalHandler{}
}

type sequentialSignalHandler struct {
	mu      sync.RWMutex
	closed  bool
	signals []*sequentialSignalChannelData
}

func (sh *sequentialSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
	sh.mu.RLock()
	defer sh.mu.RUnlock()
	if sh.closed {
		return
	}
	for _, scd := range sh.signals {
		scd.deliver(signal)
	}
}

func (sh *sequentialSignalHandler) Terminate() {
	sh.mu.Lock()
	defer sh.mu.Unlock()
	if sh.closed {
		return
	}

	for _, scd := range sh.signals {
		scd.close()
		close(scd.ch)
	}
	sh.closed = true
	sh.signals = nil
}

func (sh *sequentialSignalHandler) AddSignal(ch chan<- *Signal) {
	sh.mu.Lock()
	defer sh.mu.Unlock()
	if sh.closed {
		return
	}
	sh.signals = append(sh.signals, newSequentialSignalChannelData(ch))
}

func (sh *sequentialSignalHandler) RemoveSignal(ch chan<- *Signal) {
	sh.mu.Lock()
	defer sh.mu.Unlock()
	if sh.closed {
		return
	}
	for i := len(sh.signals) - 1; i >= 0; i-- {
		if ch == sh.signals[i].ch {
			sh.signals[i].close()
			copy(sh.signals[i:], sh.signals[i+1:])
			sh.signals[len(sh.signals)-1] = nil
			sh.signals = sh.signals[:len(sh.signals)-1]
		}
	}
}

type sequentialSignalChannelData struct {
	ch   chan<- *Signal
	in   chan *Signal
	done chan struct{}
}

func newSequentialSignalChannelData(ch chan<- *Signal) *sequentialSignalChannelData {
	scd := &sequentialSignalChannelData{
		ch:   ch,
		in:   make(chan *Signal),
		done: make(chan struct{}),
	}
	go scd.bufferSignals()
	return scd
}

func (scd *sequentialSignalChannelData) bufferSignals() {
	defer close(scd.done)

	// Ensure that signals are delivered to scd.ch in the same
	// order they are received from scd.in.
	var queue []*Signal
	for {
		if len(queue) == 0 {
			signal, ok := <- scd.in
			if !ok {
				return
			}
			queue = append(queue, signal)
		}
		select {
		case scd.ch <- queue[0]:
			copy(queue, queue[1:])
			queue[len(queue)-1] = nil
			queue = queue[:len(queue)-1]
		case signal, ok := <-scd.in:
			if !ok {
				return
			}
			queue = append(queue, signal)
		}
	}
}

func (scd *sequentialSignalChannelData) deliver(signal *Signal) {
	scd.in <- signal
}

func (scd *sequentialSignalChannelData) close() {
	close(scd.in)
	// Ensure that bufferSignals() has exited and won't attempt
	// any future sends on scd.ch
	<-scd.done
}
<|endoftext|>


<commit_before>package render

import (
	"image"
	"image/draw"
	"time"

	"github.com/oakmound/oak/event"
	"github.com/oakmound/oak/render/mod"
	"github.com/oakmound/oak/timing"
)

// A Sequence is a series of modifiables drawn as an animation. It is more
// primitive than animation, but less efficient.
type Sequence struct {
	LayeredPoint
	pauseBool
	InterruptBool
	rs         []Modifiable
	lastChange time.Time
	sheetPos   int
	frameTime  int64
	cID        event.CID
}

// NewSequence returns a new sequence from the input modifiables, playing at
// fps rate
func NewSequence(fps float64, mods ...Modifiable) *Sequence {
	return &Sequence{
		LayeredPoint: NewLayeredPoint(0, 0, 0),
		pauseBool: pauseBool{
			playing: true,
		},
		InterruptBool: InterruptBool{
			Interruptable: true,
		},
		sheetPos:   0,
		frameTime:  timing.FPSToNano(fps),
		rs:         mods,
		lastChange: time.Now(),
	}
}

// Copy copies each modifiable inside this sequence in order to produce a new
// copied sequence
func (sq *Sequence) Copy() Modifiable {
	newSq := new(Sequence)
	*newSq = *sq

	newRs := make([]Modifiable, len(sq.rs))
	for i, r := range sq.rs {
		newRs[i] = r.Copy()
	}

	newSq.rs = newRs
	newSq.LayeredPoint = sq.LayeredPoint.Copy()
	return newSq
}

// SetTriggerID sets the ID that AnimationEnd will be triggered on when this
// sequence loops over from its last frame to its first
func (sq *Sequence) SetTriggerID(id event.CID) {
	sq.cID = id
}

func (sq *Sequence) update() {
	if sq.playing && time.Since(sq.lastChange).Nanoseconds() > sq.frameTime {
		sq.lastChange = time.Now()
		sq.sheetPos = (sq.sheetPos + 1) % len(sq.rs)
		if sq.sheetPos == (len(sq.rs)-1) && sq.cID != 0 {
			sq.cID.Trigger(event.AnimationEnd, nil)
		}
	}
}

// Get returns the Modifiable stored at this sequence's ith index. If the sequence
// does not have an ith index this returns nil
func (sq *Sequence) Get(i int) Modifiable {
	if i < 0 || i >= len(sq.rs) {
		return nil
	}
	return sq.rs[i]
}

// DrawOffset draws this sequence at +xOff, +yOff
func (sq *Sequence) DrawOffset(buff draw.Image, xOff, yOff float64) {
	sq.update()
	sq.rs[sq.sheetPos].DrawOffset(buff, sq.X()+xOff, sq.Y()+yOff)
}

// Draw draws this sequence to the input buffer
func (sq *Sequence) Draw(buff draw.Image) {
	sq.update()
	sq.rs[sq.sheetPos].DrawOffset(buff, sq.X(), sq.Y())
}

// GetRGBA returns the RGBA of the currently showing frame of this sequence
func (sq *Sequence) GetRGBA() *image.RGBA {
	return sq.rs[sq.sheetPos].GetRGBA()
}

// Modify alters each renderable in this sequence by the given
// modifications
func (sq *Sequence) Modify(ms ...mod.Mod) Modifiable {
	for _, r := range sq.rs {
		r.Modify(ms...)
	}
	return sq
}

// Filter filters each element in the sequence by the inputs
func (sq *Sequence) Filter(fs ...mod.Filter) {
	for _, r := range sq.rs {
		r.Filter(fs...)
	}
}

// IsStatic returns false for sequences
func (sq *Sequence) IsStatic() bool {
	return false
}

// TweenSequence returns a sequence that is the tweening between the input images
// at the given frame rate over the given frame count.
func TweenSequence(a, b image.Image, frames int, fps float64) *Sequence {
	images := Tween(a, b, frames)
	ms := make([]Modifiable, len(images))
	for i, v := range images {
		ms[i] = NewSprite(0, 0, v)
	}
	return NewSequence(fps, ms...)
}
<commit_msg>Allow the FPS of a Sequence to be changed after creation<commit_after>package render

import (
	"image"
	"image/draw"
	"time"

	"github.com/oakmound/oak/event"
	"github.com/oakmound/oak/render/mod"
	"github.com/oakmound/oak/timing"
)

// A Sequence is a series of modifiables drawn as an animation. It is more
// primitive than animation, but less efficient.
type Sequence struct {
	LayeredPoint
	pauseBool
	InterruptBool
	rs         []Modifiable
	lastChange time.Time
	sheetPos   int
	frameTime  int64
	cID        event.CID
}

// NewSequence returns a new sequence from the input modifiables, playing at
// fps rate
func NewSequence(fps float64, mods ...Modifiable) *Sequence {
	return &Sequence{
		LayeredPoint: NewLayeredPoint(0, 0, 0),
		pauseBool: pauseBool{
			playing: true,
		},
		InterruptBool: InterruptBool{
			Interruptable: true,
		},
		sheetPos:   0,
		frameTime:  timing.FPSToNano(fps),
		rs:         mods,
		lastChange: time.Now(),
	}
}

// SetFPS sets the number of frames that should advance per second to be
// the input fps
func (sq *Sequence) SetFPS(fps float64) {
	sq.frameTime = timing.FPSToNano(fps)
}

// Copy copies each modifiable inside this sequence in order to produce a new
// copied sequence
func (sq *Sequence) Copy() Modifiable {
	newSq := new(Sequence)
	*newSq = *sq

	newRs := make([]Modifiable, len(sq.rs))
	for i, r := range sq.rs {
		newRs[i] = r.Copy()
	}

	newSq.rs = newRs
	newSq.LayeredPoint = sq.LayeredPoint.Copy()
	return newSq
}

// SetTriggerID sets the ID that AnimationEnd will be triggered on when this
// sequence loops over from its last frame to its first
func (sq *Sequence) SetTriggerID(id event.CID) {
	sq.cID = id
}

func (sq *Sequence) update() {
	if sq.playing && time.Since(sq.lastChange).Nanoseconds() > sq.frameTime {
		sq.lastChange = time.Now()
		sq.sheetPos = (sq.sheetPos + 1) % len(sq.rs)
		if sq.sheetPos == (len(sq.rs)-1) && sq.cID != 0 {
			sq.cID.Trigger(event.AnimationEnd, nil)
		}
	}
}

// Get returns the Modifiable stored at this sequence's ith index. If the sequence
// does not have an ith index this returns nil
func (sq *Sequence) Get(i int) Modifiable {
	if i < 0 || i >= len(sq.rs) {
		return nil
	}
	return sq.rs[i]
}

// DrawOffset draws this sequence at +xOff, +yOff
func (sq *Sequence) DrawOffset(buff draw.Image, xOff, yOff float64) {
	sq.update()
	sq.rs[sq.sheetPos].DrawOffset(buff, sq.X()+xOff, sq.Y()+yOff)
}

// Draw draws this sequence to the input buffer
func (sq *Sequence) Draw(buff draw.Image) {
	sq.update()
	sq.rs[sq.sheetPos].DrawOffset(buff, sq.X(), sq.Y())
}

// GetRGBA returns the RGBA of the currently showing frame of this sequence
func (sq *Sequence) GetRGBA() *image.RGBA {
	return sq.rs[sq.sheetPos].GetRGBA()
}

// Modify alters each renderable in this sequence by the given
// modifications
func (sq *Sequence) Modify(ms ...mod.Mod) Modifiable {
	for _, r := range sq.rs {
		r.Modify(ms...)
	}
	return sq
}

// Filter filters each element in the sequence by the inputs
func (sq *Sequence) Filter(fs ...mod.Filter) {
	for _, r := range sq.rs {
		r.Filter(fs...)
	}
}

// IsStatic returns false for sequences
func (sq *Sequence) IsStatic() bool {
	return false
}

// TweenSequence returns a sequence that is the tweening between the input images
// at the given frame rate over the given frame count.
func TweenSequence(a, b image.Image, frames int, fps float64) *Sequence {
	images := Tween(a, b, frames)
	ms := make([]Modifiable, len(images))
	for i, v := range images {
		ms[i] = NewSprite(0, 0, v)
	}
	return NewSequence(fps, ms...)
}
<|endoftext|>


<commit_before>package sse

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

	"github.com/stellar/go-horizon/log"
	"golang.org/x/net/context"
)

// Event is the packet of data that gets sent over the wire to a connected
// client.
type Event struct {
	Data  interface{}
	Error error
	ID    string
	Event string
	Retry int
}

// SseEvent returns the SSE compatible form of the Event... itself.
func (e Event) SseEvent() Event {
	return e
}

// Upon initial stream creation, we send this event to inform the client
// that they may retry an errored connection after 1 second.
var helloEvent = Event{
	Data:  "hello",
	Event: "open",
	Retry: 1000,
}

// Upon successful completion of a query (i.e. the client didn't disconnect
// and we didn't error) we send a "Goodbye" event.  This is a dummy event
// so that we can set a low retry value so that the client will immediately
// recoonnect and request more data.  This helpes to give the feel of a infinite
// stream of data, even though we're actually responding in PAGE_SIZE chunks.
var goodbyeEvent = Event{
	Data:  "byebye",
	Event: "close",
	Retry: 10,
}

// Eventable represents an object that can be converted to an SSE compatible
// event.
type Eventable interface {
	// SseEvent returns the SSE compatible form of the implementer
	SseEvent() Event
}

// Streamer handles the work of turning a channel of Eventable objects
// into a http response to a client.  Construct one and call `ServeHTTP` to do
// so
type Streamer struct {
	Ctx  context.Context
	Data <-chan Eventable
}

func (s *Streamer) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	_, flushable := w.(http.Flusher)

	if !flushable {
		//TODO: render a problem struct instead of simple string
		http.Error(w, "Streaming Not Supported", http.StatusBadRequest)
		return
	}

	w.Header().Set("Content-Type", "text/event-stream")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.WriteHeader(200)

	// wait for data and stream it as it becomes available
	// finish when either the client closes the connection
	// or the data provider closes the channel
	WriteEvent(s.Ctx, w, helloEvent)
	for {
		select {
		case eventable, more := <-s.Data:
			if !more {
				WriteEvent(s.Ctx, w, goodbyeEvent)
				return
			}
			WriteEvent(s.Ctx, w, eventable.SseEvent())
		case <-s.Ctx.Done():
			return
		}
	}
}

// WriteEvent does the actual work of formatting an SSE compliant message
// sending it over the provided ResponseWriter and flushing.
func WriteEvent(ctx context.Context, w http.ResponseWriter, e Event) {
	if e.Error != nil {
		fmt.Fprint(w, "event: err\n")
		fmt.Fprintf(w, "data: %s\n\n", e.Error.Error())
		w.(http.Flusher).Flush()
		log.Error(ctx, e.Error)
		return
	}

	// TODO: add tests to ensure retry get's properly rendered
	if e.Retry != 0 {
		fmt.Fprintf(w, "retry: %d\n", e.Retry)
	}

	if e.ID != "" {
		fmt.Fprintf(w, "id: %s\n", e.ID)
	}

	if e.Event != "" {
		fmt.Fprintf(w, "event: %s\n", e.Event)
	}

	fmt.Fprintf(w, "data: %s\n\n", getJSON(e.Data))
	w.(http.Flusher).Flush()
}

func getJSON(val interface{}) string {
	js, err := json.Marshal(val)

	if err != nil {
		panic(err)
	}

	return string(js)
}
<commit_msg>Extract sse.WritePreamble<commit_after>package sse

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

	"github.com/stellar/go-horizon/log"
	"golang.org/x/net/context"
)

// Event is the packet of data that gets sent over the wire to a connected
// client.
type Event struct {
	Data  interface{}
	Error error
	ID    string
	Event string
	Retry int
}

// SseEvent returns the SSE compatible form of the Event... itself.
func (e Event) SseEvent() Event {
	return e
}

// Upon initial stream creation, we send this event to inform the client
// that they may retry an errored connection after 1 second.
var helloEvent = Event{
	Data:  "hello",
	Event: "open",
	Retry: 1000,
}

// Upon successful completion of a query (i.e. the client didn't disconnect
// and we didn't error) we send a "Goodbye" event.  This is a dummy event
// so that we can set a low retry value so that the client will immediately
// recoonnect and request more data.  This helpes to give the feel of a infinite
// stream of data, even though we're actually responding in PAGE_SIZE chunks.
var goodbyeEvent = Event{
	Data:  "byebye",
	Event: "close",
	Retry: 10,
}

// Eventable represents an object that can be converted to an SSE compatible
// event.
type Eventable interface {
	// SseEvent returns the SSE compatible form of the implementer
	SseEvent() Event
}

// Streamer handles the work of turning a channel of Eventable objects
// into a http response to a client.  Construct one and call `ServeHTTP` to do
// so
type Streamer struct {
	Ctx  context.Context
	Data <-chan Eventable
}

func (s *Streamer) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	if !WritePreamble(s.Ctx, w) {
		return
	}

	// wait for data and stream it as it becomes available
	// finish when either the client closes the connection
	// or the data provider closes the channel
	for {
		select {
		case eventable, more := <-s.Data:
			if !more {
				WriteEvent(s.Ctx, w, goodbyeEvent)
				return
			}
			WriteEvent(s.Ctx, w, eventable.SseEvent())
		case <-s.Ctx.Done():
			return
		}
	}
}

func WritePreamble(ctx context.Context, w http.ResponseWriter) bool {
	_, flushable := w.(http.Flusher)

	if !flushable {
		//TODO: render a problem struct instead of simple string
		http.Error(w, "Streaming Not Supported", http.StatusBadRequest)
		return false
	}

	w.Header().Set("Content-Type", "text/event-stream")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.WriteHeader(200)

	WriteEvent(ctx, w, helloEvent)

	return true
}

// WriteEvent does the actual work of formatting an SSE compliant message
// sending it over the provided ResponseWriter and flushing.
func WriteEvent(ctx context.Context, w http.ResponseWriter, e Event) {
	if e.Error != nil {
		fmt.Fprint(w, "event: err\n")
		fmt.Fprintf(w, "data: %s\n\n", e.Error.Error())
		w.(http.Flusher).Flush()
		log.Error(ctx, e.Error)
		return
	}

	// TODO: add tests to ensure retry get's properly rendered
	if e.Retry != 0 {
		fmt.Fprintf(w, "retry: %d\n", e.Retry)
	}

	if e.ID != "" {
		fmt.Fprintf(w, "id: %s\n", e.ID)
	}

	if e.Event != "" {
		fmt.Fprintf(w, "event: %s\n", e.Event)
	}

	fmt.Fprintf(w, "data: %s\n\n", getJSON(e.Data))
	w.(http.Flusher).Flush()
}

func getJSON(val interface{}) string {
	js, err := json.Marshal(val)

	if err != nil {
		panic(err)
	}

	return string(js)
}
<|endoftext|>


<commit_before>package handler

import (
	"bytes"
	"fmt"
	modelServer "github.com/vladpereskokov/Technopark_HighLoad-nginx/src/models/server"
	"net"
	"net/url"
	"os"
	"path"
	"strconv"
	"strings"
)

type Handler struct {
	Connection net.Conn
	Request    *modelServer.Request
	Response   *modelServer.Response
	Constants  *modelServer.Constants
	Dir        string
}

type HandlerFunc func(chan net.Conn)

// ?
func CreateHandler(config *modelServer.Constants, dir string) (handlerFunc HandlerFunc) {
	handler := Handler{}
	handler.create(config, dir)

	return func(channel chan net.Conn) {
		go handler.start(channel)
	}
}

func (handler *Handler) create(config *modelServer.Constants, dir string) {
	handler.Request = new(modelServer.Request)

	handler.Response = new(modelServer.Response)
	handler.Response.Status = new(modelServer.Status)
	handler.Response.Headers = make(map[string]string)

	handler.Constants = config
	handler.Dir = dir
}

func (handler *Handler) start(channel chan net.Conn) {
	for {
		handler.Connection = <-channel
		handler.handle()
	}
}

func (handler *Handler) handle() {
	handler.readRequest()
	handler.close()
}

func (handler *Handler) readRequest() {
	buffer := make([]byte, 1024)

	_, err := handler.Connection.Read(buffer)
	if err != nil {
		fmt.Println("Error reading:", err.Error())

		return
	}

	raw_request := string(buffer[:bytes.Index(buffer, []byte{0})])
	start_string := strings.Split(raw_request, "\r\n")[0]
	fmt.Println(start_string)
	handler.parse_start_string(start_string)
}

func (handler *Handler) parse_start_string(start_string string) {
	splited_string := strings.Split(start_string, " ")
	if len(splited_string) != 3 {
		handler.Response.Status.Message = "bad_request"
		handler.Response.Status.Code = 400

		return
	}
	handler.Request.Method.Type = splited_string[0]
	parsed_url, err := url.Parse(splited_string[1])
	if err != nil || !strings.HasPrefix(splited_string[2], "HTTP/") {
		handler.Response.Status.Message = "bad_request"
		handler.Response.Status.Code = 400
	}
	handler.Request.Url = parsed_url
}

func (handler *Handler) process_request() {
	if handler.Response.Status.Code != 200 {
		handler.set_content_headers(nil)
		return
	}

	if !handler.Constants.Methods.Contains(handler.Request.Method.Type) {
		handler.Response.Status.Message = "method_not_allowed"
		handler.Response.Status.Code = 405
	} else {
		handler.preprocess_path()
	}
}

//preproccess path and check file errors
func (handler *Handler) preprocess_path() {
	handler.Request.SetPath(handler.Dir + handler.Request.GetPath())
	file_info := handler.check_path(false)

	if file_info != nil && file_info.IsDir() {
		handler.Request.SetPath(handler.Request.GetPath() + "/index.html")
		file_info = handler.check_path(true)
	}

	handler.set_content_headers(file_info)
}

func (handler *Handler) check_path(is_dir bool) os.FileInfo {
	request_path := handler.Request.GetPath()
	clear_path := path.Clean(request_path)
	handler.Request.SetPath(clear_path)
	info, err := os.Stat(request_path)
	if err != nil {

		if os.IsNotExist(err) && !is_dir {
			handler.Response.Status.Message = "not_found"
			handler.Response.Status.Code = 404
		} else {
			handler.Response.Status.Message = "forbidden"
			handler.Response.Status.Code = 403
		}
	} else if !strings.Contains(clear_path, handler.Dir) {
		handler.Response.Status.Message = "forbidden"
		handler.Response.Status.Code = 403
	}
	return info
}

func (handler *Handler) set_content_headers(info os.FileInfo) {
	if handler.Response.Status.Code == 200 {
		handler.set_header("Content-Length", strconv.Itoa(int(info.Size())))
		handler.set_header("Content-Type", handler.get_content_type())
	} else {
		handler.set_header("Content-Length", strconv.Itoa(len(handler.get_error_body())))
		handler.set_header("Content-Type", ERROR_BODY_MIME_TYPE)
	}
}

func (handler *Handler) get_content_type() string {
	extension := ""
	request_path := handler.get_path()
	last_dot := strings.LastIndex(request_path, ".")
	if last_dot >= 0 {
		extension = request_path[last_dot:]
	}
	val, ok := CONTENT_TYPES[extension]
	if ok {
		return val
	} else {
		return DEFAULT_MIME_TYPE
	}
}

func (handler *Handler) close() {
	handler.Connection.Close()
}
<commit_msg>add get headers<commit_after>package handler

import (
	"bytes"
	"fmt"
	modelServer "github.com/vladpereskokov/Technopark_HighLoad-nginx/src/models/server"
	"net"
	"net/url"
	"os"
	"path"
	"strconv"
	"strings"
)

type Handler struct {
	Connection net.Conn
	Request    *modelServer.Request
	Response   *modelServer.Response
	Constants  *modelServer.Constants
	Dir        string
}

type HandlerFunc func(chan net.Conn)

// ?
func CreateHandler(config *modelServer.Constants, dir string) (handlerFunc HandlerFunc) {
	handler := Handler{}
	handler.create(config, dir)

	return func(channel chan net.Conn) {
		go handler.start(channel)
	}
}

func (handler *Handler) create(config *modelServer.Constants, dir string) {
	handler.Request = new(modelServer.Request)

	handler.Response = new(modelServer.Response)
	handler.Response.Status = new(modelServer.Status)
	handler.Response.Headers = make(map[string]string)

	handler.Constants = config
	handler.Dir = dir
}

func (handler *Handler) start(channel chan net.Conn) {
	for {
		handler.Connection = <-channel
		handler.handle()
	}
}

func (handler *Handler) handle() {
	handler.readRequest()
	handler.close()
}

func (handler *Handler) readRequest() {
	buffer := make([]byte, 1024)

	_, err := handler.Connection.Read(buffer)
	if err != nil {
		fmt.Println("Error reading:", err.Error())

		return
	}

	raw_request := string(buffer[:bytes.Index(buffer, []byte{0})])
	start_string := strings.Split(raw_request, "\r\n")[0]
	fmt.Println(start_string)
	handler.parse_start_string(start_string)
}

func (handler *Handler) parse_start_string(start_string string) {
	splited_string := strings.Split(start_string, " ")
	if len(splited_string) != 3 {
		handler.Response.Status.Message = "bad_request"
		handler.Response.Status.Code = 400

		return
	}
	handler.Request.Method.Type = splited_string[0]
	parsed_url, err := url.Parse(splited_string[1])
	if err != nil || !strings.HasPrefix(splited_string[2], "HTTP/") {
		handler.Response.Status.Message = "bad_request"
		handler.Response.Status.Code = 400
	}
	handler.Request.Url = parsed_url
}

func (handler *Handler) process_request() {
	if handler.Response.Status.Code != 200 {
		handler.set_content_headers(nil)
		return
	}

	if !handler.Constants.Methods.Contains(handler.Request.Method.Type) {
		handler.Response.Status.Message = "method_not_allowed"
		handler.Response.Status.Code = 405
	} else {
		handler.preprocess_path()
	}
}

//preproccess path and check file errors
func (handler *Handler) preprocess_path() {
	handler.Request.SetPath(handler.Dir + handler.Request.GetPath())
	file_info := handler.check_path(false)

	if file_info != nil && file_info.IsDir() {
		handler.Request.SetPath(handler.Request.GetPath() + "/index.html")
		file_info = handler.check_path(true)
	}

	handler.set_content_headers(file_info)
}

func (handler *Handler) check_path(is_dir bool) os.FileInfo {
	request_path := handler.Request.GetPath()
	clear_path := path.Clean(request_path)
	handler.Request.SetPath(clear_path)
	info, err := os.Stat(request_path)
	if err != nil {

		if os.IsNotExist(err) && !is_dir {
			handler.Response.Status.Message = "not_found"
			handler.Response.Status.Code = 404
		} else {
			handler.Response.Status.Message = "forbidden"
			handler.Response.Status.Code = 403
		}
	} else if !strings.Contains(clear_path, handler.Dir) {
		handler.Response.Status.Message = "forbidden"
		handler.Response.Status.Code = 403
	}
	return info
}

func (handler *Handler) set_content_headers(info os.FileInfo) {
	if handler.Response.Status.Code == 200 {
		handler.Response.Headers["Content-Length"] = strconv.Itoa(int(info.Size()))
		handler.Response.Headers["Content-Type"] = handler.get_content_type()
	} else {
		handler.Response.Headers["Content-Length"] = strconv.Itoa(len(handler.get_error_body()))
		handler.Response.Headers["Content-Type"] = "text/html"
	}
}

func (handler *Handler) get_error_body() string {
	body := "
"
	body += handler.Response.Status.Message
	body += "
"
	return body
}

func (handler *Handler) get_content_type() string {
	//extension := ""
	//request_path := handler.Request.GetPath()
	//last_dot := strings.LastIndex(request_path, ".")
	//if last_dot >= 0 {
	//	extension = request_path[last_dot:]
	//}
	val, ok := "top", 200
	if ok {
		return val
	} else {
		return "text/html"
	}
}

func (handler *Handler) close() {
	handler.Connection.Close()
}
<|endoftext|>


<commit_before>package ultimate

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/hellodudu/comment/config"
)

var testChan chan interface{} = make(chan interface{}, 1)

type HttpServer struct {
}

func NewHttpServer() (*HttpServer, error) {
	return &HttpServer{}, nil
}

func (server *HttpServer) Run() {
	http.HandleFunc("/create_app", createAppHandler)
	http.HandleFunc("/task", taskHandler)
	http.HandleFunc("/ws", wsHandler)
	http.HandleFunc("/bn", binaryHandler)
	log.Fatal(http.ListenAndServe(config.HttpListenAddr, nil))
}

func taskHandler(w http.ResponseWriter, r *http.Request) {
	c := make(chan struct{}, 1)
	GetUltimateAPI().AddTask(func() {
		w.Write([]byte("taskHandler Callback!"))
		c <- struct{}{}
	})
	<-c
	log.Printf("taskHandler over\n", w)
}

func wsHandler(w http.ResponseWriter, r *http.Request) {
	conn, err := config.Upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
	}

	for {
		msgtype, p, err := conn.ReadMessage()
		if err != nil {
			log.Println(err)
			return
		}

		res := []byte("server recv:")
		if err := conn.WriteMessage(msgtype, append(res, p...)); err != nil {
			log.Println(err)
			return
		}
	}
}

func createAppHandler(w http.ResponseWriter, r *http.Request) {

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Fatal(err)
	}

	newApp := &App{}
	if err := json.Unmarshal(body, newApp); err != nil {
		log.Fatal(err)
	}

	// add app
	if err := GetUltimateAPI().AddNewApp(newApp); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	retBuf, retErr := json.Marshal(newApp)
	if retErr != nil {
		log.Fatal("create app response json marshal error!")
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(retBuf)
}

// for test
func binaryHandler(w http.ResponseWriter, r *http.Request) {
	data := []byte{58, 0, 0, 0, 94, 144, 225, 39, 10, 52, 10, 9, 104, 101, 108, 108, 111, 100, 117, 100, 117, 16, 161, 96, 26, 21, 104, 101, 108, 108, 111, 100, 117, 100, 117, 56, 54, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 13, 10, 11, 49, 51, 52, 48, 49, 48, 51, 57, 50, 57, 55}

	GetUltimateAPI().GetWorldSession().HandleMessage(nil, data)
}
<commit_msg>add pprof api<commit_after>package ultimate

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	_ "net/http/pprof"

	"github.com/hellodudu/comment/config"
)

var testChan chan interface{} = make(chan interface{}, 1)

type HttpServer struct {
}

func NewHttpServer() (*HttpServer, error) {
	return &HttpServer{}, nil
}

func (server *HttpServer) Run() {
	http.HandleFunc("/create_app", createAppHandler)
	http.HandleFunc("/task", taskHandler)
	http.HandleFunc("/ws", wsHandler)
	http.HandleFunc("/bn", binaryHandler)
	log.Fatal(http.ListenAndServe(config.HttpListenAddr, nil))
}

func taskHandler(w http.ResponseWriter, r *http.Request) {
	c := make(chan struct{}, 1)
	GetUltimateAPI().AddTask(func() {
		w.Write([]byte("taskHandler Callback!"))
		c <- struct{}{}
	})
	<-c
	log.Printf("taskHandler over\n", w)
}

func wsHandler(w http.ResponseWriter, r *http.Request) {
	conn, err := config.Upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
	}

	for {
		msgtype, p, err := conn.ReadMessage()
		if err != nil {
			log.Println(err)
			return
		}

		res := []byte("server recv:")
		if err := conn.WriteMessage(msgtype, append(res, p...)); err != nil {
			log.Println(err)
			return
		}
	}
}

func createAppHandler(w http.ResponseWriter, r *http.Request) {

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Fatal(err)
	}

	newApp := &App{}
	if err := json.Unmarshal(body, newApp); err != nil {
		log.Fatal(err)
	}

	// add app
	if err := GetUltimateAPI().AddNewApp(newApp); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	retBuf, retErr := json.Marshal(newApp)
	if retErr != nil {
		log.Fatal("create app response json marshal error!")
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(retBuf)
}

// for test
func binaryHandler(w http.ResponseWriter, r *http.Request) {
	data := []byte{58, 0, 0, 0, 94, 144, 225, 39, 10, 52, 10, 9, 104, 101, 108, 108, 111, 100, 117, 100, 117, 16, 161, 96, 26, 21, 104, 101, 108, 108, 111, 100, 117, 100, 117, 56, 54, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 13, 10, 11, 49, 51, 52, 48, 49, 48, 51, 57, 50, 57, 55}

	GetUltimateAPI().GetWorldSession().HandleMessage(nil, data)
}
<|endoftext|>


<commit_before>// Copyright 2014 Unknown
//
// 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 macaron

import (
	"net/http"
	"net/http/httptest"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
)

func Test_Return_Handler(t *testing.T) {
	Convey("Return with status and body", t, func() {
		m := Classic()
		m.Get("/", func() (int, string) {
			return 418, "i'm a teapot"
		})

		resp := httptest.NewRecorder()
		req, err := http.NewRequest("GET", "/", nil)
		So(err, ShouldBeNil)
		m.ServeHTTP(resp, req)

		So(resp.Code, ShouldEqual, http.StatusTeapot)
		So(resp.Body.String(), ShouldEqual, "i'm a teapot")
	})
}
<commit_msg>More test cases, make test coverage to 70.4%<commit_after>// Copyright 2014 Unknown
//
// 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 macaron

import (
	"net/http"
	"net/http/httptest"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
)

func Test_Return_Handler(t *testing.T) {
	Convey("Return with status and body", t, func() {
		m := Classic()
		m.Get("/", func() (int, string) {
			return 418, "i'm a teapot"
		})

		resp := httptest.NewRecorder()
		req, err := http.NewRequest("GET", "/", nil)
		So(err, ShouldBeNil)
		m.ServeHTTP(resp, req)

		So(resp.Code, ShouldEqual, http.StatusTeapot)
		So(resp.Body.String(), ShouldEqual, "i'm a teapot")
	})

	Convey("Return with pointer", t, func() {
		m := Classic()
		m.Get("/", func() *string {
			str := "hello world"
			return &str
		})

		resp := httptest.NewRecorder()
		req, err := http.NewRequest("GET", "/", nil)
		So(err, ShouldBeNil)
		m.ServeHTTP(resp, req)

		So(resp.Body.String(), ShouldEqual, "hello world")
	})

	Convey("Return with byte slice", t, func() {
		m := Classic()
		m.Get("/", func() []byte {
			return []byte("hello world")
		})

		resp := httptest.NewRecorder()
		req, err := http.NewRequest("GET", "/", nil)
		So(err, ShouldBeNil)
		m.ServeHTTP(resp, req)

		So(resp.Body.String(), ShouldEqual, "hello world")
	})
}
<|endoftext|>


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

package io_test

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

func ExampleCopy() {
	r := strings.NewReader("some io.Reader stream to be read\n")

	if _, err := io.Copy(os.Stdout, r); err != nil {
		log.Fatal(err)
	}

	// Output:
	// some io.Reader stream to be read
}

func ExampleCopyBuffer() {
	r1 := strings.NewReader("first reader\n")
	r2 := strings.NewReader("second reader\n")
	buf := make([]byte, 8)

	// buf is used here...
	if _, err := io.CopyBuffer(os.Stdout, r1, buf); err != nil {
		log.Fatal(err)
	}

	// ... reused here also. No need to allocate an extra buffer.
	if _, err := io.CopyBuffer(os.Stdout, r2, buf); err != nil {
		log.Fatal(err)
	}

	// Output:
	// first reader
	// second reader
}

func ExampleCopyN() {
	r := strings.NewReader("some io.Reader stream to be read")

	if _, err := io.CopyN(os.Stdout, r, 5); err != nil {
		log.Fatal(err)
	}

	// Output:
	// some
}

func ExampleReadAtLeast() {
	r := strings.NewReader("some io.Reader stream to be read\n")

	buf := make([]byte, 33)
	if _, err := io.ReadAtLeast(r, buf, 4); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", buf)

	// buffer smaller than minimal read size.
	shortBuf := make([]byte, 3)
	if _, err := io.ReadAtLeast(r, shortBuf, 4); err != nil {
		fmt.Println("error:", err)
	}

	// minimal read size bigger than io.Reader stream
	longBuf := make([]byte, 64)
	if _, err := io.ReadAtLeast(r, longBuf, 64); err != nil {
		fmt.Println("error:", err)
	}

	// Output:
	// some io.Reader stream to be read
	//
	// error: short buffer
	// error: EOF
}

func ExampleReadFull() {
	r := strings.NewReader("some io.Reader stream to be read\n")

	buf := make([]byte, 4)
	if _, err := io.ReadFull(r, buf); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", buf)

	// minimal read size bigger than io.Reader stream
	longBuf := make([]byte, 64)
	if _, err := io.ReadFull(r, longBuf); err != nil {
		fmt.Println("error:", err)
	}

	// Output:
	// some
	// error: unexpected EOF
}

func ExampleWriteString() {
	io.WriteString(os.Stdout, "Hello World")

	// Output: Hello World
}

func ExampleLimitReader() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	lr := io.LimitReader(r, 4)

	if _, err := io.Copy(os.Stdout, lr); err != nil {
		log.Fatal(err)
	}

	// Output:
	// some
}

func ExampleMultiReader() {
	r1 := strings.NewReader("first reader ")
	r2 := strings.NewReader("second reader ")
	r3 := strings.NewReader("third reader\n")
	r := io.MultiReader(r1, r2, r3)

	if _, err := io.Copy(os.Stdout, r); err != nil {
		log.Fatal(err)
	}

	// Output:
	// first reader second reader third reader
}

func ExampleTeeReader() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	var buf bytes.Buffer
	tee := io.TeeReader(r, &buf)

	printall := func(r io.Reader) {
		b, err := ioutil.ReadAll(r)
		if err != nil {
			log.Fatal(err)
		}

		fmt.Printf("%s", b)
	}

	printall(tee)
	printall(&buf)

	// Output:
	// some io.Reader stream to be read
	// some io.Reader stream to be read
}

func ExampleSectionReader() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	s := io.NewSectionReader(r, 5, 17)

	if _, err := io.Copy(os.Stdout, s); err != nil {
		log.Fatal(err)
	}

	// Output:
	// io.Reader stream
}

func ExampleSectionReader_ReadAt() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	s := io.NewSectionReader(r, 5, 16)

	buf := make([]byte, 6)
	if _, err := s.ReadAt(buf, 10); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", buf)

	// Output:
	// stream
}

func ExampleSectionReader_Seek() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	s := io.NewSectionReader(r, 5, 16)

	if _, err := s.Seek(10, io.SeekStart); err != nil {
		log.Fatal(err)
	}

	buf := make([]byte, 6)
	if _, err := s.Read(buf); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", buf)

	// Output:
	// stream
}

func ExampleMultiWriter() {
	r := strings.NewReader("some io.Reader stream to be read\n")

	var buf1, buf2 bytes.Buffer
	w := io.MultiWriter(&buf1, &buf2)

	if _, err := io.Copy(w, r); err != nil {
		log.Fatal(err)
	}

	fmt.Print(buf1.String())
	fmt.Print(buf2.String())

	// Output:
	// some io.Reader stream to be read
	// some io.Reader stream to be read
}
<commit_msg>io: Add example to io.Seeker's Seek() method.<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io_test

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

func ExampleCopy() {
	r := strings.NewReader("some io.Reader stream to be read\n")

	if _, err := io.Copy(os.Stdout, r); err != nil {
		log.Fatal(err)
	}

	// Output:
	// some io.Reader stream to be read
}

func ExampleCopyBuffer() {
	r1 := strings.NewReader("first reader\n")
	r2 := strings.NewReader("second reader\n")
	buf := make([]byte, 8)

	// buf is used here...
	if _, err := io.CopyBuffer(os.Stdout, r1, buf); err != nil {
		log.Fatal(err)
	}

	// ... reused here also. No need to allocate an extra buffer.
	if _, err := io.CopyBuffer(os.Stdout, r2, buf); err != nil {
		log.Fatal(err)
	}

	// Output:
	// first reader
	// second reader
}

func ExampleCopyN() {
	r := strings.NewReader("some io.Reader stream to be read")

	if _, err := io.CopyN(os.Stdout, r, 5); err != nil {
		log.Fatal(err)
	}

	// Output:
	// some
}

func ExampleReadAtLeast() {
	r := strings.NewReader("some io.Reader stream to be read\n")

	buf := make([]byte, 33)
	if _, err := io.ReadAtLeast(r, buf, 4); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", buf)

	// buffer smaller than minimal read size.
	shortBuf := make([]byte, 3)
	if _, err := io.ReadAtLeast(r, shortBuf, 4); err != nil {
		fmt.Println("error:", err)
	}

	// minimal read size bigger than io.Reader stream
	longBuf := make([]byte, 64)
	if _, err := io.ReadAtLeast(r, longBuf, 64); err != nil {
		fmt.Println("error:", err)
	}

	// Output:
	// some io.Reader stream to be read
	//
	// error: short buffer
	// error: EOF
}

func ExampleReadFull() {
	r := strings.NewReader("some io.Reader stream to be read\n")

	buf := make([]byte, 4)
	if _, err := io.ReadFull(r, buf); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", buf)

	// minimal read size bigger than io.Reader stream
	longBuf := make([]byte, 64)
	if _, err := io.ReadFull(r, longBuf); err != nil {
		fmt.Println("error:", err)
	}

	// Output:
	// some
	// error: unexpected EOF
}

func ExampleWriteString() {
	io.WriteString(os.Stdout, "Hello World")

	// Output: Hello World
}

func ExampleLimitReader() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	lr := io.LimitReader(r, 4)

	if _, err := io.Copy(os.Stdout, lr); err != nil {
		log.Fatal(err)
	}

	// Output:
	// some
}

func ExampleMultiReader() {
	r1 := strings.NewReader("first reader ")
	r2 := strings.NewReader("second reader ")
	r3 := strings.NewReader("third reader\n")
	r := io.MultiReader(r1, r2, r3)

	if _, err := io.Copy(os.Stdout, r); err != nil {
		log.Fatal(err)
	}

	// Output:
	// first reader second reader third reader
}

func ExampleTeeReader() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	var buf bytes.Buffer
	tee := io.TeeReader(r, &buf)

	printall := func(r io.Reader) {
		b, err := ioutil.ReadAll(r)
		if err != nil {
			log.Fatal(err)
		}

		fmt.Printf("%s", b)
	}

	printall(tee)
	printall(&buf)

	// Output:
	// some io.Reader stream to be read
	// some io.Reader stream to be read
}

func ExampleSectionReader() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	s := io.NewSectionReader(r, 5, 17)

	if _, err := io.Copy(os.Stdout, s); err != nil {
		log.Fatal(err)
	}

	// Output:
	// io.Reader stream
}

func ExampleSectionReader_ReadAt() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	s := io.NewSectionReader(r, 5, 16)

	buf := make([]byte, 6)
	if _, err := s.ReadAt(buf, 10); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", buf)

	// Output:
	// stream
}

func ExampleSectionReader_Seek() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	s := io.NewSectionReader(r, 5, 16)

	if _, err := s.Seek(10, io.SeekStart); err != nil {
		log.Fatal(err)
	}

	buf := make([]byte, 6)
	if _, err := s.Read(buf); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", buf)

	// Output:
	// stream
}

func ExampleSeeker_Seek() {
	r := strings.NewReader("some io.Reader stream to be read\n")
	if _, err := io.Copy(os.Stdout, r); err != nil {
		log.Fatal(err)
	}

	r.Seek(15, io.SeekStart)
	if _, err := io.Copy(os.Stdout, r); err != nil {
		log.Fatal(err)
	}

	r.Seek(-5, io.SeekEnd)
	if _, err := io.Copy(os.Stdout, r); err != nil {
		log.Fatal(err)
	}

	// Output:
	// some io.Reader stream to be read
	// stream to be read
	// read
}

func ExampleMultiWriter() {
	r := strings.NewReader("some io.Reader stream to be read\n")

	var buf1, buf2 bytes.Buffer
	w := io.MultiWriter(&buf1, &buf2)

	if _, err := io.Copy(w, r); err != nil {
		log.Fatal(err)
	}

	fmt.Print(buf1.String())
	fmt.Print(buf2.String())

	// Output:
	// some io.Reader stream to be read
	// some io.Reader stream to be read
}
<|endoftext|>