<commit_before>/*
 * Copyright (c) 2014 Matt Jibson <matt.jibson@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
Party is a tool to automate the use of third party packages.

Many existing Go package managers provide solutions to the problem of relying on
other projects' code. Go handles the use of other packages elegantly, but is
prone to problems when that code has breaking changes or is removed from the
Internet. As a solution, the FAQ suggests copying any third party repositories
into your own project and changing your import paths to match. This is a
recursive process, as you must then perform the same procedure for those copied
packages and so on, until all leaf packages have no external imports.

party is a tool that performs all of this work. It:

1. Rewrites all external imports in both your project and the third party
directory from "other.com/user/package" to
"host.com/user/your_project/_third_party/other.com/user/package".

2. Updates or copies files from "$GOPATH/src/other.com/user/package" to
"$GOPATH/src/host.com/user/your_project/_third_party/other.com/user/package".

3. Returns to step 1 until no more rewrites are performed.

Usage

From your project's root directory, for the first run:

	$ party -c

Subsequent invocations can omit -c.

The flags are:
	-c
		create the third party directory if it does not exist
	-u
		run "go get -d -u <pkg>" on packages imported by party for the
		current package
	-d="_third_party"
		set the third party directory
	-v
		enable verbose output
	-n
		dry run: actions are printed instead of run
	-r
		import third party packages as relative, local imports

App Engine and Relative Imports

When working on an App Engine project, use the -r flag. This will cause all
third party imports to be local packages. This is needed because otherwise App
Engine will run init() routines from your .go files twice if your app is also in
your $GOPATH.

Bugs

There is no guarantee that the source directory exists. For example, a package
may have a OS-specific file (file_windows.go) which imports another package. On
non-Windows, that other package will not have been fetched during "go get" and
will thus not exist. These packages must be fetched using "go get" or some other
method by hand. Or, running party on a Windows machine (in this case) will
correctly copy those files. These cases are reported when running party.

party performs the equivalent of gofmt on any files affected by the import
rewrite, thus the diff may be somewhat larger than just the import lines.

Third party imports that use local (relative) packages will fail, as those
packages are assumed to be part of the standard library. Those packages will not
be copied.

*/
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/printer"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strconv"
	"strings"

	"code.google.com/p/go.tools/astutil"
)

const dirMode os.FileMode = 0755

var (
	dryrun     = flag.Bool("n", false, "don't perform any action, instead print them")
	create     = flag.Bool("c", false, "create the third party directory if needed")
	relative   = flag.Bool("r", false, "use a relative third party directory (needed on App Engine)")
	verbose    = flag.Bool("v", false, "print actions")
	thirdParty = flag.String("d", "_third_party", "name of third party directory")
	flagUpdate = flag.Bool("u", false, "update (go get -d -u) used packages")

	relpath, gopath, ThirdParty string
)

func main() {
	flag.Parse()
	if *dryrun {
		*verbose = true
	}

	ThirdParty = filepath.Base(*thirdParty)
	if ThirdParty != *thirdParty {
		log.Fatal("third party directory cannot contain path separators")
	}
	if *create {
		os.Mkdir(ThirdParty, dirMode)
	}
	if _, err := os.Open(ThirdParty); err != nil {
		log.Fatalf("could not open %s directory: run with -c or create it manually", ThirdParty)
	}

	pwd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	var importSites []string
	for _, s := range filepath.SplitList(os.Getenv("GOPATH")) {
		s, err := filepath.Abs(s)
		if err != nil {
			log.Fatal(err)
		}
		s, err = filepath.EvalSymlinks(s)
		if err != nil {
			log.Fatal(err)
		}
		if sf, err := os.Open(filepath.Join(s, "src")); err == nil {
			names, err := sf.Readdirnames(0)
			if err == nil {
				for _, name := range names {
					importSites = append(importSites, name)
				}
			}
		}
		if !strings.HasPrefix(pwd, s) {
			continue
		}
		gopath = s
		relpath = strings.TrimPrefix(pwd, filepath.Join(s, "src")+string(os.PathSeparator))
		break
	}
	if relpath == "" {
		log.Fatal("couldn't determine current directory relative to $GOPATH")
	}

	if *verbose {
		log.Println("using GOPATH:", gopath)
		log.Println("using relative path:", relpath)
	}
	for {
		update()
		if !rewriteImports(importSites) {
			break
		}
	}
}

func update() {
	paths := make(map[string]struct{})
	reltp := ThirdParty + "/"
	if !*relative {
		reltp = filepath.ToSlash(relpath) + "/" + reltp
	}
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return nil
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
		if err != nil {
			return nil
		}
		for _, im := range f.Imports {
			v := im.Path.Value[1 : len(im.Path.Value)-1]
			if !strings.HasPrefix(v, reltp) {
				continue
			}
			paths[strings.TrimPrefix(v, reltp)] = struct{}{}
		}
		return nil
	})
	for k := range paths {
		fpath := filepath.Join(gopath, "src", k)
		f, err := os.Open(fpath)
		if err != nil {
			log.Printf("%s required, but could not be found at %s", k, fpath)
			continue
		}
		if *flagUpdate {
			if *verbose {
				log.Printf("go get -d -u %v", k)
			}
			if !*dryrun {
				out, err := exec.Command("go", "get", "-d", "-u", k).CombinedOutput()
				if len(out) > 0 {
					log.Println(string(out))
				}
				if err != nil {
					log.Println("go get", k, "err:", err)
				}
			}
		}
		files, err := f.Readdir(0)
		if err != nil {
			log.Fatal(err)
		}
		f.Close()
		for _, source := range files {
			if source.IsDir() || strings.HasPrefix(source.Name(), ".") {
				continue
			}
			spath := filepath.Join(f.Name(), source.Name())
			destdir := filepath.Join(ThirdParty, k)
			dest := filepath.Join(destdir, source.Name())
			if err := os.MkdirAll(destdir, dirMode); err != nil {
				log.Fatal(err)
			}
			dst, err := os.Open(dest)
			created := false
			newer := false
			if os.IsNotExist(err) {
				if *verbose {
					log.Println("create", dest)
				}
				created = true
			} else if err != nil {
				log.Fatal(err)
			} else {
				destination, err := dst.Stat()
				if err != nil {
					log.Fatal(err)
				}
				newer = source.ModTime().After(destination.ModTime())
				dst.Close()
			}
			if created || newer {
				if *verbose {
					log.Printf("copy %s -> %s\n", spath, dest)
				}
				if !*dryrun {
					b, err := ioutil.ReadFile(spath)
					if err != nil {
						log.Fatal(err)
					}
					if filepath.Ext(spath) == ".go" {
						b, err = fixImportCheck(b, path.Join(relpath, destdir))
						if err != nil {
							log.Fatal(err)
						}
					}
					if err := ioutil.WriteFile(dest, b, source.Mode()); err != nil {
						log.Fatal(err)
					}
				}
			}
		}
	}
}

func fixImportCheck(body []byte, importPath string) ([]byte, error) {
	fset := token.NewFileSet()
	// todo: see if we can restrict the mode some more
	f, err := parser.ParseFile(fset, "", body, parser.ParseComments)
	if err != nil {
		log.Fatal(err)
	}
	var after *ast.CommentGroup
	var pos token.Pos = token.Pos(len(body))
	for _, v := range f.Comments {
		text := strings.TrimSpace(v.Text())
		if v.Pos() > f.Package && v.Pos() < pos && strings.HasPrefix(text, "import") {
			pos = v.Pos()
			after = v
		}
	}
	if bytes.IndexByte(body[f.Package:pos], '\n') == -1 {
		comment := fmt.Sprintf(`// import "%s"`, importPath)
		buf := new(bytes.Buffer)
		buf.Write(body[:after.Pos()-1])
		buf.WriteString(comment)
		buf.Write(body[after.End()-1:])
		body = buf.Bytes()
	}
	return body, nil
}

func rewriteImports(importSites []string) (rewritten bool) {
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return nil
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
		if err != nil {
			return nil
		}
		for _, im := range f.Imports {
			for _, site := range importSites {
				v, err := strconv.Unquote(im.Path.Value)
				if err != nil {
					log.Fatal(err)
				}
				// don't replace ourself
				if v == relpath || strings.HasPrefix(v, relpath+"/") {
					if *verbose {
						log.Printf("skipping %s because it is in %s\n", v, relpath)
					}
					continue
				}
				if strings.HasPrefix(v, site+"/") {
					target := ThirdParty + "/" + v
					if !*relative {
						target = relpath + "/" + target
					}
					if *verbose {
						log.Printf("rewrite %s: %s -> %s\n", path, v, target)
					}
					if *dryrun {
						break
					}
					if !astutil.RewriteImport(fset, f, v, target) {
						log.Fatalf("%s: could not rewrite %s", path, im.Path.Value)
					}
					rewritten = true
					break
				}
			}
		}
		var buf bytes.Buffer
		if err := printer.Fprint(&buf, fset, f); err != nil {
			log.Fatal(err)
		}
		fb, err := format.Source(buf.Bytes())
		if err != nil {
			log.Fatal(err)
		}
		if err := ioutil.WriteFile(path, fb, info.Mode()); err != nil {
			log.Fatal(err)
		}
		return nil
	})
	return
}
<commit_msg>Only update once during -u<commit_after>/*
 * Copyright (c) 2014 Matt Jibson <matt.jibson@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
Party is a tool to automate the use of third party packages.

Many existing Go package managers provide solutions to the problem of relying on
other projects' code. Go handles the use of other packages elegantly, but is
prone to problems when that code has breaking changes or is removed from the
Internet. As a solution, the FAQ suggests copying any third party repositories
into your own project and changing your import paths to match. This is a
recursive process, as you must then perform the same procedure for those copied
packages and so on, until all leaf packages have no external imports.

party is a tool that performs all of this work. It:

1. Rewrites all external imports in both your project and the third party
directory from "other.com/user/package" to
"host.com/user/your_project/_third_party/other.com/user/package".

2. Updates or copies files from "$GOPATH/src/other.com/user/package" to
"$GOPATH/src/host.com/user/your_project/_third_party/other.com/user/package".

3. Returns to step 1 until no more rewrites are performed.

Usage

From your project's root directory, for the first run:

	$ party -c

Subsequent invocations can omit -c.

The flags are:
	-c
		create the third party directory if it does not exist
	-u
		run "go get -d -u <pkg>" on packages imported by party for the
		current package
	-d="_third_party"
		set the third party directory
	-v
		enable verbose output
	-n
		dry run: actions are printed instead of run
	-r
		import third party packages as relative, local imports

App Engine and Relative Imports

When working on an App Engine project, use the -r flag. This will cause all
third party imports to be local packages. This is needed because otherwise App
Engine will run init() routines from your .go files twice if your app is also in
your $GOPATH.

Bugs

There is no guarantee that the source directory exists. For example, a package
may have a OS-specific file (file_windows.go) which imports another package. On
non-Windows, that other package will not have been fetched during "go get" and
will thus not exist. These packages must be fetched using "go get" or some other
method by hand. Or, running party on a Windows machine (in this case) will
correctly copy those files. These cases are reported when running party.

party performs the equivalent of gofmt on any files affected by the import
rewrite, thus the diff may be somewhat larger than just the import lines.

Third party imports that use local (relative) packages will fail, as those
packages are assumed to be part of the standard library. Those packages will not
be copied.

*/
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/printer"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strconv"
	"strings"

	"code.google.com/p/go.tools/astutil"
)

