<commit_before>package main

import (
	"fmt"
	"net/http"
	"os"

	"github.com/jawher/mow.cli"
)

const (
	Version      = "0.5.0"
	DefaultTheme = "clean"
)

func main() {
	app := cli.App("servemd", "a simple http server for markdown content")
	app.Version("v version", Version)
	app.Spec = "[OPTIONS] [DIR]"

	var (
		// HTTP Options
		host = app.String(cli.StringOpt{
			Name:   "a host",
			Desc:   "Host/IP address to listen on for HTTP",
			Value:  "",
			EnvVar: "HOST",
		})
		port = app.Int(cli.IntOpt{
			Name:   "p port",
			Desc:   "TCP PORT to listen on for HTTP",
			Value:  3000,
			EnvVar: "PORT",
		})
		users = app.Strings(cli.StringsOpt{
			Name:   "u auth",
			Desc:   "Username and password for basic authentication in the form of user:pass",
			EnvVar: "BASIC_AUTH",
		})
		robotsTag = app.String(cli.StringOpt{
			Name:   "r x-robots-tag",
			Desc:   "Sets a X-Robots-Tag header",
			EnvVar: "X_ROBOTS_TAG",
			Value:  "",
		})

		// Content
		dir = app.String(cli.StringArg{
			Name:   "DIR",
			Desc:   "Directory to serve content from",
			Value:  ".",
			EnvVar: "DOCUMENT_ROOT",
		})
		extension = app.String(cli.StringOpt{
			Name:   "e extension",
			Desc:   "Extension used for markdown files",
			Value:  ".md",
			EnvVar: "DOCUMENT_EXTENSION",
		})
		index = app.String(cli.StringOpt{
			Name:   "i index",
			Desc:   "Filename (without extension) to use for directory index",
			Value:  "index",
			EnvVar: "DIRECTORY_INDEX",
		})

		// Theme
		markdownTheme = app.String(cli.StringOpt{
			Name:   "m markdown-theme",
			Desc:   "Theme to use for styling markdown html",
			Value:  DefaultTheme,
			EnvVar: "MARKDOWN_THEME",
		})
		typekitKitID = app.String(cli.StringOpt{
			Name:   "t typekit-kit-id",
			Desc:   "ID of webfont kit to include from typekit",
			Value:  DefaultTheme,
			EnvVar: "TYPEKIT_KIT_ID",
		})
		codeTheme = app.String(cli.StringOpt{
			Name:   "c code-theme",
			Desc:   "Highlight.js theme to use for syntax highlighting",
			Value:  "",
			EnvVar: "CODE_THEME",
		})
	)

	app.Action = func() {
		// Static Asset Handler
		staticAssetHandler := staticAssetServer()
		staticAssetHandlerFunc := func(w http.ResponseWriter, r *http.Request) {
			staticAssetHandler.ServeHTTP(w, r)
		}
		http.HandleFunc("/assets/", headerMiddleware(staticAssetHandlerFunc))

		// Setup the markdown theme (may be custom or bundled)
		themePath, themeHandler := theme(*markdownTheme)
		if themeHandler != nil {
			http.HandleFunc(themePath, themeHandler)
		}

		// Markdown File Handler
		markdownHandlerFunc := markdownHandleFunc(MarkdownHandlerOptions{
			DocRoot:       *dir,
			DocExtension:  *extension,
			DirIndex:      *index,
			MarkdownTheme: themePath,
			TypekitKitID:  *typekitKitID,
			CodeTheme:     *codeTheme,
		})
		markdownHandlerFunc = headerMiddleware(markdownHandlerFunc)
		markdownHandlerFunc = basicAuthMiddleware(markdownHandlerFunc, *users)
		markdownHandlerFunc = robotsTagMiddleware(markdownHandlerFunc, *robotsTag)
		http.HandleFunc("/", markdownHandlerFunc)

		// Start HTTP server
		addr := fmt.Sprintf("%s:%d", *host, *port)
		err := http.ListenAndServe(addr, nil)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error starting server (%s).", err)
			cli.Exit(1)
		}

	}

	app.Run(os.Args)
}
<commit_msg>Adds logging output before starting HTTP server<commit_after>package main

import (
	"fmt"
	"net/http"
	"os"

	"log"

	"github.com/jawher/mow.cli"
)

const (
	Version      = "0.5.0"
	DefaultTheme = "clean"
)

