<commit_before>package main

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"

	"github.com/blakesmith/ar"
)

type semaphore chan int

type Conf struct {
	ListenPort   string   `json:"listenPort"`
	RootRepoPath string   `json:"rootRepoPath"`
	SupportArch  []string `json:"supportedArch"`
}

type DeleteObj struct {
	Filename string
	Arch     string
}

var sem = make(semaphore, 1)
var configFile = flag.String("c", "conf.json", "config file location")
var config = &Conf{}

func main() {
	flag.Parse()
	file, err := ioutil.ReadFile(*configFile)
	if err != nil {
		log.Panic("unable to read config file, exiting...")
	}
	config = &Conf{}
	if err := json.Unmarshal(file, &config); err != nil {
		log.Panic("unable to marshal config file, exiting...")
	}

	if !createDirs() {
		log.Println("error creating directory structure, exiting")
		os.Exit(1)
	}
	http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(config.RootRepoPath))))
	http.HandleFunc("/upload", uploadHandler)
	http.HandleFunc("/delete", deleteHandler)
	http.ListenAndServe(":"+config.ListenPort, nil)
}

func createDirs() bool {
	for _, archDir := range config.SupportArch {
		if _, err := os.Stat(config.RootRepoPath + "/dists/stable/main/binary-" + archDir); err != nil {
			if os.IsNotExist(err) {
				log.Printf("Directory for %s does not exist, creating", archDir)
				dirErr := os.MkdirAll(config.RootRepoPath+"/dists/stable/main/binary-"+archDir, 0755)
				if dirErr != nil {
					log.Printf("error creating directory for %s: %s\n", archDir, dirErr)
					return false
				}
			} else {
				log.Printf("error inspecting %s: %s\n", archDir, err)
				return false
			}
		}
	}
	return true
}

func inspectPackage(filename string) string {
	f, err := os.Open(filename)
	if err != nil {
		log.Printf("error opening package file %s: %s\n", filename, err)
		return ""
	}
	defer f.Close()

	arReader := ar.NewReader(f)
	var controlBuf bytes.Buffer

	for {
		header, err := arReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Println("error in inspectPackage loop: ", err)
			return ""
		}

		if header.Name == "control.tar.gz" {
			io.Copy(&controlBuf, arReader)
			return inspectPackageControl(controlBuf)

		}

	}
	return ""
}

func inspectPackageControl(filename bytes.Buffer) string {
	gzf, err := gzip.NewReader(bytes.NewReader(filename.Bytes()))
	if err != nil {
		log.Println("error creating gzip reader: ", err)
		return ""
	}

	tarReader := tar.NewReader(gzf)
	var controlBuf bytes.Buffer
	for {
		header, err := tarReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Println("error in inspectPackage loop: ", err)
			return ""
		}

		name := header.Name

		switch header.Typeflag {
		case tar.TypeDir:
			continue
		case tar.TypeReg:
			if name == "./control" {
				io.Copy(&controlBuf, tarReader)
				log.Printf("control file: %s\n", controlBuf.String())
				return controlBuf.String()
			}
		default:
			log.Printf("%s : %c %s %s\n",
				"Yikes! Unable to figure out type",
				header.Typeflag,
				"in file",
				name,
			)
		}
	}
	return ""
}

func createPackagesTar(arch string) bool {
	var packBuf bytes.Buffer
	// loop through each directory
	// run inspectPackage
	dirList, err := ioutil.ReadDir(config.RootRepoPath + "/dists/stable/main/binary-" + arch)
	if err != nil {
		log.Printf("error scanning %s: %s\n", config.RootRepoPath+"/dists/stable/main/binary-"+arch, err)
		return false
	}
	for _, debFile := range dirList {
		if strings.HasSuffix(debFile.Name(), "deb") {
			tempCtlData := inspectPackage(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name())
			packBuf.WriteString(tempCtlData)
			packBuf.WriteString("Filename: " + config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name() + "\n")
			packBuf.WriteString("Size: " + strconv.FormatInt(debFile.Size(), 10) + "\n")
			f, _ := ioutil.ReadFile(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name())
			md5hash := md5.New()
			io.WriteString(md5hash, string(f[:]))
			md5sum := hex.EncodeToString(md5hash.Sum(nil))
			packBuf.WriteString("MD5sum: " + md5sum + "\n")
			sha1hash := sha1.New()
			io.WriteString(sha1hash, string(f[:]))
			sha1sum := hex.EncodeToString(sha1hash.Sum(nil))
			packBuf.WriteString("SHA1: " + sha1sum + "\n")
			sha256hash := sha256.New()
			io.WriteString(sha256hash, string(f[:]))
			sha256sum := hex.EncodeToString(sha256hash.Sum(nil))
			packBuf.WriteString("SHA256: " + sha256sum + "\n")
			packBuf.WriteString("\n\n")
		}
	}

	outfile, err := os.Create(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/Packages.gz")
	if err != nil {
		log.Println("error creating packages.gz file")
		return false
	}
	defer outfile.Close()
	gzOut := gzip.NewWriter(outfile)
	defer gzOut.Close()
	gzOut.Write(packBuf.Bytes())
	gzOut.Flush()
	return true
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		archType := r.FormValue("arch")
		if archType == "" {
			archType = "all"
		}
		log.Println("archType is: ", archType)
		file, header, err := r.FormFile("file")
		if err != nil {
			log.Println("error parsing file: ", err)
		}
		log.Println("filename is: ", header.Filename)
		out, err := os.Create(config.RootRepoPath + "/dists/stable/main/binary-" + archType + "/" + header.Filename)
		if err != nil {
			log.Println("error creating file: ", err)
		}
		hash := md5.New()
		_, err = io.Copy(out, io.TeeReader(file, hash))
		defer file.Close()
		if err != nil {
			log.Println("error saving file: ", err)
		}
		md5sum := hex.EncodeToString(hash.Sum(nil))
		log.Println("md5sum = ", md5sum)
		log.Println("grabbing lock...")
		sem.Lock()
		log.Println("got lock, updating package list...")
		if !createPackagesTar(archType) {
			log.Println("unable to create Packages.gz")
		}
		sem.Unlock()
		log.Println("lock returned")
	} else {
		log.Println("not a POST")
	}
}

func deleteHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "DELETE" {
		decoder := json.NewDecoder(r.Body)
		var toDelete DeleteObj
		err := decoder.Decode(&toDelete)
		if err != nil {
			log.Println("error decoding DELETE json: ", err)
		}
		err = os.Remove(config.RootRepoPath + "/dists/stable/main/binary-" + toDelete.Arch + "/" + toDelete.Filename)
		log.Println("grabbing lock...")
		sem.Lock()
		log.Println("got lock, updating package list...")
		if !createPackagesTar(toDelete.Arch) {
			log.Println("unable to create Packages.gz")
		}
		sem.Unlock()
		log.Println("lock returned")
	} else {
		log.Println("not a DELETE")
	}
}

func (s semaphore) Lock() {
	s <- 1
}

func (s semaphore) Unlock() {
	<-s
}
<commit_msg>fix filename path<commit_after>package main

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"

	"github.com/blakesmith/ar"
)

type semaphore chan int

type Conf struct {
	ListenPort   string   `json:"listenPort"`
	RootRepoPath string   `json:"rootRepoPath"`
	SupportArch  []string `json:"supportedArch"`
}

type DeleteObj struct {
	Filename string
	Arch     string
}

var sem = make(semaphore, 1)
var configFile = flag.String("c", "conf.json", "config file location")
var config = &Conf{}

func main() {
	flag.Parse()
	file, err := ioutil.ReadFile(*configFile)
	if err != nil {
		log.Panic("unable to read config file, exiting...")
	}
	config = &Conf{}
	if err := json.Unmarshal(file, &config); err != nil {
		log.Panic("unable to marshal config file, exiting...")
	}

	if !createDirs() {
		log.Println("error creating directory structure, exiting")
		os.Exit(1)
	}
	http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(config.RootRepoPath))))
	http.HandleFunc("/upload", uploadHandler)
	http.HandleFunc("/delete", deleteHandler)
	http.ListenAndServe(":"+config.ListenPort, nil)
}

func createDirs() bool {
	for _, archDir := range config.SupportArch {
		if _, err := os.Stat(config.RootRepoPath + "/dists/stable/main/binary-" + archDir); err != nil {
			if os.IsNotExist(err) {
				log.Printf("Directory for %s does not exist, creating", archDir)
				dirErr := os.MkdirAll(config.RootRepoPath+"/dists/stable/main/binary-"+archDir, 0755)
				if dirErr != nil {
					log.Printf("error creating directory for %s: %s\n", archDir, dirErr)
					return false
				}
			} else {
				log.Printf("error inspecting %s: %s\n", archDir, err)
				return false
			}
		}
	}
	return true
}

func inspectPackage(filename string) string {
	f, err := os.Open(filename)
	if err != nil {
		log.Printf("error opening package file %s: %s\n", filename, err)
		return ""
	}
	defer f.Close()

	arReader := ar.NewReader(f)
	var controlBuf bytes.Buffer

	for {
		header, err := arReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Println("error in inspectPackage loop: ", err)
			return ""
		}

		if header.Name == "control.tar.gz" {
			io.Copy(&controlBuf, arReader)
			return inspectPackageControl(controlBuf)

		}

	}
	return ""
}

func inspectPackageControl(filename bytes.Buffer) string {
	gzf, err := gzip.NewReader(bytes.NewReader(filename.Bytes()))
	if err != nil {
		log.Println("error creating gzip reader: ", err)
		return ""
	}

	tarReader := tar.NewReader(gzf)
	var controlBuf bytes.Buffer
	for {
		header, err := tarReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Println("error in inspectPackage loop: ", err)
			return ""
		}

		name := header.Name

		switch header.Typeflag {
		case tar.TypeDir:
			continue
		case tar.TypeReg:
			if name == "./control" {
				io.Copy(&controlBuf, tarReader)
				log.Printf("control file: %s\n", controlBuf.String())
				return controlBuf.String()
			}
		default:
			log.Printf("%s : %c %s %s\n",
				"Yikes! Unable to figure out type",
				header.Typeflag,
				"in file",
				name,
			)
		}
	}
	return ""
}

func createPackagesTar(arch string) bool {
	var packBuf bytes.Buffer
	// loop through each directory
	// run inspectPackage
	dirList, err := ioutil.ReadDir(config.RootRepoPath + "/dists/stable/main/binary-" + arch)
	if err != nil {
		log.Printf("error scanning %s: %s\n", config.RootRepoPath+"/dists/stable/main/binary-"+arch, err)
		return false
	}
	for _, debFile := range dirList {
		if strings.HasSuffix(debFile.Name(), "deb") {
			tempCtlData := inspectPackage(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name())
			packBuf.WriteString(tempCtlData)
			packBuf.WriteString("Filename: " + "dists/stable/main/binary-" + arch + "/" + debFile.Name() + "\n")
			packBuf.WriteString("Size: " + strconv.FormatInt(debFile.Size(), 10) + "\n")
			f, _ := ioutil.ReadFile(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/" + debFile.Name())
			md5hash := md5.New()
			io.WriteString(md5hash, string(f[:]))
			md5sum := hex.EncodeToString(md5hash.Sum(nil))
			packBuf.WriteString("MD5sum: " + md5sum + "\n")
			sha1hash := sha1.New()
			io.WriteString(sha1hash, string(f[:]))
			sha1sum := hex.EncodeToString(sha1hash.Sum(nil))
			packBuf.WriteString("SHA1: " + sha1sum + "\n")
			sha256hash := sha256.New()
			io.WriteString(sha256hash, string(f[:]))
			sha256sum := hex.EncodeToString(sha256hash.Sum(nil))
			packBuf.WriteString("SHA256: " + sha256sum + "\n")
			packBuf.WriteString("\n\n")
		}
	}

	outfile, err := os.Create(config.RootRepoPath + "/dists/stable/main/binary-" + arch + "/Packages.gz")
	if err != nil {
		log.Println("error creating packages.gz file")
		return false
	}
	defer outfile.Close()
	gzOut := gzip.NewWriter(outfile)
	defer gzOut.Close()
	gzOut.Write(packBuf.Bytes())
	gzOut.Flush()
	return true
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		archType := r.FormValue("arch")
		if archType == "" {
			archType = "all"
		}
		log.Println("archType is: ", archType)
		file, header, err := r.FormFile("file")
		if err != nil {
			log.Println("error parsing file: ", err)
		}
		log.Println("filename is: ", header.Filename)
		out, err := os.Create(config.RootRepoPath + "/dists/stable/main/binary-" + archType + "/" + header.Filename)
		if err != nil {
			log.Println("error creating file: ", err)
		}
		hash := md5.New()
		_, err = io.Copy(out, io.TeeReader(file, hash))
		defer file.Close()
		if err != nil {
			log.Println("error saving file: ", err)
		}
		md5sum := hex.EncodeToString(hash.Sum(nil))
		log.Println("md5sum = ", md5sum)
		log.Println("grabbing lock...")
		sem.Lock()
		log.Println("got lock, updating package list...")
		if !createPackagesTar(archType) {
			log.Println("unable to create Packages.gz")
		}
		sem.Unlock()
		log.Println("lock returned")
	} else {
		log.Println("not a POST")
	}
}

func deleteHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "DELETE" {
		decoder := json.NewDecoder(r.Body)
		var toDelete DeleteObj
		err := decoder.Decode(&toDelete)
		if err != nil {
			log.Println("error decoding DELETE json: ", err)
		}
		err = os.Remove(config.RootRepoPath + "/dists/stable/main/binary-" + toDelete.Arch + "/" + toDelete.Filename)
		log.Println("grabbing lock...")
		sem.Lock()
		log.Println("got lock, updating package list...")
		if !createPackagesTar(toDelete.Arch) {
			log.Println("unable to create Packages.gz")
		}
		sem.Unlock()
		log.Println("lock returned")
	} else {
		log.Println("not a DELETE")
	}
}

func (s semaphore) Lock() {
	s <- 1
}

func (s semaphore) Unlock() {
	<-s
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"text/template"
)

var (
	name    = flag.String("name", "", "how to identify this run (default: basename of command)")
	success = flag.String("success", "success: {{.Name}}", "say this message on success")
	failure = flag.String("failure", "failure: {{.Name}}", "say this message on failure")
)

var templates = template.New("speech")

type Info struct {
	name string
	Cmd  *exec.Cmd
}

func (i *Info) Name() string {
	if *name != "" {
		return *name
	}
	return filepath.Base(i.Cmd.Args[0])
}

func (i *Info) Status() int {
	if i.Cmd.ProcessState.Success() {
		return 0
	}
	if status, ok := i.Cmd.ProcessState.Sys().(syscall.WaitStatus); ok {
		if status.Exited() {
			return status.ExitStatus()
		}
		if status.Signaled() {
			return 128 + int(status.Signal())
		}
	}
	// uhh.. something. 1 is too common, and 2 is typical usage error.
	return 3
}

func run(args []string) (*Info, error) {
	i := &Info{
		Cmd: exec.Command(args[0], args[1:]...),
	}
	i.Cmd.Stdin = os.Stdin
	i.Cmd.Stdout = os.Stdout
	i.Cmd.Stderr = os.Stderr

	if err := i.Cmd.Run(); err != nil {
		switch err.(type) {
		case *exec.ExitError:
			// we don't consider runs that actually start the child as failures
		default:
			return i, err
		}
	}
	return i, nil
}

func report(i *Info) error {
	msg, err := format(i)
	if err != nil {
		return err
	}
	if err := speak(msg); err != nil {
		return err
	}
	return nil
}

func format(i *Info) (string, error) {
	tmpl := templates.Lookup("success")
	if !i.Cmd.ProcessState.Success() {
		tmpl = templates.Lookup("failure")
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, i); err != nil {
		return "", err
	}
	return buf.String(), nil
}

func speak(msg string) error {
	cmd := exec.Command("espeak", "--", msg)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

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

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", prog)
	fmt.Fprintf(os.Stderr, "  %s [OPTS] [--] COMMAND [ARGS..]\n", prog)
	fmt.Fprintf(os.Stderr, "\n")
	fmt.Fprintf(os.Stderr, "Options:\n")
	flag.PrintDefaults()
}

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

	flag.Usage = usage
	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
		os.Exit(2)
	}

	// exit 2 here as we consider these usage errors
	if _, err := templates.New("success").Parse(*success); err != nil {
		log.Print(err)
		os.Exit(2)
	}
	if _, err := templates.New("failure").Parse(*failure); err != nil {
		log.Print(err)
		os.Exit(2)
	}

	i, err := run(flag.Args())
	if err != nil {
		log.Fatalf("starting command: %v", err)
	}
	if err := report(i); err != nil {
		log.Fatalf("espeak: %v", err)
	}
	os.Exit(i.Status())
}
<commit_msg>Don't use command line flags outside of main<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"text/template"
)

var templates = template.New("speech")

type Info struct {
	name string
	Cmd  *exec.Cmd
}

func (i *Info) Name() string {
	if i.name != "" {
		return i.name
	}
	return filepath.Base(i.Cmd.Args[0])
}

func (i *Info) Status() int {
	if i.Cmd.ProcessState.Success() {
		return 0
	}
	if status, ok := i.Cmd.ProcessState.Sys().(syscall.WaitStatus); ok {
		if status.Exited() {
			return status.ExitStatus()
		}
		if status.Signaled() {
			return 128 + int(status.Signal())
		}
	}
	// uhh.. something. 1 is too common, and 2 is typical usage error.
	return 3
}

func run(name string, args []string) (*Info, error) {
	i := &Info{
		name: name,
		Cmd:  exec.Command(args[0], args[1:]...),
	}
	i.Cmd.Stdin = os.Stdin
	i.Cmd.Stdout = os.Stdout
	i.Cmd.Stderr = os.Stderr

	if err := i.Cmd.Run(); err != nil {
		switch err.(type) {
		case *exec.ExitError:
			// we don't consider runs that actually start the child as failures
		default:
			return i, err
		}
	}
	return i, nil
}

func report(i *Info) error {
	msg, err := format(i)
	if err != nil {
		return err
	}
	if err := speak(msg); err != nil {
		return err
	}
	return nil
}

func format(i *Info) (string, error) {
	tmpl := templates.Lookup("success")
	if !i.Cmd.ProcessState.Success() {
		tmpl = templates.Lookup("failure")
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, i); err != nil {
		return "", err
	}
	return buf.String(), nil
}

func speak(msg string) error {
	cmd := exec.Command("espeak", "--", msg)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

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

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", prog)
	fmt.Fprintf(os.Stderr, "  %s [OPTS] [--] COMMAND [ARGS..]\n", prog)
	fmt.Fprintf(os.Stderr, "\n")
	fmt.Fprintf(os.Stderr, "Options:\n")
	flag.PrintDefaults()
}

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

	var (
		name    = flag.String("name", "", "how to identify this run (default: basename of command)")
		success = flag.String("success", "success: {{.Name}}", "say this message on success")
		failure = flag.String("failure", "failure: {{.Name}}", "say this message on failure")
	)

	flag.Usage = usage
	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
		os.Exit(2)
	}

	// exit 2 here as we consider these usage errors
	if _, err := templates.New("success").Parse(*success); err != nil {
		log.Print(err)
		os.Exit(2)
	}
	if _, err := templates.New("failure").Parse(*failure); err != nil {
		log.Print(err)
		os.Exit(2)
	}

	i, err := run(*name, flag.Args())
	if err != nil {
		log.Fatalf("starting command: %v", err)
	}
	if err := report(i); err != nil {
		log.Fatalf("espeak: %v", err)
	}
	os.Exit(i.Status())
}
<|endoftext|>


<commit_before>/*
Welcome! Let's start main package so we'll get executable binary.

By the way, this is where we write package comment.
*/
package main

// This is how we import code from other packages.
import (
	"errors"
	"fmt"
	"log"
	"math"
	"math/rand"
	"runtime"
	"time"
)

// init is run when the file loads
func init() {
	// do nothing
}

// main is function runs when executable starts
func main() {
	fmt.Println("Here is how we print something to standard output.")
	log.Println("We can also print to standard error.")
}

// whatIsCheatsheetFor is private to package because it starts with lower case.
func whatIsCheatsheetFor() {
	fmt.Println("I need to learn go.")
}

// WhatIsGoFor is public; it can be imported by other packages.
func WhatIsGoFor() {
	fmt.Println("Go is great for server-side programming.")
}

// PI is a untyped numeric constant.
const Pi = 3.14159

// AUTHOR is a untyped string constant.
const Author = "Rafal Radulski"

// letsDefineVariables defines some variables.
func letsDefineVariables() {
	// int
	var a = 1
	var b int = 42
	var c, d int = 9, 27
	e := 3

	// char
	letter := 'l'

	// string
	abc := "text"

	// float
	x := 1.7

	// array of length 3
	var arr [3]int
	arr[0] = 91

	// slide of length 3, capacity 10
	s := make([]int, 3, 10)
	s = append(s, 20)

	// map of string -> int
	var m map[string]int
	m = make(map[string]int)
	m["zero"] = 0

	n := map[string]int{"zero": 0, "one": 1}
	delete(n, "one")

	// Local variables must be used or Go won't compile.
	fmt.Println(a, b, c, d, e, letter, abc, x)
}

// letsDoTypeConversion converts between char, string and int
func letsDoTypeConversion() {
	c := 'R'
	s := string(c)
	i := int(c)
	fmt.Println(c, s, i)
}

// letsDoConditional uses if statement. If can have two parts, init and condition
func letsDoConditional() {
	rand.Seed(time.Now().UTC().UnixNano())

	if r := rand.Intn(100); r > 9 {
		fmt.Println("We generated number greater than 9.")
	} else {
		fmt.Println("We generated a small number.")
	}
}

// letsDoLoops runs "for" statement a couple of ways
func letsDoLoops(start, stop int) int {
	sum := 0

	// we start with traditional for loop
	for i := start; i < stop; i++ {
		sum += i
	}

	// next is "while" loop
	for sum < 20 {
		sum += 1
	}

	// next is infinit loop
	for true {
		// but we are not going to wait forever
		break
	}

	// let's try range, which returns index and value
	list := [6]int{1, 2, 3, 5, 7, 11}
	for _, v := range list {
		sum += v
	}

	// or just index
	for i := range list {
		sum += list[i]
	}
	return sum
}

// letsDoSwitch uses switch statement
func letsDoSwitch() {
	// traditional way
	name := runtime.GOOS
	switch name {
	case "darwin":
		fmt.Println("We are on OS X.")
	default:
		fmt.Printf("We are on %s.", name)
	}

	// Go way
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("We are on OS X.")
	default:
		fmt.Printf("We are on %s.", os)
	}
}

// letsUseDefer runs defered code at the end of a function
func letsUseDefer() {
	defer fmt.Print("world.\n")
	fmt.Print("Hello ")
}

// HowDoYouReturnErrors indicates error with return value
func HowDoYouReturnErrors(wantError bool) (string, err) {
	if wantError {
		return "", errors.New("if you must... here is an error")
	} else {
		return "No error this time!", nil
	}
}

// Vertex is a simple struct
type Vertex struct {
	X int // X cordinate (uppercase == public field)
	Y int // Y cordinate
}

// String is a method which implements Stringer interface and returns string representation of an object
func (v Vertex) String() string {
	return fmt.Sprintf("(%d, %d)", v.X, v.Y)
}

// abs is a method private to package (it's lower case)
func (v Vertex) abs() float64 {
	return math.Sqrt(float64(v.X)*float64(v.X) + float64(v.Y)*float64(v.Y))
}

// Currency is a custom type.
type Currency float64

// currency is another type, but it's private to pckage.
type currency float64

// GetNamer is interface which requires a single method GetName, which must take no parameters and return string
type GetNamer interface {
	GetName() string
}

// Animal is a new type, a struct
type Animal struct {
	name string // animal's name (lowercase == private field)
}

// GetName is a method on Animal
func (a Animal) GetName() string {
	return a.name
}

// Cat is a struct with anonymouse field. Fields and methods are inherited from Animal.
type Cat struct {
	Animal
	size int
}

// Mouse is another type. It has the same fields as Animal, but it has no methods.
type Mouse Animal

// TryToGetName accepts object of any type, and tries to get a name from object.
func TryToGetName(obj interface{}) string {
	switch o := obj.(type) {
	default:
		return "unnamed"
	case GetNamer:
		return o.GetName()
	case fmt.Stringer:
		return o.String()
	}
}
<commit_msg>Fix getter/setter<commit_after>/*
Welcome! Let's start main package so we'll get executable binary.

By the way, this is where we write package comment.
*/
package main

// This is how we import code from other packages.
import (
	"errors"
	"fmt"
	"log"
	"math"
	"math/rand"
	"runtime"
	"time"
)

// init is run when the file loads
func init() {
	// do nothing
}

// main is function runs when executable starts
func main() {
	fmt.Println("Here is how we print something to standard output.")
	log.Println("We can also print to standard error.")
}