const dirMode os.FileMode = 0755

var (
	dryrun     = flag.Bool("n", false, "don't perform any action, instead print them")
	create     = flag.Bool("c", false, "create the third party directory if needed")
	relative   = flag.Bool("r", false, "use a relative third party directory (needed on App Engine)")
	verbose    = flag.Bool("v", false, "print actions")
	thirdParty = flag.String("d", "_third_party", "name of third party directory")
	flagUpdate = flag.Bool("u", false, "update (go get -d -u) used packages")

	relpath, gopath, ThirdParty string
)

func main() {
	flag.Parse()
	if *dryrun {
		*verbose = true
	}

	ThirdParty = filepath.Base(*thirdParty)
	if ThirdParty != *thirdParty {
		log.Fatal("third party directory cannot contain path separators")
	}
	if *create {
		os.Mkdir(ThirdParty, dirMode)
	}
	if _, err := os.Open(ThirdParty); err != nil {
		log.Fatalf("could not open %s directory: run with -c or create it manually", ThirdParty)
	}

	pwd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	var importSites []string
	for _, s := range filepath.SplitList(os.Getenv("GOPATH")) {
		s, err := filepath.Abs(s)
		if err != nil {
			log.Fatal(err)
		}
		s, err = filepath.EvalSymlinks(s)
		if err != nil {
			log.Fatal(err)
		}
		if sf, err := os.Open(filepath.Join(s, "src")); err == nil {
			names, err := sf.Readdirnames(0)
			if err == nil {
				for _, name := range names {
					importSites = append(importSites, name)
				}
			}
		}
		if !strings.HasPrefix(pwd, s) {
			continue
		}
		gopath = s
		relpath = strings.TrimPrefix(pwd, filepath.Join(s, "src")+string(os.PathSeparator))
		break
	}
	if relpath == "" {
		log.Fatal("couldn't determine current directory relative to $GOPATH")
	}

	if *verbose {
		log.Println("using GOPATH:", gopath)
		log.Println("using relative path:", relpath)
	}
	updated := make(map[string]bool)
	for {
		update(updated)
		if !rewriteImports(importSites) {
			break
		}
	}
}

func update(updated map[string]bool) {
	paths := make(map[string]struct{})
	reltp := ThirdParty + "/"
	if !*relative {
		reltp = filepath.ToSlash(relpath) + "/" + reltp
	}
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return nil
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
		if err != nil {
			return nil
		}
		for _, im := range f.Imports {
			v := im.Path.Value[1 : len(im.Path.Value)-1]
			if !strings.HasPrefix(v, reltp) {
				continue
			}
			paths[strings.TrimPrefix(v, reltp)] = struct{}{}
		}
		return nil
	})
	for k := range paths {
		fpath := filepath.Join(gopath, "src", k)
		f, err := os.Open(fpath)
		if err != nil {
			log.Printf("%s required, but could not be found at %s", k, fpath)
			continue
		}
		if *flagUpdate && !updated[k] {
			updated[k] = true
			if *verbose {
				log.Printf("go get -d -u %v", k)
			}
			if !*dryrun {
				out, err := exec.Command("go", "get", "-d", "-u", k).CombinedOutput()
				if len(out) > 0 {
					log.Println(string(out))
				}
				if err != nil {
					log.Println("go get", k, "err:", err)
				}
			}
		}
		files, err := f.Readdir(0)
		if err != nil {
			log.Fatal(err)
		}
		f.Close()
		for _, source := range files {
			if source.IsDir() || strings.HasPrefix(source.Name(), ".") {
				continue
			}
			spath := filepath.Join(f.Name(), source.Name())
			destdir := filepath.Join(ThirdParty, k)
			dest := filepath.Join(destdir, source.Name())
			if err := os.MkdirAll(destdir, dirMode); err != nil {
				log.Fatal(err)
			}
			dst, err := os.Open(dest)
			created := false
			newer := false
			if os.IsNotExist(err) {
				if *verbose {
					log.Println("create", dest)
				}
				created = true
			} else if err != nil {
				log.Fatal(err)
			} else {
				destination, err := dst.Stat()
				if err != nil {
					log.Fatal(err)
				}
				newer = source.ModTime().After(destination.ModTime())
				dst.Close()
			}
			if created || newer {
				if *verbose {
					log.Printf("copy %s -> %s\n", spath, dest)
				}
				if !*dryrun {
					b, err := ioutil.ReadFile(spath)
					if err != nil {
						log.Fatal(err)
					}
					if filepath.Ext(spath) == ".go" {
						b, err = fixImportCheck(b, path.Join(relpath, destdir))
						if err != nil {
							log.Fatal(err)
						}
					}
					if err := ioutil.WriteFile(dest, b, source.Mode()); err != nil {
						log.Fatal(err)
					}
				}
			}
		}
	}
}

func fixImportCheck(body []byte, importPath string) ([]byte, error) {
	fset := token.NewFileSet()
	// todo: see if we can restrict the mode some more
	f, err := parser.ParseFile(fset, "", body, parser.ParseComments)
	if err != nil {
		log.Fatal(err)
	}
	var after *ast.CommentGroup
	var pos token.Pos = token.Pos(len(body))
	for _, v := range f.Comments {
		text := strings.TrimSpace(v.Text())
		if v.Pos() > f.Package && v.Pos() < pos && strings.HasPrefix(text, "import") {
			pos = v.Pos()
			after = v
		}
	}
	if bytes.IndexByte(body[f.Package:pos], '\n') == -1 {
		comment := fmt.Sprintf(`// import "%s"`, importPath)
		buf := new(bytes.Buffer)
		buf.Write(body[:after.Pos()-1])
		buf.WriteString(comment)
		buf.Write(body[after.End()-1:])
		body = buf.Bytes()
	}
	return body, nil
}

func rewriteImports(importSites []string) (rewritten bool) {
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return nil
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
		if err != nil {
			return nil
		}
		for _, im := range f.Imports {
			for _, site := range importSites {
				v, err := strconv.Unquote(im.Path.Value)
				if err != nil {
					log.Fatal(err)
				}
				// don't replace ourself
				if v == relpath || strings.HasPrefix(v, relpath+"/") {
					if *verbose {
						log.Printf("skipping %s because it is in %s\n", v, relpath)
					}
					continue
				}
				if strings.HasPrefix(v, site+"/") {
					target := ThirdParty + "/" + v
					if !*relative {
						target = relpath + "/" + target
					}
					if *verbose {
						log.Printf("rewrite %s: %s -> %s\n", path, v, target)
					}
					if *dryrun {
						break
					}
					if !astutil.RewriteImport(fset, f, v, target) {
						log.Fatalf("%s: could not rewrite %s", path, im.Path.Value)
					}
					rewritten = true
					break
				}
			}
		}
		var buf bytes.Buffer
		if err := printer.Fprint(&buf, fset, f); err != nil {
			log.Fatal(err)
		}
		fb, err := format.Source(buf.Bytes())
		if err != nil {
			log.Fatal(err)
		}
		if err := ioutil.WriteFile(path, fb, info.Mode()); err != nil {
			log.Fatal(err)
		}
		return nil
	})
	return
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/hex"
	"encoding/json"
	"flag"
	"fmt"
	"net/http"
	"net/url"
	"os"
)

const usage = "factom -s [server] -c [chainid] -e [extid] -e [extid2] <data"

type entry struct {
	ChainID string
	ExtIDs  []string
	Data    string
}

type extids []string

func (e *extids) String() string {
	return fmt.Sprint(*e)
}

func (e *extids) Set(s string) error {
	*e = append(*e, s)
	return nil
}

func main() {
	var (
		help = flag.Bool("h", false, usage)
		cid  = flag.String("c", "", "hex encoded chainid for the entry")
		serv = flag.String("s", "localhost:8088", "path to the factomclient")
		eids extids
	)

	flag.Var(&eids, "e", "external id for the entry")
	flag.Parse()

	if *help {
		fmt.Println(usage)
		return
	}

	server := "http://" + *serv + "/v1/submitentry"

	fmt.Println(server)

	d := make([]byte, 1024)
	n, _ := os.Stdin.Read(d)
	d = d[:n]

	e := new(entry)
	e.ChainID = *cid
	for _, v := range eids {
		e.ExtIDs = append(e.ExtIDs, string(v))
	}
	e.Data = hex.EncodeToString(d)

	b, err := json.Marshal(e)
	if err != nil {
		return
	}

	data := url.Values{
		"datatype": {"entry"},
		"format":   {"json"},
		"entry":    {string(b)},
	}

	_, err = http.PostForm(server, data)
	if err != nil {
		fmt.Println("Error: ", err)
	}

	return
}
<commit_msg>post code for entry submission<commit_after>package main

import (
	"encoding/hex"
	"encoding/json"
	"flag"
	"fmt"
	"net/http"
	"net/url"
	"os"
)

const usage = "factom -s [server] -c [chainid] -e [extid] -e [extid2] <data"

type entry struct {
	ChainID string
	ExtIDs  []string
	Data    string
}

type extids []string

func (e *extids) String() string {
	return fmt.Sprint(*e)
}

func (e *extids) Set(s string) error {
	*e = append(*e, s)
	return nil
}

func main() {
	var (
		help = flag.Bool("h", false, usage)
		cid  = flag.String("c", "", "hex encoded chainid for the entry")
		serv = flag.String("s", "localhost:8088", "path to the factomclient")
		eids extids
	)

	flag.Var(&eids, "e", "external id for the entry")
	flag.Parse()

	if *help {
		fmt.Println(usage)
		return
	}

	server := "http://" + *serv + "/v1/submitentry"

	fmt.Println(server)

	d := make([]byte, 1024)
	n, _ := os.Stdin.Read(d)
	d = d[:n]

	e := new(entry)
	e.ChainID = *cid
	for _, v := range eids {
		e.ExtIDs = append(e.ExtIDs, string(v))
	}
	e.Data = hex.EncodeToString(d)

	b, err := json.Marshal(e)
	if err != nil {
		return
	}

	data := url.Values{
		"datatype": {"entry"},
		"format":   {"json"},
		"entry":    {string(b)},
	}

	_, err := http.PostForm(server, data)
	if err != nil {
		fmt.Println("Error: ", err)
	}

	return
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"path/filepath"

	dnotifier "github.com/satoshun/dnotifier/lib"
)