func main() {
	app := cli.App("servemd", "a simple http server for markdown content")
	app.Version("v version", Version)
	app.Spec = "[OPTIONS] [DIR]"

	var (
		// HTTP Options
		host = app.String(cli.StringOpt{
			Name:   "a host",
			Desc:   "Host/IP address to listen on for HTTP",
			Value:  "",
			EnvVar: "HOST",
		})
		port = app.Int(cli.IntOpt{
			Name:   "p port",
			Desc:   "TCP PORT to listen on for HTTP",
			Value:  3000,
			EnvVar: "PORT",
		})
		users = app.Strings(cli.StringsOpt{
			Name:   "u auth",
			Desc:   "Username and password for basic authentication in the form of user:pass",
			EnvVar: "BASIC_AUTH",
		})
		robotsTag = app.String(cli.StringOpt{
			Name:   "r x-robots-tag",
			Desc:   "Sets a X-Robots-Tag header",
			EnvVar: "X_ROBOTS_TAG",
			Value:  "",
		})

		// Content
		dir = app.String(cli.StringArg{
			Name:   "DIR",
			Desc:   "Directory to serve content from",
			Value:  ".",
			EnvVar: "DOCUMENT_ROOT",
		})
		extension = app.String(cli.StringOpt{
			Name:   "e extension",
			Desc:   "Extension used for markdown files",
			Value:  ".md",
			EnvVar: "DOCUMENT_EXTENSION",
		})
		index = app.String(cli.StringOpt{
			Name:   "i index",
			Desc:   "Filename (without extension) to use for directory index",
			Value:  "index",
			EnvVar: "DIRECTORY_INDEX",
		})

		// Theme
		markdownTheme = app.String(cli.StringOpt{
			Name:   "m markdown-theme",
			Desc:   "Theme to use for styling markdown html",
			Value:  DefaultTheme,
			EnvVar: "MARKDOWN_THEME",
		})
		typekitKitID = app.String(cli.StringOpt{
			Name:   "t typekit-kit-id",
			Desc:   "ID of webfont kit to include from typekit",
			Value:  DefaultTheme,
			EnvVar: "TYPEKIT_KIT_ID",
		})
		codeTheme = app.String(cli.StringOpt{
			Name:   "c code-theme",
			Desc:   "Highlight.js theme to use for syntax highlighting",
			Value:  "",
			EnvVar: "CODE_THEME",
		})
	)

	app.Action = func() {
		// Static Asset Handler
		staticAssetHandler := staticAssetServer()
		staticAssetHandlerFunc := func(w http.ResponseWriter, r *http.Request) {
			staticAssetHandler.ServeHTTP(w, r)
		}
		http.HandleFunc("/assets/", headerMiddleware(staticAssetHandlerFunc))

		// Setup the markdown theme (may be custom or bundled)
		themePath, themeHandler := theme(*markdownTheme)
		if themeHandler != nil {
			http.HandleFunc(themePath, themeHandler)
		}

		// Markdown File Handler
		markdownHandlerFunc := markdownHandleFunc(MarkdownHandlerOptions{
			DocRoot:       *dir,
			DocExtension:  *extension,
			DirIndex:      *index,
			MarkdownTheme: themePath,
			TypekitKitID:  *typekitKitID,
			CodeTheme:     *codeTheme,
		})
		markdownHandlerFunc = headerMiddleware(markdownHandlerFunc)
		markdownHandlerFunc = basicAuthMiddleware(markdownHandlerFunc, *users)
		markdownHandlerFunc = robotsTagMiddleware(markdownHandlerFunc, *robotsTag)
		http.HandleFunc("/", markdownHandlerFunc)

		// Start HTTP server
		addr := fmt.Sprintf("%s:%d", *host, *port)
		log.Printf("Starting server on %s", addr)
		err := http.ListenAndServe(addr, nil)
		if err != nil {
			log.Printf("Error starting server: %s", err)
			cli.Exit(1)
		}

	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>// Copyright 2016 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 main

import (
	"flag"
	"fmt"
	"go/build"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

var (
	flagAll    = flag.Bool("all", false, "build for all GOOS/GOARCH platforms")
	flagBase   = flag.String("base", "", "revision to compare against")
	flagRace   = flag.Bool("race", false, "build with -race")
	flagRemake = flag.Bool("remake", false, "build new toolchain with make.bash instead of go install std cmd")
	flagWork   = flag.Bool("work", false, "build with -work")
)

func usage() {
	fmt.Fprintln(os.Stderr, "usage: toolstash-check [options] [commit]")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()

	if *flagAll {
		if *flagRace {
			log.Fatal("-all and -race are incompatible")
			os.Exit(2)
		}
		if *flagWork {
			log.Fatal("-all and -work are incompatible")
			os.Exit(2)
		}
	}

	spec := "HEAD"
	switch flag.NArg() {
	case 0:
	case 1:
		spec = flag.Arg(0)
	default:
		flag.Usage()
		os.Exit(2)
	}

	goroot := runtime.GOROOT()

	commit, err := revParse(goroot, spec)
	must(err)

	base := *flagBase
	if base == "" {
		base = commit + "^"
	}
	base, err = revParse(goroot, base)
	must(err)

	pkg, err := build.Import("golang.org/x/tools/cmd/toolstash", "", build.FindOnly)
	must(err)

	tmpdir, err := ioutil.TempDir("", "toolstash-check-")
	must(err)
	defer os.RemoveAll(tmpdir)

	tmproot := filepath.Join(tmpdir, "go")
	must(command("git", "clone", goroot, tmproot).Run())

	cmd := command("git", "checkout", base)
	cmd.Dir = tmproot
	must(cmd.Run())

	must(ioutil.WriteFile(filepath.Join(tmproot, "VERSION"), []byte("devel"), 0666))

	cmd = command("./make.bash")
	cmd.Dir = filepath.Join(tmproot, "src")
	must(cmd.Run())

	envPath := os.Getenv("PATH")
	if envPath != "" {
		envPath = string(os.PathListSeparator) + envPath
	}
	must(os.Setenv("PATH", filepath.Join(tmproot, "bin")+envPath))
	must(os.Setenv("GOROOT", tmproot))

	must(command("toolstash", "save").Run())

	cmd = command("git", "checkout", commit)
	cmd.Dir = tmproot
	must(cmd.Run())

	if *flagRemake {
		cmd = command("./make.bash")
		cmd.Dir = filepath.Join(tmproot, "src")
	} else {
		cmd = command("go", "install", "std", "cmd")
	}
	must(cmd.Run())

	if *flagAll {
		must(command(filepath.Join(pkg.Dir, "buildall")).Run())
	} else {
		buildArgs := []string{"build", "-a"}
		if *flagRace {
			buildArgs = append(buildArgs, "-race")
		}
		if *flagWork {
			buildArgs = append(buildArgs, "-work")
		}
		buildArgs = append(buildArgs, "-toolexec", "toolstash -cmp", "std", "cmd")
		must(command("go", buildArgs...).Run())
	}

	fmt.Println("toolstash-check passed for " + commit)
}

// revParse runs "git rev-parse $spec" in $GOROOT to parse a Git
// revision specifier.
func revParse(dir, spec string) (string, error) {
	cmd := exec.Command("git", "rev-parse", spec)
	cmd.Dir = dir
	out, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return strings.TrimSuffix(string(out), "\n"), nil
}

func command(name string, args ...string) *exec.Cmd {
	cmd := exec.Command(name, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd
}

func must(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>toolstash-check: print successful range when using -base<commit_after>// Copyright 2016 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 main

import (
	"flag"
	"fmt"
	"go/build"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

var (
	flagAll    = flag.Bool("all", false, "build for all GOOS/GOARCH platforms")
	flagBase   = flag.String("base", "", "revision to compare against")
	flagRace   = flag.Bool("race", false, "build with -race")
	flagRemake = flag.Bool("remake", false, "build new toolchain with make.bash instead of go install std cmd")
	flagWork   = flag.Bool("work", false, "build with -work")
)

func usage() {
	fmt.Fprintln(os.Stderr, "usage: toolstash-check [options] [commit]")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()

	if *flagAll {
		if *flagRace {
			log.Fatal("-all and -race are incompatible")
			os.Exit(2)
		}
		if *flagWork {
			log.Fatal("-all and -work are incompatible")
			os.Exit(2)
		}
	}

	spec := "HEAD"
	switch flag.NArg() {
	case 0:
	case 1:
		spec = flag.Arg(0)
	default:
		flag.Usage()
		os.Exit(2)
	}

	goroot := runtime.GOROOT()

	commit, err := revParse(goroot, spec)
	must(err)

	base := *flagBase
	if base == "" {
		base = commit + "^"
	}
	base, err = revParse(goroot, base)
	must(err)

	pkg, err := build.Import("golang.org/x/tools/cmd/toolstash", "", build.FindOnly)
	must(err)

	tmpdir, err := ioutil.TempDir("", "toolstash-check-")
	must(err)
	defer os.RemoveAll(tmpdir)

	tmproot := filepath.Join(tmpdir, "go")
	must(command("git", "clone", goroot, tmproot).Run())

	cmd := command("git", "checkout", base)
	cmd.Dir = tmproot
	must(cmd.Run())

	must(ioutil.WriteFile(filepath.Join(tmproot, "VERSION"), []byte("devel"), 0666))

	cmd = command("./make.bash")
	cmd.Dir = filepath.Join(tmproot, "src")
	must(cmd.Run())

	envPath := os.Getenv("PATH")
	if envPath != "" {
		envPath = string(os.PathListSeparator) + envPath
	}
	must(os.Setenv("PATH", filepath.Join(tmproot, "bin")+envPath))
	must(os.Setenv("GOROOT", tmproot))

	must(command("toolstash", "save").Run())

	cmd = command("git", "checkout", commit)
	cmd.Dir = tmproot
	must(cmd.Run())

	if *flagRemake {
		cmd = command("./make.bash")
		cmd.Dir = filepath.Join(tmproot, "src")
	} else {
		cmd = command("go", "install", "std", "cmd")
	}
	must(cmd.Run())

	if *flagAll {
		must(command(filepath.Join(pkg.Dir, "buildall")).Run())
	} else {
		buildArgs := []string{"build", "-a"}
		if *flagRace {
			buildArgs = append(buildArgs, "-race")
		}
		if *flagWork {
			buildArgs = append(buildArgs, "-work")
		}
		buildArgs = append(buildArgs, "-toolexec", "toolstash -cmp", "std", "cmd")
		must(command("go", buildArgs...).Run())
	}

	revs := commit
	if *flagBase != "" {
		revs = base + ".." + commit
	}
	fmt.Println("toolstash-check passed for", revs)
}

// revParse runs "git rev-parse $spec" in $GOROOT to parse a Git
// revision specifier.
func revParse(dir, spec string) (string, error) {
	cmd := exec.Command("git", "rev-parse", "--short", spec)
	cmd.Dir = dir
	out, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return strings.TrimSuffix(string(out), "\n"), nil
}

func command(name string, args ...string) *exec.Cmd {
	cmd := exec.Command(name, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd
}

func must(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// sci is a shameful CI.
//
// It is a simple Github webhook that runs a Go build and an hardcoded
// command upon PR or push from whitelisted users.
//
// It posts the stdout to a Github gist and updates the PR status.
//
// It doesn't stream data so it cannot be used for slow task.
package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"sync"
	"time"

	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
)

type config struct {
	Port              int      // TCP port number for HTTP server.
	WebHookSecret     string   // https://developer.github.com/webhooks/
	Oauth2AccessToken string   // https://github.com/settings/tokens, check "repo:status" and "gist"
	UseSSH            bool     // Use ssh (instead of https) for checkout. Required for private repositories.
	Name              string   // Display name to use in the status report on Github.
	Check             []string // Command to run to test the repository. It is run from the repository's root.
}

func loadConfig() (*config, error) {
	c := &config{
		Port:              8080,
		WebHookSecret:     "Create a secret and set it at github.com/'name'/'repo'/settings/hooks",
		Oauth2AccessToken: "Get one at https://github.com/settings/tokens",
		UseSSH:            false,
		Name:              "sci",
		Check:             []string{"go", "test"},
	}
	b, err := ioutil.ReadFile("sci.json")
	if err != nil {
		b, err = json.MarshalIndent(c, "", "  ")
		if err != nil {
			return nil, err
		}
		if err = ioutil.WriteFile("sci.json", b, 0600); err != nil {
			return nil, err
		}
		return nil, errors.New("wrote new sci.json")
	}
	if err = json.Unmarshal(b, c); err != nil {
		return nil, err
	}
	d, err := json.MarshalIndent(c, "", "  ")
	if err != nil {
		return nil, err
	}
	// Update the file in canonical format.
	if !bytes.Equal(b, d) {
		log.Printf("Updating sci.json in canonical format")
		if err := ioutil.WriteFile("sci.json", d, 0600); err != nil {
			return nil, err
		}
	}
	return c, nil
}

func isInList(i string, list []string) bool {
	// Brute force is fine for short list.
	for _, s := range list {
		if i == s {
			return true
		}
	}
	return false
}

func run(cwd string, cmd ...string) (string, bool) {
	cmds := strings.Join(cmd, " ")
	log.Printf("- cwd=%s : %s", cwd, cmds)
	c := exec.Command(cmd[0], cmd[1:]...)
	c.Dir = cwd
	start := time.Now()
	out, err := c.CombinedOutput()
	duration := time.Since(start)
	// Assumes UTF-8.
	return fmt.Sprintf("$ %s\nin %s\n%s", cmds, duration, string(out)), err == nil
}

// runCheck syncs then runs the check.
//
// It runs the check in a temporary GOPATH at the specified commit.
func runCheck(cmd []string, repoName string, useSSH bool, commit, gopath string) (string, string, bool) {
	metadata := fmt.Sprintf("Commit: %s\nVersion: %s\nGOROOT: %s\nGOPATH: %s\nCPUs: %d\n---\n",
		commit, runtime.Version(), runtime.GOROOT(), gopath, runtime.NumCPU())
	repoPath := "github.com/" + repoName
	base := filepath.Join(gopath, "src", repoPath)
	if _, err := os.Stat(base); err != nil {
		up := path.Dir(base)
		if err := os.MkdirAll(up, 0700); err != nil && !os.IsExist(err) {
			log.Printf("- %v", err)
		}
		url := "https://" + repoPath
		if useSSH {
			url = "git@github.com:" + repoName
		}
		out1, ok := run(up, "git", "clone", "--quiet", url)
		metadata += out1
		if !ok {
			return metadata, "", ok
		}
	} else {
		out1, ok := run(base, "git", "fetch", "--prune", "--quiet")
		metadata += out1
		if !ok {
			return metadata, "", ok
		}
	}
	out1, ok := run(base, "git", "checkout", "--quiet", commit)
	metadata += out1
	if !ok {
		return metadata, "", ok
	}
	// TODO(maruel): update dependencies manually!
	out1, ok = run(gopath, "go", "get", "-v", "-d", "-t", repoPath)
	metadata += out1
	if !ok {
		return metadata, "", ok
	}
	out, ok := run(base, cmd...)
	return metadata, out, ok
}

type server struct {
	c       *config
	client  *github.Client
	gopath  string
	mu      sync.Mutex
	collabs map[string]map[string]bool
}

func (s *server) canCollab(owner, repo, user string) bool {
	key := owner + "/" + repo
	s.mu.Lock()
	defer s.mu.Unlock()
	if _, ok := s.collabs[key]; !ok {
		s.collabs[key] = map[string]bool{}
	}
	if v, ok := s.collabs[key][user]; ok {
		return v
	}
	v, _, _ := s.client.Repositories.IsCollaborator(owner, repo, user)
	if v {
		// Only cache hits because otherwise adding a collaborator would mean
		// restarting every sci instances.
		s.collabs[key][user] = v
	}
	log.Printf("- %s: %s access: %t", key, user, v)
	return v
}

func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Printf("HTTP: %s %s", r.RemoteAddr, r.URL.Path)
	defer r.Body.Close()
	if r.Method != "POST" {
		http.Error(w, "Invalid method", http.StatusMethodNotAllowed)
		log.Printf("- invalid method")
		return
	}
	payload, err := github.ValidatePayload(r, []byte(s.c.WebHookSecret))
	if err != nil {
		http.Error(w, "Invalid secret", http.StatusUnauthorized)
		log.Printf("- invalid secret")
		return
	}
	event, err := github.ParseWebHook(github.WebHookType(r), payload)
	if err != nil {
		http.Error(w, "Invalid payload", http.StatusBadRequest)
		log.Printf("- invalid payload")
		return
	}
	switch event := event.(type) {
	// TODO(maruel): For *github.CommitCommentEvent and
	// *github.IssueCommentEvent, when the comment is 'run tests' from a
	// collaborator, run the tests.
	case *github.PullRequestEvent:
		log.Printf("- PR #%d %s %s", *event.PullRequest.ID, *event.Sender.Login, *event.Action)
		if *event.Action != "opened" && *event.Action != "synchronized" {
			log.Printf("- ignoring action %q for PR from %q", *event.Action, *event.Sender.Login)
		} else if !s.canCollab(*event.Repo.Owner.Login, *event.Repo.Name, *event.Sender.Login) {
			log.Printf("- ignoring owner %q for PR", *event.Sender.Login)
		} else if err = s.runCheck(*event.Repo.FullName, *event.PullRequest.Head.SHA); err != nil {
			log.Printf("- %v", err)
		}
	case *github.PushEvent:
		log.Printf("- Push %s %s", *event.Ref, *event.HeadCommit.ID)
		if !strings.HasPrefix(*event.Ref, "refs/heads/") {
			log.Printf("- ignoring branch %q for push", *event.Ref)
		} else if err = s.runCheck(*event.Repo.FullName, *event.HeadCommit.ID); err != nil {
			log.Printf("- %v", err)
		}
	default:
		log.Printf("- ignoring hook type %s", reflect.TypeOf(event).Elem().Name())
	}
	io.WriteString(w, "{}")
}

func (s *server) runCheck(repo, commit string) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	log.Printf("- Running test for %s at %s", repo, commit)
	metadata, out, success := runCheck(s.c.Check, repo, s.c.UseSSH, commit, s.gopath)
	if metadata == "" {
		metadata = "<missing>"
	}
	if out == "" {
		out = "<missing>"
	}
	// https://developer.github.com/v3/gists/#create-a-gist
	gist := &github.Gist{
		Description: github.String("Output for https://github.com/" + repo + "/commit/" + commit),
		// It is still accessible via the URL;
		Public: github.Bool(false),
		Files: map[github.GistFilename]github.GistFile{
			"metadata": github.GistFile{Content: &metadata},
			"stdout":   github.GistFile{Content: &out},
		},
	}
	var err error
	if gist, _, err = s.client.Gists.Create(gist); err != nil {
		return err
	}
	log.Printf("- Gist at %s", *gist.HTMLURL)

	// https://developer.github.com/v3/repos/statuses/#create-a-status
	status := &github.RepoStatus{
		State:       github.String("success"),
		TargetURL:   gist.HTMLURL,
		Description: github.String(fmt.Sprintf("Ran: %s", strings.Join(s.c.Check, " "))),
		Context:     github.String("sci"),
	}
	if !success {
		status.State = github.String("failure")
	}
	parts := strings.SplitN(repo, "/", 2)
	_, _, err = s.client.Repositories.CreateStatus(parts[0], parts[1], commit, status)
	return err
}

func mainImpl() error {
	test := flag.String("test", "", "runs a simulation locally, specify the git repository name (not URL) to test, e.g. 'maruel/sci'")
	flag.Parse()
	c, err := loadConfig()
	if err != nil {
		return err
	}
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	gopath := filepath.Join(wd, "sci-gopath")
	os.Setenv("GOPATH", gopath)
	if len(*test) != 0 {
		metadata, out, success := runCheck(c.Check, *test, c.UseSSH, "HEAD", gopath)
		_, err := fmt.Printf("%s---\n%sSuccess: %t\n", metadata, out, success)
		return err
	}

	tc := oauth2.NewClient(oauth2.NoContext, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: c.Oauth2AccessToken}))
	s := server{c: c, client: github.NewClient(tc), gopath: gopath, collabs: map[string]map[string]bool{}}
	http.Handle("/", &s)
	log.Printf("Running in %s", wd)
	log.Printf("Listening on %d", c.Port)
	return http.ListenAndServe(fmt.Sprintf(":%d", c.Port), nil)
}

func main() {
	if err := mainImpl(); err != nil {
		fmt.Fprintf(os.Stderr, "sci: %s.\n", err)
		os.Exit(1)
	}
}
<commit_msg>Remove dead code, add support for ping<commit_after>// Copyright 2016 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// sci is a shameful CI.
//
// It is a simple Github webhook that runs a Go build and an hardcoded
// command upon PR or push from whitelisted users.
//
// It posts the stdout to a Github gist and updates the PR status.
//
// It doesn't stream data so it cannot be used for slow task.
package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"sync"
	"time"

	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
)

type config struct {
	Port              int      // TCP port number for HTTP server.
	WebHookSecret     string   // https://developer.github.com/webhooks/
	Oauth2AccessToken string   // https://github.com/settings/tokens, check "repo:status" and "gist"
	UseSSH            bool     // Use ssh (instead of https) for checkout. Required for private repositories.
	Name              string   // Display name to use in the status report on Github.
	Check             []string // Command to run to test the repository. It is run from the repository's root.
}

func loadConfig() (*config, error) {
	c := &config{
		Port:              8080,
		WebHookSecret:     "Create a secret and set it at github.com/'name'/'repo'/settings/hooks",
		Oauth2AccessToken: "Get one at https://github.com/settings/tokens",
		UseSSH:            false,
		Name:              "sci",
		Check:             []string{"go", "test"},
	}
	b, err := ioutil.ReadFile("sci.json")
	if err != nil {
		b, err = json.MarshalIndent(c, "", "  ")
		if err != nil {
			return nil, err
		}
		if err = ioutil.WriteFile("sci.json", b, 0600); err != nil {
			return nil, err
		}
		return nil, errors.New("wrote new sci.json")
	}
	if err = json.Unmarshal(b, c); err != nil {
		return nil, err
	}
	d, err := json.MarshalIndent(c, "", "  ")
	if err != nil {
		return nil, err
	}
	// Update the file in canonical format.
	if !bytes.Equal(b, d) {
		log.Printf("Updating sci.json in canonical format")
		if err := ioutil.WriteFile("sci.json", d, 0600); err != nil {
			return nil, err
		}
	}
	return c, nil
}

func run(cwd string, cmd ...string) (string, bool) {
	cmds := strings.Join(cmd, " ")
	log.Printf("- cwd=%s : %s", cwd, cmds)
	c := exec.Command(cmd[0], cmd[1:]...)
	c.Dir = cwd
	start := time.Now()
	out, err := c.CombinedOutput()
	duration := time.Since(start)
	// Assumes UTF-8.
	return fmt.Sprintf("$ %s\nin %s\n%s", cmds, duration, string(out)), err == nil
}

// runCheck syncs then runs the check.
//
// It runs the check in a temporary GOPATH at the specified commit.
func runCheck(cmd []string, repoName string, useSSH bool, commit, gopath string) (string, string, bool) {
	metadata := fmt.Sprintf("Commit: %s\nVersion: %s\nGOROOT: %s\nGOPATH: %s\nCPUs: %d\n---\n",
		commit, runtime.Version(), runtime.GOROOT(), gopath, runtime.NumCPU())
	repoPath := "github.com/" + repoName
	base := filepath.Join(gopath, "src", repoPath)
	if _, err := os.Stat(base); err != nil {
		up := path.Dir(base)
		if err := os.MkdirAll(up, 0700); err != nil && !os.IsExist(err) {
			log.Printf("- %v", err)
		}
		url := "https://" + repoPath
		if useSSH {
			url = "git@github.com:" + repoName
		}
		out1, ok := run(up, "git", "clone", "--quiet", url)
		metadata += out1
		if !ok {
			return metadata, "", ok
		}
	} else {
		out1, ok := run(base, "git", "fetch", "--prune", "--quiet")
		metadata += out1
		if !ok {
			return metadata, "", ok
		}
	}
	out1, ok := run(base, "git", "checkout", "--quiet", commit)
	metadata += out1
	if !ok {
		return metadata, "", ok
	}
	// TODO(maruel): update dependencies manually!
	out1, ok = run(gopath, "go", "get", "-v", "-d", "-t", repoPath)
	metadata += out1
	if !ok {
		return metadata, "", ok
	}
	out, ok := run(base, cmd...)
	return metadata, out, ok
}

type server struct {
	c       *config
	client  *github.Client
	gopath  string
	mu      sync.Mutex
	collabs map[string]map[string]bool
}

func (s *server) canCollab(owner, repo, user string) bool {
	key := owner + "/" + repo
	s.mu.Lock()
	defer s.mu.Unlock()
	if _, ok := s.collabs[key]; !ok {
		s.collabs[key] = map[string]bool{}
	}
	if v, ok := s.collabs[key][user]; ok {
		return v
	}
	v, _, _ := s.client.Repositories.IsCollaborator(owner, repo, user)
	if v {
		// Only cache hits because otherwise adding a collaborator would mean
		// restarting every sci instances.
		s.collabs[key][user] = v
	}
	log.Printf("- %s: %s access: %t", key, user, v)
	return v
}

func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Printf("HTTP: %s %s", r.RemoteAddr, r.URL.Path)
	defer r.Body.Close()
	if r.Method != "POST" {
		http.Error(w, "Invalid method", http.StatusMethodNotAllowed)
		log.Printf("- invalid method")
		return
	}
	payload, err := github.ValidatePayload(r, []byte(s.c.WebHookSecret))
	if err != nil {
		http.Error(w, "Invalid secret", http.StatusUnauthorized)
		log.Printf("- invalid secret")
		return
	}
	t := github.WebHookType(r)
	if t != "ping" {
		event, err := github.ParseWebHook(t, payload)
		if err != nil {
			http.Error(w, "Invalid payload", http.StatusBadRequest)
			log.Printf("- invalid payload")
			return
		}
		switch event := event.(type) {
		// TODO(maruel): For *github.CommitCommentEvent and
		// *github.IssueCommentEvent, when the comment is 'run tests' from a
		// collaborator, run the tests.
		case *github.PullRequestEvent:
			log.Printf("- PR #%d %s %s", *event.PullRequest.ID, *event.Sender.Login, *event.Action)
			if *event.Action != "opened" && *event.Action != "synchronized" {
				log.Printf("- ignoring action %q for PR from %q", *event.Action, *event.Sender.Login)
			} else if !s.canCollab(*event.Repo.Owner.Login, *event.Repo.Name, *event.Sender.Login) {
				log.Printf("- ignoring owner %q for PR", *event.Sender.Login)
			} else if err = s.runCheck(*event.Repo.FullName, *event.PullRequest.Head.SHA); err != nil {
				log.Printf("- %v", err)
			}
		case *github.PushEvent:
			log.Printf("- Push %s %s", *event.Ref, *event.HeadCommit.ID)
			if !strings.HasPrefix(*event.Ref, "refs/heads/") {
				log.Printf("- ignoring branch %q for push", *event.Ref)
			} else if err = s.runCheck(*event.Repo.FullName, *event.HeadCommit.ID); err != nil {
				log.Printf("- %v", err)
			}
		default:
			log.Printf("- ignoring hook type %s", reflect.TypeOf(event).Elem().Name())
		}
	}
	io.WriteString(w, "{}")
}

func (s *server) runCheck(repo, commit string) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	log.Printf("- Running test for %s at %s", repo, commit)
	metadata, out, success := runCheck(s.c.Check, repo, s.c.UseSSH, commit, s.gopath)
	if metadata == "" {
		metadata = "<missing>"
	}
	if out == "" {
		out = "<missing>"
	}
	// https://developer.github.com/v3/gists/#create-a-gist
	gist := &github.Gist{
		Description: github.String("Output for https://github.com/" + repo + "/commit/" + commit),
		// It is still accessible via the URL;
		Public: github.Bool(false),
		Files: map[github.GistFilename]github.GistFile{
			"metadata": github.GistFile{Content: &metadata},
			"stdout":   github.GistFile{Content: &out},
		},
	}
	var err error
	if gist, _, err = s.client.Gists.Create(gist); err != nil {
		return err
	}
	log.Printf("- Gist at %s", *gist.HTMLURL)

	// https://developer.github.com/v3/repos/statuses/#create-a-status
	status := &github.RepoStatus{
		State:       github.String("success"),
		TargetURL:   gist.HTMLURL,
		Description: github.String(fmt.Sprintf("Ran: %s", strings.Join(s.c.Check, " "))),
		Context:     github.String("sci"),
	}
	if !success {
		status.State = github.String("failure")
	}
	parts := strings.SplitN(repo, "/", 2)
	_, _, err = s.client.Repositories.CreateStatus(parts[0], parts[1], commit, status)
	return err
}