// whatIsCheatsheetFor is private to package because it starts with lower case.
func whatIsCheatsheetFor() {
	fmt.Println("I need to learn go.")
}

// WhatIsGoFor is public; it can be imported by other packages.
func WhatIsGoFor() {
	fmt.Println("Go is great for server-side programming.")
}

// PI is a untyped numeric constant.
const Pi = 3.14159

// AUTHOR is a untyped string constant.
const Author = "Rafal Radulski"

// letsDefineVariables defines some variables.
func letsDefineVariables() {
	// int
	var a = 1
	var b int = 42
	var c, d int = 9, 27
	e := 3

	// char
	letter := 'l'

	// string
	abc := "text"

	// float
	x := 1.7

	// array of length 3
	var arr [3]int
	arr[0] = 91

	// slide of length 3, capacity 10
	s := make([]int, 3, 10)
	s = append(s, 20)

	// map of string -> int
	var m map[string]int
	m = make(map[string]int)
	m["zero"] = 0

	n := map[string]int{"zero": 0, "one": 1}
	delete(n, "one")

	// Local variables must be used or Go won't compile.
	fmt.Println(a, b, c, d, e, letter, abc, x)
}

// letsDoTypeConversion converts between char, string and int
func letsDoTypeConversion() {
	c := 'R'
	s := string(c)
	i := int(c)
	fmt.Println(c, s, i)
}

// letsDoConditional uses if statement. If can have two parts, init and condition
func letsDoConditional() {
	rand.Seed(time.Now().UTC().UnixNano())

	if r := rand.Intn(100); r > 9 {
		fmt.Println("We generated number greater than 9.")
	} else {
		fmt.Println("We generated a small number.")
	}
}

// letsDoLoops runs "for" statement a couple of ways
func letsDoLoops(start, stop int) int {
	sum := 0

	// we start with traditional for loop
	for i := start; i < stop; i++ {
		sum += i
	}

	// next is "while" loop
	for sum < 20 {
		sum += 1
	}

	// next is infinit loop
	for true {
		// but we are not going to wait forever
		break
	}

	// let's try range, which returns index and value
	list := [6]int{1, 2, 3, 5, 7, 11}
	for _, v := range list {
		sum += v
	}

	// or just index
	for i := range list {
		sum += list[i]
	}
	return sum
}

// letsDoSwitch uses switch statement
func letsDoSwitch() {
	// traditional way
	name := runtime.GOOS
	switch name {
	case "darwin":
		fmt.Println("We are on OS X.")
	default:
		fmt.Printf("We are on %s.", name)
	}

	// Go way
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("We are on OS X.")
	default:
		fmt.Printf("We are on %s.", os)
	}
}

// letsUseDefer runs defered code at the end of a function
func letsUseDefer() {
	defer fmt.Print("world.\n")
	fmt.Print("Hello ")
}

// HowDoYouReturnErrors indicates error with return value
func HowDoYouReturnErrors(wantError bool) (string, err) {
	if wantError {
		return "", errors.New("if you must... here is an error")
	} else {
		return "No error this time!", nil
	}
}

// Vertex is a simple struct
type Vertex struct {
	X int // X cordinate (uppercase == public field)
	Y int // Y cordinate
}

// String is a method which implements Stringer interface and returns string representation of an object
func (v Vertex) String() string {
	return fmt.Sprintf("(%d, %d)", v.X, v.Y)
}

// abs is a method private to package (it's lower case)
func (v Vertex) abs() float64 {
	return math.Sqrt(float64(v.X)*float64(v.X) + float64(v.Y)*float64(v.Y))
}

// Currency is a custom type.
type Currency float64

// currency is another type, but it's private to pckage.
type currency float64

// GetNamer is interface which requires a single method GetName, which must take no parameters and return string
type Namer interface {
	Name() string
}

// Animal is a new type, a struct
type Animal struct {
	name string // animal's name (lowercase == private field)
}

// GetName is a getter method; we don't use "Get" prefix in Go
func (a Animal) Name() string {
	return a.name
}

// SetName is a setter method
func (a Animal) SetName(newName string) {
	a.name = newName
}

// Cat is a struct with anonymouse field. Fields and methods are inherited from Animal.
type Cat struct {
	Animal
	size int
}

// Mouse is another type. It has the same fields as Animal, but it has no methods.
type Mouse Animal

// TryToGetName accepts object of any type, and tries to get a name from object.
func TryToGetName(obj interface{}) string {
	switch o := obj.(type) {
	default:
		return "unnamed"
	case Namer:
		return o.Name()
	case fmt.Stringer:
		return o.String()
	}
}
<|endoftext|>


<commit_before>package main

// Implements a server that tails Graphite's logs
// finds out when new data sources become available
// and serves out a UI that lets you see/render those
// continuously.

// Written by J.A. Oldenbeuving / ojilles@gmail.com

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/ActiveState/tail"
	"github.com/elazarl/go-bindata-assetfs"
	"github.com/rcrowley/go-metrics"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
	"time"
)

type (

	// Structure of a single data source. Anything in capitals will
	// get marshalled over to any connecting browser
	Datasource struct {
		Name        string
		Create_date time.Time
		Params      string
	}

	// Holds the state (all newly detected data sources)
	state struct {
		*sync.RWMutex // inherits locking methods
		Vals          []Datasource
	}

	// Holds all configuration items for main. Anything with a capital
	// will get marshalled towards any browsers connecting
	configuration struct {
		JsonPullInterval int
		GraphiteURL      string
		ServerPort       int
		logfileLocation  loglocslice
	}

	// used for parsing Flags input params
	loglocslice []string
)

var (
	// declare a globally scoped State variable, otherwise
	// the request handlers can't get to it. If there is a better
	// way to do this, plmk.
	State = &state{&sync.RWMutex{}, []Datasource{}}

	// Instantiate struct to hold our configuration
	C = configuration{JsonPullInterval: 5000}
)

const (
	// Maximum number of data sources to hold in memory before
	// pruning out as new ones come in
	maxState    int = 100
	myLogFormat     = log.Ldate | log.Ltime
)

func (i *loglocslice) String() string {
	return fmt.Sprintf("%v", *i)
}

// Used to do Flag parsing of unbounded number of input logfiles
func (i *loglocslice) Set(value string) error {
	*i = AppendIfMissing(*i, value)
	return nil
}

func init() {
	flag.IntVar(&C.JsonPullInterval, "i", 5000, "Number of [ms] interval for Web UI's to update themselves. Clients only update their config every 5min")
	flag.IntVar(&C.ServerPort, "p", 2934, "Port number the webserver will bind to (pick a free one please)")
	flag.StringVar(&C.GraphiteURL, "s", "http://localhost:8080", "URL of the Graphite render API, no trailing slash. Apple rendezvous domains do not work (like http://machine.local, use IPs in that case)")
	flag.Var(&C.logfileLocation, "l", "One or more locations of the Carbon logfiles we need to tail. (F.ex. -l file1 -l file2 -l *.log)")

	flag.Usage = func() {
		fmt.Printf("Usage: graphite-news [-i sec] [-p port] [-s graphite url] -l logfile \n\n")
		flag.PrintDefaults()
	}
}

func makeHandler(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		l := log.New(os.Stdout, "http	", myLogFormat)

		m := metrics.GetOrRegisterTimer(fmt.Sprintf("%s%s", r.Method, r.URL.Path), metrics.DefaultRegistry)
		m.Time(func() {
			fn(w, r)
		})
		l.Printf("Request: %v %v %v", r.Method, r.URL, r.RemoteAddr)
	}
}

func jsonHandler(w http.ResponseWriter, r *http.Request) {
	State.RLock() // grab a lock, but then don't forget to
	js, err := json.Marshal(State.Vals)
	State.RUnlock() // unlock it again once we're done

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func statsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	metrics.WriteJSONOnce(metrics.DefaultRegistry, w)
}

func configHandler(w http.ResponseWriter, r *http.Request) {
	js, _ := json.Marshal(C)
	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func frontpageHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	data, _ := Asset("index.html")
	if len(data) == 0 {
		data = []byte("Fatal Error: index.html file not found.")
	}
	w.Write(data)
}

func faviconHandler(w http.ResponseWriter, r *http.Request) {
	data, _ := Asset("favicon.ico")
	w.Write(data)
}

func parseTime(s string) time.Time {
	// 24/08/2014 20:59:54
	var t, _ = time.Parse("02/01/2006 15:04:05", s)
	return t
}

func addItemToState(ds Datasource) {
	var foundDuplicate = false
	l := log.New(os.Stdout, "tail	", myLogFormat)
	m_ds := metrics.GetOrRegisterCounter("tail/datasources", metrics.DefaultRegistry)

	if strings.HasSuffix(ds.Name, ".") {
		return
	}

	// Find out if we already have one with the same name, if
	// so skip it.
	State.RLock()

	// TODO: change to range
	for i := 0; i < len(State.Vals) && !foundDuplicate; i++ {
		if ds.Name == State.Vals[i].Name {
			foundDuplicate = true
		}
	}
	State.RUnlock()

	if !foundDuplicate {
		// We're writing to shared datastructures, grab a Write-lock
		State.Lock()
		defer State.Unlock()
		State.Vals = append(State.Vals, ds)
		defer m_ds.Inc(1)
		if len(State.Vals) > maxState {
			State.Vals = State.Vals[len(State.Vals)-maxState : maxState]
		}
		l.Printf("New datasource: %+v (total: %v)", ds.Name, len(State.Vals))
	}
}

func parseLine(line string) {
	m_lines := metrics.GetOrRegisterCounter("tail/input_lines", metrics.DefaultRegistry)
	var dataPath = regexp.MustCompile(`[a-zA-Z\:]*([0-9].*) :: \[creates\] creating database file .*/whisper/(.*)\.wsp (.*)`)
	m_lines.Inc(1)
	match := dataPath.FindStringSubmatch(line)
	if len(match) > 0 {
		ds := fmt.Sprintf("%s", strings.Replace(match[2], `/`, `.`, -1))
		tmp := Datasource{Name: ds, Create_date: parseTime(match[1]), Params: match[3]}
		addItemToState(tmp)
	}

}

func tailLogfile(c chan string, file string) {
	l := log.New(os.Stdout, "main	", myLogFormat)
	tc := tail.Config{Follow: true, ReOpen: true, MustExist: true}
	t, err := tail.TailFile(file, tc)
	if err == nil {
		l.Print(fmt.Sprintf("Tailing File:[%s]\n", file))
		for line := range t.Lines {
			parseLine(line.Text)
		}
	}
	c <- fmt.Sprintf("%s", err)
}

func tailLogfiles(c chan string) {
	var files []string

	// loop through the configured locations, and do filesystem
	// globbing, building up a new list. There is probably a special
	// place in POSIX-hell for me :-)
	for _, file := range C.logfileLocation {
		matches, _ := filepath.Glob(file)
		for _, match := range matches {
			files = AppendIfMissing(files, match)
		}
	}
	for _, file := range files {
		go tailLogfile(c, file)
	}
}

func AppendIfMissing(slice []string, i string) []string {
	for _, ele := range slice {
		if ele == i {
			return slice
		}
	}
	return append(slice, i)
}

func main() {
	error_channel := make(chan string)
	l := log.New(os.Stdout, "main	", myLogFormat)
	flag.Parse()

	// grab any remaining arguments and pretend they belong
	// to -l :-) (Also solves the -l * case for example)
	for _, argument := range flag.Args() {
		C.logfileLocation = AppendIfMissing(C.logfileLocation, argument)
	}

	// Set up metrics registry
	//	go metrics.Log(
	//		metrics.DefaultRegistry,
	//		5e9, // Xe9 -> X seconds
	//		log.New(os.Stdout, "metrics	", myLogFormat))

	// Set up web handlers in goroutines
	http.HandleFunc("/", makeHandler(frontpageHandler))
	http.HandleFunc("/json/", makeHandler(jsonHandler))
	http.HandleFunc("/stats/", makeHandler(statsHandler))
	http.HandleFunc("/config/", makeHandler(configHandler))
	http.HandleFunc("/favicon.ico", makeHandler(faviconHandler))

	http.Handle("/assets/",
		http.FileServer(
			&assetfs.AssetFS{Asset, AssetDir, ""}))

	go http.ListenAndServe(fmt.Sprintf(":%v", C.ServerPort), nil)
	go tailLogfiles(error_channel)

	l.Println("Graphite News -- Showing which new metrics are available since 2014\n")
	l.Println(fmt.Sprintf("Graphite News -- http://localhost:%v		:: Main User Interface", C.ServerPort))
	l.Println(fmt.Sprintf("Graphite News -- http://localhost:%v/config/	:: Internal configuration in JSON", C.ServerPort))
	l.Println(fmt.Sprintf("Graphite News -- http://localhost:%v/stats/	:: Internal Metrics in JSON", C.ServerPort))
	l.Println(fmt.Sprintf("Configuration: %+v", C))
	// Wait for errors to appear then shut down
	l.Println(<-error_channel)
}
<commit_msg>Added better way of dealing with the static files (still need to loop in the index.html, etc) and Apache Common logging for the server.<commit_after>package main