var (
	slackHookURL = flag.String("u", "", "your slack hook url")
	channel      = flag.String("c", "general", "your channel name. default general")
	files        arrayFlags
)

type arrayFlags []string

func (i *arrayFlags) String() string {
	return "want to watch files"
}

func (i *arrayFlags) Set(value string) error {
	*i = append(*i, value)
	return nil
}

func main() {
	flag.Var(&files, "f", "specified files")
	flag.Parse()

	if *slackHookURL == "" {
		log.Fatal("please specify -u option")
	}

	if len(files) == 0 {
		log.Fatal("please specify -f option")
	}

	api := dnotifier.Slack{
		HookURL: *slackHookURL,
	}

	log.Println("test")

	for i, f := range files {
		files[i], _ = filepath.Abs(f)
		fmt.Println("Watching: " + f)
	}

	w := dnotifier.Watch(files...)

	for {
		select {
		case msg := <-w.Event:
			log.Println("post:" + msg)
			if msg != "" {
				api.PostMessage(msg)
			}
		}
	}
}
<commit_msg>remove debug mesage<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"path/filepath"

	dnotifier "github.com/satoshun/dnotifier/lib"
)

var (
	slackHookURL = flag.String("u", "", "your slack hook url")
	channel      = flag.String("c", "general", "your channel name. default general")
	files        arrayFlags
)

type arrayFlags []string

func (i *arrayFlags) String() string {
	return "want to watch files"
}

func (i *arrayFlags) Set(value string) error {
	*i = append(*i, value)
	return nil
}

func main() {
	flag.Var(&files, "f", "specified files")
	flag.Parse()

	if *slackHookURL == "" {
		log.Fatal("please specify -u option")
	}

	if len(files) == 0 {
		log.Fatal("please specify -f option")
	}

	api := dnotifier.Slack{
		HookURL: *slackHookURL,
	}

	for i, f := range files {
		files[i], _ = filepath.Abs(f)
		fmt.Println("Watching: " + f)
	}

	w := dnotifier.Watch(files...)

	for {
		select {
		case msg := <-w.Event:
			log.Println("post:" + msg)
			if msg != "" {
				api.PostMessage(msg)
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	//"encoding/json"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/fsouza/go-dockerclient"
	"github.com/jmcvetta/restclient"
	"os"
)

func main() {

	/*
		endpoint := "http://104.131.90.110:4243"
		client, _ := docker.NewClient(endpoint)
		imgs, _ := client.ListImages(docker.ListImagesOptions{All: false})
		for _, img := range imgs {
			fmt.Println("ID: ", img.ID)
			fmt.Println("RepoTags: ", img.RepoTags)
			fmt.Println("Created: ", img.Created)
			fmt.Println("Size: ", img.Size)
			fmt.Println("VirtualSize: ", img.VirtualSize)
			fmt.Println("ParentId: ", img.ParentID)
		}*/

	app := cli.NewApp()

	app.Commands = []cli.Command{
		{

			Name:  "attach",
			Usage: "attach docker stdout",

			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "docker",
					Value: "api",
					Usage: "docker image name to connect",
				},
				cli.StringFlag{
					Name:  "protocol",
					Value: "http",
					Usage: "docker remote api protocol to connect",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "127.0.0.1",
					Usage: "docker host ip",
				},
				cli.StringFlag{
					Name:  "port",
					Value: "4243",
					Usage: "docker host port",
				},
				cli.StringFlag{
					Name:  "unixsocket",
					Value: "var/run/docker.sock",
					Usage: "docker unix socket path",
				},
			},

			Action: func(c *cli.Context) {

				name := c.String("docker")
				protocol := c.String("protocol")
				host := c.String("host")
				port := c.String("port")
				socket := c.String("unixsocket")

				//fmt.Printf("Image ----------------> %s", c)

				endpoint := fmt.Sprintf("http://%s:%s", host, port)

				if protocol == "unix" {

					endpoint = fmt.Sprintf("unix:///%s", socket)

				}

				client, _ := docker.NewClient(endpoint)
				imgs, _ := client.ListContainers(docker.ListContainersOptions{All: false})

				imageID := "0"
				imageFound := false

				for _, img := range imgs {
					fmt.Println("ID: ", img.ID)
					fmt.Println("Image: ", img.Image)
					fmt.Println("Command: ", img.Command)
					fmt.Println("Created: ", img.Created)
					fmt.Println("Status: ", img.Status)
					fmt.Println("Names: ", img.Names)

					for _, a := range img.Names {
						if a == name {
							imageFound = true
							fmt.Printf("Image found ....... %s", img.ID)
							imageID = img.ID
							break
						}
					}

					if imageFound == true {
						break
					}
				}

				//r, w := io.Pipe()

				if imageFound {
					err := client.AttachToContainer(docker.AttachToContainerOptions{Container: imageID, OutputStream: os.Stdout, InputStream: os.Stdin, Logs: true, Stream: false, Stdin: true, Stdout: true, Stderr: true, RawTerminal: true})
					if err != nil {

						fmt.Printf("%s", err)

					}
				} else {

					fmt.Printf("Image not found ----------------> %s", name)

				}

			},
		},

		{

			Name:  "install",
			Usage: "install templates in given host",

			Flags: []cli.Flag{

				cli.StringFlag{
					Name:  "protocol",
					Value: "http",
					Usage: "docker remote api protocol to connect",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "127.0.0.1",
					Usage: "docker host ip",
				},
				cli.StringFlag{
					Name:  "port",
					Value: "4243",
					Usage: "docker host port",
				},
				cli.StringFlag{
					Name:  "unixsocket",
					Value: "var/run/docker.sock",
					Usage: "docker unix socket path",
				},
				cli.StringFlag{
					Name:  "template",
					Value: "DBTEMPLATE",
					Usage: "template name to be install",
				},
			},

			Action: func(c *cli.Context) {

				protocol := c.String("protocol")
				host := c.String("host")
				port := c.String("port")
				socket := c.String("unixsocket")
				template := c.String("template")

				fmt.Printf("Image ----------------> %s", c)

				endpoint := fmt.Sprintf("http://%s:%s", host, port)

				if protocol == "unix" {

					endpoint = fmt.Sprintf("unix:///%s", socket)

				}

				client, _ := docker.NewClient(endpoint)
				//client.ListContainers(docker.ListContainersOptions{All: false})

				/////////--------------------------------------------------------------------------------------------->

				type Variable struct {
					Name         string
					Description  string
					DefaultValue string
					Export       bool
					Type         string
				}

				type Template_Image struct {
					Type     string
					Priority int
				}

				type Image struct {
					Name               string
					Description        string
					Version            string
					VersionStatus      string
					SourceUrl          string
					DockerUrl          string
					Class              string
					Type               string
					Cmd                string
					Category           string
					Importance         string
					CSDB_TemplateImage Template_Image
					SystemVariables    []Variable
					Dependants         []Image
				}

				type Template struct {
					Name          string
					Description   string
					Class         string
					Type          string
					Category      string
					CompanyId     int
					TenantId      int
					TemplateImage []Image
				}

				type Result struct {
					Exception     string
					CustomMessage string
					IsSuccess     bool
					Result        []Template
				}

				url := fmt.Sprintf("http://127.0.0.1:9093/DVP/API/1.0/SystemRegistry/TemplateByName/%s", template)

				var s Result

				r := restclient.RequestResponse{
					Url:    url,
					Method: "GET",
					Result: &s,
				}
				status, err := restclient.Do(&r)
				if err != nil {
					//panic(err)
				}
				if status == 200 {

					//json.Unmarshal([]byte(r.RawText), &s)

					fmt.Println("Template Data  -->", r.RawText)

					fmt.Println("Template Data  -->", s)

					if s.IsSuccess == true {

						if s.Result != nil {

							for _, temp := range s.Result {

								for _, img := range temp.TemplateImage {
									fmt.Println(img.CSDB_TemplateImage.Type)
									if img.CSDB_TemplateImage.Type == "Mandetory" {

										fmt.Println(img.Class)
										if img.Class == "DOCKER" {

											fmt.Println(img.DockerUrl)

											pullImage := docker.PullImageOptions{Repository: img.DockerUrl, Tag: "latest"}
											authConf := docker.AuthConfiguration{}
											erry := client.PullImage(pullImage, authConf)
											fmt.Printf("pull --->", erry)
											if erry == nil {

												container := docker.CreateContainerOptions{}
												container.Name = img.Name
												//img.Cmd = "postgres"
												cmd := []string{img.Cmd}

												/*
													a := []int{1,2,3}
													a = append(a, 4)
													fmt.Println(a)

												*/

												Var := []string{}

												for _, vars := range img.SystemVariables {

													Var = append(Var, fmt.Sprintf("%s=%s", vars.Name, vars.DefaultValue))

												}

												container.Config = &docker.Config{Image: img.DockerUrl, Cmd: cmd, Env: Var}

												fmt.Println(container.Config.Image)

												_, errx := client.CreateContainer(container)

												fmt.Printf("Container --->", errx)

												if errx == nil {

													//fmt.Printf("Container ---> ", cont)

													hostConfig := &docker.HostConfig{}

													errz := client.StartContainer(img.Name, hostConfig)
													fmt.Printf("Container --->", errz)
												}
											}

										} else if img.Class == "DOCKERFILE" {

											buildOption := docker.BuildImageOptions{Name: img.Name, Dockerfile: "Dockerfile", SuppressOutput: true, OutputStream: os.Stdout, Remote: img.SourceUrl}

											err := client.BuildImage(buildOption)
											fmt.Printf("BuildContainer --->", err)

										}

									} else if img.CSDB_TemplateImage.Type == "Optional" {

									}

								}

							}

						}
					}

				}

			},
		},

		{

			Name:  "list",
			Usage: "list dockers in given host",

			Flags: []cli.Flag{

				cli.StringFlag{
					Name:  "protocol",
					Value: "http",
					Usage: "docker remote api protocol to connect",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "127.0.0.1",
					Usage: "docker host ip",
				},
				cli.StringFlag{
					Name:  "port",
					Value: "4243",
					Usage: "docker host port",
				},
				cli.StringFlag{
					Name:  "unixsocket",
					Value: "var/run/docker.sock",
					Usage: "docker unix socket path",
				},
			},

			Action: func(c *cli.Context) {

				protocol := c.String("protocol")
				host := c.String("host")
				port := c.String("port")
				socket := c.String("unixsocket")

				//fmt.Printf("Image ----------------> %s", c)

				endpoint := fmt.Sprintf("http://%s:%s", host, port)

				if protocol == "unix" {

					endpoint = fmt.Sprintf("unix:///%s", socket)

				}

				client, _ := docker.NewClient(endpoint)
				imgs, _ := client.ListContainers(docker.ListContainersOptions{All: false})

				for _, img := range imgs {
					fmt.Println("ID: ", img.ID)
					fmt.Println("Image: ", img.Image)
					fmt.Println("Command: ", img.Command)
					fmt.Println("Created: ", img.Created)
					fmt.Println("Status: ", img.Status)
					fmt.Println("Names: ", img.Names)

				}

			},
		},

		{

			Name:  "log",
			Usage: "get docker logs through stdout and stderr",

			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "docker",
					Value: "api",
					Usage: "docker image name to connect",
				},
				cli.StringFlag{
					Name:  "protocol",
					Value: "http",
					Usage: "docker remote api protocol to connect",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "127.0.0.1",
					Usage: "docker host ip",
				},
				cli.StringFlag{
					Name:  "port",
					Value: "4243",
					Usage: "docker host port",
				},
				cli.StringFlag{
					Name:  "unixsocket",
					Value: "var/run/docker.sock",
					Usage: "docker unix socket path",
				},
			},

			Action: func(c *cli.Context) {

				name := c.String("docker")
				protocol := c.String("protocol")
				host := c.String("host")
				port := c.String("port")
				socket := c.String("unixsocket")

				//fmt.Printf("Image ----------------> %s", c)

				endpoint := fmt.Sprintf("http://%s:%s", host, port)

				if protocol == "unix" {

					endpoint = fmt.Sprintf("unix:///%s", socket)

				}

				client, _ := docker.NewClient(endpoint)
				imgs, _ := client.ListContainers(docker.ListContainersOptions{All: false})

				imageID := "0"
				imageFound := false

				for _, img := range imgs {
					fmt.Println("ID: ", img.ID)
					fmt.Println("Image: ", img.Image)
					fmt.Println("Command: ", img.Command)
					fmt.Println("Created: ", img.Created)
					fmt.Println("Status: ", img.Status)
					fmt.Println("Names: ", img.Names)

					for _, a := range img.Names {
						if a == name {
							imageFound = true
							fmt.Printf("Image found ....... %s", img.ID)
							imageID = img.ID
							break
						}
					}

					if imageFound == true {
						break
					}
				}

				//r, w := io.Pipe()

				if imageFound {
					err := client.Logs(docker.LogsOptions{Container: imageID, OutputStream: os.Stdout, Stdout: true, Stderr: true, Timestamps: true})
					if err != nil {

						fmt.Printf("%s", err)

					}
				} else {

					fmt.Printf("Image not found ----------------> %s", name)

				}

			},
		},
	}

	app.Run(os.Args)

}
<commit_msg>DOCKERFILE deployment done with optional enabled<commit_after>package main