func mainImpl() error {
	test := flag.String("test", "", "runs a simulation locally, specify the git repository name (not URL) to test, e.g. 'maruel/sci'")
	flag.Parse()
	c, err := loadConfig()
	if err != nil {
		return err
	}
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	gopath := filepath.Join(wd, "sci-gopath")
	os.Setenv("GOPATH", gopath)
	if len(*test) != 0 {
		metadata, out, success := runCheck(c.Check, *test, c.UseSSH, "HEAD", gopath)
		_, err := fmt.Printf("%s---\n%sSuccess: %t\n", metadata, out, success)
		return err
	}

	tc := oauth2.NewClient(oauth2.NoContext, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: c.Oauth2AccessToken}))
	s := server{c: c, client: github.NewClient(tc), gopath: gopath, collabs: map[string]map[string]bool{}}
	http.Handle("/", &s)
	log.Printf("Running in %s", wd)
	log.Printf("Listening on %d", c.Port)
	return http.ListenAndServe(fmt.Sprintf(":%d", c.Port), nil)
}

func main() {
	if err := mainImpl(); err != nil {
		fmt.Fprintf(os.Stderr, "sci: %s.\n", err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/maxmind/geoip2-csv-converter/convert"
)

func main() {
	input := flag.String("block-file", "", "The path to the block CSV file to use as input (REQUIRED)")
	output := flag.String("output-file", "", "The path to the output CSV (REQUIRED)")
	ipRange := flag.Bool("include-range", false, "Include the IP range of the network in string format")
	intRange := flag.Bool("include-integer-range", false, "Include the IP range of the network in integer format")
	cidr := flag.Bool("include-cidr", false, "Include the network in CIDR format")

	flag.Parse()

	var errors []string

	if *input == "" {
		errors = append(errors, "-block-file is required")
	}

	if *output == "" {
		errors = append(errors, "-output-file is required")
	}

	if !*ipRange && !*intRange && !*cidr {
		errors = append(errors, "At least one of -include-* param is required")
	}

	args := flag.Args()
	if len(args) > 0 {
		errors = append(errors, "unknown argument(s): "+strings.Join(args, ", "))
	}

	if len(errors) != 0 {
		printHelp(errors)
		os.Exit(1)
	}

	err := convert.ConvertFile(*input, *output, *cidr, *ipRange, *intRange)
	if err != nil {
		fmt.Fprintf(flag.CommandLine.Output(), "Error: %v\n", err)
	}
}

func printHelp(errors []string) {
	for _, message := range errors {
		fmt.Fprintln(flag.CommandLine.Output(), message)
	}
	flag.PrintDefaults()
}
<commit_msg>Make -include-* error message more similar to others<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/maxmind/geoip2-csv-converter/convert"
)

func main() {
	input := flag.String("block-file", "", "The path to the block CSV file to use as input (REQUIRED)")
	output := flag.String("output-file", "", "The path to the output CSV (REQUIRED)")
	ipRange := flag.Bool("include-range", false, "Include the IP range of the network in string format")
	intRange := flag.Bool("include-integer-range", false, "Include the IP range of the network in integer format")
	cidr := flag.Bool("include-cidr", false, "Include the network in CIDR format")

	flag.Parse()

	var errors []string

	if *input == "" {
		errors = append(errors, "-block-file is required")
	}

	if *output == "" {
		errors = append(errors, "-output-file is required")
	}

	if !*ipRange && !*intRange && !*cidr {
		errors = append(errors, "-include-cidr, -include-range, or -include-integer-range is required")
	}

	args := flag.Args()
	if len(args) > 0 {
		errors = append(errors, "unknown argument(s): "+strings.Join(args, ", "))
	}

	if len(errors) != 0 {
		printHelp(errors)
		os.Exit(1)
	}

	err := convert.ConvertFile(*input, *output, *cidr, *ipRange, *intRange)
	if err != nil {
		fmt.Fprintf(flag.CommandLine.Output(), "Error: %v\n", err)
	}
}

func printHelp(errors []string) {
	for _, message := range errors {
		fmt.Fprintln(flag.CommandLine.Output(), message)
	}
	flag.PrintDefaults()
}
<|endoftext|>


<commit_before>package main

import (
  "net/http"
  "os"
  "os/exec"
  "fmt"
  "strings"
)

func JekyllBuild(rw http.ResponseWriter, r *http.Request) {
  // webhook must be POST
  if r.Method != "POST" {
    rw.WriteHeader(http.StatusNotFound)
    return
  }

  dir := "/Users/mkruk/Desktop/jekyll_test"   // 1
  repo := "git@github.com:tamagokun/tamagokun.github.com.git"   // 2
  dest := "/Users/mkruk/Desktop/jekyll_build"   // 3

  cmd := []string{
    "git clone %[2]s %[1]s",
    "cd %[1]s",
    // "git checkout master",
    "jekyll build -s %[1]s -d %[3]s",
    "rm -Rf %[1]s"}

  fmt.Println("-----> Building Jekyll site ...")
  out, err := exec.Command("sh", "-c", fmt.Sprintf(strings.Join(cmd, " && "), dir, repo, dest)).Output()
  if err != nil {
    fmt.Printf("%s", err)
    rw.WriteHeader(http.StatusInternalServerError)
    return
  }
  fmt.Printf("%s", out)
  fmt.Println("-----> Jekyll site built successfully.")

  JekyllPublish(dest)

  rw.WriteHeader(http.StatusOK)
}

func JekyllPublish(dir string) {

  // rsync to remote
  // rsync -avz --delete _site/ location:/var/www/html/jekyll

  // publish to S3
  // https://github.com/developmentseed/jekyll-hook/blob/master/scripts/publish-s3.sh

}

func main() {
  http.HandleFunc("/fridgehook", JekyllBuild)
  port := os.Getenv("PORT")
  if port == "" {
      port = "8080"
  }
  http.ListenAndServe(":"+port, nil)
}

<commit_msg>builds are structured from request URL. syncing to S3 working<commit_after>package main

import (
  "net/http"
  "os"
  "os/exec"
  "fmt"
  "strings"
)

/*
 * POST /build/:host/:user/:name
 */
func JekyllBuild(rw http.ResponseWriter, r *http.Request) {
  // webhook must be POST
  if r.Method != "POST" {
    rw.WriteHeader(http.StatusNotFound)
    return
  }

  url := strings.Split(r.URL.Path, "/")
  host, user, name := url[2], url[3], url[4]
  // tmp := "/tmp"
  tmp := "/Users/mkruk/Desktop"

  dir  := tmp + "/src/" + name
  dest := tmp + "/build/" + name
  repo := "git@" + host + ":" + user + "/" + name + ".git"

  cmd := []string{
    "git clone %[2]s %[1]s",
    "cd %[1]s",
    // "git checkout master",
    "jekyll build -s %[1]s -d %[3]s",
    "rm -Rf %[1]s"}

  fmt.Println("-----> Cloning " + repo)
  fmt.Println("-----> Building Jekyll site ...")
  out, err := exec.Command("sh", "-c", fmt.Sprintf(strings.Join(cmd, " && "), dir, repo, dest)).Output()
  if err != nil {
    fmt.Printf("%s", err)
    rw.WriteHeader(http.StatusInternalServerError)
    return
  }
  fmt.Printf("%s", out)
  fmt.Println("-----> Jekyll site built successfully.")

  status, message := JekyllPublish(dest)
  fmt.Println(string(status))
  fmt.Println(message)

  rw.WriteHeader(http.StatusOK)
}

func JekyllPublish(dir string) (int, string) {

  // Find S3 Bucket location from the BUCKET file
  bucket, err := exec.Command("sh", "-c", fmt.Sprintf("cd %s && cat BUCKET", dir)).Output()
  if err != nil {
    return 500, "No bucket specified"
  }

  // Sync files to S3
  fmt.Printf("-----> Publishing to Amazon S3 Bucket %s...\n", bucket)
  out, err := exec.Command("sh", "-c", fmt.Sprintf("s3cmd sync \"%[1]s/\" s3://%[2]s --delete-removed --acl-public", dir, bucket)).Output()
  fmt.Printf("%s", out)
  if err != nil {
    fmt.Printf("%s", err)
    return 500, "Problem syncing"
  }

  // TODO Optional - Use rsync to remote web server
  // rsync -avz --delete _site/ location:/var/www/html/jekyll

  return 200, "Success"
}

func main() {
  http.HandleFunc("/build/", JekyllBuild)
  port := os.Getenv("PORT")
  if port == "" {
      port = "8080"
  }
  http.ListenAndServe(":"+port, nil)
}

<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"syscall"
)