// Implements a server that tails Graphite's logs
// finds out when new data sources become available
// and serves out a UI that lets you see/render those
// continuously.

// Written by J.A. Oldenbeuving / ojilles@gmail.com

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/ActiveState/tail"
	"github.com/cespare/go-apachelog"
	"github.com/rcrowley/go-metrics"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
	"time"
)

type (

	// Structure of a single data source. Anything in capitals will
	// get marshalled over to any connecting browser
	Datasource struct {
		Name        string
		Create_date time.Time
		Params      string
	}

	// Holds the state (all newly detected data sources)
	state struct {
		*sync.RWMutex // inherits locking methods
		Vals          []Datasource
	}

	// Holds all configuration items for main. Anything with a capital
	// will get marshalled towards any browsers connecting
	configuration struct {
		JsonPullInterval int
		GraphiteURL      string
		ServerPort       int
		logfileLocation  loglocslice
	}

	// used for parsing Flags input params
	loglocslice []string
)

var (
	// declare a globally scoped State variable, otherwise
	// the request handlers can't get to it. If there is a better
	// way to do this, plmk.
	State = &state{&sync.RWMutex{}, []Datasource{}}

	// Instantiate struct to hold our configuration
	C = configuration{JsonPullInterval: 5000}
)

const (
	// Maximum number of data sources to hold in memory before
	// pruning out as new ones come in
	maxState    int = 100
	myLogFormat     = log.Ldate | log.Ltime
)

func (i *loglocslice) String() string {
	return fmt.Sprintf("%v", *i)
}

// Used to do Flag parsing of unbounded number of input logfiles
func (i *loglocslice) Set(value string) error {
	*i = AppendIfMissing(*i, value)
	return nil
}

func init() {
	flag.IntVar(&C.JsonPullInterval, "i", 5000, "Number of [ms] interval for Web UI's to update themselves. Clients only update their config every 5min")
	flag.IntVar(&C.ServerPort, "p", 2934, "Port number the webserver will bind to (pick a free one please)")
	flag.StringVar(&C.GraphiteURL, "s", "http://localhost:8080", "URL of the Graphite render API, no trailing slash. Apple rendezvous domains do not work (like http://machine.local, use IPs in that case)")
	flag.Var(&C.logfileLocation, "l", "One or more locations of the Carbon logfiles we need to tail. (F.ex. -l file1 -l file2 -l *.log)")

	flag.Usage = func() {
		fmt.Printf("Usage: graphite-news [-i sec] [-p port] [-s graphite url] -l logfile \n\n")
		flag.PrintDefaults()
	}
}

func makeHandler(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		m := metrics.GetOrRegisterTimer(fmt.Sprintf("%s%s", r.Method, r.URL.Path), metrics.DefaultRegistry)
		m.Time(func() {
			fn(w, r)
		})
	}
}

func jsonHandler(w http.ResponseWriter, r *http.Request) {
	State.RLock() // grab a lock, but then don't forget to
	js, err := json.Marshal(State.Vals)
	State.RUnlock() // unlock it again once we're done

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func statsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	metrics.WriteJSONOnce(metrics.DefaultRegistry, w)
}

func configHandler(w http.ResponseWriter, r *http.Request) {
	js, _ := json.Marshal(C)
	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func frontpageHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	data, _ := Asset("index.html")
	if len(data) == 0 {
		data = []byte("Fatal Error: index.html file not found.")
	}
	w.Write(data)
}

func staticHandler(w http.ResponseWriter, r *http.Request) {
	tmp, _ := Asset(r.RequestURI[1:])
	w.Write(tmp)
}

func faviconHandler(w http.ResponseWriter, r *http.Request) {
	data, _ := Asset("favicon.ico")
	w.Write(data)
}

func parseTime(s string) time.Time {
	// 24/08/2014 20:59:54
	var t, _ = time.Parse("02/01/2006 15:04:05", s)
	return t
}

func addItemToState(ds Datasource) {
	var foundDuplicate = false
	l := log.New(os.Stdout, "tail	", myLogFormat)
	m_ds := metrics.GetOrRegisterCounter("tail/datasources", metrics.DefaultRegistry)

	if strings.HasSuffix(ds.Name, ".") {
		return
	}

	// Find out if we already have one with the same name, if
	// so skip it.
	State.RLock()

	// TODO: change to range
	for i := 0; i < len(State.Vals) && !foundDuplicate; i++ {
		if ds.Name == State.Vals[i].Name {
			foundDuplicate = true
		}
	}
	State.RUnlock()

	if !foundDuplicate {
		// We're writing to shared datastructures, grab a Write-lock
		State.Lock()
		defer State.Unlock()
		State.Vals = append(State.Vals, ds)
		defer m_ds.Inc(1)
		if len(State.Vals) > maxState {
			State.Vals = State.Vals[len(State.Vals)-maxState : maxState]
		}
		l.Printf("New datasource: %+v (total: %v)", ds.Name, len(State.Vals))
	}
}

func parseLine(line string) {
	m_lines := metrics.GetOrRegisterCounter("tail/input_lines", metrics.DefaultRegistry)
	var dataPath = regexp.MustCompile(`[a-zA-Z\:]*([0-9].*) :: \[creates\] creating database file .*/whisper/(.*)\.wsp (.*)`)
	m_lines.Inc(1)
	match := dataPath.FindStringSubmatch(line)
	if len(match) > 0 {
		ds := fmt.Sprintf("%s", strings.Replace(match[2], `/`, `.`, -1))
		tmp := Datasource{Name: ds, Create_date: parseTime(match[1]), Params: match[3]}
		addItemToState(tmp)
	}

}

func tailLogfile(c chan string, file string) {
	l := log.New(os.Stdout, "main	", myLogFormat)
	tc := tail.Config{Follow: true, ReOpen: true, MustExist: true}
	t, err := tail.TailFile(file, tc)
	if err == nil {
		l.Print(fmt.Sprintf("Tailing File:[%s]\n", file))
		for line := range t.Lines {
			parseLine(line.Text)
		}
	}
	c <- fmt.Sprintf("%s", err)
}

func tailLogfiles(c chan string) {
	var files []string

	// loop through the configured locations, and do filesystem
	// globbing, building up a new list. There is probably a special
	// place in POSIX-hell for me :-)
	for _, file := range C.logfileLocation {
		matches, _ := filepath.Glob(file)
		for _, match := range matches {
			files = AppendIfMissing(files, match)
		}
	}
	for _, file := range files {
		go tailLogfile(c, file)
	}
}

func AppendIfMissing(slice []string, i string) []string {
	for _, ele := range slice {
		if ele == i {
			return slice
		}
	}
	return append(slice, i)
}

func main() {
	error_channel := make(chan string)
	l := log.New(os.Stdout, "main	", myLogFormat)
	flag.Parse()

	// grab any remaining arguments and pretend they belong
	// to -l :-) (Also solves the -l * case for example)
	for _, argument := range flag.Args() {
		C.logfileLocation = AppendIfMissing(C.logfileLocation, argument)
	}

	// Set up metrics registry
	//	go metrics.Log(
	//		metrics.DefaultRegistry,
	//		5e9, // Xe9 -> X seconds
	//		log.New(os.Stdout, "metrics	", myLogFormat))

	// Set up web handlers in goroutines
	mux := http.NewServeMux()
	mux.HandleFunc("/", makeHandler(frontpageHandler))
	mux.HandleFunc("/json/", makeHandler(jsonHandler))
	mux.HandleFunc("/stats/", makeHandler(statsHandler))
	mux.HandleFunc("/config/", makeHandler(configHandler))
	mux.HandleFunc("/favicon.ico", makeHandler(faviconHandler))
	mux.HandleFunc("/assets/", makeHandler(staticHandler))
	loggingHandler := apachelog.NewHandler(mux, os.Stdout)
	server := &http.Server{
		Addr:    fmt.Sprintf(":%v", C.ServerPort),
		Handler: loggingHandler,
	}

	go server.ListenAndServe()

	go tailLogfiles(error_channel)

	l.Println("Graphite News -- Showing which new metrics are available since 2014\n")
	l.Println(fmt.Sprintf("Graphite News -- http://localhost:%v		:: Main User Interface", C.ServerPort))
	l.Println(fmt.Sprintf("Graphite News -- http://localhost:%v/config/	:: Internal configuration in JSON", C.ServerPort))
	l.Println(fmt.Sprintf("Graphite News -- http://localhost:%v/stats/	:: Internal Metrics in JSON", C.ServerPort))
	l.Println(fmt.Sprintf("Configuration: %+v", C))
	// Wait for errors to appear then shut down
	l.Println(<-error_channel)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/stratospark/torro/bencoding"
	"io/ioutil"
)

func main() {
	println("TORRO!")

	data, err := ioutil.ReadFile("ubuntu.torrent")
	if err != nil {
		panic(err)
	}

	torrentStr := string(data)
	lex := bencoding.BeginLexing(".torrent", torrentStr, bencoding.LexBegin)
	tokens := bencoding.Collect(lex)

	tokenCounts := make(map[bencoding.Token]int)
	for _, t := range tokens {
		tokenCounts[t]++
		fmt.Println(t)
	}
	fmt.Println(tokenCounts)
}
<commit_msg>Pretty print the parsed torrent file.<commit_after>package main

import (
	"github.com/stratospark/torro/bencoding"
	"io/ioutil"
	"github.com/kr/pretty"
)

func main() {
	println("TORRO!")

	data, err := ioutil.ReadFile("ubuntu.torrent")
	if err != nil {
		panic(err)
	}

	torrentStr := string(data)
	lex := bencoding.BeginLexing(".torrent", torrentStr, bencoding.LexBegin)
	tokens := bencoding.Collect(lex)

	output := bencoding.Parse(tokens)

//	reuslt := output.Output.(map[string]interface{})

	pretty.Print(output.Output)
//	tokenCounts := make(map[bencoding.Token]int)
//	for _, t := range tokens {
//		tokenCounts[t]++
//		fmt.Println(t)
//	}
//	fmt.Println(tokenCounts)
}
<|endoftext|>


<commit_before>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// 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 (
	"log"

	"github.com/venicegeo/pz-gocommon/elasticsearch"
	piazza "github.com/venicegeo/pz-gocommon/gocommon"
	pzlogger "github.com/venicegeo/pz-logger/logger"
	pzuuidgen "github.com/venicegeo/pz-uuidgen/uuidgen"
	pzworkflow "github.com/venicegeo/pz-workflow/workflow"
)