import (
	//"encoding/json"
	"bufio"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/fsouza/go-dockerclient"
	"github.com/jmcvetta/restclient"
	"os"
)

func main() {

	/*
		endpoint := "http://104.131.90.110:4243"
		client, _ := docker.NewClient(endpoint)
		imgs, _ := client.ListImages(docker.ListImagesOptions{All: false})
		for _, img := range imgs {
			fmt.Println("ID: ", img.ID)
			fmt.Println("RepoTags: ", img.RepoTags)
			fmt.Println("Created: ", img.Created)
			fmt.Println("Size: ", img.Size)
			fmt.Println("VirtualSize: ", img.VirtualSize)
			fmt.Println("ParentId: ", img.ParentID)
		}*/

	app := cli.NewApp()

	app.Commands = []cli.Command{
		{

			Name:  "attach",
			Usage: "attach docker stdout",

			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "docker",
					Value: "api",
					Usage: "docker image name to connect",
				},
				cli.StringFlag{
					Name:  "protocol",
					Value: "http",
					Usage: "docker remote api protocol to connect",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "127.0.0.1",
					Usage: "docker host ip",
				},
				cli.StringFlag{
					Name:  "port",
					Value: "4243",
					Usage: "docker host port",
				},
				cli.StringFlag{
					Name:  "unixsocket",
					Value: "var/run/docker.sock",
					Usage: "docker unix socket path",
				},
			},

			Action: func(c *cli.Context) {

				name := c.String("docker")
				protocol := c.String("protocol")
				host := c.String("host")
				port := c.String("port")
				socket := c.String("unixsocket")

				//fmt.Printf("Image ----------------> %s", c)

				endpoint := fmt.Sprintf("http://%s:%s", host, port)

				if protocol == "unix" {

					endpoint = fmt.Sprintf("unix:///%s", socket)

				}

				client, _ := docker.NewClient(endpoint)
				imgs, _ := client.ListContainers(docker.ListContainersOptions{All: false})

				imageID := "0"
				imageFound := false

				for _, img := range imgs {
					fmt.Println("ID: ", img.ID)
					fmt.Println("Image: ", img.Image)
					fmt.Println("Command: ", img.Command)
					fmt.Println("Created: ", img.Created)
					fmt.Println("Status: ", img.Status)
					fmt.Println("Names: ", img.Names)

					for _, a := range img.Names {
						if a == name {
							imageFound = true
							fmt.Printf("Image found ....... %s", img.ID)
							imageID = img.ID
							break
						}
					}

					if imageFound == true {
						break
					}
				}

				//r, w := io.Pipe()

				if imageFound {
					err := client.AttachToContainer(docker.AttachToContainerOptions{Container: imageID, OutputStream: os.Stdout, InputStream: os.Stdin, Logs: true, Stream: false, Stdin: true, Stdout: true, Stderr: true, RawTerminal: true})
					if err != nil {

						fmt.Printf("%s", err)

					}
				} else {

					fmt.Printf("Image not found ----------------> %s", name)

				}

			},
		},

		{

			Name:  "install",
			Usage: "install templates in given host",

			Flags: []cli.Flag{

				cli.StringFlag{
					Name:  "protocol",
					Value: "http",
					Usage: "docker remote api protocol to connect",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "127.0.0.1",
					Usage: "docker host ip",
				},
				cli.StringFlag{
					Name:  "port",
					Value: "4243",
					Usage: "docker host port",
				},
				cli.StringFlag{
					Name:  "unixsocket",
					Value: "var/run/docker.sock",
					Usage: "docker unix socket path",
				},
				cli.StringFlag{
					Name:  "template",
					Value: "DBTEMPLATE",
					Usage: "template name to be install",
				},
			},

			Action: func(c *cli.Context) {

				protocol := c.String("protocol")
				host := c.String("host")
				port := c.String("port")
				socket := c.String("unixsocket")
				template := c.String("template")

				fmt.Printf("Image ----------------> %s", c)

				endpoint := fmt.Sprintf("http://%s:%s", host, port)

				if protocol == "unix" {

					endpoint = fmt.Sprintf("unix:///%s", socket)

				}

				client, _ := docker.NewClient(endpoint)
				//client.ListContainers(docker.ListContainersOptions{All: false})

				/////////--------------------------------------------------------------------------------------------->

				type Variable struct {
					Name         string
					Description  string
					DefaultValue string
					Export       bool
					Type         string
				}

				type Template_Image struct {
					Type     string
					Priority int
				}

				type Image struct {
					Name               string
					Description        string
					Version            string
					VersionStatus      string
					SourceUrl          string
					DockerUrl          string
					Class              string
					Type               string
					Cmd                string
					Category           string
					Importance         string
					CSDB_TemplateImage Template_Image
					SystemVariables    []Variable
					Dependants         []Image
				}

				type Template struct {
					Name          string
					Description   string
					Class         string
					Type          string
					Category      string
					CompanyId     int
					TenantId      int
					TemplateImage []Image
				}

				type Result struct {
					Exception     string
					CustomMessage string
					IsSuccess     bool
					Result        []Template
				}

				url := fmt.Sprintf("http://127.0.0.1:9093/DVP/API/1.0/SystemRegistry/TemplateByName/%s", template)

				var s Result

				r := restclient.RequestResponse{
					Url:    url,
					Method: "GET",
					Result: &s,
				}
				status, err := restclient.Do(&r)
				if err != nil {
					//panic(err)
				}
				if status == 200 {

					//json.Unmarshal([]byte(r.RawText), &s)

					fmt.Println("Template Data  -->", r.RawText)

					fmt.Println("Template Data  -->", s)

					if s.IsSuccess == true {

						if s.Result != nil {

							for _, temp := range s.Result {

								for _, img := range temp.TemplateImage {
									fmt.Println(img.CSDB_TemplateImage.Type)
									isInstall := false

									if img.CSDB_TemplateImage.Type == "Mandetory" {
										isInstall = true

									} else if img.CSDB_TemplateImage.Type == "Optional" {

										fmt.Printf("%s This Service is optional do you want to install it?", img.Name)

										reader := bufio.NewReader(os.Stdin)
										text, _ := reader.ReadString('y')
										fmt.Println(text)

										if text == "y" {

											isInstall = true
											fmt.Printf("Install is true")

										} else {
											fmt.Printf("Install is false")
										}

									}

									if isInstall {
										fmt.Println(img.Class)
										if img.Class == "DOCKER" {

											fmt.Println(img.DockerUrl)

											pullImage := docker.PullImageOptions{Repository: img.DockerUrl, Tag: "latest"}
											authConf := docker.AuthConfiguration{}
											erry := client.PullImage(pullImage, authConf)
											fmt.Printf("pull --->", erry)
											if erry == nil {

												container := docker.CreateContainerOptions{}
												container.Name = img.Name
												//img.Cmd = "postgres"
												cmd := []string{img.Cmd}

												/*
													a := []int{1,2,3}
													a = append(a, 4)
													fmt.Println(a)

												*/

												Var := []string{}

												for _, vars := range img.SystemVariables {

													Var = append(Var, fmt.Sprintf("%s=%s", vars.Name, vars.DefaultValue))

												}

												container.Config = &docker.Config{Image: img.DockerUrl, Cmd: cmd, Env: Var}

												fmt.Println(container.Config.Image)

												_, errx := client.CreateContainer(container)

												fmt.Printf("Container --->", errx)

												if errx == nil {

													//fmt.Printf("Container ---> ", cont)

													hostConfig := &docker.HostConfig{}

													errz := client.StartContainer(img.Name, hostConfig)
													fmt.Printf("Container --->", errz)
												}
											}

										} else if img.Class == "DOCKERFILE" {

											buildOption := docker.BuildImageOptions{Name: img.Name, Dockerfile: "Dockerfile", SuppressOutput: true, OutputStream: os.Stdout, Remote: img.SourceUrl}

											erry := client.BuildImage(buildOption)
											fmt.Printf("BuildContainer --->", err)

											if erry == nil {

												container := docker.CreateContainerOptions{}
												container.Name = img.Name
												//img.Cmd = "postgres"
												cmd := []string{img.Cmd}

												/*
													a := []int{1,2,3}
													a = append(a, 4)
													fmt.Println(a)

												*/

												Var := []string{}

												for _, vars := range img.SystemVariables {

													Var = append(Var, fmt.Sprintf("%s=%s", vars.Name, vars.DefaultValue))

												}

												container.Config = &docker.Config{Image: img.DockerUrl, Cmd: cmd, Env: Var}

												fmt.Println(container.Config.Image)

												_, errx := client.CreateContainer(container)

												fmt.Printf("Container --->", errx)

												if errx == nil {

													//fmt.Printf("Container ---> ", cont)

													hostConfig := &docker.HostConfig{}

													errz := client.StartContainer(img.Name, hostConfig)
													fmt.Printf("Container --->", errz)
												}
											}
										}

									}

								}

							}

						}
					}

				}

			},
		},

		{

			Name:  "list",
			Usage: "list dockers in given host",

			Flags: []cli.Flag{

				cli.StringFlag{
					Name:  "protocol",
					Value: "http",
					Usage: "docker remote api protocol to connect",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "127.0.0.1",
					Usage: "docker host ip",
				},
				cli.StringFlag{
					Name:  "port",
					Value: "4243",
					Usage: "docker host port",
				},
				cli.StringFlag{
					Name:  "unixsocket",
					Value: "var/run/docker.sock",
					Usage: "docker unix socket path",
				},
			},

			Action: func(c *cli.Context) {

				protocol := c.String("protocol")
				host := c.String("host")
				port := c.String("port")
				socket := c.String("unixsocket")

				//fmt.Printf("Image ----------------> %s", c)

				endpoint := fmt.Sprintf("http://%s:%s", host, port)

				if protocol == "unix" {

					endpoint = fmt.Sprintf("unix:///%s", socket)

				}

				client, _ := docker.NewClient(endpoint)
				imgs, _ := client.ListContainers(docker.ListContainersOptions{All: false})

				for _, img := range imgs {
					fmt.Println("ID: ", img.ID)
					fmt.Println("Image: ", img.Image)
					fmt.Println("Command: ", img.Command)
					fmt.Println("Created: ", img.Created)
					fmt.Println("Status: ", img.Status)
					fmt.Println("Names: ", img.Names)

				}

			},
		},

		{

			Name:  "log",
			Usage: "get docker logs through stdout and stderr",

			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "docker",
					Value: "api",
					Usage: "docker image name to connect",
				},
				cli.StringFlag{
					Name:  "protocol",
					Value: "http",
					Usage: "docker remote api protocol to connect",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "127.0.0.1",
					Usage: "docker host ip",
				},
				cli.StringFlag{
					Name:  "port",
					Value: "4243",
					Usage: "docker host port",
				},
				cli.StringFlag{
					Name:  "unixsocket",
					Value: "var/run/docker.sock",
					Usage: "docker unix socket path",
				},
			},

			Action: func(c *cli.Context) {

				name := c.String("docker")
				protocol := c.String("protocol")
				host := c.String("host")
				port := c.String("port")
				socket := c.String("unixsocket")

				//fmt.Printf("Image ----------------> %s", c)

				endpoint := fmt.Sprintf("http://%s:%s", host, port)

				if protocol == "unix" {

					endpoint = fmt.Sprintf("unix:///%s", socket)

				}

				client, _ := docker.NewClient(endpoint)
				imgs, _ := client.ListContainers(docker.ListContainersOptions{All: false})

				imageID := "0"
				imageFound := false

				for _, img := range imgs {
					fmt.Println("ID: ", img.ID)
					fmt.Println("Image: ", img.Image)
					fmt.Println("Command: ", img.Command)
					fmt.Println("Created: ", img.Created)
					fmt.Println("Status: ", img.Status)
					fmt.Println("Names: ", img.Names)

					for _, a := range img.Names {
						if a == name {
							imageFound = true
							fmt.Printf("Image found ....... %s", img.ID)
							imageID = img.ID
							break
						}
					}

					if imageFound == true {
						break
					}
				}

				//r, w := io.Pipe()

				if imageFound {
					err := client.Logs(docker.LogsOptions{Container: imageID, OutputStream: os.Stdout, Stdout: true, Stderr: true, Timestamps: true})
					if err != nil {

						fmt.Printf("%s", err)

					}
				} else {

					fmt.Printf("Image not found ----------------> %s", name)

				}

			},
		},
	}

	app.Run(os.Args)

}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"
	"net"
)