var prog = filepath.Base(os.Args[0])

func main() {
	log.SetFlags(0)
	log.SetPrefix(prog + ": ")

	if err := os.Setenv("GOOS", "nacl"); err != nil {
		log.Fatal(err)
	}

	arch := runtime.GOARCH
	if userArch := os.Getenv("GOARCH"); userArch != "" {
		// explicit in environment
		arch = userArch
	}

	// translate to nacl-specific architecture
	switch arch {
	case "amd64":
		arch = "amd64p32"
	}

	if err := os.Setenv("GOARCH", arch); err != nil {
		log.Fatal(err)
	}

	var bin string
	var err error
	if bin, err = exec.LookPath("go"); err != nil {
		log.Fatal(err)
	}
	args := os.Args
	args[0] = bin

	if len(args) >= 2 {
		switch args[1] {
		case "test", "run":
			var loader string
			switch arch {
			case "amd64p32":
				loader = "sel_ldr_x86_64"
			case "386":
				loader = "sel_ldr_x86_32"
			default:
				log.Fatalf("no NaCl loader for architecture: %v", arch)
			}
			args = append(args, "")
			copy(args[2+1:], args[2:])
			args[2] = "-exec=" + loader
		}
	}

	if err := syscall.Exec(bin, args, os.Environ()); err != nil {
		log.Fatal(err)
	}
	panic("still running after successful exec")
}
<commit_msg>Remove explicit sel_ldr_x86_* handling.<commit_after>package main

import (
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"syscall"
)

var prog = filepath.Base(os.Args[0])

func main() {
	log.SetFlags(0)
	log.SetPrefix(prog + ": ")

	if err := os.Setenv("GOOS", "nacl"); err != nil {
		log.Fatal(err)
	}

	arch := runtime.GOARCH
	if userArch := os.Getenv("GOARCH"); userArch != "" {
		// explicit in environment
		arch = userArch
	}

	// translate to nacl-specific architecture
	switch arch {
	case "amd64":
		arch = "amd64p32"
	}

	if err := os.Setenv("GOARCH", arch); err != nil {
		log.Fatal(err)
	}

	var bin string
	var err error
	if bin, err = exec.LookPath("go"); err != nil {
		log.Fatal(err)
	}
	args := os.Args
	args[0] = bin
	if err := syscall.Exec(bin, args, os.Environ()); err != nil {
		log.Fatal(err)
	}
	panic("still running after successful exec")
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"fmt"
	"github.com/cptaffe/mpris2"
)

func main() {
	if len(os.Args) != 2 {
		fmt.Printf(os.Args[0] + " [play | pause | playpause]\n")
	} else {
		player := mpris2.NewPlayer("spotify")
		switch os.Args[1] {
		case "playpause":
			player.PlayPause()
		case "next":
			player.Next()
		case "prev":
			player.Previous()
		default:
			fmt.Printf("%s is currently unsupported\n", os.Args[1])
		}
	}
}
<commit_msg>update<commit_after>package main

import (
	"os"
	"fmt"
	"github.com/cptaffe/mpris2"
)