func main() {

	required := []piazza.ServiceName{
		piazza.PzElasticSearch,
		piazza.PzLogger,
		piazza.PzUuidgen,
		piazza.PzKafka,
		piazza.PzServiceController,
	}

	sys, err := piazza.NewSystemConfig(piazza.PzWorkflow, required)
	if err != nil {
		log.Fatal(err)
	}

	logger, err := pzlogger.NewClient(sys)
	if err != nil {
		log.Fatal(err)
	}

	//	uuidgen, err := uuidgenPkg.NewMockUuidGenService(sys)
	uuidgen, err := pzuuidgen.NewClient(sys)

	if err != nil {
		log.Fatal(err)
	}

	eventtypesIndex, err := elasticsearch.NewIndex(sys, "eventtypes", pzworkflow.EventTypeIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	eventsIndex, err := elasticsearch.NewIndex(sys, "events001", pzworkflow.EventIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	triggersIndex, err := elasticsearch.NewIndex(sys, "triggers", pzworkflow.TriggerIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	alertsIndex, err := elasticsearch.NewIndex(sys, "alerts", pzworkflow.AlertIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	cronIndex, err := elasticsearch.NewIndex(sys, "crons", pzworkflow.CronIndexSettings)
	if err != nil {
		log.Fatal(err)
	}

	logger.Info("pz-workflow starting...")

	workflowService := &pzworkflow.WorkflowService{}
	err = workflowService.Init(
		sys,
		logger,
		uuidgen,
		eventtypesIndex,
		eventsIndex,
		triggersIndex,
		alertsIndex,
		cronIndex)
	if err != nil {
		log.Fatal(err)
	}

	err = workflowService.InitCron()
	if err != nil {
		log.Fatal(err)
	}

	workflowServer := &pzworkflow.WorkflowServer{}
	err = workflowServer.Init(workflowService)
	if err != nil {
		log.Fatal(err)
	}

	genericServer := piazza.GenericServer{Sys: sys}

	err = genericServer.Configure(workflowServer.Routes)
	if err != nil {
		log.Fatal(err)
	}

	done, err := genericServer.Start()
	if err != nil {
		log.Fatal(err)
	}

	err = <-done
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Added version numbers<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// 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 (
	"log"

	"github.com/venicegeo/pz-gocommon/elasticsearch"
	piazza "github.com/venicegeo/pz-gocommon/gocommon"
	pzlogger "github.com/venicegeo/pz-logger/logger"
	pzuuidgen "github.com/venicegeo/pz-uuidgen/uuidgen"
	pzworkflow "github.com/venicegeo/pz-workflow/workflow"
)

func main() {

	required := []piazza.ServiceName{
		piazza.PzElasticSearch,
		piazza.PzLogger,
		piazza.PzUuidgen,
		piazza.PzKafka,
		piazza.PzServiceController,
	}

	sys, err := piazza.NewSystemConfig(piazza.PzWorkflow, required)
	if err != nil {
		log.Fatal(err)
	}

	logger, err := pzlogger.NewClient(sys)
	if err != nil {
		log.Fatal(err)
	}

	//	uuidgen, err := uuidgenPkg.NewMockUuidGenService(sys)
	uuidgen, err := pzuuidgen.NewClient(sys)

	if err != nil {
		log.Fatal(err)
	}

	eventtypesIndex, err := elasticsearch.NewIndex(sys, "eventtypes001", pzworkflow.EventTypeIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	eventsIndex, err := elasticsearch.NewIndex(sys, "events002", pzworkflow.EventIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	triggersIndex, err := elasticsearch.NewIndex(sys, "triggers001", pzworkflow.TriggerIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	alertsIndex, err := elasticsearch.NewIndex(sys, "alerts001", pzworkflow.AlertIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	cronIndex, err := elasticsearch.NewIndex(sys, "crons001", pzworkflow.CronIndexSettings)
	if err != nil {
		log.Fatal(err)
	}

	logger.Info("pz-workflow starting...")

	workflowService := &pzworkflow.WorkflowService{}
	err = workflowService.Init(
		sys,
		logger,
		uuidgen,
		eventtypesIndex,
		eventsIndex,
		triggersIndex,
		alertsIndex,
		cronIndex)
	if err != nil {
		log.Fatal(err)
	}

	err = workflowService.InitCron()
	if err != nil {
		log.Fatal(err)
	}

	workflowServer := &pzworkflow.WorkflowServer{}
	err = workflowServer.Init(workflowService)
	if err != nil {
		log.Fatal(err)
	}

	genericServer := piazza.GenericServer{Sys: sys}

	err = genericServer.Configure(workflowServer.Routes)
	if err != nil {
		log.Fatal(err)
	}

	done, err := genericServer.Start()
	if err != nil {
		log.Fatal(err)
	}

	err = <-done
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"
)

var min int

func main() {

	defer disableDND()
	flag.IntVar(&min, "t", 15, "Time in minutes for \"Do not disturb\" mode")
	flag.Parse()

	timerChan := time.NewTimer(time.Minute * time.Duration(min)).C
	tickerChan := time.NewTicker(time.Minute * 1).C
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

	go enableDND()

	for {
		select {
		case <-timerChan:
			return
		case <-tickerChan:
			min--
			fmt.Printf("Turning off \"Do not disturb\" mode in %d minutes \n", min)
		case <-sigChan:
			fmt.Println("Got SIGTERM")
			return
		}
	}

}

func enableDND() {
	fmt.Printf("Turning on \"Do not disturb\" mode for %d minutes \n", min)
	_, _ = exec.Command("sh", "-c", "defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb -boolean true").Output()
	_, err := exec.Command("sh", "-c", "defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturbDate -date \"`date -u +\"%Y-%m-%d %H:%M:%S +000\"`\"").Output()
	if err != nil {
		log.Fatal("2", err)
	}
	_, _ = exec.Command("sh", "-c", "killall NotificationCenter").Output()

}

func disableDND() {
	_, _ = exec.Command("sh", "-c", "defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb -boolean false").Output()
	_, _ = exec.Command("sh", "-c", "killall NotificationCenter").Output()
	fmt.Println("Turning off \"Do not disturb\" mode")
}
<commit_msg>Minor tweak<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"
)

var min int

func main() {

	defer disableDND()
	flag.IntVar(&min, "t", 15, "Time in minutes for \"Do not disturb\" mode")
	flag.Parse()

	timerChan := time.NewTimer(time.Minute * time.Duration(min)).C
	tickerChan := time.NewTicker(time.Minute * 1).C
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

	go enableDND()

	for {
		select {
		case <-timerChan:
			return
		case <-tickerChan:
			min--
			fmt.Printf("Turning off \"Do not disturb\" mode in %d minutes \n", min)
		case <-sigChan:
			fmt.Println("Got SIGTERM")
			return
		}
	}

}

func enableDND() {
	fmt.Printf("Turning on \"Do not disturb\" mode for %d minutes \n", min)

	// we don´t do error checking
	_, _ = exec.Command("sh", "-c", "defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb -boolean true").Output()
	_, _ = exec.Command("sh", "-c", "defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturbDate -date \"`date -u +\"%Y-%m-%d %H:%M:%S +000\"`\"").Output()
	_, _ = exec.Command("sh", "-c", "killall NotificationCenter").Output()

}

func disableDND() {
	// we don´t do error checking
	_, _ = exec.Command("sh", "-c", "defaults -currentHost write ~/Library/Preferences/ByHost/com.apple.notificationcenterui doNotDisturb -boolean false").Output()
	_, _ = exec.Command("sh", "-c", "killall NotificationCenter").Output()

	fmt.Println("Turning off \"Do not disturb\" mode")
}
<|endoftext|>


<commit_before>// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package resource_test

import (
	"fmt"
	"testing"

	"sigs.k8s.io/kustomize/api/konfig"

	"github.com/stretchr/testify/assert"
	"sigs.k8s.io/kustomize/api/filesys"
	"sigs.k8s.io/kustomize/api/loader"
	. "sigs.k8s.io/kustomize/api/resource"
	"sigs.k8s.io/kustomize/api/types"
)

func TestSliceFromBytes(t *testing.T) {
	type testCase struct {
		input    string
		expected []string
	}
	testCases := map[string]testCase{
		"empty1": {
			input:    "",
			expected: []string{},
		},
		"empty2": {
			input: `
---
---
`,
			expected: []string{},
		},
		"deployment1": {
			input: `
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pooh
---
`,
			expected: []string{
				`apiVersion: apps/v1
kind: Deployment
metadata:
  name: pooh
`,
			},
		},
		"deployment2": {
			input: `
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    baseAnno: This is a base annotation
  labels:
    app: mungebot
    foo: bar
  name: baseprefix-mungebot
spec:
  replicas: 1
  selector:
    matchLabels:
      foo: bar
  template:
    metadata:
      annotations:
        baseAnno: This is a base annotation
      labels:
        app: mungebot
        foo: bar
    spec:
      containers:
      - env:
        - name: foo
          value: bar
        image: nginx
        name: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    baseAnno: This is a base annotation
  labels:
    app: mungebot
    foo: bar
  name: baseprefix-mungebot-service
spec:
  ports:
  - port: 7002
  selector:
    app: mungebot
    foo: bar
`,
			expected: []string{
				`apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    baseAnno: This is a base annotation
  labels:
    app: mungebot
    foo: bar
  name: baseprefix-mungebot
spec:
  replicas: 1
  selector:
    matchLabels:
      foo: bar
  template:
    metadata:
      annotations:
        baseAnno: This is a base annotation
      labels:
        app: mungebot
        foo: bar
    spec:
      containers:
      - env:
        - name: foo
          value: bar
        image: nginx
        name: nginx
        ports:
        - containerPort: 80
`,
				`apiVersion: v1
kind: Service
metadata:
  annotations:
    baseAnno: This is a base annotation
  labels:
    app: mungebot
    foo: bar
  name: baseprefix-mungebot-service
spec:
  ports:
  - port: 7002
  selector:
    app: mungebot
    foo: bar
`,
			},
		},
	}

	for name := range testCases {
		tc := testCases[name]
		t.Run(name, func(t *testing.T) {
			result, err := factory.SliceFromBytes([]byte(tc.input))
			if err != nil {
				t.Fatalf("%v: fails with err: %v", name, err)
			}
			if len(result) != len(tc.expected) {
				for i := range result {
					bytes, err := result[i].AsYAML()
					if err != nil {
						t.Fatalf("%v: result to YAML fails with err: %v", name, err)
					}
					tmp := string(bytes)
					t.Logf("--- %d:\n%s", i, tmp)
				}
				t.Fatalf(
					"%v: actual len %d != expected len %d",
					name, len(result), len(tc.expected))
			}
			for i := range tc.expected {
				bytes, err := result[i].AsYAML()
				if err != nil {
					t.Fatalf("%v: result to YAML fails with err: %v", name, err)
				}
				tmp := string(bytes)
				if tmp != tc.expected[i] {
					t.Fatalf(
						"%v: string mismatch in item %d\n"+
							"actual:\n-----\n%s\n-----\n"+
							"expected:\n-----\n%s\n-----\n",
						name, i, tmp, tc.expected[i])
				}
			}
		})
	}
}

func TestSliceFromPatches(t *testing.T) {
	patchGood1 := types.PatchStrategicMerge("patch1.yaml")
	patch1 := `
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pooh
`
	patchGood2 := types.PatchStrategicMerge("patch2.yaml")
	patch2 := `
apiVersion: v1
kind: ConfigMap
metadata:
  name: winnie
  namespace: hundred-acre-wood
---
# some comment
---
---
`
	patchBad := types.PatchStrategicMerge("patch3.yaml")
	patch3 := `
WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOT: woot
`
	patchList := types.PatchStrategicMerge("patch4.yaml")
	patch4 := `
apiVersion: v1
kind: List
items:
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: pooh
- apiVersion: v1
  kind: ConfigMap
  metadata:
    name: winnie
    namespace: hundred-acre-wood
`
	patchList2 := types.PatchStrategicMerge("patch5.yaml")
	patch5 := `
apiVersion: v1
kind: DeploymentList
items:
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: deployment-a
  spec: &hostAliases
    template:
      spec:
        hostAliases:
        - hostnames:
          - a.example.com
          ip: 8.8.8.8
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: deployment-b
  spec:
    <<: *hostAliases
`
	patchList3 := types.PatchStrategicMerge("patch6.yaml")
	patch6 := `
apiVersion: v1
kind: List
items:
`
	patchList4 := types.PatchStrategicMerge("patch7.yaml")
	patch7 := `
apiVersion: v1
kind: List
`
	testDeploymentSpec := map[string]interface{}{
		"template": map[string]interface{}{
			"spec": map[string]interface{}{
				"hostAliases": []interface{}{
					map[string]interface{}{
						"hostnames": []interface{}{
							"a.example.com",
						},
						"ip": "8.8.8.8",
					},
				},
			},
		},
	}
	testDeploymentA := factory.FromMap(
		map[string]interface{}{
			"apiVersion": "apps/v1",
			"kind":       "Deployment",
			"metadata": map[string]interface{}{
				"name": "deployment-a",
			},
			"spec": testDeploymentSpec,
		})
	testDeploymentB := factory.FromMap(
		map[string]interface{}{
			"apiVersion": "apps/v1",
			"kind":       "Deployment",
			"metadata": map[string]interface{}{
				"name": "deployment-b",
			},
			"spec": testDeploymentSpec,
		})

	fSys := filesys.MakeFsInMemory()
	fSys.WriteFile(string(patchGood1), []byte(patch1))
	fSys.WriteFile(string(patchGood2), []byte(patch2))
	fSys.WriteFile(string(patchBad), []byte(patch3))
	fSys.WriteFile(string(patchList), []byte(patch4))
	fSys.WriteFile(string(patchList2), []byte(patch5))
	fSys.WriteFile(string(patchList3), []byte(patch6))
	fSys.WriteFile(string(patchList4), []byte(patch7))

	ldr, err := loader.NewLoader(
		loader.RestrictionRootOnly, filesys.Separator, fSys)
	if err != nil {
		t.Fatal(err)
	}

	tests := []struct {
		name        string
		input       []types.PatchStrategicMerge
		expectedOut []*Resource
		expectedErr bool
	}{
		{
			name:        "happy",
			input:       []types.PatchStrategicMerge{patchGood1, patchGood2},
			expectedOut: []*Resource{testDeployment, testConfigMap},
			expectedErr: false,
		},
		{
			name:        "badFileName",
			input:       []types.PatchStrategicMerge{patchGood1, "doesNotExist"},
			expectedOut: []*Resource{},
			expectedErr: true,
		},
		{
			name:        "badData",
			input:       []types.PatchStrategicMerge{patchGood1, patchBad},
			expectedOut: []*Resource{},
			expectedErr: true,
		},
		{
			name:        "listOfPatches",
			input:       []types.PatchStrategicMerge{patchList},
			expectedOut: []*Resource{testDeployment, testConfigMap},
			expectedErr: false,
		},
		{
			name:        "listWithAnchorReference",
			input:       []types.PatchStrategicMerge{patchList2},
			expectedOut: []*Resource{testDeploymentA, testDeploymentB},
			// TODO(#3271) This shouldn't have an error, but does when kyaml is used.
			// The error using kyaml is:
			//   json: unsupported type: map[interface {}]interface {}
			// maybe arising from too many conversions between
			// yaml, json, Resource, RNode, Unstructured etc.
			// These conversions go away after closing #3506
			// TODO(#3304): DECISION - open bug with anchor references.
			expectedErr: konfig.FlagEnableKyamlDefaultValue,
		},
		{
			name:        "listWithNoEntries",
			input:       []types.PatchStrategicMerge{patchList3},
			expectedOut: []*Resource{},
			expectedErr: false,
		},
		{
			name:        "listWithNoItems",
			input:       []types.PatchStrategicMerge{patchList4},
			expectedOut: []*Resource{},
			expectedErr: false,
		},
	}
	for _, test := range tests {
		rs, err := factory.SliceFromPatches(ldr, test.input)
		if err != nil {
			assert.True(t, test.expectedErr,
				fmt.Sprintf("in test %s, got unexpected error: %v", test.name, err))
			continue
		}
		assert.False(t, test.expectedErr, "expected no error in "+test.name)
		assert.Equal(t, len(test.expectedOut), len(rs))
		for i := range rs {
			expYaml, err := test.expectedOut[i].AsYAML()
			assert.NoError(t, err)
			actYaml, err := rs[i].AsYAML()
			assert.NoError(t, err)
			assert.Equal(t, expYaml, actYaml)
		}
	}
}
<commit_msg>Update factory_test.go<commit_after>// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package resource_test

import (
	"fmt"
	"testing"

	"sigs.k8s.io/kustomize/api/konfig"

	"github.com/stretchr/testify/assert"
	"sigs.k8s.io/kustomize/api/filesys"
	"sigs.k8s.io/kustomize/api/loader"
	. "sigs.k8s.io/kustomize/api/resource"
	"sigs.k8s.io/kustomize/api/types"
)

func TestSliceFromBytes(t *testing.T) {
	type testCase struct {
		input    string
		expected []string
	}
	testCases := map[string]testCase{
		"empty1": {
			input:    "",
			expected: []string{},
		},
		"empty2": {
			input: `
---
---
`,
			expected: []string{},
		},
		"deployment1": {
			input: `
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pooh
---
`,
			expected: []string{
				`apiVersion: apps/v1
kind: Deployment
metadata:
  name: pooh
`,
			},
		},
		"deployment2": {
			input: `
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    baseAnno: This is a base annotation
  labels:
    app: mungebot
    foo: bar
  name: baseprefix-mungebot
spec:
  replicas: 1
  selector:
    matchLabels:
      foo: bar
  template:
    metadata:
      annotations:
        baseAnno: This is a base annotation
      labels:
        app: mungebot
        foo: bar
    spec:
      containers:
      - env:
        - name: foo
          value: bar
        image: nginx
        name: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    baseAnno: This is a base annotation
  labels:
    app: mungebot
    foo: bar
  name: baseprefix-mungebot-service
spec:
  ports:
  - port: 7002
  selector:
    app: mungebot
    foo: bar
`,
			expected: []string{
				`apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    baseAnno: This is a base annotation
  labels:
    app: mungebot
    foo: bar
  name: baseprefix-mungebot
spec:
  replicas: 1
  selector:
    matchLabels:
      foo: bar
  template:
    metadata:
      annotations:
        baseAnno: This is a base annotation
      labels:
        app: mungebot
        foo: bar
    spec:
      containers:
      - env:
        - name: foo
          value: bar
        image: nginx
        name: nginx
        ports:
        - containerPort: 80
`,
				`apiVersion: v1
kind: Service
metadata:
  annotations:
    baseAnno: This is a base annotation
  labels:
    app: mungebot
    foo: bar
  name: baseprefix-mungebot-service
spec:
  ports:
  - port: 7002
  selector:
    app: mungebot
    foo: bar
`,
			},
		},
	}

	for name := range testCases {
		tc := testCases[name]
		t.Run(name, func(t *testing.T) {
			result, err := factory.SliceFromBytes([]byte(tc.input))
			if err != nil {
				t.Fatalf("%v: fails with err: %v", name, err)
			}
			if len(result) != len(tc.expected) {
				for i := range result {
					bytes, err := result[i].AsYAML()
					if err != nil {
						t.Fatalf("%v: result to YAML fails with err: %v", name, err)
					}
					tmp := string(bytes)
					t.Logf("--- %d:\n%s", i, tmp)
				}
				t.Fatalf(
					"%v: actual len %d != expected len %d",
					name, len(result), len(tc.expected))
			}
			for i := range tc.expected {
				bytes, err := result[i].AsYAML()
				if err != nil {
					t.Fatalf("%v: result to YAML fails with err: %v", name, err)
				}
				tmp := string(bytes)
				if tmp != tc.expected[i] {
					t.Fatalf(
						"%v: string mismatch in item %d\n"+
							"actual:\n-----\n%s\n-----\n"+
							"expected:\n-----\n%s\n-----\n",
						name, i, tmp, tc.expected[i])
				}
			}
		})
	}
}

func TestSliceFromPatches(t *testing.T) {
	patchGood1 := types.PatchStrategicMerge("patch1.yaml")
	patch1 := `
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pooh
`
	patchGood2 := types.PatchStrategicMerge("patch2.yaml")
	patch2 := `
apiVersion: v1
kind: ConfigMap
metadata:
  name: winnie
  namespace: hundred-acre-wood
---
# some comment
---
---
`
	patchBad := types.PatchStrategicMerge("patch3.yaml")
	patch3 := `
WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOT: woot
`
	patchList := types.PatchStrategicMerge("patch4.yaml")
	patch4 := `
apiVersion: v1
kind: List
items:
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: pooh
- apiVersion: v1
  kind: ConfigMap
  metadata:
    name: winnie
    namespace: hundred-acre-wood
`
	patchList2 := types.PatchStrategicMerge("patch5.yaml")
	patch5 := `
apiVersion: v1
kind: DeploymentList
items:
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: deployment-a
  spec: &hostAliases
    template:
      spec:
        hostAliases:
        - hostnames:
          - a.example.com
          ip: 8.8.8.8
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: deployment-b
  spec:
    <<: *hostAliases
`
	patchList3 := types.PatchStrategicMerge("patch6.yaml")
	patch6 := `
apiVersion: v1
kind: List
items:
`
	patchList4 := types.PatchStrategicMerge("patch7.yaml")
	patch7 := `
apiVersion: v1
kind: List
`
	testDeploymentSpec := map[string]interface{}{
		"template": map[string]interface{}{
			"spec": map[string]interface{}{
				"hostAliases": []interface{}{
					map[string]interface{}{
						"hostnames": []interface{}{
							"a.example.com",
						},
						"ip": "8.8.8.8",
					},
				},
			},
		},
	}
	testDeploymentA := factory.FromMap(
		map[string]interface{}{
			"apiVersion": "apps/v1",
			"kind":       "Deployment",
			"metadata": map[string]interface{}{
				"name": "deployment-a",
			},
			"spec": testDeploymentSpec,
		})
	testDeploymentB := factory.FromMap(
		map[string]interface{}{
			"apiVersion": "apps/v1",
			"kind":       "Deployment",
			"metadata": map[string]interface{}{
				"name": "deployment-b",
			},
			"spec": testDeploymentSpec,
		})

	fSys := filesys.MakeFsInMemory()
	fSys.WriteFile(string(patchGood1), []byte(patch1))
	fSys.WriteFile(string(patchGood2), []byte(patch2))
	fSys.WriteFile(string(patchBad), []byte(patch3))
	fSys.WriteFile(string(patchList), []byte(patch4))
	fSys.WriteFile(string(patchList2), []byte(patch5))
	fSys.WriteFile(string(patchList3), []byte(patch6))
	fSys.WriteFile(string(patchList4), []byte(patch7))

	ldr, err := loader.NewLoader(
		loader.RestrictionRootOnly, filesys.Separator, fSys)
	if err != nil {
		t.Fatal(err)
	}

	tests := []struct {
		name        string
		input       []types.PatchStrategicMerge
		expectedOut []*Resource
		expectedErr bool
	}{
		{
			name:        "happy",
			input:       []types.PatchStrategicMerge{patchGood1, patchGood2},
			expectedOut: []*Resource{testDeployment, testConfigMap},
			expectedErr: false,
		},
		{
			name:        "badFileName",
			input:       []types.PatchStrategicMerge{patchGood1, "doesNotExist"},
			expectedOut: []*Resource{},
			expectedErr: true,
		},
		{
			name:        "badData",
			input:       []types.PatchStrategicMerge{patchGood1, patchBad},
			expectedOut: []*Resource{},
			expectedErr: true,
		},
		{
			name:        "listOfPatches",
			input:       []types.PatchStrategicMerge{patchList},
			expectedOut: []*Resource{testDeployment, testConfigMap},
			expectedErr: false,
		},
		{
			name:        "listWithAnchorReference",
			input:       []types.PatchStrategicMerge{patchList2},
			expectedOut: []*Resource{testDeploymentA, testDeploymentB},
			// The error using kyaml is:
			//   json: unsupported type: map[interface {}]interface {}
			// maybe arising from too many conversions between
			// yaml, json, Resource, RNode, Unstructured etc.
			// These conversions go away after closing #3506
			// TODO(#3271) This shouldn't have an error, but does when kyaml is used.
			// TODO(#3304): DECISION - still a bug, but not a blocker to #3304 or #2506
			expectedErr: konfig.FlagEnableKyamlDefaultValue,
		},
		{
			name:        "listWithNoEntries",
			input:       []types.PatchStrategicMerge{patchList3},
			expectedOut: []*Resource{},
			expectedErr: false,
		},
		{
			name:        "listWithNoItems",
			input:       []types.PatchStrategicMerge{patchList4},
			expectedOut: []*Resource{},
			expectedErr: false,
		},
	}
	for _, test := range tests {
		rs, err := factory.SliceFromPatches(ldr, test.input)
		if err != nil {
			assert.True(t, test.expectedErr,
				fmt.Sprintf("in test %s, got unexpected error: %v", test.name, err))
			continue
		}
		assert.False(t, test.expectedErr, "expected no error in "+test.name)
		assert.Equal(t, len(test.expectedOut), len(rs))
		for i := range rs {
			expYaml, err := test.expectedOut[i].AsYAML()
			assert.NoError(t, err)
			actYaml, err := rs[i].AsYAML()
			assert.NoError(t, err)
			assert.Equal(t, expYaml, actYaml)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"math/rand"
	"os"
	"path/filepath"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"
)

const version = "0.1"

type shakableFile struct {
	filepath string
	isShaked bool
}

func main() {

	var (
		sources = kingpin.Arg("source",
			"Files or directories to skake.").Required().Strings()

		paths []shakableFile
	)

	kingpin.Version(version)
	kingpin.CommandLine.Help = "File shaker for the Masses."
	kingpin.Parse()

	rand.Seed(time.Now().UTC().UnixNano())

	for _, source := range *sources {

		file, err := filepath.Abs(source)
		if err != nil {
			continue
		}
		paths = append(paths, shakableFile{filepath: file, isShaked: false})
	}

	dest := make([]shakableFile, len(paths))
	copy(dest, paths)

	ランダム(dest)

	shake(paths, dest)

}

func ランダム(slice []shakableFile) {

	for i := len(slice) - 1; i > 0; i-- {
		j := rand.Intn(i)
		slice[i], slice[j] = slice[j], slice[i]
	}

}

func shake(source, dest []shakableFile) {

	for i := len(source) - 1; i > 0; i-- {
		if source[i].isShaked == false || dest[i].isShaked == false {

			file, err := ioutil.TempFile(filepath.Dir(source[i].filepath),
				"mvshaker")
			defer os.Remove(file.Name())

			if err != nil {
				panic(err)
			}

			if err := os.Rename(source[i].filepath, file.Name()); err != nil {
				panic(err)
			}
			if err := os.Rename(dest[i].filepath, source[i].filepath); err != nil {
				panic(err)
			}
			if err := os.Rename(file.Name(), dest[i].filepath); err != nil {
				panic(err)
			}

			source[i].isShaked = true
			dest[i].isShaked = true
		}
	}
}
<commit_msg>Move collection of sources in a function<commit_after>package main

import (
	"io/ioutil"
	"math/rand"
	"os"
	"path/filepath"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"
)

const version = "0.1"

type shakableFile struct {
	filepath string
	isShaked bool
}

func main() {

	var (
		sources = kingpin.Arg("source",
			"Files or directories to skake.").Required().Strings()
	)

	kingpin.Version(version)
	kingpin.CommandLine.Help = "File shaker for the Masses."
	kingpin.Parse()

	rand.Seed(time.Now().UTC().UnixNano())

	paths := collect(*sources)

	dest := make([]shakableFile, len(paths))
	copy(dest, paths)

	ランダム(dest)

	shake(paths, dest)

}

func collect(sources []string) []shakableFile {

	var paths []shakableFile

	for _, source := range sources {

		file, err := filepath.Abs(source)
		if err != nil {
			continue
		}
		paths = append(paths, shakableFile{filepath: file, isShaked: false})
	}

	return paths

}

func ランダム(slice []shakableFile) {

	for i := len(slice) - 1; i > 0; i-- {
		j := rand.Intn(i)
		slice[i], slice[j] = slice[j], slice[i]
	}

}

func shake(source, dest []shakableFile) {

	for i := len(source) - 1; i > 0; i-- {
		if source[i].isShaked == false || dest[i].isShaked == false {

			file, err := ioutil.TempFile(filepath.Dir(source[i].filepath),
				"mvshaker")
			defer os.Remove(file.Name())

			if err != nil {
				panic(err)
			}

			if err := os.Rename(source[i].filepath, file.Name()); err != nil {
				panic(err)
			}
			if err := os.Rename(dest[i].filepath, source[i].filepath); err != nil {
				panic(err)
			}
			if err := os.Rename(file.Name(), dest[i].filepath); err != nil {
				panic(err)
			}

			source[i].isShaked = true
			dest[i].isShaked = true
		}
	}
}
<|endoftext|>


<commit_before>/*
   Nging is a toolbox for webmasters
   Copyright (C) 2018-present  Wenhui Shen <swh@admpub.com>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published
   by the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

// 也可以以服务的方式启动nging
// 服务支持的操作有：
// nging service install  	-- 安装服务
// nging service uninstall  -- 卸载服务
// nging service start 		-- 启动服务
// nging service stop 		-- 停止服务
// nging service restart 	-- 重启服务
package main

//go:generate go get github.com/go-bindata/go-bindata/...
//go:generate go get github.com/admpub/go-bindata-assetfs/...
//go:generate go-bindata-assetfs -ignore "\\.(git|svn|DS_Store|less|scss)$" -tags bindata public/assets/... template/... config/i18n/...

import (
	"github.com/admpub/log"
	"github.com/admpub/nging/application/cmd"
	"github.com/webx-top/echo"

	//register
	_ "github.com/admpub/nging/application"
	_ "github.com/admpub/nging/application/initialize/manager"
	_ "github.com/admpub/nging/application/library/sqlite"
)

var (
	BUILD_TIME string
	CLOUD_GOX  string
	COMMIT     string
	LABEL      = `dev` //beta/alpha/stable
	VERSION    = `2.0.0`

	version   string
	schemaVer = 2.2 //数据表结构版本
)

func main() {
	defer log.Sync()
	echo.Set(`BUILD_TIME`, BUILD_TIME)
	echo.Set(`COMMIT`, COMMIT)
	echo.Set(`LABEL`, LABEL)
	echo.Set(`VERSION`, VERSION)
	echo.Set(`SCHEMA_VER`, schemaVer)
	exec()
}

func exec() {
	cmd.Execute()
}
<commit_msg>update<commit_after>/*
   Nging is a toolbox for webmasters
   Copyright (C) 2018-present  Wenhui Shen <swh@admpub.com>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published
   by the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

// 也可以以服务的方式启动nging
// 服务支持的操作有：
// nging service install  	-- 安装服务
// nging service uninstall  -- 卸载服务
// nging service start 		-- 启动服务
// nging service stop 		-- 停止服务
// nging service restart 	-- 重启服务
package main

//go:generate go get github.com/go-bindata/go-bindata/...
//go:generate go-bindata -fs -o bindata_assetfs.go -ignore "\\.(git|svn|DS_Store|less|scss)$" -tags bindata public/assets/... template/... config/i18n/...

import (
	"github.com/admpub/log"
	"github.com/admpub/nging/application/cmd"
	"github.com/webx-top/echo"

	//register
	_ "github.com/admpub/nging/application"
	_ "github.com/admpub/nging/application/initialize/manager"
	_ "github.com/admpub/nging/application/library/sqlite"
)

var (
	BUILD_TIME string
	CLOUD_GOX  string
	COMMIT     string
	LABEL      = `dev` //beta/alpha/stable
	VERSION    = `2.0.0`

	version   string
	schemaVer = 2.2 //数据表结构版本
)

func main() {
	defer log.Sync()
	echo.Set(`BUILD_TIME`, BUILD_TIME)
	echo.Set(`COMMIT`, COMMIT)
	echo.Set(`LABEL`, LABEL)
	echo.Set(`VERSION`, VERSION)
	echo.Set(`SCHEMA_VER`, schemaVer)
	exec()
}

func exec() {
	cmd.Execute()
}
<|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"
	"strconv"
	"net/url"
  	"io/ioutil"
	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client

type GeoContent struct {
	LatLong    string `json:"latLon"`
	Utm string `json:"utm"`
        Mgrs string `json:"mgrs"`
}

func main() {
	// fixie
	fixieUrl, err := url.Parse(os.Getenv("FIXIE_URL"))
  	customClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(fixieUrl)}}
  	resp, err := customClient.Get("http://welcome.usefixie.com")
  	if (err != nil) {
    		println(err.Error())
    		return
  	}
  	defer resp.Body.Close()
  	body, err := ioutil.ReadAll(resp.Body)
  	println(string(body))

	// end fixie

	// line bot
	strID := os.Getenv("ChannelID")
	numID, err := strconv.ParseInt(strID, 10, 64)
	if err != nil {
		log.Fatal("Wrong environment setting about ChannelID")
	}

	bot, err = linebot.NewClient(numID, os.Getenv("ChannelSecret"), os.Getenv("MID"))
	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) {
	received, err := bot.ParseRequest(r)
	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	for _, result := range received.Results {
		content := result.Content()
		log.Println("-->", content)

		//Log detail receive content
		if content != nil {
			log.Println("RECEIVE Msg:", content.IsMessage, " OP:", content.IsOperation, " type:", content.ContentType, " from:", content.From, "to:", content.To, " ID:", content.ID)
		}
		/*
		if content != nil && content.IsMessage && content.ContentType == linebot.ContentTypeText {
			text, err := content.TextContent()
			_, err = bot.SendText([]string{content.From}, "Bot received : "+text.Text)

			if err != nil {
				log.Println(err)
			}
		}*/
		if content != nil && content.ContentType == linebot.ContentTypeLocation {
			loc, err := content.LocationContent()

			// add eggyo geo test
			resp, err := http.Get("http://eggyo-geo-node.herokuapp.com/geo/" + FloatToString(loc.Latitude) + "/" + FloatToString(loc.Longitude))
			if (err != nil) {
    				println(err.Error())
    				return
  			}
  			defer resp.Body.Close()
			body, err := ioutil.ReadAll(resp.Body)
			log.Println(string(body))

			//_, err = bot.SendText([]string{content.From}, "OK "+text.Text)
			_, err = bot.SendText([]string{content.From}, "Geo test :" + string(body))

			if err != nil {
				log.Println(err)
			}
		}
	}
}
func FloatToString(input_num float64) string {
    // to convert a float number to a string
    return strconv.FormatFloat(input_num, 'f', 6, 64)
}
<commit_msg>Update main.go<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"
	"strconv"
	"net/url"
  	"io/ioutil"
	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client

type GeoContent struct {
	LatLong    string `json:"latLon"`
	Utm string `json:"utm"`
        Mgrs string `json:"mgrs"`
}

func main() {
	// fixie
	fixieUrl, err := url.Parse(os.Getenv("FIXIE_URL"))
  	customClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(fixieUrl)}}
  	resp, err := customClient.Get("http://welcome.usefixie.com")
  	if (err != nil) {
    		println(err.Error())
    		return
  	}
  	defer resp.Body.Close()
  	body, err := ioutil.ReadAll(resp.Body)
  	println(string(body))

	// end fixie

	// line bot
	strID := os.Getenv("ChannelID")
	numID, err := strconv.ParseInt(strID, 10, 64)
	if err != nil {
		log.Fatal("Wrong environment setting about ChannelID")
	}

	bot, err = linebot.NewClient(numID, os.Getenv("ChannelSecret"), os.Getenv("MID"))
	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) {
	received, err := bot.ParseRequest(r)
	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	for _, result := range received.Results {
		content := result.Content()
		log.Println("-->", content)

		//Log detail receive content
		if content != nil {
			log.Println("RECEIVE Msg:", content.IsMessage, " OP:", content.IsOperation, " type:", content.ContentType, " from:", content.From, "to:", content.To, " ID:", content.ID)
		}
		/*
		if content != nil && content.IsMessage && content.ContentType == linebot.ContentTypeText {
			text, err := content.TextContent()
			_, err = bot.SendText([]string{content.From}, "Bot received : "+text.Text)

			if err != nil {
				log.Println(err)
			}
		}*/
		if content != nil && content.ContentType == linebot.ContentTypeLocation {
			loc, err := content.LocationContent()

			// add eggyo geo test
			resp, err := http.Get("http://eggyo-geo-node.herokuapp.com/geo/" + FloatToString(loc.Latitude) + "/" + FloatToString(loc.Longitude))
			if (err != nil) {
    				println(err.Error())
    				return
  			}
  			defer resp.Body.Close()
			body, err := ioutil.ReadAll(resp.Body)
			log.Println(string(body))

		        var geo GeoContent
                        _, err := json.Unmarshal(body, &geo)
                        if err != nil {
				log.Println(err)
			}
			//_, err = bot.SendText([]string{content.From}, "OK "+text.Text)
			_, err = bot.SendText([]string{content.From}, "Geo Results :" + geo.Mgrs)

			if err != nil {
				log.Println(err)
			}
		}
	}
}
func FloatToString(input_num float64) string {
    // to convert a float number to a string
    return strconv.FormatFloat(input_num, 'f', 6, 64)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"path"
	"strconv"
	"time"

	"github.com/coreos/etcd/etcdserver"
	"github.com/coreos/etcd/etcdserver/etcdhttp"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/store"
	"github.com/coreos/etcd/wal"
)

var (
	fid     = flag.String("id", "0xBEEF", "Id of this server")
	timeout = flag.Duration("timeout", 10*time.Second, "Request Timeout")
	laddr   = flag.String("l", ":8080", "HTTP service address (e.g., ':8080')")
	dir     = flag.String("d", "", "Directory to store wal files and snapshot files")

	peers = etcdhttp.Peers{}
)

func init() {
	flag.Var(peers, "peers", "your peers")
}

func main() {
	flag.Parse()

	id, err := strconv.ParseInt(*fid, 0, 64)
	if err != nil {
		log.Fatal(err)
	}

	if peers.Pick(id) == "" {
		log.Fatalf("%#x=<addr> must be specified in peers", id)
	}

	if *dir == "" {
		*dir = fmt.Sprintf("%v", *fid)
		log.Printf("main: no data dir is given, use default data dir ./%s", *dir)
	}
	if err := os.MkdirAll(*dir, 0700); err != nil {
		log.Fatal(err)
	}

	waldir := path.Join(*dir, "wal")

	var w *wal.WAL
	var n raft.Node
	if wal.Exist(waldir) {
		// TODO(xiangli): check snapshot; not open from zero
		w, err = wal.OpenFromIndex(waldir, 0)
		if err != nil {
			log.Fatal(err)
		}
		// TODO(xiangli): save/recovery nodeID?
		_, st, ents, err := w.ReadAll()
		if err != nil {
			log.Fatal(err)
		}
		n = raft.Restart(id, peers.Ids(), 10, 1, st, ents)
	} else {
		w, err = wal.Create(waldir)
		if err != nil {
			log.Fatal(err)
		}
		n = raft.Start(id, peers.Ids(), 10, 1)
	}

	tk := time.NewTicker(100 * time.Millisecond)
	s := &etcdserver.Server{
		Store:  store.New(),
		Node:   n,
		Save:   w.Save,
		Send:   etcdhttp.Sender(peers),
		Ticker: tk.C,
	}
	etcdserver.Start(s)
	h := &etcdhttp.Handler{
		Timeout: *timeout,
		Server:  s,
	}
	http.Handle("/", h)
	log.Fatal(http.ListenAndServe(*laddr, nil))
}
<commit_msg>main: use data-dir as the path to data directory flag<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"path"
	"strconv"
	"time"

	"github.com/coreos/etcd/etcdserver"
	"github.com/coreos/etcd/etcdserver/etcdhttp"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/store"
	"github.com/coreos/etcd/wal"
)

var (
	fid     = flag.String("id", "0xBEEF", "Id of this server")
	timeout = flag.Duration("timeout", 10*time.Second, "Request Timeout")
	laddr   = flag.String("l", ":8080", "HTTP service address (e.g., ':8080')")
	dir     = flag.String("data-dir", "", "Path to the data directory")
	peers   = etcdhttp.Peers{}
)

func init() {
	flag.Var(peers, "peers", "your peers")
}

func main() {
	flag.Parse()

	id, err := strconv.ParseInt(*fid, 0, 64)
	if err != nil {
		log.Fatal(err)
	}

	if peers.Pick(id) == "" {
		log.Fatalf("%#x=<addr> must be specified in peers", id)
	}

	if *dir == "" {
		*dir = fmt.Sprintf("%v", *fid)
		log.Printf("main: no data-dir is given, use default data-dir ./%s", *dir)
	}
	if err := os.MkdirAll(*dir, 0700); err != nil {
		log.Fatal(err)
	}

	waldir := path.Join(*dir, "wal")

	var w *wal.WAL
	var n raft.Node
	if wal.Exist(waldir) {
		// TODO(xiangli): check snapshot; not open from zero
		w, err = wal.OpenFromIndex(waldir, 0)
		if err != nil {
			log.Fatal(err)
		}
		// TODO(xiangli): save/recovery nodeID?
		_, st, ents, err := w.ReadAll()
		if err != nil {
			log.Fatal(err)
		}
		n = raft.Restart(id, peers.Ids(), 10, 1, st, ents)
	} else {
		w, err = wal.Create(waldir)
		if err != nil {
			log.Fatal(err)
		}
		n = raft.Start(id, peers.Ids(), 10, 1)
	}

	tk := time.NewTicker(100 * time.Millisecond)
	s := &etcdserver.Server{
		Store:  store.New(),
		Node:   n,
		Save:   w.Save,
		Send:   etcdhttp.Sender(peers),
		Ticker: tk.C,
	}
	etcdserver.Start(s)
	h := &etcdhttp.Handler{
		Timeout: *timeout,
		Server:  s,
	}
	http.Handle("/", h)
	log.Fatal(http.ListenAndServe(*laddr, nil))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	asc "github.com/aerospike/aerospike-client-go"
)

func panicOnErr(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {
	// define a client to connect to
	host := os.Getenv("AEROSPIKE_PORT_3000_TCP_ADDR")
	port := 3000
	cl, err := asc.NewClient(host, port)
	panicOnErr(err)

	key, err := asc.NewKey("test", "aerospike", "key")
	panicOnErr(err)

	// define some bins with data
	bins := asc.BinMap{
		"bin1": 42,
		"bin2": "elephant",
		"bin3": []interface{}{"Go", 2009},
	}

	// write the bins
	wp := asc.NewWritePolicy(0, 0)
	wp.SendKey = true
	err = cl.Put(wp, key, bins)
	panicOnErr(err)

	rec, err := cl.Get(nil, key)
	panicOnErr(err)

	fmt.Printf("%#v\n", *rec)

	//existed, err := cl.Delete(nil, key)
	//panicOnErr(err)
	//fmt.Printf("Record existed before delete? %v\n", existed)
}
<commit_msg>main: use k0kubun/pp to print result<commit_after>package main

import (
	"os"

	asc "github.com/aerospike/aerospike-client-go"
	"github.com/k0kubun/pp"
)

func panicOnErr(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {
	// define a client to connect to
	host := os.Getenv("AEROSPIKE_PORT_3000_TCP_ADDR")
	port := 3000
	cl, err := asc.NewClient(host, port)
	panicOnErr(err)

	key, err := asc.NewKey("test", "aerospike", "key")
	panicOnErr(err)

	// define some bins with data
	bins := asc.BinMap{
		"bin1": 42,
		"bin2": "elephant",
		"bin3": []interface{}{"Go", 2009},
	}

	// write the bins
	wp := asc.NewWritePolicy(0, 0)
	wp.SendKey = true
	err = cl.Put(wp, key, bins)
	panicOnErr(err)

	rec, err := cl.Get(nil, key)
	panicOnErr(err)

	_, _ = pp.Printf("key: %v\nbins: %v\n", *rec.Key, rec.Bins)

	//existed, err := cl.Delete(nil, key)
	//panicOnErr(err)
	//fmt.Printf("Record existed before delete? %v\n", existed)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"log"
	"math"
	"net"
	"os"
	"time"
)

const multicastAddress = "239.255.42.99:1511"

func record() error {
	log.Println("Recording packets")
	addr, err := net.ResolveUDPAddr("udp4", multicastAddress)
	if err != nil {
		return err
	}
	conn, err := net.ListenMulticastUDP("udp4", nil, addr)
	if err != nil {
		return err
	}
	defer conn.Close()
	filename := time.Now().Format("2005-01-02_15-04.bin")
	outfile, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer outfile.Close()
	defer outfile.Sync()

	recieved := 0
	buf := make([]byte, 5000)
	for i := 0; true; i++ {
		n, _, err := conn.ReadFromUDP(buf)
		if err != nil {
			return err
		}
		outfile.Write(buf)
		recieved += n
		if i%100 == 0 {
			log.Printf("Recieved %d bytes\n", recieved)
		}
	}
	return nil
}

// Packet parsing attempt (not finished)
func parsePacket(buf []byte) {
	var offset int
	iMessage, _ := binary.Uvarint(buf[offset : offset+2])
	offset += 2
	numBytes, _ := binary.Uvarint(buf[offset : offset+2])
	offset += 2
	if iMessage != 7 { // 7 - mocap data
		return
	}
	frame, _ := binary.Uvarint(buf[offset : offset+4])
	offset += 4
	numDataSets, _ := binary.Uvarint(buf[offset : offset+4])
	offset += 4
	fmt.Println(iMessage, numBytes, frame, numDataSets)
	var numMarkers int
	var markers []byte
	for ms := 0; ms < int(numDataSets); ms++ {
		bb := new(bytes.Buffer)
		var i int
		for i = 0; buf[offset+i] != 0; i++ {
			bb.WriteByte(buf[offset+i])
		}
		offset += i + 1
		fmt.Println(bb.String())
		nm, _ := binary.Uvarint(buf[offset : offset+4])
		numMarkers = int(nm)
		offset += 4
		nbytes := numMarkers * 3 * 4
		markers = buf[offset : offset+nbytes]
		offset += nbytes
		fmt.Println(numMarkers, nbytes, markers, buf[offset:])
		for i = 0; i < numMarkers; i++ {
			var x, y, z float64
			off := 0
			x0, _ := binary.Uvarint(markers[off : off+4])
			x = math.Float64frombits(x0)
			off += 4
			y0, _ := binary.Uvarint(markers[off : off+4])
			y = math.Float64frombits(y0)
			off += 4
			z0, _ := binary.Uvarint(markers[off : off+4])
			z = math.Float64frombits(z0)
			fmt.Println(x, y, z)
		}
	}
}

func main() {
	record()
}
<commit_msg>Replaying recorded data to multicast UDP address<commit_after>package main

import (
	"bytes"
	"encoding/binary"
	"errors"
	"flag"
	"fmt"
	"log"
	"math"
	"net"
	"os"
	"time"

	"golang.org/x/net/ipv4"
)

const (
	multicastAddress = "239.255.42.99:1511"
	bufferSize       = 5000
)

func address() *net.UDPAddr {
	addr, err := net.ResolveUDPAddr("udp4", multicastAddress)
	if err != nil {
		log.Fatal(err)
	}
	return addr
}

func record() error {
	log.Println("Recording packets")
	conn, err := net.ListenMulticastUDP("udp4", nil, address())
	if err != nil {
		return err
	}
	defer conn.Close()
	filename := time.Now().Format("2005-01-02_15-04.bin")
	outfile, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer outfile.Close()
	defer outfile.Sync()

	recieved := 0
	buf := make([]byte, bufferSize)
	for i := 0; true; i++ {
		n, _, err := conn.ReadFromUDP(buf)
		if err != nil {
			return err
		}
		outfile.Write(buf)
		recieved += n
		if i%100 == 0 {
			log.Printf("Recieved %d bytes\n", recieved)
		}
	}
	return nil
}

type frameInfo struct {
	frameType     uint64
	frameNumber   uint64
	datasetsCount uint64
	size          int
}

// Packet parsing attempt (not finished)
func parsePacket(buf []byte) (frameInfo, error) {
	var packet frameInfo
	var offset int

	packet.frameType, _ = binary.Uvarint(buf[offset : offset+2])
	offset += 2
	if packet.frameType != 7 { // 7 - mocap data
		return packet, errors.New("Not mocap data packet")
	}

	//	numBytes, _ := binary.Uvarint(buf[offset : offset+2]) // unknown nature
	offset += 2
	packet.frameNumber, _ = binary.Uvarint(buf[offset : offset+4])
	offset += 4
	packet.datasetsCount, _ = binary.Uvarint(buf[offset : offset+4])
	offset += 4
	fmt.Println(packet)

	var numMarkers int
	var markers []byte
	for ms := 0; ms < int(packet.datasetsCount); ms++ {
		bb := new(bytes.Buffer)
		var i int
		for i = 0; buf[offset+i] != 0; i++ {
			bb.WriteByte(buf[offset+i])
		}
		offset += i + 1
		fmt.Println(bb.String())

		nm, _ := binary.Uvarint(buf[offset : offset+4])
		numMarkers = int(nm)
		offset += 4
		nbytes := numMarkers * 3 * 4
		markers = buf[offset : offset+nbytes]
		offset += nbytes
		fmt.Println(numMarkers, nbytes, markers, buf[offset:])
		for i = 0; i < numMarkers; i++ {
			var x, y, z float64
			off := 0
			x0, _ := binary.Uvarint(markers[off : off+4])
			x = math.Float64frombits(x0)
			off += 4
			y0, _ := binary.Uvarint(markers[off : off+4])
			y = math.Float64frombits(y0)
			off += 4
			z0, _ := binary.Uvarint(markers[off : off+4])
			z = math.Float64frombits(z0)
			fmt.Println(x, y, z)
		}
	}
	packet.size = offset
	return packet, nil
}

func play(filename string, fps int) error {
	log.Printf("Replaying %s in %d fps", filename, fps)

	datafile, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer datafile.Close()

	addr := address()
	c, err := net.ListenMulticastUDP("udp4", nil, addr)
	if err != nil {
		return err
	}
	defer c.Close()
	// Some low-lvl syscall magic to allow multicast on localhost
	conn := ipv4.NewPacketConn(c)
	conn.SetMulticastLoopback(true)
	defer conn.Close() // not sure if should close wrapper, no errors both ways

	frameTime := time.Duration(1000000.0/float64(fps)) * time.Microsecond
	log.Println("Using frame time", frameTime)

	buf := make([]byte, bufferSize)
	var frameCount int
	for frameCount = 0; true; frameCount++ {
		_, err := datafile.Read(buf)
		if err != nil {
			log.Println(err)
			break
		}
		//		packet, err := parsePacket(buf)
		//		fmt.Println(buf[:packet.size])
		conn.WriteTo(buf, nil, addr)
		time.Sleep(frameTime) // Replaying in given fps
	}
	log.Printf("Played %d frames\n", frameCount)

	return nil
}

func main() {
	var recordMode = flag.Bool("record", false, "Run in record mode")
	var replayMode = flag.Bool("replay", false, "Replay recorded data")
	var fps = flag.Int("fps", 30, "Replay FPS")
	flag.Parse()

	switch {
	case *recordMode:
		record()
	case *replayMode:
		if len(flag.Args()) == 0 {
			log.Println("Filename required")
		} else {
			play(flag.Arg(0), *fps)
		}
	default:
		log.Println("Select mode (-help)")
	}
}
<|endoftext|>