func main() {

	port := flag.Int("port", 8888, "specify port to listen on")
	flag.Parse()

	log.Println("Listening on", *port)
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
	if err != nil {
		log.Fatalf("Could not listen for connections: %v\n", err)
	}

	connCounter := 0

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Printf("Could not accept connection: %v\n", err)
		}
		go handle(conn, connCounter)
		connCounter++
	}
}

func handle(conn net.Conn, connId int) {
	s := socksConn{connId: connId, conn: conn}
	if err := s.handle(); err != nil {
		log.Printf("Error handling connection %d: %v\n", connId, err)
	}
}

type socksConn struct {
	connId int
	conn   net.Conn
	sConn  net.Conn
}

const (
	VERSION_5             = 0x05
	NO_AUTH_REQUIRED      = 0x00
	NO_ACCEPTABLE_METHODS = 0xFF
	CONNECT               = 0x01
	BIND                  = 0x02
	UDP_ASSOCIATE         = 0x03
	RESERVED              = 0x00
	ATYP_IP_V4            = 0x01
	ATYP_DOMAINNAME       = 0x03
	ATYP_IP_V6            = 0x04
)

var (
	validCmds   = []byte{CONNECT, BIND, UDP_ASSOCIATE}
	validAtypes = []byte{ATYP_IP_V4, ATYP_DOMAINNAME, ATYP_IP_V6}
)

type atypdef struct {
	raw   []byte
	proto string
	addr  string
}

func (s *socksConn) handle() error {
	defer s.conn.Close()

	header, err := s.read(2)
	if err != nil {
		return err
	}

	// SOCKS version
	if header[0] != VERSION_5 {
		return fmt.Errorf("header: VER expected %x got %x", VERSION_5, header[0])
	}
	// NMETHODS
	if header[1] == 0 {
		return fmt.Errorf("header: NMETHODS zero")
	}

	// METHOD
	methods, err := s.read(int(header[1]))
	if err != nil {
		return err
	}

	if !hasNoAuthMethod(methods) {
		if err = s.write(VERSION_5, NO_ACCEPTABLE_METHODS); err != nil {
			return err
		}
		//TODO: reutrn nil instead since this is not a "real" errer/valid behaviour?
		return fmt.Errorf("header: METHODS must contain %x (NO AUTH REQUIRED): % x", NO_AUTH_REQUIRED, methods)
	}

	// send NO_AUTH_REQUIRED response
	if err := s.write(VERSION_5, NO_AUTH_REQUIRED); err != nil {
		return err
	}

	request, err := s.read(4)
	if err != nil {
		return err
	}

	if request[0] != VERSION_5 {
		return fmt.Errorf("connect: VER expected %x got %x", VERSION_5, request[0])
	}

	cmd := request[1]
	if bytes.IndexByte(validCmds, cmd) < 0 {
		return fmt.Errorf("connect: CMD expected do be one of (% x) got %x", validCmds, cmd)
	}

	if request[2] != RESERVED {
		return fmt.Errorf("connect: RSV expected %x got %x", RESERVED, request[2])
	}

	atyp := request[3]
	var atypfunc func(s *socksConn) (*atypdef, error)
	switch atyp {
	case ATYP_IP_V4:
		atypfunc = atypIp4
	case ATYP_DOMAINNAME:
		atypfunc = atypDomainname
	case ATYP_IP_V6:
		atypfunc = atypIp6
	default:
		return fmt.Errorf("connect: ATYP expected do be one of (% x) got %x", validAtypes, atyp)
	}

	def, err := atypfunc(s)
	if err != nil {
		return err
	}

	destPort := 80
	sConn, err := net.Dial(def.proto, fmt.Sprintf("%s:%d", def.addr, destPort))
	if err != nil {
		return fmt.Errorf("could not connect do destionation host: %v", err)
	}
	s.sConn = sConn

	return nil
}

func atypIp4(s *socksConn) (*atypdef, error) {
	return nil, nil
}
func atypIp6(s *socksConn) (*atypdef, error) {
	return nil, nil
}
func atypDomainname(s *socksConn) (*atypdef, error) {
	return nil, nil
}

func hasNoAuthMethod(methods []byte) bool {
	for _, m := range methods {
		if m == NO_AUTH_REQUIRED {
			return true
		}
	}
	return false
}

func (s *socksConn) write(data ...byte) error {
	n, err := s.conn.Write(data)
	if n < len(data) || err != nil {
		return fmt.Errorf("could not write to connection: %v", err)
	}
	return nil
}

func (s *socksConn) read(len int) ([]byte, error) {
	buf := make([]byte, len)
	n, err := s.conn.Read(buf)
	if n != len || err != nil {
		return nil, fmt.Errorf("could not read from connection %d: %v", s.connId, err)
	}
	return buf, nil
}
<commit_msg>ipv4 connection<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"
	"net"
)

func main() {

	port := flag.Int("port", 8888, "specify port to listen on")
	flag.Parse()

	log.Println("Listening on", *port)
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
	if err != nil {
		log.Fatalf("Could not listen for connections: %v\n", err)
	}

	connCounter := 0

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Printf("Could not accept connection: %v\n", err)
		}
		go handle(conn, connCounter)
		connCounter++
	}
}

func handle(conn net.Conn, connId int) {
	s := socksConn{connId: connId, conn: conn}
	if err := s.handle(); err != nil {
		log.Printf("Error handling connection %d: %v\n", connId, err)
	}
}

type socksConn struct {
	connId int
	conn   net.Conn
	sConn  net.Conn
}

const (
	VERSION_5             = 0x05
	NO_AUTH_REQUIRED      = 0x00
	NO_ACCEPTABLE_METHODS = 0xFF
	CONNECT               = 0x01
	BIND                  = 0x02
	UDP_ASSOCIATE         = 0x03
	RESERVED              = 0x00
	ATYP_IP_V4            = 0x01
	ATYP_DOMAINNAME       = 0x03
	ATYP_IP_V6            = 0x04
)

var (
	validCmds   = []byte{CONNECT, BIND, UDP_ASSOCIATE}
	validAtypes = []byte{ATYP_IP_V4, ATYP_DOMAINNAME, ATYP_IP_V6}
)

type atypdef struct {
	raw   []byte
	proto string
	addr  string
}