func main() {
	if len(os.Args) != 2 {
		fmt.Printf(os.Args[0] + " [play | pause | playpause]\n")
	} else {
		players, err := mpris2.Players()
		if err != nil {
			fmt.Printf("Error: %s\n", err)
		}
		if len(players) > 0 {
			player := players[0]
			switch os.Args[1] {
			case "playpause":
				player.PlayPause()
			case "next":
				player.Next()
			case "prev":
				player.Previous()
			default:
				fmt.Printf("%s is currently unsupported\n", os.Args[1])
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/disiqueira/tindergo"
)

func main() {
	token := flag.String("token", "", "Your Facebook Token.")

	flag.Parse()

	if *token == "" {
		fmt.Println("You must provide a valid Facebook Token.")
		os.Exit(2)
	}

	t := tindergo.New()

	err := t.Authenticate(*token)
	checkError(err)

	profile, err := t.Profile()
	checkError(err)

	fmt.Println("Your Profile:")
	fmt.Println("Name: " + profile.Name)
	fmt.Println("")

	var allRecs map[string]tindergo.RecsCoreUser
	var countRecs map[string]int

	for j := 0; j <= 3; j++ {
		recs, err := t.RecsCore()
		checkError(err)

		for _, elem := range recs {
			_, exist := allRecs[elem.ID]
			if exist {
				countRecs[elem.ID] = countRecs[elem.ID] + 1
			} else {
				countRecs[elem.ID] = 1
				allRecs[elem.ID] = elem
			}
		}
	}

	for i, e := range allRecs {
		if countRecs[i] > 1 {
			fmt.Println(e.Name, countRecs[i])
		}
	}
}

// checkError Panic application if has an error returned.
func checkError(err error) {
	if err != nil {
		panic(err)
	}
}
<commit_msg>Resuming<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/disiqueira/tindergo"
)

func main() {
	token := flag.String("token", "", "Your Facebook Token.")

	flag.Parse()

	if *token == "" {
		fmt.Println("You must provide a valid Facebook Token.")
		os.Exit(2)
	}

	t := tindergo.New()

	err := t.Authenticate(*token)
	checkError(err)

	profile, err := t.Profile()
	checkError(err)

	fmt.Println("Your Profile:")
	fmt.Println("Name: " + profile.Name)
	fmt.Println("")

	var allRecs map[string]tindergo.RecsCoreUser
	var countRecs map[string]int

	for j := 0; j <= 3; j++ {
		recs, err := t.RecsCore()
		checkError(err)

		for _, elem := range recs {
			_, exist := allRecs[elem.ID]
			if exist {
				countRecs[elem.ID] = countRecs[elem.ID] + 1
			} else {
				countRecs[elem.ID] = 1
				allRecs[elem.ID] = elem
			}
		}
	}

	for i, e := range allRecs {
		if countRecs[i] > 2
		{
			fmt.Println(e.Name, countRecs[i])
		}
	}
}

// checkError Panic application if has an error returned.
func checkError(err error) {
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	broker "github.com/abdulkadiryaman/hrotti/broker"
	command "github.com/hashicorp/consul/command"
	"github.com/hashicorp/consul/command/agent"
	consul "github.com/hashicorp/consul/consul"
	"github.com/mitchellh/cli"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func bootstrapConsul(dc string, bootstrap bool) {
	private, err := consul.GetPrivateIP()
	if err != nil {
		log.Fatal("err: %v", err)
	}

	var agentArgs []string
	if bootstrap {
		agentArgs = []string{"-server", "-bootstrap", "-node", private.String(), "-dc", dc, "-data-dir", "/tmp/consul"}
	} else {
		agentArgs = []string{"-server", "-node", private.String(), "-dc", dc, "-data-dir", "/tmp/consul"}
	}
	ui := &cli.BasicUi{Writer: os.Stdout}
	agentCommand := &agent.Command{
		Ui:         ui,
		ShutdownCh: make(chan struct{}),
	}
	agentCommand.Run(agentArgs)

	time.Sleep(10 * time.Second)
	joinArgs := []string{"172.17.0.2"}

	Join(joinArgs)

	//	joinCommand := &command.JoinCommand{
	//		Ui: ui,
	//	}
	//	joinCommand.Run(joinArgs)

}

func bootstrapMqttServer() {
	listener := broker.NewListenerConfig("tcp://0.0.0.0:1883")

	h := broker.NewHrotti(100)

	h.AddListener("self", listener)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	<-c
	h.Stop()
}

func Join(args []string) int {
	var wan bool
	log.Println("Joining to cluster with addresses : ", args)
	cmdFlags := flag.NewFlagSet("join", flag.ContinueOnError)
	cmdFlags.BoolVar(&wan, "wan", false, "wan")
	rpcAddr := command.RPCAddrFlag(cmdFlags)
	if err := cmdFlags.Parse(args); err != nil {
		log.Fatal("Error occured : ", err)
		return 1
	}

	addrs := cmdFlags.Args()
	if len(addrs) == 0 {
		log.Fatal("At least one address to join must be specified.")
		return 1
	}

	client, err := command.RPCClient(*rpcAddr)
	if err != nil {
		log.Fatal("Error connecting to Consul agent: %s", err)
		return 1
	}
	defer client.Close()

	n, err := client.Join(addrs, wan)
	if err != nil {
		log.Fatal("Error joining the cluster: %s", err)
		return 1
	}

	log.Println(
		"Successfully joined cluster by contacting %d nodes.", n)
	return 0
}

func main() {
	log.Println("Arguments are : ", os.Args)
	var bootstrap bool
	if len(os.Args) < 2 {
		bootstrap = true
	} else {
		bootstrap = os.Args[1] != "false"
	}

	go bootstrapConsul("dc1", bootstrap)
	bootstrapMqttServer()
}
<commit_msg>node name settings to default ip address<commit_after>package main

import (
	"flag"
	"fmt"
	broker "github.com/abdulkadiryaman/hrotti/broker"
	command "github.com/hashicorp/consul/command"
	"github.com/hashicorp/consul/command/agent"
	consul "github.com/hashicorp/consul/consul"
	"github.com/mitchellh/cli"
	"log"
	"os"
	"os/signal"
	"syscall"
)

func bootstrapConsul(dc string, bootstrap bool) {
	private, err := consul.GetPrivateIP()
	if err != nil {
		fmt.Errorf("err: %v", err)
	}

	var agentArgs []string
	if bootstrap {
		agentArgs = []string{"-server", "-bootstrap", "-node", private.String(), "-dc", dc, "-data-dir", "/tmp/consul"}
	} else {
		agentArgs = []string{"-server", "-node", private.String(), "-dc", dc, "-data-dir", "/tmp/consul"}
	}
	ui := &cli.BasicUi{Writer: os.Stdout}
	agentCommand := &agent.Command{
		Ui:         ui,
		ShutdownCh: make(chan struct{}),
	}
	agentCommand.Run(agentArgs)
}

func bootstrapMqttServer() {
	listener := broker.NewListenerConfig("tcp://0.0.0.0:1883")

	h := broker.NewHrotti(100)

	h.AddListener("self", listener)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	<-c
	h.Stop()
}

func Join(args []string) int {
	var wan bool
	log.Println("Joining to cluster with addresses : ", args)
	cmdFlags := flag.NewFlagSet("join", flag.ContinueOnError)
	cmdFlags.BoolVar(&wan, "wan", false, "wan")
	rpcAddr := command.RPCAddrFlag(cmdFlags)
	if err := cmdFlags.Parse(args); err != nil {
		fmt.Errorf("Error occured : %v", err)
		return 1
	}

	addrs := cmdFlags.Args()
	if len(addrs) == 0 {
		log.Fatal("At least one address to join must be specified.")
		return 1
	}

	client, err := command.RPCClient(*rpcAddr)
	if err != nil {
		log.Fatal("Error connecting to Consul agent: %s", err)
		return 1
	}
	defer client.Close()

	n, err := client.Join(addrs, wan)
	if err != nil {
		log.Fatal("Error joining the cluster: %s", err)
		return 1
	}

	log.Println(
		"Successfully joined cluster by contacting %d nodes.", n)
	return 0
}

func main() {
	var bootstrap bool
	if len(os.Args) < 2 {
		bootstrap = true
	} else {
		bootstrap = os.Args[1] != "false"
	}

	go bootstrapConsul("dc1", bootstrap)

	if !bootstrap {
		joinArgs := []string{"172.17.0.2"}
		go Join(joinArgs)
	}

	bootstrapMqttServer()
}
<|endoftext|>


<commit_before>// Some parts of this file are taken from Lakrizz' example on GitHub
// https://github.com/lakrizz/go-pidioder/blob/master/main.go

package dioder

import (
	"bufio"
	"errors"
	"image/color"
	"os"
	"strconv"
)

//Pins the numbers of the RGB-pins
type Pins struct {
	Red   uint8
	Green uint8
	Blue  uint8
}

//Dioder the main structure
type Dioder struct {
	PinConfiguration   Pins
	ColorConfiguration color.RGBA
}

//New creates a new instance
func (d *Dioder) New(pinConfiguration Pins) {
	d.SetPins(pinConfiguration)
}

// GetCurrentColor returns the current color
func (d *Dioder) GetCurrentColor() color.RGBA {
	return d.ColorConfiguration
}

// SetAll sets the given values for the channels
func (d *Dioder) SetAll(colorSet color.RGBA) {
	SetRed(colorSet.R)
	SetGreen(colorSet.G)
	SetBlue(colorSet.B)

	d.ColorConfiguration = colorSet
}

// SetBlue sets the given value on the Blue channel
func (d *Dioder) SetBlue(value uint8) error {
	// Do nothing if the new value is the same as the old
	if value == d.ColorConfiguration.B {
		return nil
	}

	d.ColorConfiguration.B = value
	return setChannelInteger(value, d.PinConfiguration.Blue)
}

// SetGreen sets the given value on the Green channel
func (d *Dioder) SetGreen(value uint8) error {
	// Do nothing if the new value is the same as the old
	if value == d.ColorConfiguration.G {
		return nil
	}

	d.ColorConfiguration.G = value
	return setChannelInteger(value, d.PinConfiguration.Green)
}

//SetPins configures the pin-layout
func (d *Dioder) SetPins(pinConfiguration Pins) {
	d.PinConfiguration = pinConfiguration
}

// SetRed sets the given value on the Red channel
func (d *Dioder) SetRed(value uint8) error {
	// Do nothing if the new value is the same as the old
	if value == d.ColorConfiguration.R {
		return nil
	}

	d.ColorConfiguration.R = value
	return setChannelInteger(value, d.PinConfiguration.Red)
}

//TurnOff turns off the dioder-strips and saves the current configuration
func (d *Dioder) TurnOff() {
	//Temporary save the configuration
	configuration := d.ColorConfiguration
	SetAll(color.RGBA{})
	d.ColorConfiguration = configuration
}

//TurnOn turns the dioder-strips on and restores the previous configuration
func (d *Dioder) TurnOn() {
	if d.ColorConfiguration.A == 0 && d.ColorConfiguration.B == 0 && d.ColorConfiguration.G == 0 && d.ColorConfiguration.R == 0 {
		d.ColorConfiguration = color.RGBA{255, 255, 255, 100}
	}

	d.SetAll(d.ColorConfiguration)
}

func floatToString(floatValue float64) string {
	return strconv.FormatFloat(floatValue, 'f', 6, 64)
}

func setColor(channel string, value float64) error {
	piBlasterCommand := channel + "=" + floatToString(value) + "\n"

	file, error := os.OpenFile("/dev/pi-blaster", os.O_RDWR, os.ModeNamedPipe)

	if error != nil {
		panic(error)
	}

	defer file.Close()

	stream := bufio.NewWriter(file)

	_, error = stream.WriteString(piBlasterCommand)

	if error != nil {
		panic(error)
	}

	stream.Flush()

	return nil
}

func setChannelInteger(value uint8, channel string) error {
	if value > 255 {
		return errors.New("Value can not be over 255")
	}

	if value < 0 {
		return errors.New("Value can not be under 0")
	}

	floatval := float64(value) / 255.0

	setColor(channel, float64(floatval))

	return nil
}
<commit_msg>CI-Fixes<commit_after>// Some parts of this file are taken from Lakrizz' example on GitHub
// https://github.com/lakrizz/go-pidioder/blob/master/main.go

package dioder

import (
	"bufio"
	"errors"
	"image/color"
	"os"
	"strconv"
)

//Pins the numbers of the RGB-pins
type Pins struct {
	Red   string
	Green string
	Blue  string
}

//Dioder the main structure
type Dioder struct {
	PinConfiguration   Pins
	ColorConfiguration color.RGBA
}

//New creates a new instance
func (d *Dioder) New(pinConfiguration Pins) {
	d.SetPins(pinConfiguration)
}

// GetCurrentColor returns the current color
func (d *Dioder) GetCurrentColor() color.RGBA {
	return d.ColorConfiguration
}

// SetAll sets the given values for the channels
func (d *Dioder) SetAll(colorSet color.RGBA) {
	d.SetRed(colorSet.R)
	d.SetGreen(colorSet.G)
	d.SetBlue(colorSet.B)

	d.ColorConfiguration = colorSet
}

// SetBlue sets the given value on the Blue channel
func (d *Dioder) SetBlue(value uint8) error {
	// Do nothing if the new value is the same as the old
	if value == d.ColorConfiguration.B {
		return nil
	}

	d.ColorConfiguration.B = value
	return setChannelInteger(value, d.PinConfiguration.Blue)
}

// SetGreen sets the given value on the Green channel
func (d *Dioder) SetGreen(value uint8) error {
	// Do nothing if the new value is the same as the old
	if value == d.ColorConfiguration.G {
		return nil
	}

	d.ColorConfiguration.G = value
	return setChannelInteger(value, d.PinConfiguration.Green)
}

//SetPins configures the pin-layout
func (d *Dioder) SetPins(pinConfiguration Pins) {
	d.PinConfiguration = pinConfiguration
}

// SetRed sets the given value on the Red channel
func (d *Dioder) SetRed(value uint8) error {
	// Do nothing if the new value is the same as the old
	if value == d.ColorConfiguration.R {
		return nil
	}

	d.ColorConfiguration.R = value
	return setChannelInteger(value, d.PinConfiguration.Red)
}

//TurnOff turns off the dioder-strips and saves the current configuration
func (d *Dioder) TurnOff() {
	//Temporary save the configuration
	configuration := d.ColorConfiguration
	d.SetAll(color.RGBA{})
	d.ColorConfiguration = configuration
}

//TurnOn turns the dioder-strips on and restores the previous configuration
func (d *Dioder) TurnOn() {
	if d.ColorConfiguration.A == 0 && d.ColorConfiguration.B == 0 && d.ColorConfiguration.G == 0 && d.ColorConfiguration.R == 0 {
		d.ColorConfiguration = color.RGBA{255, 255, 255, 100}
	}

	d.SetAll(d.ColorConfiguration)
}

func floatToString(floatValue float64) string {
	return strconv.FormatFloat(floatValue, 'f', 6, 64)
}

func setColor(channel string, value float64) error {
	piBlasterCommand := channel + "=" + floatToString(value) + "\n"

	file, error := os.OpenFile("/dev/pi-blaster", os.O_RDWR, os.ModeNamedPipe)

	if error != nil {
		panic(error)
	}

	defer file.Close()

	stream := bufio.NewWriter(file)

	_, error = stream.WriteString(piBlasterCommand)

	if error != nil {
		panic(error)
	}

	stream.Flush()

	return nil
}

func setChannelInteger(value uint8, channel string) error {
	if value > 255 {
		return errors.New("Value can not be over 255")
	}

	if value < 0 {
		return errors.New("Value can not be under 0")
	}

	floatval := float64(value) / 255.0

	setColor(channel, float64(floatval))

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"net/http"
	"log"
	"fmt"
)

func getEnv(key string, defVal string) (env string) {
	env = os.Getenv(key)

	if env == "" {
		env = defVal
	}
	return
}

func main() {
	host := getEnv("HOST", "")
	port := getEnv("PORT", "8080")
	wsPort := getEnv("WSPORT", "8080")
//	mongoURL := getEnv("MONGOHQ_URL", "localhost")

	bind := fmt.Sprintf("%s:%s", host, port)
	log.Println("Starting server on", bind, "with websocket on port", wsPort)

	err := http.ListenAndServe(bind, nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<commit_msg>Added sample<commit_after>package main

import (
	"os"
	"net/http"
	"log"
	"fmt"
)

func getEnv(key string, defVal string) (env string) {
	env = os.Getenv(key)

	if env == "" {
		env = defVal
	}
	return
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello world!")
}

func main() {
	host := getEnv("HOST", "")
	port := getEnv("PORT", "8080")

	bind := fmt.Sprintf("%s:%s", host, port)
	log.Println("Starting server on", bind)

	http.HandleFunc("/", handler)
	err := http.ListenAndServe(bind, nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<|endoftext|>


<commit_before>package main

import "fmt"

// Taken from https://github.com/xboard/sudoku_solver
var games = []string{
	"85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4.",
	"..53.....8......2..7..1.5..4....53...1..7...6..32...8..6.5....9..4....3......97..",
	"12..4......5.69.1...9...5.........7.7...52.9..3......2.9.6...5.4..9..8.1..3...9.4",
	"...57..3.1......2.7...234......8...4..7..4...49....6.5.42...3.....7..9....18.....",
	"7..1523........92....3.....1....47.8.......6............9...5.6.4.9.7...8....6.1.",
	"1....7.9..3..2...8..96..5....53..9...1..8...26....4...3......1..4......7..7...3..",
	"1...34.8....8..5....4.6..21.18......3..1.2..6......81.52..7.9....6..9....9.64...2",
	"...92......68.3...19..7...623..4.1....1...7....8.3..297...8..91...5.72......64...",
	".6.5.4.3.1...9...8.........9...5...6.4.6.2.7.7...4...5.........4...8...1.5.2.3.4.",
	"7.....4...2..7..8...3..8.799..5..3...6..2..9...1.97..6...3..9...3..4..6...9..1.35",
	"....7..2.8.......6.1.2.5...9.54....8.........3....85.1...3.2.8.4.......9.7..6...."}

func decodeGame(game string) (result [][]int) {
	result = make([][]int, 9)
	for r := 0; r < 9; r++ {
		result[r] = make([]int, 9)
		for c := 0; c < 9; c++ {
			ch := game[r*9+c]
			if ch == '.' {
				result[r][c] = 0
			} else {
				result[r][c] = int(ch - '0')
			}
		}
	}
	return
}

func main() {
	for i := range games {
		solveSudoku(decodeGame(games[i]))
		fmt.Println()
	}
}
<commit_msg>Added the hardest example from Peter Norvig's article.<commit_after>package main

import "fmt"

// Taken from https://github.com/xboard/sudoku_solver
var games = []string{
	"85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4.",
	"..53.....8......2..7..1.5..4....53...1..7...6..32...8..6.5....9..4....3......97..",
	"12..4......5.69.1...9...5.........7.7...52.9..3......2.9.6...5.4..9..8.1..3...9.4",
	"...57..3.1......2.7...234......8...4..7..4...49....6.5.42...3.....7..9....18.....",
	"7..1523........92....3.....1....47.8.......6............9...5.6.4.9.7...8....6.1.",
	"1....7.9..3..2...8..96..5....53..9...1..8...26....4...3......1..4......7..7...3..",
	"1...34.8....8..5....4.6..21.18......3..1.2..6......81.52..7.9....6..9....9.64...2",
	"...92......68.3...19..7...623..4.1....1...7....8.3..297...8..91...5.72......64...",
	".6.5.4.3.1...9...8.........9...5...6.4.6.2.7.7...4...5.........4...8...1.5.2.3.4.",
	"7.....4...2..7..8...3..8.799..5..3...6..2..9...1.97..6...3..9...3..4..6...9..1.35",
	"....7..2.8.......6.1.2.5...9.54....8.........3....85.1...3.2.8.4.......9.7..6....",
	// The hardest example from http://norvig.com/sudoku.html
	".....5.8....6.1.43..........1.5........1.6...3.......553.....61........4........."}

func decodeGame(game string) (result [][]int) {
	result = make([][]int, 9)
	for r := 0; r < 9; r++ {
		result[r] = make([]int, 9)
		for c := 0; c < 9; c++ {
			ch := game[r*9+c]
			if ch == '.' {
				result[r][c] = 0
			} else {
				result[r][c] = int(ch - '0')
			}
		}
	}
	return
}

func main() {
	for i := range games {
		solveSudoku(decodeGame(games[i]))
		fmt.Println()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/bfirsh/whalebrew/cmd"
)

func main() {

	if len(os.Args) > 1 {
		// Check if not command exists
		if _, _, err := cmd.RootCmd.Find(os.Args); err != nil {
			// Check if file exists
			if _, err := os.Stat(os.Args[1]); err == nil {
				cmd.RootCmd.SetArgs(append([]string{"run"}, os.Args[1:]...))
			}
		}
	}

	if err := cmd.RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}
<commit_msg>Revert "Fix checking args (for working on windows)"<commit_after>package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/bfirsh/whalebrew/cmd"
)

func main() {
	// HACK: if first argument starts with "/", prefix the subcommand run.
	// This allows us to use this command as a shebang, because we can't pass
	// the argument "run" in the shebang on Linux.
	if len(os.Args) > 1 && strings.HasPrefix(os.Args[1], "/") {
		cmd.RootCmd.SetArgs(append([]string{"run"}, os.Args[1:]...))
	}

	if err := cmd.RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/DrItanium/unicornhat"
	"log"
	"math/rand"
	"runtime"
	"time"
)

type Memory []byte
type Word uint32

const (
	NumCpus    = 64
	Kilo       = 1024
	Meg        = Kilo * Kilo
	MemorySize = 128 * Meg
	CpuStart   = 64 * Meg
	OneMeg     = 1 * Meg
	MemSize    = 16 * Meg
	µcoreSize  = MemSize / 64
)

type µcore struct {
	index  uint
	memory Memory
	done   chan int
}

func (this *µcore) Execute() {
	log.Printf("µcore %d: Randomizing memory", this.index)
	for i := 0; i < len(this.memory); i++ {
		this.memory[i] = byte(rand.Uint32())
	}
	log.Printf("µcore %d: Done randomizing memory", this.index)
	log.Printf("µcore %d: Walking through memory", this.index)
	for i := 0; i < len(this.memory); i += 4 {
		unicornhat.SetPixelColor(this.index, this.memory[0], this.memory[1], this.memory[2])
		MicrosecondDelay(time.Duration(this.memory[3]))
	}
	log.Printf("µcore %d: done walking", this.index)
	this.done <- 0
	close(this.done)
}

func New(index uint, memory Memory) *µcore {
	var c µcore
	c.memory = memory
	c.index = index
	c.done = make(chan int)
	return &c
}

func main() {
	var cpus []*µcore
	var memory Memory
	runtime.GOMAXPROCS(runtime.NumCPU())
	defer unicornhat.Terminate(0)
	unicornhat.SetBrightness(unicornhat.DefaultBrightness())
	unicornhat.Init(NumCpus)
	unicornhat.ClearLEDBuffer()
	cpus = make([]*µcore, NumCpus)
	memory = make(Memory, MemSize)
	upperHalf := memory
	for i := 0; i < 64; i++ {
		targetMem := upperHalf[:µcoreSize]
		cpus[i] = New(uint(i), targetMem)
		go cpus[i].Execute()
		upperHalf = upperHalf[µcoreSize:]
	}

	count := 0
	for {
		if count >= 64 {
			break
		} else {
			for i := 0; i < 64; i++ {
				c := cpus[i].done
				select {
				case <-c:
					fmt.Println("done")
					count++
				default:
					unicornhat.Show()
					MicrosecondDelay(10)
				}
			}
			unicornhat.Show()
			MicrosecondDelay(10)
		}
	}
}

func MicrosecondDelay(usec time.Duration) {
	time.Sleep(usec * time.Microsecond)
}
<commit_msg>The grid of goroutines now uses channels<commit_after>package main

import (
	"fmt"
	"github.com/DrItanium/unicornhat"
	"log"
	"math/rand"
	"runtime"
	"time"
)

type Memory []byte
type Word uint32

const (
	NumCpus    = 64
	Kilo       = 1024
	Meg        = Kilo * Kilo
	MemorySize = 128 * Meg
	CpuStart   = 64 * Meg
	OneMeg     = 1 * Meg
	MemSize    = 8 * Meg
	µcoreSize  = MemSize / 64
)

type µcore struct {
	index  int
	memory Memory
	result chan *unicornhat.Pixel
	done   chan int
}

func (this *µcore) Execute() {
	log.Printf("µcore %d: Walking through memory", this.index)
	for i := 0; i < len(this.memory); i += 4 {
		this.result <- unicornhat.NewPixel(this.memory[i+0], this.memory[i+1], this.memory[i+2])
		MillisecondDelay(this.memory[i+3] % 17)
	}
	log.Printf("µcore %d: done walking", this.index)
	this.done <- 0
	close(this.done)
}

func New(index int, memory Memory) *µcore {
	var c µcore
	c.memory = memory
	c.index = index
	c.done = make(chan int)
	c.result = make(chan *unicornhat.Pixel)
	return &c
}

func main() {
	var cpus []*µcore
	var memory Memory
	runtime.GOMAXPROCS(runtime.NumCPU())
	defer unicornhat.Shutdown()
	unicornhat.SetBrightness(128)
	if err := unicornhat.Initialize(); err != nil {
		fmt.Println(err)
		return
	}
	unicornhat.ClearLEDBuffer()
	unicornhat.Show()
	cpus = make([]*µcore, NumCpus)
	memory = make(Memory, MemSize)
	log.Print("Randomizing memory")
	for i := 0; i < len(memory); i++ {
		memory[i] = byte(rand.Uint32()) % 64
	}
	log.Print("Done randomizing memory")
	upperHalf := memory
	for i := 0; i < 64; i++ {
		targetMem := upperHalf[:µcoreSize]
		cpus[i] = New(i, targetMem)
		go cpus[i].Execute()
		upperHalf = upperHalf[µcoreSize:]
	}

	count := 0
	for {
		if count >= 64 {
			break
		}
		for i := 0; i < 64; i++ {
			c := cpus[i]
			if c == nil {
				continue
			}
			select {
			case value := <-c.result:
				unicornhat.SetPixelColor(c.index, value.R, value.G, value.B)
			case <-c.done:
				fmt.Println("done")
				count++
				cpus[i] = nil
			default:
			}
		}
		unicornhat.Show()
		MillisecondDelay(33)
	}
}
func MillisecondDelay(msec time.Duration) {
	time.Sleep(usec * time.Millisecond)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"

	"github.com/urfave/cli"
)

const (
	banner = `
 _____ _____ _____
|   __|  _  |  _  |___ ___ ___
|__   |   __|     |  _| . | -_|
|_____|__|  |__|__|_| |_  |___| %s
                      |___|
Single Page Application server  ________
_______________________________/__\__\__\
                               \__/__/__/

`
)

// version set by LDFLAGS
var version string

	e := echo.New()
	e.HideBanner = true
	e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
		Root:   root,
		Index:  "index.html",
		HTML5:  true,
		Browse: false,
	}))

	fmt.Printf(banner, "v"+version)
	fmt.Printf("» http server started on port %d\n", port)
	e.Use(middleware.Logger())

	e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", port)))
}

func main() {
	app := cli.NewApp()
	app.Name = "sparge"
	app.Usage = "A SPA (single-page application) server"
	app.Version = version

	app.Flags = []cli.Flag{}

	app.Commands = []cli.Command{
		{
			Name:  "start",
			Usage: "Start the SPA server",
			Action: func(c *cli.Context) error {
				start(c.String("dir"), c.Int("port"))
				return nil
			},
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "dir, d",
					Value: "./public",
				},
				cli.StringFlag{
					Name:  "port, p",
					Value: "8080",
				},
			},
		},
	}

	// start()
	app.Run(os.Args)
}
<commit_msg>fix: move Logger middleware and fix 404 error<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"

	"github.com/urfave/cli"
)

const (
	banner = `
 _____ _____ _____
|   __|  _  |  _  |___ ___ ___
|__   |   __|     |  _| . | -_|
|_____|__|  |__|__|_| |_  |___| %s
                      |___|
Single Page Application server  ________
_______________________________/__\__\__\
                               \__/__/__/

`
)

// version set by LDFLAGS
var version string

	e := echo.New()
	e.HideBanner = true

	e.Use(middleware.Logger())

	e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
		Root:   root,
		Index:  "index.html",
		HTML5:  true,
		Browse: false,
	}))

	fmt.Printf(banner, "v"+version)
	fmt.Printf("» http server started on port %d\n", port)

	e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", port)))
}

func main() {
	app := cli.NewApp()
	app.Name = "sparge"
	app.Usage = "A SPA (single-page application) server"
	app.Version = version

	app.Flags = []cli.Flag{}

	app.Commands = []cli.Command{
		{
			Name:  "start",
			Usage: "Start the SPA server",
			Action: func(c *cli.Context) error {
				start(c.String("dir"), c.Int("port"))
				return nil
			},
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "dir, d",
					Value: "./public",
				},
				cli.StringFlag{
					Name:  "port, p",
					Value: "8080",
				},
			},
		},
	}

	// start()
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"regexp"
)

func main() {
	// validate the input parameters
	if len(os.Args) != 2 {
		fmt.Println("Please specifiy a file name")
		os.Exit(2)
	}

	// get the filepath parameter
	filepath := os.Args[1]
	file, err := os.Open(filepath)
	if err != nil {
		fmt.Printf("File %q not found.\n", filepath)
		os.Exit(2)
	}

	// split into lines
	lines := getLines(file)

	for _, line := range lines {

		normalizedLine := []byte(line)

		// replace the session id
		sessionIdPattern := regexp.MustCompile(`<sessionId>[^<]+?</sessionId`)
		normalizedLine = sessionIdPattern.ReplaceAll(normalizedLine, []byte(`<sessionId>?</sessionId>`))

		// remove white space
		normalizedLine = bytes.TrimSpace(normalizedLine)

		// print the normalized line
		if len(normalizedLine) > 0 {
			fmt.Printf("%s\n", normalizedLine)
		}
	}
}