func (s *socksConn) handle() error {
	defer s.conn.Close()

	header, err := s.read(2)
	if err != nil {
		return err
	}

	// SOCKS version
	if header[0] != VERSION_5 {
		return fmt.Errorf("header: VER expected %x got %x", VERSION_5, header[0])
	}
	// NMETHODS
	if header[1] == 0 {
		return fmt.Errorf("header: NMETHODS zero")
	}

	// METHOD
	methods, err := s.read(int(header[1]))
	if err != nil {
		return err
	}

	if !hasNoAuthMethod(methods) {
		if err = s.write(VERSION_5, NO_ACCEPTABLE_METHODS); err != nil {
			return err
		}
		//TODO: reutrn nil instead since this is not a "real" errer/valid behaviour?
		return fmt.Errorf("header: METHODS must contain %x (NO AUTH REQUIRED): % x", NO_AUTH_REQUIRED, methods)
	}

	// send NO_AUTH_REQUIRED response
	if err := s.write(VERSION_5, NO_AUTH_REQUIRED); err != nil {
		return err
	}

	request, err := s.read(4)
	if err != nil {
		return err
	}

	if request[0] != VERSION_5 {
		return fmt.Errorf("connect: VER expected %x got %x", VERSION_5, request[0])
	}

	cmd := request[1]
	if bytes.IndexByte(validCmds, cmd) < 0 {
		return fmt.Errorf("connect: CMD expected do be one of (% x) got %x", validCmds, cmd)
	}

	if request[2] != RESERVED {
		return fmt.Errorf("connect: RSV expected %x got %x", RESERVED, request[2])
	}

	atyp := request[3]
	var atypfunc func(s *socksConn) (*atypdef, error)
	switch atyp {
	case ATYP_IP_V4:
		atypfunc = atypIp4
	case ATYP_DOMAINNAME:
		atypfunc = atypDomainname
	case ATYP_IP_V6:
		atypfunc = atypIp6
	default:
		return fmt.Errorf("connect: ATYP expected do be one of (% x) got %x", validAtypes, atyp)
	}

	def, err := atypfunc(s)
	if err != nil {
		return err
	}

	destPort := 80
	sConn, err := net.Dial(def.proto, fmt.Sprintf("%s:%d", def.addr, destPort))
	if err != nil {
		return fmt.Errorf("could not connect do destionation host: %v", err)
	}
	s.sConn = sConn

	return nil
}

func atypIp4(s *socksConn) (*atypdef, error) {
	bytes, err := s.read(4)
	if err != nil {
		return nil, err}
	def := atypdef{proto: "tcp4", addr: IP(bytes).String() }
	return def, nil
}
func atypIp6(s *socksConn) (*atypdef, error) {
	return nil, nil
}
func atypDomainname(s *socksConn) (*atypdef, error) {
	return nil, nil
}

func hasNoAuthMethod(methods []byte) bool {
	for _, m := range methods {
		if m == NO_AUTH_REQUIRED {
			return true
		}
	}
	return false
}

func (s *socksConn) write(data ...byte) error {
	n, err := s.conn.Write(data)
	if n < len(data) || err != nil {
		return fmt.Errorf("could not write to connection: %v", err)
	}
	return nil
}

func (s *socksConn) read(len int) ([]byte, error) {
	buf := make([]byte, len)
	n, err := s.conn.Read(buf)
	if n != len || err != nil {
		return nil, fmt.Errorf("could not read from connection %d: %v", s.connId, err)
	}
	return buf, nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

type PostCache struct {
	Url   string
	Items map[string]*item
}

var postCache = PostCache{Items: map[string]*item{}}

const DEFAULT_FOLDER = "<from title>"
const HOST_HACKER_NEWS = "news.ycombinator.com"

var Verbose *bool
var Quiet *bool

func main() {
	cacheFile := flag.String("readfrom", "", "Read posts from a json file instead of querying firebase (mainly used for testing)")
	dump := flag.Bool("dump", false, "Fetch the given url only and dump the response. Do not fetch its children")
	folder := flag.String("o", DEFAULT_FOLDER, "Save mails into the given directory instead of the default one")
	Verbose = flag.Bool("v", false, "Verbose")
	Quiet = flag.Bool("q", false, "Be quiet")
	flag.Parse()
	if *Quiet {
		*Verbose = false
	}

	var arg string
	if *cacheFile != "" {
		if fileExists(*cacheFile) {
			readCacheFile(*cacheFile)
		} else {
			bail("readfrom: file %s does not exist", *cacheFile)
		}
		arg = postCache.Url
	} else {
		if flag.NArg() != 1 {
			printError("Usage: fetchpost <url|dir>")
			os.Exit(1)
		}
		arg = flag.Arg(0)
	}

	var url string
	if strings.HasPrefix(arg, "https://") {
		url = arg
		postCache.Url = url
	} else {
		dir, file := filepath.Split(filepath.Clean(arg))
		if dir != "" {
			err := os.Chdir(dir)
			if err != nil {
				bail(err.Error())
			}
		}
		arg = file
		url = readUrlFile(arg)
		if strings.HasPrefix(url, "https://") {
			postCache.Url = url
		}
	}

	/**
	1. Get post
	2. If mail for post doesn't exist:
		2.1 write mail in maildir
	3. else if post body or title changed:
		3.1 Update subject or body and mark mail as new
	4. Repeat from step 1 for each kid in post.
	*/
	post := mustGetPost(url)
	if *dump {
		buf, err := json.Marshal(post)
		if err != nil {
			bail("dump: %v", err)
		}
		fmt.Printf("%s\n", string(buf))
		os.Exit(0)
	}

	added, updated, deleted := saveComments(post, arg, url, *folder)
	if !*Quiet {
		fmt.Printf("Comments: %d added, %d updated, %d deleted\n",
			added, updated, deleted)
	}

	postDir := getPostDir(post)
	fmt.Println(postDir)
	postTestFile := filepath.Join(postDir, postDir+".json")
	buf, err := json.Marshal(postCache)
	if err != nil {
		printError("Marshal postCache: %v", err)
	}
	err = ioutil.WriteFile(postTestFile, append(buf, '\n'), 0644)
	if err != nil {
		printError("Write postCache: %v", err)
	}
}

func saveComments(post Post, arg, url string, folder string) (added, updated, deleted int) {
	dir := getPostDir(post)
	if folder == DEFAULT_FOLDER && arg != url && arg != dir {
		renamePostDir(arg, dir)
	}

	mails, err := NewMails(dir)
	if err != nil {
		bail("saveComments(): error: %v", err)
	}
	maybeSavePostUrl(dir, url)
	maybeReportScoreChange(mails, post)
	return mails.SavePost(nil, post, 0)
}

func maybeReportScoreChange(mails *Mails, post Post) {
	mid := post.MessageId()
	key, exist := mails.keyForMessageId[mid]
	if !exist {
		return
	}

	msg := mails.mustGetMessage(key)
	score, exist := msg.Header["X-Score"]
	if !exist || len(score[0]) == 0 {
		printError("X-Score header missing in %s", key)
		return
	}
	oldScore, err := strconv.Atoi(score[0])
	if err != nil {
		printError("X-Score: %v", err)
		return
	}
	newScore := post.Points()

	if oldScore != newScore {
		fmt.Printf("Points changed from %d to %d\n", oldScore, newScore)
	}
}

func renamePostDir(olddir, newdir string) {
	if fileExists(newdir) {
		bail("renamePostDir(): post title changed but directory for new title"+
			" already exist\n\told title: %s\n\tnew title: %s",
			olddir, newdir)
	}
	err := os.Rename(olddir, newdir)
	if err != nil {
		bail("renamePostDir(): Rename: %v", err)
	}
	printNotice("post title has changed:\n\told: %s\n\tnew: %s", olddir, newdir)

}

func readCacheFile(f string) {
	buf, err := ioutil.ReadFile(f)
	if err != nil {
		bail("Read %s: %v", f, err)
	}
	err = json.Unmarshal(buf, &postCache)
	if err != nil {
		bail("Unmarshal %s: %v", f, err)
	}
}

func fileExists(path string) bool {
	_, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			return false
		} else {
			bail("fileExists: %s: %v", path, err)
		}
	}
	return true
}

func (mails *Mails) SavePost(parent, child Post, threadLevel int) (added, updated, deleted int) {
	mid := child.MessageId()
	key, exist := mails.keyForMessageId[mid]
	if exist {
		msg, err := mails.md.Message(key)
		if err != nil {
			bail("SavePost(): Error getting mail for key %s: %v", key, err)
		}

		path, err := mails.md.Filename(key)
		if err != nil {
			bail("SavePost(): could not get Filename for key %s", key)
		}
		contentChanged := updateMail(parent, child, path, msg)
		if contentChanged {
			p := strings.Replace(path, "/cur/", "/new/", 1)
			if path != p {
				err = os.Rename(path, p)
				if err != nil {
					bail("SavePost(): Rename(%s, %s): %v", path, p, err)
				}
				verbose("Renamed %s to %s", path, p)
			}
			if child.Removed() {
				deleted++
			} else {
				updated++
			}
		}
		showThreadLevel(threadLevel, "*")
	} else {
		mail := NewMail(parent, child)
		err := mails.SaveMail(mail)
		if err != nil {
			bail("SavePost(): %v", err)
		}
		showThreadLevel(threadLevel, "+")
		added++
	}

	n, u, d := mails.SavePostChildren(child, threadLevel+1)
	added += n
	updated += u
	deleted += d
	return
}

func (mails *Mails) SavePostChildren(p Post, threadLevel int) (added, updated, deleted int) {
	for _, idStr := range p.Children() {
		child, err := fetchHNPost(idStr)
		if err != nil {
			printError("error: %v", err)
			continue
		}
		if child == nil {
			printError("WARN p.Children(%s) gave nil child (could be temporary error). Parent: %+v", idStr, p)
			continue
		}
		a, u, d := mails.SavePost(p, child, threadLevel)
		added += a
		updated += u
		deleted += d
	}
	return
}

func showThreadLevel(level int, symbol string) {
	for i := 0; i < level; i++ {
		fmt.Print(" ")
	}
	fmt.Println(symbol)
}

func maybeSavePostUrl(dir, url string) {
	if !fileExists(dir) {
		os.Mkdir(dir, 0755)
	}
	f := filepath.Join(dir, "url.txt")
	if fileExists(f) {
		return
	}
	err := ioutil.WriteFile(f, []byte(url), 0644)
	if err != nil {
		bail("%s: %v", f, err)
	}
}

func mustGetPost(href string) Post {
	url, err := url.Parse(href)
	if err != nil {
		bail("bad url: %s", err)
	}

	switch strings.ToLower(url.Host) {
	case HOST_HACKER_NEWS:
		return GetHNPost(url)
	default:
		bail("Unsupported url: %s", url.Host)
	}
	return nil
}

func bail(format string, args ...interface{}) {
	printError(format, args...)
	os.Exit(1)
}

func readUrlFile(arg string) string {
	urlFile := filepath.Join(arg, "url.txt")
	buf, err := ioutil.ReadFile(urlFile)
	if err != nil {
		bail("readUrlFile: error: %v", err)
	}
	return string(buf)
}

func verbose(format string, args ...interface{}) {
	if !*Verbose {
		return
	}
	fmt.Fprintf(os.Stderr, format+"\n", args...)
}

func printError(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format+"\n", args...)
}

func printNotice(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "notice:"+format+"\n", args...)
}
<commit_msg>Print post title at beginning as well as at the end<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

type PostCache struct {
	Url   string
	Items map[string]*item
}

var postCache = PostCache{Items: map[string]*item{}}

const DEFAULT_FOLDER = "<from title>"
const HOST_HACKER_NEWS = "news.ycombinator.com"

var Verbose *bool
var Quiet *bool

func main() {
	cacheFile := flag.String("readfrom", "", "Read posts from a json file instead of querying firebase (mainly used for testing)")
	dump := flag.Bool("dump", false, "Fetch the given url only and dump the response. Do not fetch its children")
	folder := flag.String("o", DEFAULT_FOLDER, "Save mails into the given directory instead of the default one")
	Verbose = flag.Bool("v", false, "Verbose")
	Quiet = flag.Bool("q", false, "Be quiet")
	flag.Parse()
	if *Quiet {
		*Verbose = false
	}

	var arg string
	if *cacheFile != "" {
		if fileExists(*cacheFile) {
			readCacheFile(*cacheFile)
		} else {
			bail("readfrom: file %s does not exist", *cacheFile)
		}
		arg = postCache.Url
	} else {
		if flag.NArg() != 1 {
			printError("Usage: fetchpost <url|dir>")
			os.Exit(1)
		}
		arg = flag.Arg(0)
	}

	var url string
	if strings.HasPrefix(arg, "https://") {
		url = arg
		postCache.Url = url
	} else {
		dir, file := filepath.Split(filepath.Clean(arg))
		if dir != "" {
			err := os.Chdir(dir)
			if err != nil {
				bail(err.Error())
			}
		}
		arg = file
		url = readUrlFile(arg)
		if strings.HasPrefix(url, "https://") {
			postCache.Url = url
		}
	}

	/**
	1. Get post
	2. If mail for post doesn't exist:
		2.1 write mail in maildir
	3. else if post body or title changed:
		3.1 Update subject or body and mark mail as new
	4. Repeat from step 1 for each kid in post.
	*/
	post := mustGetPost(url)
	if *dump {
		buf, err := json.Marshal(post)
		if err != nil {
			bail("dump: %v", err)
		}
		fmt.Printf("%s\n", string(buf))
		os.Exit(0)
	}
	postDir := getPostDir(post)
	fmt.Println(postDir)

	added, updated, deleted := saveComments(post, arg, url, *folder)
	if !*Quiet {
		fmt.Printf("Comments: %d added, %d updated, %d deleted\n",
			added, updated, deleted)
	}

	fmt.Println(postDir)
	postTestFile := filepath.Join(postDir, postDir+".json")
	buf, err := json.Marshal(postCache)
	if err != nil {
		printError("Marshal postCache: %v", err)
	}
	err = ioutil.WriteFile(postTestFile, append(buf, '\n'), 0644)
	if err != nil {
		printError("Write postCache: %v", err)
	}
}

func saveComments(post Post, arg, url string, folder string) (added, updated, deleted int) {
	dir := getPostDir(post)
	if folder == DEFAULT_FOLDER && arg != url && arg != dir {
		renamePostDir(arg, dir)
	}

	mails, err := NewMails(dir)
	if err != nil {
		bail("saveComments(): error: %v", err)
	}
	maybeSavePostUrl(dir, url)
	maybeReportScoreChange(mails, post)
	return mails.SavePost(nil, post, 0)
}

func maybeReportScoreChange(mails *Mails, post Post) {
	mid := post.MessageId()
	key, exist := mails.keyForMessageId[mid]
	if !exist {
		return
	}

	msg := mails.mustGetMessage(key)
	score, exist := msg.Header["X-Score"]
	if !exist || len(score[0]) == 0 {
		printError("X-Score header missing in %s", key)
		return
	}
	oldScore, err := strconv.Atoi(score[0])
	if err != nil {
		printError("X-Score: %v", err)
		return
	}
	newScore := post.Points()

	if oldScore != newScore {
		fmt.Printf("Points changed from %d to %d\n", oldScore, newScore)
	}
}

func renamePostDir(olddir, newdir string) {
	if fileExists(newdir) {
		bail("renamePostDir(): post title changed but directory for new title"+
			" already exist\n\told title: %s\n\tnew title: %s",
			olddir, newdir)
	}
	err := os.Rename(olddir, newdir)
	if err != nil {
		bail("renamePostDir(): Rename: %v", err)
	}
	printNotice("post title has changed:\n\told: %s\n\tnew: %s", olddir, newdir)

}

func readCacheFile(f string) {
	buf, err := ioutil.ReadFile(f)
	if err != nil {
		bail("Read %s: %v", f, err)
	}
	err = json.Unmarshal(buf, &postCache)
	if err != nil {
		bail("Unmarshal %s: %v", f, err)
	}
}

func fileExists(path string) bool {
	_, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			return false
		} else {
			bail("fileExists: %s: %v", path, err)
		}
	}
	return true
}

func (mails *Mails) SavePost(parent, child Post, threadLevel int) (added, updated, deleted int) {
	mid := child.MessageId()
	key, exist := mails.keyForMessageId[mid]
	if exist {
		msg, err := mails.md.Message(key)
		if err != nil {
			bail("SavePost(): Error getting mail for key %s: %v", key, err)
		}

		path, err := mails.md.Filename(key)
		if err != nil {
			bail("SavePost(): could not get Filename for key %s", key)
		}
		contentChanged := updateMail(parent, child, path, msg)
		if contentChanged {
			p := strings.Replace(path, "/cur/", "/new/", 1)
			if path != p {
				err = os.Rename(path, p)
				if err != nil {
					bail("SavePost(): Rename(%s, %s): %v", path, p, err)
				}
				verbose("Renamed %s to %s", path, p)
			}
			if child.Removed() {
				deleted++
			} else {
				updated++
			}
		}
		showThreadLevel(threadLevel, "*")
	} else {
		mail := NewMail(parent, child)
		err := mails.SaveMail(mail)
		if err != nil {
			bail("SavePost(): %v", err)
		}
		showThreadLevel(threadLevel, "+")
		added++
	}

	n, u, d := mails.SavePostChildren(child, threadLevel+1)
	added += n
	updated += u
	deleted += d
	return
}

func (mails *Mails) SavePostChildren(p Post, threadLevel int) (added, updated, deleted int) {
	for _, idStr := range p.Children() {
		child, err := fetchHNPost(idStr)
		if err != nil {
			printError("error: %v", err)
			continue
		}
		if child == nil {
			printError("WARN p.Children(%s) gave nil child (could be temporary error). Parent: %+v", idStr, p)
			continue
		}
		a, u, d := mails.SavePost(p, child, threadLevel)
		added += a
		updated += u
		deleted += d
	}
	return
}

func showThreadLevel(level int, symbol string) {
	for i := 0; i < level; i++ {
		fmt.Print(" ")
	}
	fmt.Println(symbol)
}

func maybeSavePostUrl(dir, url string) {
	if !fileExists(dir) {
		os.Mkdir(dir, 0755)
	}
	f := filepath.Join(dir, "url.txt")
	if fileExists(f) {
		return
	}
	err := ioutil.WriteFile(f, []byte(url), 0644)
	if err != nil {
		bail("%s: %v", f, err)
	}
}

func mustGetPost(href string) Post {
	url, err := url.Parse(href)
	if err != nil {
		bail("bad url: %s", err)
	}

	switch strings.ToLower(url.Host) {
	case HOST_HACKER_NEWS:
		return GetHNPost(url)
	default:
		bail("Unsupported url: %s", url.Host)
	}
	return nil
}

func bail(format string, args ...interface{}) {
	printError(format, args...)
	os.Exit(1)
}

func readUrlFile(arg string) string {
	urlFile := filepath.Join(arg, "url.txt")
	buf, err := ioutil.ReadFile(urlFile)
	if err != nil {
		bail("readUrlFile: error: %v", err)
	}
	return string(buf)
}

func verbose(format string, args ...interface{}) {
	if !*Verbose {
		return
	}
	fmt.Fprintf(os.Stderr, format+"\n", args...)
}

func printError(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format+"\n", args...)
}

func printNotice(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "notice:"+format+"\n", args...)
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	"github.com/gorilla/mux"
	_ "github.com/mattn/go-sqlite3"
)

const (
	ADDRESS = "http://localhost:9900"
	LENGTH  = 6
	TEXT    = "$ <command> | curl -F 'p=<-' " + ADDRESS + "\n"
	PORT    = ":9900"
)