// readLine returns a single line (without the ending \n)
// from the input buffered reader.
// An error is returned iff there is an error with the
// buffered reader.
func readLine(bufferedReader *bufio.Reader) (string, error) {
	var (
		isPrefix bool  = true
		err      error = nil
		line, ln []byte
	)

	for isPrefix && err == nil {
		line, isPrefix, err = bufferedReader.ReadLine()
		ln = append(ln, line...)
	}

	return string(ln), err
}

// Get all lines of a given file
func getLines(inFile io.Reader) []string {

	lines := make([]string, 0, 10)
	bufferedReader := bufio.NewReader(inFile)
	line, err := readLine(bufferedReader)
	for err == nil {
		lines = append(lines, line)
		line, err = readLine(bufferedReader)
	}

	return lines
}
<commit_msg>Bug fix: the session id regex had an error in it<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"regexp"
)

func main() {
	// validate the input parameters
	if len(os.Args) != 2 {
		fmt.Println("Please specifiy a file name")
		os.Exit(2)
	}

	// get the filepath parameter
	filepath := os.Args[1]
	file, err := os.Open(filepath)
	if err != nil {
		fmt.Printf("File %q not found.\n", filepath)
		os.Exit(2)
	}

	// split into lines
	lines := getLines(file)

	for _, line := range lines {

		normalizedLine := []byte(line)

		// replace the session id
		sessionIdPattern := regexp.MustCompile(`<sessionId>[^<]+?</sessionId>`)
		normalizedLine = sessionIdPattern.ReplaceAll(normalizedLine, []byte(`<sessionId>?</sessionId>`))

		// remove white space
		normalizedLine = bytes.TrimSpace(normalizedLine)

		// print the normalized line
		if len(normalizedLine) > 0 {
			fmt.Printf("%s\n", normalizedLine)
		}
	}
}

// readLine returns a single line (without the ending \n)
// from the input buffered reader.
// An error is returned iff there is an error with the
// buffered reader.
func readLine(bufferedReader *bufio.Reader) (string, error) {
	var (
		isPrefix bool  = true
		err      error = nil
		line, ln []byte
	)

	for isPrefix && err == nil {
		line, isPrefix, err = bufferedReader.ReadLine()
		ln = append(ln, line...)
	}

	return string(ln), err
}

// Get all lines of a given file
func getLines(inFile io.Reader) []string {

	lines := make([]string, 0, 10)
	bufferedReader := bufio.NewReader(inFile)
	line, err := readLine(bufferedReader)
	for err == nil {
		lines = append(lines, line)
		line, err = readLine(bufferedReader)
	}

	return lines
}
<|endoftext|>


<commit_before>package main

import (
  "bufio"
  "fmt"
  "os"
  "os/exec"
  "path/filepath"
  "strings"
  xtc_compiler "bitbucket.org/yyuu/xtc/compiler"
)

func main() {
  compiler := xtc_compiler.NewCompiler(os.Args[0], os.Args[1:])
  files := compiler.SourceFiles()
  if 0 < len(files) {
    _, err := compiler.Compile()
    if err != nil {
      fmt.Fprintln(os.Stderr, err)
    }
  } else {
    repl(compiler)
  }
}

func repl(compiler *xtc_compiler.Compiler) {
  defer func() {
    if s := recover(); s != nil {
      fmt.Fprintf(os.Stderr, "recovered: %s\n", s)
      repl(compiler)
    }
  }()
  stdin  := bufio.NewReader(os.Stdin)
  stdout := bufio.NewWriter(os.Stdout)

  var sources []string
  for {
    stdout.WriteString("> ")
    stdout.Flush()
    line, err := stdin.ReadString('\n')
    if err != nil {
      os.Exit(1)
    }
    trimedLine := strings.TrimSpace(line)
    // FIXME: should not use such a stupid command-line
    if 0 < len(trimedLine) && strings.Index(trimedLine, ":") == 0 {
      switch trimedLine[1:] {
        case "clear": fallthrough
        case "cls": fallthrough
        case "reset": {
          sources = []string { }
        }
        case "eval": fallthrough
        case "run": {
          dst, err := compiler.CompileString(strings.Join(sources, ""))
          if err != nil {
            fmt.Fprintln(os.Stderr, err)
            continue
          }
          _, err = os.Stat(dst)
          if os.IsNotExist(err) {
            fmt.Fprintln(os.Stderr, err)
            continue
          }
          abspath, err := filepath.Abs(dst)
          if err != nil {
            fmt.Fprintln(os.Stderr, err)
            continue
          }
          cmd := exec.Command(abspath)
          out, err := cmd.CombinedOutput()
          if err != nil {
            fmt.Fprint(os.Stderr, string(out))
            fmt.Fprintln(os.Stderr, err)
            continue
          }
          fmt.Fprint(os.Stdout, string(out))
        }
        case "exit": fallthrough
        case "quit": {
          os.Exit(0)
        }
        case "list": fallthrough
        case "ls": fallthrough
        case "show": {
          fmt.Print(strings.Join(sources, ""))
        }
        default: {
          fmt.Fprintln(os.Stderr, "available commands:")
          fmt.Fprintln(os.Stderr, "clean, clear, cls, reset, eval, run, exit, quit, list, ls, show")
        }
      }
    } else {
      sources = append(sources, line)
    }
  }
}
<commit_msg>Add `:delete` command to REPL<commit_after>package main

import (
  "bufio"
  "fmt"
  "os"
  "os/exec"
  "path/filepath"
  "strings"
  xtc_compiler "bitbucket.org/yyuu/xtc/compiler"
)

func main() {
  compiler := xtc_compiler.NewCompiler(os.Args[0], os.Args[1:])
  files := compiler.SourceFiles()
  if 0 < len(files) {
    _, err := compiler.Compile()
    if err != nil {
      fmt.Fprintln(os.Stderr, err)
    }
  } else {
    repl(compiler)
  }
}

func repl(compiler *xtc_compiler.Compiler) {
  defer func() {
    if s := recover(); s != nil {
      fmt.Fprintf(os.Stderr, "recovered: %s\n", s)
      repl(compiler)
    }
  }()
  stdin  := bufio.NewReader(os.Stdin)
  stdout := bufio.NewWriter(os.Stdout)

  var sources []string
  for {
    stdout.WriteString("> ")
    stdout.Flush()
    line, err := stdin.ReadString('\n')
    if err != nil {
      os.Exit(1)
    }
    trimedLine := strings.TrimSpace(line)
    // FIXME: should not use such a stupid command-line
    if 0 < len(trimedLine) && strings.Index(trimedLine, ":") == 0 {
      switch trimedLine[1:] {
        case "clear": fallthrough
        case "cls": fallthrough
        case "reset": {
          sources = []string { }
        }
        case "eval": fallthrough
        case "run": {
          dst, err := compiler.CompileString(strings.Join(sources, ""))
          if err != nil {
            fmt.Fprintln(os.Stderr, err)
            continue
          }
          _, err = os.Stat(dst)
          if os.IsNotExist(err) {
            fmt.Fprintln(os.Stderr, err)
            continue
          }
          abspath, err := filepath.Abs(dst)
          if err != nil {
            fmt.Fprintln(os.Stderr, err)
            continue
          }
          cmd := exec.Command(abspath)
          out, err := cmd.CombinedOutput()
          if err != nil {
            fmt.Fprint(os.Stderr, string(out))
            fmt.Fprintln(os.Stderr, err)
            continue
          }
          fmt.Fprint(os.Stdout, string(out))
        }
        case "exit": fallthrough
        case "quit": {
          os.Exit(0)
        }
        case "list": fallthrough
        case "ls": fallthrough
        case "show": {
          fmt.Print(strings.Join(sources, ""))
        }
        case "del": fallthrough
        case "delete": {
          var lineno int
          fmt.Print("line number: ")
          fmt.Scanf("%d", &lineno)
          if lineno <= len(sources) {
            if lineno == 1 {
              sources = sources[1:]
            } else {
              sources = append(sources[0:lineno-1], sources[lineno:]...)
            }
          } else {
            fmt.Fprintln(os.Stderr, "out of range")
          }
        }
        default: {
          fmt.Fprintln(os.Stderr, "available commands:")
          fmt.Fprintln(os.Stderr, "clean, clear, cls, reset, eval, run, exit, quit, list, ls, show")
        }
      }
    } else {
      sources = append(sources, line)
    }
  }
}
<|endoftext|>


<commit_before>package main

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

	"github.com/nats-io/nats"

	"gopkg.in/mgo.v2"
)

const (
	metricsAPIPath = "/api/metrics"
	agentsAPIPath  = "/api/agents"
)

// TODO: Instead of using a global for each collection,
// abstract this into an interface, which makes it
// easier for testing.
var (
	// agents collection
	agentsC *mgo.Collection
)

// Command line flags
// prepend flag to variable names to not pollute the global namespace.
var (
	flagAddr    = flag.String("addr", ":8080", "serve HTTP on `address`")
	flagNatsURL = flag.String("nats", nats.DefaultURL, "nats URL")
)

func main() {
	log.SetFlags(0)
	log.SetPrefix("marksman: ")

	flag.Parse()

	http.HandleFunc(metricsAPIPath, metricsHandler)
	http.HandleFunc(agentsAPIPath, agentsHandler)
	http.Handle("/", http.FileServer(http.Dir("./public")))

	session, err := mgo.Dial("localhost")
	if err != nil {
		panic(err)
	}
	defer session.Close()

	// Optional. Switch the session to a monotonic behavior.
	session.SetMode(mgo.Monotonic, true)
	agentsC = session.DB("recon-dev").C("agents")

	log.Println("Server started: http://localhost" + *flagAddr)
	log.Fatal(http.ListenAndServe(*flagAddr, nil))
}

func metricsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	fmt.Fprintf(w, "TODO")
}

func agentsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	switch r.Method {
	case "GET":
		var R []Agent
		err := agentsC.Find(nil).All(&R)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		enc := json.NewEncoder(w)
		if err := enc.Encode(R); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		return
	case "POST":
		var a Agent
		dec := json.NewDecoder(r.Body)
		if err := dec.Decode(&a); err != nil {
			http.Error(w, "unable to decode json", http.StatusBadRequest)
			return
		}
		if a.UID == "" {
			http.Error(w, "UID can't be empty", http.StatusBadRequest)
			return
		}
		err := agentsC.Insert(a)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.WriteHeader(http.StatusCreated)
		nurl := struct {
			NatsURL string `json:"nats_url"`
		}{
			NatsURL: *flagNatsURL,
		}
		enc := json.NewEncoder(w)
		if err := enc.Encode(nurl); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		return
	default:
		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
		return
	}
}

// Agent represents a recon agent running on
// a machine.
type Agent struct {
	UID string
}
<commit_msg>use recon.Agent type instead of Agent type<commit_after>package main

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

	"github.com/codeignition/recon"
	"github.com/nats-io/nats"

	"gopkg.in/mgo.v2"
)

const (
	metricsAPIPath = "/api/metrics"
	agentsAPIPath  = "/api/agents"
)

// TODO: Instead of using a global for each collection,
// abstract this into an interface, which makes it
// easier for testing.
var (
	// agents collection
	agentsC *mgo.Collection
)

// Command line flags
// prepend flag to variable names to not pollute the global namespace.
var (
	flagAddr    = flag.String("addr", ":8080", "serve HTTP on `address`")
	flagNatsURL = flag.String("nats", nats.DefaultURL, "nats URL")
)

func main() {
	log.SetFlags(0)
	log.SetPrefix("marksman: ")

	flag.Parse()

	http.HandleFunc(metricsAPIPath, metricsHandler)
	http.HandleFunc(agentsAPIPath, agentsHandler)
	http.Handle("/", http.FileServer(http.Dir("./public")))

	session, err := mgo.Dial("localhost")
	if err != nil {
		panic(err)
	}
	defer session.Close()

	// Optional. Switch the session to a monotonic behavior.
	session.SetMode(mgo.Monotonic, true)
	agentsC = session.DB("recon-dev").C("agents")

	log.Println("Server started: http://localhost" + *flagAddr)
	log.Fatal(http.ListenAndServe(*flagAddr, nil))
}

func metricsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	fmt.Fprintf(w, "TODO")
}

func agentsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	switch r.Method {
	case "GET":
		var R []recon.Agent
		err := agentsC.Find(nil).All(&R)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		enc := json.NewEncoder(w)
		if err := enc.Encode(R); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		return
	case "POST":
		var a recon.Agent
		dec := json.NewDecoder(r.Body)
		if err := dec.Decode(&a); err != nil {
			http.Error(w, "unable to decode json", http.StatusBadRequest)
			return
		}
		if a.UID == "" {
			http.Error(w, "UID can't be empty", http.StatusBadRequest)
			return
		}
		err := agentsC.Insert(a)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.WriteHeader(http.StatusCreated)
		nurl := struct {
			NatsURL string `json:"nats_url"`
		}{
			NatsURL: *flagNatsURL,
		}
		enc := json.NewEncoder(w)
		if err := enc.Encode(nurl); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		return
	default:
		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
		return
	}
}

// Agent represents a recon agent running on
// a machine.
type Agent struct {
	UID string
}
<|endoftext|>


<commit_before>// 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 main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"

	luis "github.com/kkdai/luis"
	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client
var luisAction *LuisAction
var allIntents *luis.IntentListResponse
var currentUtterance string

func main() {
	var err error
	appID := os.Getenv("APP_ID")
	apiKey := os.Getenv("APP_KEY")
	log.Println("Luis:", appID, apiKey)
	luisAction = NewLuisAction(appID, apiKey)

	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		switch event.Type {
		case linebot.EventTypeMessage:
			log.Println("event.Type == EventTypeMessage")
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				res, err := luisAction.GetIntents()
				if err != nil {
					log.Println(err)
					return
				}
				var intentList []string
				log.Println("All intent:", *res)
				for _, v := range *res {
					if strings.EqualFold(message.Text, v.Name) {
						//if input text equal to intents, just leave. (ignore dual event on post action)
						return
					}

					if v.Name != "None" {
						intentList = append(intentList, v.Name)
					}
				}

				ret := luisAction.Predict(message.Text)
				if ret.Intent == "None" || ret.Intent == "" || ret.Score < 0.5 {

					//List all intents
					ListAllIntents(bot, event.ReplyToken, intentList, message.Text)

				} else {
					if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(fmt.Sprintf("Daddy/Mommy, I just want to %s (%d %%)", ret.Intent, int(ret.Score*100)))).Do(); err != nil {
						log.Print(err)
					}
				}
			}
		case linebot.EventTypePostback:
			log.Println("event.Type == linebot.EventTypePostback")
			//Add new utterance into original intent
			luisAction.AddUtterance(event.Postback.Data, currentUtterance)

			retStr := fmt.Sprintf("Daddy/Mommy, I just learn new utterance %s for intent: %s.", currentUtterance, event.Postback.Data)
			if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(retStr)).Do(); err != nil {
				log.Print(err)
			}

			//Train it right away
			luisAction.Train()
			return
		}
	}
}

//ListAllIntents :
func ListAllIntents(bot *linebot.Client, replyToken string, intents []string, utterance string) {
	askStmt := fmt.Sprintf("Your utterance %s is not exist, please select correct intent.", utterance)
	log.Println("askStmt:", askStmt)

	var sliceTemplateAction []linebot.TemplateAction
	for _, v := range intents {
		sliceTemplateAction = append(sliceTemplateAction, linebot.NewPostbackAction(v, v, v, ""))
	}

	template := linebot.NewButtonsTemplate("", "Select your intent for your baby", utterance, sliceTemplateAction...)

	if _, err := bot.ReplyMessage(
		replyToken,
		linebot.NewTemplateMessage("Select your intent for your baby", template)).Do(); err != nil {
		log.Print(err)
	}
	currentUtterance = utterance
}
<commit_msg>fix build break<commit_after>// 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 main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"

	luis "github.com/kkdai/luis"
	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client
var luisAction *LuisAction
var allIntents *luis.IntentListResponse
var currentUtterance string

func main() {
	var err error
	appID := os.Getenv("APP_ID")
	apiKey := os.Getenv("APP_KEY")
	log.Println("Luis:", appID, apiKey)
	luisAction = NewLuisAction(appID, apiKey)

	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		switch event.Type {
		case linebot.EventTypeMessage:
			log.Println("event.Type == EventTypeMessage")
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				res, err := luisAction.GetIntents()
				if err != nil {
					log.Println(err)
					return
				}
				var intentList []string
				log.Println("All intent:", *res)
				for _, v := range *res {
					if strings.EqualFold(message.Text, v.Name) {
						//if input text equal to intents, just leave. (ignore dual event on post action)
						return
					}

					if v.Name != "None" {
						intentList = append(intentList, v.Name)
					}
				}

				ret := luisAction.Predict(message.Text)
				if ret.Intent == "None" || ret.Intent == "" || ret.Score < 0.5 {
					//List all intents
					ListAllIntents(bot, event.ReplyToken, intentList, message.Text)

				} else {
					if _, err := bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(fmt.Sprintf("Daddy/Mommy, I just want to %s (%d %%)", ret.Intent, int(ret.Score*100)))).Do(); err != nil {
						log.Print(err)
					}
				}
			}
		case linebot.EventTypePostback:
			log.Println("event.Type == linebot.EventTypePostback")
			//Add new utterance into original intent
			luisAction.AddUtterance(event.Postback.Data, currentUtterance)

			retStr := fmt.Sprintf("Daddy/Mommy, I just learn new utterance %s for intent: %s.", currentUtterance, event.Postback.Data)
			if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(retStr)).Do(); err != nil {
				log.Print(err)
			}

			//Train it right away
			luisAction.Train()
			return
		}
	}
}

//ListAllIntents :
func ListAllIntents(bot *linebot.Client, replyToken string, intents []string, utterance string) {
	askStmt := fmt.Sprintf("Your utterance %s is not exist, please select correct intent.", utterance)
	log.Println("askStmt:", askStmt)

	var sliceTemplateAction []linebot.TemplateAction
	for _, v := range intents {
		sliceTemplateAction = append(sliceTemplateAction, linebot.NewPostbackAction(v, v, v, ""))
	}

	template := linebot.NewButtonsTemplate("", "Select your intent for your baby", utterance, sliceTemplateAction...)

	if _, err := bot.ReplyMessage(
		replyToken,
		linebot.NewTemplateMessage("Select your intent for your baby", template)).Do(); err != nil {
		log.Print(err)
	}
	currentUtterance = utterance
}
<|endoftext|>


<commit_before>// 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 main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	luis "github.com/kkdai/luis"
	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client
var luisAction *LuisAction
var allIntents *luis.IntentListResponse
var currentUtterance string

func main() {
	var err error
	appID := os.Getenv("APP_ID")
	apiKey := os.Getenv("APP_KEY")
	log.Println("Luis:", appID, apiKey)
	luisAction = NewLuisAction(appID, apiKey)

	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				ret := luisAction.Predict(message.Text)

				if ret.Name == "None" || ret.Name == "" {

					res, err := luisAction.GetIntents()
					if err != nil {
						log.Println(err)
						return
					}
					var intentList []string
					log.Println("All intent:", *res)
					for _, v := range *res {
						if v.Name != "None" {
							intentList = append(intentList, v.Name)
						}
					}
					//List all intents
					ListAllIntents(bot, event.ReplyToken, intentList, message.Text)

				} else {
					if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(fmt.Sprintf("Daddy/Mommy, I just want to :%s (%f)", ret.Name, ret.Score))).Do(); err != nil {
						log.Print(err)
					}
				}
			}
		} else if event.Type == linebot.EventTypePostback {
			//Add new utterance into original intent
			luisAction.AddUtterance(event.Postback.Data, currentUtterance)
			retStr := fmt.Sprintf("Daddy/Mommy, I just learn new utterance :%s for intent: %s.", currentUtterance, event.Postback.Data)
			if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(retStr)).Do(); err != nil {
				log.Print(err)
			}

			//Train it right away
			luisAction.Train()
		}
	}
}

//ListAllIntents :
func ListAllIntents(bot *linebot.Client, replyToken string, intents []string, utterance string) {
	askStmt := fmt.Sprintf("Your utterance %s is not exist, please select correct intent.", utterance)
	log.Println("askStmt:", askStmt)

	var sliceTemplateAction []linebot.TemplateAction
	for _, v := range intents {
		sliceTemplateAction = append(sliceTemplateAction, linebot.NewPostbackTemplateAction(v, v, ""))
	}

	template := linebot.NewButtonsTemplate("", "Select your intent for your baby", utterance, sliceTemplateAction...)

	// template := linebot.NewButtonsTemplate("", "Select your intent for your baby", utterance,
	// 	linebot.NewPostbackTemplateAction(intents[0], intents[0], ""),
	// 	linebot.NewPostbackTemplateAction(intents[1], intents[1], ""),
	// 	linebot.NewPostbackTemplateAction(intents[2], intents[2], ""),
	// 	linebot.NewPostbackTemplateAction(intents[3], intents[3], ""))

	//	if _, err := bot.ReplyMessage(replyToken, linebot.NewTemplateMessage("test....", template)).Do(); err != nil {
	if _, err := bot.ReplyMessage(
		replyToken,
		linebot.NewTemplateMessage("Select your intent for your baby", template)).Do(); err != nil {
		log.Print(err)
	}
	currentUtterance = utterance
}
<commit_msg>Refine scope policy<commit_after>// 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 main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	luis "github.com/kkdai/luis"
	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client
var luisAction *LuisAction
var allIntents *luis.IntentListResponse
var currentUtterance string

func main() {
	var err error
	appID := os.Getenv("APP_ID")
	apiKey := os.Getenv("APP_KEY")
	log.Println("Luis:", appID, apiKey)
	luisAction = NewLuisAction(appID, apiKey)

	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				ret := luisAction.Predict(message.Text)

				if ret.Name == "None" || ret.Name == "" || ret.Score < 0.5 {

					res, err := luisAction.GetIntents()
					if err != nil {
						log.Println(err)
						return
					}
					var intentList []string
					log.Println("All intent:", *res)
					for _, v := range *res {
						if v.Name != "None" {
							intentList = append(intentList, v.Name)
						}
					}
					//List all intents
					ListAllIntents(bot, event.ReplyToken, intentList, message.Text)

				} else {
					if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(fmt.Sprintf("Daddy/Mommy, I just want to %s (%d %)", ret.Name, ret.Score*100))).Do(); err != nil {
						log.Print(err)
					}
				}
			}
		} else if event.Type == linebot.EventTypePostback {
			//Add new utterance into original intent
			luisAction.AddUtterance(event.Postback.Data, currentUtterance)
			retStr := fmt.Sprintf("Daddy/Mommy, I just learn new utterance %s for intent: %s.", currentUtterance, event.Postback.Data)
			if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(retStr)).Do(); err != nil {
				log.Print(err)
			}

			//Train it right away
			luisAction.Train()
		}
	}
}

//ListAllIntents :
func ListAllIntents(bot *linebot.Client, replyToken string, intents []string, utterance string) {
	askStmt := fmt.Sprintf("Your utterance %s is not exist, please select correct intent.", utterance)
	log.Println("askStmt:", askStmt)

	var sliceTemplateAction []linebot.TemplateAction
	for _, v := range intents {
		sliceTemplateAction = append(sliceTemplateAction, linebot.NewPostbackTemplateAction(v, v, ""))
	}

	template := linebot.NewButtonsTemplate("", "Select your intent for your baby", utterance, sliceTemplateAction...)

	// template := linebot.NewButtonsTemplate("", "Select your intent for your baby", utterance,
	// 	linebot.NewPostbackTemplateAction(intents[0], intents[0], ""),
	// 	linebot.NewPostbackTemplateAction(intents[1], intents[1], ""),
	// 	linebot.NewPostbackTemplateAction(intents[2], intents[2], ""),
	// 	linebot.NewPostbackTemplateAction(intents[3], intents[3], ""))

	//	if _, err := bot.ReplyMessage(replyToken, linebot.NewTemplateMessage("test....", template)).Do(); err != nil {
	if _, err := bot.ReplyMessage(
		replyToken,
		linebot.NewTemplateMessage("Select your intent for your baby", template)).Do(); err != nil {
		log.Print(err)
	}
	currentUtterance = utterance
}
<|endoftext|>