type Response struct {
	ID     string `json:"id"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("sqlite3", "./database.db")
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste []byte) string {
	hasher := sha1.New()
	hasher.Write(paste)
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw []byte) []string {
	p := raw[86 : len(raw)-46]

	db, err := sql.Open("sqlite3", "./database.db")
	check(err)

	sha := hash(p)
	id := generateName()
	url := ADDRESS + "/p/" + id
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(string(p))

	stmt, err := db.Prepare("INSERT INTO pastebin(id, hash, data, delkey) values(?,?,?,?)")
	check(err)
	_, err = stmt.Exec(id, sha, paste, delKey)
	check(err)
	db.Close()
	return []string{id, sha, url, paste, delKey}

}

func delHandler(w http.ResponseWriter, r *http.Request) {
}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		buf, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, err.Error(), 500)
		}

		values := save(buf)
		b := &Response{
			ID:     values[0],
			HASH:   values[1],
			URL:    values[2],
			SIZE:   len(values[3]),
			DELKEY: values[4],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		default:
			io.WriteString(w, values[2]+"\n")
		}
	}

}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, TEXT)
}
func langHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s := getPaste(paste)
	highlight := pygments.Highlight(html.UnescapeString(s), lang, "html", "full, style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,", "utf-8")
	io.WriteString(w, highlight)

}

func getPaste(paste string) string {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("sqlite3", "./database.db")
	var s string
	err = db.QueryRow("select data from pastebin where id=?", param1).Scan(&s)
	db.Close()
	check(err)

	if err == sql.ErrNoRows {
		return "Error invalid paste"
	} else {
		return html.UnescapeString(s)
	}

}
func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s := getPaste(paste)
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", rootHandler)
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", langHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<commit_msg>Replace sqlite with mysql<commit_after>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"log"
	"net/http"

	"database/sql"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	TEXT     = "$ <command> | curl -F 'p=<-' " + ADDRESS + "\n"
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste []byte) string {
	hasher := sha1.New()
	hasher.Write(paste)
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw []byte) []string {
	p := raw[86 : len(raw)-46]

	db, err := sql.Open("sqlite3", "./database.db")
	check(err)

	sha := hash(p)
	id := generateName()
	url := ADDRESS + "/p/" + id
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(string(p))

	stmt, err := db.Prepare("INSERT INTO pastebin(id, hash, data, delkey) values(?,?,?,?)")
	check(err)
	_, err = stmt.Exec(id, sha, paste, delKey)
	check(err)
	db.Close()
	return []string{id, sha, url, paste, delKey}

}

func delHandler(w http.ResponseWriter, r *http.Request) {
}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		buf, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, err.Error(), 500)
		}

		values := save(buf)
		b := &Response{
			ID:     values[0],
			HASH:   values[1],
			URL:    values[2],
			SIZE:   len(values[3]),
			DELKEY: values[4],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		default:
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, TEXT)
}
func langHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s := getPaste(paste)
	highlight := pygments.Highlight(html.UnescapeString(s), lang, "html", "full, style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,", "utf-8")
	io.WriteString(w, highlight)

}

func getPaste(paste string) string {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("sqlite3", "./database.db")
	var s string
	err = db.QueryRow("select data from pastebin where id=?", param1).Scan(&s)
	db.Close()
	check(err)

	if err == sql.ErrNoRows {
		return "Error invalid paste"
	} else {
		return html.UnescapeString(s)
	}

}
func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s := getPaste(paste)
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", rootHandler)
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", langHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"path/filepath"
	"strings"

	adrianConfig "github.com/daveross/adrian/config"
	adrianFonts "github.com/daveross/adrian/fonts"
	adrianServer "github.com/daveross/adrian/server"

	"github.com/labstack/echo"
)

func main() {

	log.Println("Starting Adrian 2.0")
	log.Println("Loading adrian.yaml")
	config := adrianConfig.LoadConfig("./adrian.yaml")
	log.Println("Initializing web server")
	e := adrianServer.Instantiate(config)
	log.Println("Loading fonts and starting watchers")
	for _, folder := range config.Global.Directories {
		adrianFonts.FindFonts(folder, config)
		adrianFonts.InstantiateWatcher(folder, config)
	}
	log.Println("Defining paths")

	e.GET("/css/", func(c echo.Context) error {
		c.Response().Header().Set(echo.HeaderContentType, "text/css")
		fontFilenames := strings.Split(c.QueryParam("family"), "|")
		var fontsCSS string
		for _, fontFilename := range fontFilenames {
			fontData, err := adrianFonts.GetFont(fontFilename)
			if err != nil {
				return adrianServer.Return404(c)
			}
			fontsCSS = fontsCSS + "\n" + fontData.CSS

			pusher, ok := c.Response().Writer.(http.Pusher)
			if ok {
				// Attempt HTTP/2 Server Push with native support
				if err = pusher.Push(fmt.Sprintf("/font/%s.%s", fontData.UniqueID, fontData.Type), nil); err != nil {
					log.Fatal("Could not http/2 server push " + fontData.UniqueID + " " + fontData.Type)
				}
				log.Println("Pushing font " + fontData.UniqueID + " " + fontData.Type)
			} else {
				// Send a Link: header in case an upstream web server supports HTTP/2 server push
				c.Response().Header().Set("Link", fmt.Sprintf("/font/%s.%s>; rel=preload; as=font", fontData.UniqueID, fontData.Type))
			}
		}
		return c.String(http.StatusOK, fontsCSS)
	})

	e.GET("/font/:filename", func(c echo.Context) error {
		switch filepath.Ext(c.Param("filename")) {
		case ".ttf":
			return outputFont(c, "font/ttf")
		case ".woff":
			return outputFont(c, "font/woff")
		case ".woff2":
			return outputFont(c, "font/woff2")
		case ".otf":
			return outputFont(c, "font/otf")
		}

		return adrianServer.Return404(c)

	})

	log.Printf("Listening on port %d", config.Global.Port)
	e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", config.Global.Port)))
}

// Basename gets the base filename (minus the last extension)
func basename(s string) string {
	n := strings.LastIndexByte(s, '.')
	if n >= 0 {
		return s[:n]
	}
	return s
}

func outputFont(c echo.Context, mimeType string) error {
	fontData, err := adrianFonts.GetFontByUniqueID(basename(c.Param("filename")))
	if err != nil {
		return adrianServer.Return404(c)
	}
	fontBinary, err := ioutil.ReadFile(fontData.Path) // just pass the file name
	if err != nil {
		log.Fatal("Can't read font file " + fontData.FileName)
	}
	return c.Blob(http.StatusOK, mimeType, fontBinary)

}
<commit_msg>Remove HTTP/2 Server Push Useless with multiple font formats per CSS file<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"path/filepath"
	"strings"

	adrianConfig "github.com/daveross/adrian/config"
	adrianFonts "github.com/daveross/adrian/fonts"
	adrianServer "github.com/daveross/adrian/server"

	"github.com/labstack/echo"
)

func main() {

	log.Println("Starting Adrian 2.0")
	log.Println("Loading adrian.yaml")
	config := adrianConfig.LoadConfig("./adrian.yaml")
	log.Println("Initializing web server")
	e := adrianServer.Instantiate(config)
	log.Println("Loading fonts and starting watchers")
	for _, folder := range config.Global.Directories {
		adrianFonts.FindFonts(folder, config)
		adrianFonts.InstantiateWatcher(folder, config)
	}
	log.Println("Defining paths")

	e.GET("/css/", func(c echo.Context) error {
		c.Response().Header().Set(echo.HeaderContentType, "text/css")
		fontFilenames := strings.Split(c.QueryParam("family"), "|")
		var fontsCSS string
		for _, fontFilename := range fontFilenames {
			fontData, err := adrianFonts.GetFont(fontFilename)
			if err != nil {
				return adrianServer.Return404(c)
			}
			fontsCSS = fontsCSS + "\n" + fontData.CSS
			}
		return c.String(http.StatusOK, fontsCSS)
	})

	e.GET("/font/:filename", func(c echo.Context) error {
		switch filepath.Ext(c.Param("filename")) {
		case ".ttf":
			return outputFont(c, "font/ttf")
		case ".woff":
			return outputFont(c, "font/woff")
		case ".woff2":
			return outputFont(c, "font/woff2")
		case ".otf":
			return outputFont(c, "font/otf")
		}

		return adrianServer.Return404(c)

	})

	log.Printf("Listening on port %d", config.Global.Port)
	e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", config.Global.Port)))
}

// Basename gets the base filename (minus the last extension)
func basename(s string) string {
	n := strings.LastIndexByte(s, '.')
	if n >= 0 {
		return s[:n]
	}
	return s
}

func outputFont(c echo.Context, mimeType string) error {
	fontData, err := adrianFonts.GetFontByUniqueID(basename(c.Param("filename")))
	if err != nil {
		return adrianServer.Return404(c)
	}
	fontBinary, err := ioutil.ReadFile(fontData.Path) // just pass the file name
	if err != nil {
		log.Fatal("Can't read font file " + fontData.FileName)
	}
	return c.Blob(http.StatusOK, mimeType, fontBinary)

}
<|endoftext|>


<commit_before>// Package always goes at the top of the file
// `main` package gets compiled, any other package name is importable.
package main

import (
	"fmt" // standard formatting library, `printf` and so on
	"math/rand"
	"net/http"
	"time"

	"github.com/gorilla/mux"
)

// Functions with lowercase names are private to the package.
// Uppercase names are public
func findARandomNumber(c chan int) {
	// Seed a random number generator with the current Unix time
	src := rand.NewSource(time.Now().Unix())
	r := rand.New(src)

	// Send a random int across the channel
	c <- r.Int()
}

// Handler functions for HTTP routes take two inputs
// You write strings to `w` to send responses back to the client
// `r` contains info like headers, body, method, url, etc.
func IndexHandler(w http.ResponseWriter, r *http.Request) {
	// Make a new channel of `ints`. Channels are used to communicate between goroutines.
	c := make(chan int)
	// Create a new goroutine and run `findARandomNumber` on it.
	go findARandomNumber(c)
	// Channels block by default, so we wait for our goroutine to send a number back.
	n := <-c

	// Print to the responsewriter and terminate the connection.
	fmt.Fprintf(w, "Hello Sift. Your random number is %d", n)
}

// `main` function is the entry point, just like in C
func main() {
	// Create a new router, routers handle sets of logically related routes
	router := mux.NewRouter()
	// Add a handler for the root route
	router.HandleFunc("/", IndexHandler)
	// Create an http server on port 9090 and start serving using our router.
	http.ListenAndServe(":9090", router)
}
<commit_msg>add handler for simple file upload<commit_after>// Package always goes at the top of the file
// `main` package gets compiled, any other package name is importable.
package main

import (
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"os"
	"time"

	"github.com/gorilla/mux"
)

// Max file size to store in memory. 100MB
const MAX_FILE_SIZE = 6 << 24

// Functions with lowercase names are private to the package.
// Uppercase names are public
func findARandomNumber(c chan int) {
	// Seed a random number generator with the current Unix time
	src := rand.NewSource(time.Now().Unix())
	r := rand.New(src)

	// Send a random int across the channel
	c <- r.Int()
}

// Handler functions for HTTP routes take two inputs
// You write strings to `w` to send responses back to the client
// `r` contains info like headers, body, method, url, etc.
func IndexHandler(w http.ResponseWriter, r *http.Request) {
	// Make a new channel of `ints`. Channels are used to communicate between goroutines.
	c := make(chan int)
	// Create a new goroutine and run `findARandomNumber` on it.
	go findARandomNumber(c)
	// Channels block by default, so we wait for our goroutine to send a number back.
	n := <-c

	// Print to the responsewriter and terminate the connection.
	fmt.Fprintf(w, "Hello Sift. Your random number is %d", n)
}

// Handles uploads of multipart forms. Files should have form name `feedback`.
// Uploaded files are stored in `./uploads`
func FeedbackFormHandler(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(MAX_FILE_SIZE)
	file, handler, err := r.FormFile("feedback")
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	defer file.Close()
	f, err := os.Create(handler.Filename)
	if err != nil {
		fmt.Println("error creating file", err.Error())
		return
	}

	defer f.Close()
	_, err = io.Copy(f, file)
	if err != nil {
		fmt.Println("error copying file", err.Error())
	}
}

// `main` function is the entry point, just like in C
func main() {
	// Create a new router, routers handle sets of logically related routes
	router := mux.NewRouter()
	// Add a handler for the root route
	router.HandleFunc("/", IndexHandler)
	// Handler for the feedback upload route
	router.HandleFunc("/feedback", FeedbackFormHandler).Methods("POST")
	// Create an http server on port 9090 and start serving using our router.
	http.ListenAndServe(":9090", router)
}
<|endoftext|>