<commit_before>// Copyright 2016 Mender Software AS
//
//    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 "errors"
import "flag"
import "github.com/mendersoftware/log"
import "os"
import "strings"

type runOptionsType struct {
	imageFile  string
	committing bool
}

var errMsgNoArgumentsGiven error = errors.New("Must give either -rootfs or -commit")
var errMsgIncompatibleLogOptions error = errors.New("One or more " +
	"incompatible log log options specified.")

func argsParse(args []string) (runOptionsType, error) {
	var runOptions runOptionsType

	parsing := flag.NewFlagSet("mender", flag.ContinueOnError)

	// FLAGS ---------------------------------------------------------------

	committing := parsing.Bool("commit", false, "Commit current update.")

	debug := parsing.Bool("debug", false, "Debug log level. This is a "+
		"shorthand for '-l debug'.")

	info := parsing.Bool("info", false, "Info log level. This is a "+
		"shorthand for '-l info'.")

	imageFile := parsing.String("rootfs", "",
		"Root filesystem URI to use for update. Can be either a local "+
			"file or a URL.")

	logLevel := parsing.String("log-level", "", "Log level, which can be "+
		"'debug', 'info', 'warning', 'error', 'fatal' or 'panic'. "+
		"Earlier log levels will also log the subsequent levels (so "+
		"'debug' will log everything). The default log level is "+
		"'warning'.")

	logModules := parsing.String("log-modules", "", "Filter logging by "+
		"module. This is a comma separated list of modules to log, "+
		"other modules will be omitted. To see which modules are "+
		"available, take a look at a non-filtered log and select "+
		"the modules appropriate for you.")

	noSyslog := parsing.Bool("no-syslog", false, "Disable logging to "+
		"syslog. Note that debug message are never logged to syslog.")

	logFile := parsing.String("log-file", "", "File to log to.")

	// PARSING -------------------------------------------------------------

	if err := parsing.Parse(args); err != nil {
		return runOptions, err
	}

	// FLAG LOGIC ----------------------------------------------------------

	var logOptCount int = 0

	if *logLevel != "" {
		level, err := log.ParseLevel(*logLevel)
		if err != nil {
			return runOptions, err
		}
		log.SetLevel(level)
		logOptCount += 1
	}

	if *info {
		log.SetLevel(log.InfoLevel)
		logOptCount += 1
	}

	if *debug {
		log.SetLevel(log.DebugLevel)
		logOptCount += 1
	}

	if logOptCount > 1 {
		return runOptions, errMsgIncompatibleLogOptions
	} else if logOptCount == 0 {
		// Default log level.
		log.SetLevel(log.WarnLevel)
	}

	if *logFile != "" {
		fd, err := os.Create(*logFile)
		if err != nil {
			return runOptions, err
		}
		log.SetOutput(fd)
	}

	if *logModules != "" {
		modules := strings.Split(*logModules, ",")
		log.SetModuleFilter(modules)
	}

	if !*noSyslog {
		if err := log.AddSyslogHook(); err != nil {
			log.Warnf("Could not connect to syslog daemon: %s. "+
				"(use -no-syslog to disable completely)",
				err.Error())
		}
	}

	if *imageFile == "" && !*committing {
		return runOptions, errMsgNoArgumentsGiven
	}

	runOptions.imageFile = *imageFile
	runOptions.committing = *committing

	return runOptions, nil
}

func doMain(args []string) error {
	runOptions, err := argsParse(args)
	if err != nil {
		return err
	}

	if runOptions.imageFile != "" {
		if err := doRootfs(runOptions.imageFile); err != nil {
			return err
		}
	}
	if runOptions.committing {
		if err := doCommitRootfs(); err != nil {
			return err
		}
	}

	return nil
}

func main() {
	if err := doMain(os.Args[1:]); err != nil && err != flag.ErrHelp {
		log.Errorln(err.Error())
		os.Exit(1)
	}
}
<commit_msg>Add code for running Mender as a daemon.<commit_after>// Copyright 2016 Mender Software AS
//
//    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 "errors"
import "flag"
import "github.com/mendersoftware/log"
import "os"
import "strings"

type runOptionsType struct {
	imageFile  string
	committing bool
	daemon     bool
}

var errMsgNoArgumentsGiven error = errors.New("Must give one of -rootfs -commit " +
	"or -daemon arguments")
var errMsgIncompatibleLogOptions error = errors.New("One or more " +
	"incompatible log log options specified.")
var errMsgDaemonMixedWithOtherOptions error = errors.New("Daemon option can not " +
	"be mixed with other options.")

func argsParse(args []string) (runOptionsType, error) {
	var runOptions runOptionsType

	parsing := flag.NewFlagSet("mender", flag.ContinueOnError)

	// FLAGS ---------------------------------------------------------------

	committing := parsing.Bool("commit", false, "Commit current update.")

	debug := parsing.Bool("debug", false, "Debug log level. This is a "+
		"shorthand for '-l debug'.")

	info := parsing.Bool("info", false, "Info log level. This is a "+
		"shorthand for '-l info'.")

	imageFile := parsing.String("rootfs", "",
		"Root filesystem URI to use for update. Can be either a local "+
			"file or a URL.")

	logLevel := parsing.String("log-level", "", "Log level, which can be "+
		"'debug', 'info', 'warning', 'error', 'fatal' or 'panic'. "+
		"Earlier log levels will also log the subsequent levels (so "+
		"'debug' will log everything). The default log level is "+
		"'warning'.")

	logModules := parsing.String("log-modules", "", "Filter logging by "+
		"module. This is a comma separated list of modules to log, "+
		"other modules will be omitted. To see which modules are "+
		"available, take a look at a non-filtered log and select "+
		"the modules appropriate for you.")

	noSyslog := parsing.Bool("no-syslog", false, "Disable logging to "+
		"syslog. Note that debug message are never logged to syslog.")

	logFile := parsing.String("log-file", "", "File to log to.")

	daemon := parsing.Bool("daemon", false, "Run as a daemon.")

	// PARSING -------------------------------------------------------------

	if err := parsing.Parse(args); err != nil {
		return runOptions, err
	}

	// FLAG LOGIC ----------------------------------------------------------

	var logOptCount int = 0

	if *logLevel != "" {
		level, err := log.ParseLevel(*logLevel)
		if err != nil {
			return runOptions, err
		}
		log.SetLevel(level)
		logOptCount += 1
	}

	if *info {
		log.SetLevel(log.InfoLevel)
		logOptCount += 1
	}

	if *debug {
		log.SetLevel(log.DebugLevel)
		logOptCount += 1
	}

	if logOptCount > 1 {
		return runOptions, errMsgIncompatibleLogOptions
	} else if logOptCount == 0 {
		// Default log level.
		log.SetLevel(log.WarnLevel)
	}

	if *logFile != "" {
		fd, err := os.Create(*logFile)
		if err != nil {
			return runOptions, err
		}
		log.SetOutput(fd)
	}

	if *logModules != "" {
		modules := strings.Split(*logModules, ",")
		log.SetModuleFilter(modules)
	}

	if !*noSyslog {
		if err := log.AddSyslogHook(); err != nil {
			log.Warnf("Could not connect to syslog daemon: %s. "+
				"(use -no-syslog to disable completely)",
				err.Error())
		}
	}

	if *daemon && (*committing || *imageFile != "") {
		// Make sure that daemon switch is not passing together with
		// commit ot rootfs
		return runOptions, errMsgDaemonMixedWithOtherOptions
	}

	if *imageFile == "" && !*committing && !*daemon {
		return runOptions, errMsgNoArgumentsGiven
	}

	runOptions.imageFile = *imageFile
	runOptions.committing = *committing
	runOptions.daemon = *daemon

	return runOptions, nil
}

func doMain(args []string) error {
	runOptions, err := argsParse(args)
	if err != nil {
		return err
	}

	// run as a daemon
	if runOptions.daemon {
		if err := runAsDemon(); err != nil {
			return err
		}
	}

	if runOptions.imageFile != "" {
		if err := doRootfs(runOptions.imageFile); err != nil {
			return err
		}
	}
	if runOptions.committing {
		if err := doCommitRootfs(); err != nil {
			return err
		}
	}

	return nil
}

func runAsDemon() error {
	for {

	}
}

func main() {
	if err := doMain(os.Args[1:]); err != nil && err != flag.ErrHelp {
		log.Errorln(err.Error())
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"path/filepath"
	"regexp"
	"strings"
	"sync"

	"github.com/atotto/clipboard"
)

// re matches FILE:LINE.
var re = regexp.MustCompile(`(.+?)(\S+\.go):(\d+)(.+)`)

var matched bool
var mu sync.Mutex

func main() {
	log.SetFlags(0)

	// Execute "go" command with the same arguments.
	cmd := exec.Command("go", os.Args[1:]...)

	// Pass through standard input.
	stdin, err := cmd.StdinPipe()
	if err != nil {
		log.Fatal(err)
	}
	go io.Copy(stdin, os.Stdin)

	// Create a wait group for stdout/stderr.
	var wg sync.WaitGroup
	wg.Add(2)

	// Pass through standard out.
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		processPipe(os.Stdout, stdout)
		wg.Done()
	}()

	// Read through stderr and decorate.
	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		processPipe(os.Stderr, stderr)
		wg.Done()
	}()

	// Execute command.
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}

	// Forward signals to command.
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c)
		for sig := range c {
			cmd.Process.Signal(sig)
		}
	}()

	// Wait for pipes to finish reading and then wait for command to exit.
	wg.Wait()

	// Print a visual beep to cause the dock icon to bounce.
	fmt.Print("\x07")

	if err := cmd.Wait(); err != nil {
		os.Exit(1)
	}
}

// processPipe scans the src by line and attempts to match the first FILE:LINE.
func processPipe(dst io.Writer, src io.Reader) {
	// Find absolute path of present wording directory.
	pwd, _ := os.Getwd()
	pwd, _ = filepath.Abs(pwd)

	scanner := bufio.NewScanner(src)
	for scanner.Scan() {
		line := scanner.Text()
		func() {
			mu.Lock()
			defer mu.Unlock()

			// Ignore if already matched a line.
			if matched {
				fmt.Fprintln(dst, line)
				return
			}

			// Find .go path.
			m := re.FindStringSubmatch(line)
			if len(m) == 0 {
				fmt.Fprintln(dst, line)
				return
			}
			prefix, path, num, suffix := m[1], m[2], m[3], m[4]

			// Determine absolute path of Go file.
			path, _ = filepath.Abs(path)

			// Ignore if path is not relative to pwd.
			rel, err := filepath.Rel(pwd, path)
			if err != nil || strings.HasPrefix(rel, "..") {
				fmt.Fprintln(dst, line)
				return
			}

			// Copy match.
			clipboard.WriteAll(rel + ":" + num)

			// Bold line.
			line = prefix + pwd + "/\033[7m" + rel + ":" + num + "\033[0m" + suffix
			fmt.Fprintln(dst, line)

			// Ensure no more lines match.
			matched = true
		}()
	}
}
<commit_msg>Add ego filename matching.<commit_after>package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"path/filepath"
	"regexp"
	"strings"
	"sync"

	"github.com/atotto/clipboard"
)

// re matches FILE:LINE.
var re = regexp.MustCompile(`(.*?)(\S+?\.(?:ego|go)):(\d+)(.*)`)

var matched bool
var mu sync.Mutex

func main() {
	log.SetFlags(0)

	// Execute "go" command with the same arguments.
	cmd := exec.Command("go", os.Args[1:]...)

	// Pass through standard input.
	stdin, err := cmd.StdinPipe()
	if err != nil {
		log.Fatal(err)
	}
	go io.Copy(stdin, os.Stdin)

	// Create a wait group for stdout/stderr.
	var wg sync.WaitGroup
	wg.Add(2)

	// Pass through standard out.
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		processPipe(os.Stdout, stdout)
		wg.Done()
	}()

	// Read through stderr and decorate.
	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		processPipe(os.Stderr, stderr)
		wg.Done()
	}()

	// Execute command.
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}

	// Forward signals to command.
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c)
		for sig := range c {
			cmd.Process.Signal(sig)
		}
	}()

	// Wait for pipes to finish reading and then wait for command to exit.
	wg.Wait()

	// Print a visual beep to cause the dock icon to bounce.
	fmt.Print("\x07")

	if err := cmd.Wait(); err != nil {
		os.Exit(1)
	}
}

// processPipe scans the src by line and attempts to match the first FILE:LINE.
func processPipe(dst io.Writer, src io.Reader) {
	// Find absolute path of present wording directory.
	pwd, _ := os.Getwd()
	pwd, _ = filepath.Abs(pwd)

	scanner := bufio.NewScanner(src)
	for scanner.Scan() {
		line := scanner.Text()
		func() {
			mu.Lock()
			defer mu.Unlock()

			// Ignore if already matched a line.
			if matched {
				fmt.Fprintln(dst, line)
				return
			}

			// Find .go path.
			m := re.FindStringSubmatch(line)
			if len(m) == 0 {
				fmt.Fprintln(dst, line)
				return
			}
			prefix, path, num, suffix := m[1], m[2], m[3], m[4]

			// Determine absolute path of Go file.
			abs, _ := filepath.Abs(path)

			// Ignore if path is not relative to pwd.
			rel, err := filepath.Rel(pwd, abs)
			if err != nil || strings.HasPrefix(rel, "..") {
				fmt.Fprintln(dst, line)
				return
			}

			// Show base path if it was originally in the line.
			var base string
			if strings.HasPrefix(path, "/") {
				base = pwd + "/"
			}

			// Copy match.
			clipboard.WriteAll(rel + ":" + num)

			// Bold line.
			line = prefix + base + "\033[7m" + rel + ":" + num + "\033[0m" + suffix
			fmt.Fprintln(dst, line)

			// Ensure no more lines match.
			matched = true
		}()
	}
}
<|endoftext|>


<commit_before>package main // import "jhhgo.us/pukaws"

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

	"github.com/manyminds/api2go"
	"jhhgo.us/pukaws/bookmark"
	"jhhgo.us/pukaws/middleware"
)

var (
	port      = os.Getenv("PORT")
	baseURL   = os.Getenv("BASE_URL")
	mongoURL  = os.Getenv("MONGODB_URI")
	authToken = os.Getenv("PUKA_TOKEN")
	origin    = os.Getenv("ALLOW_ORIGIN")
)

func init() {
	if port == "" {
		port = "8088"
		fmt.Println("$PORT not set, using: 8088")
	}
	if baseURL == "" {
		baseURL = "http://localhost:" + port
		fmt.Printf("$BASE_URL not set, using: %s\n", baseURL)
	}
	if mongoURL == "" {
		mongoURL = "mongodb://localhost/test"
		fmt.Printf("$MONGODB_URI not set, using: %s\n", mongoURL)
	}
	if authToken == "" {
		fmt.Println("$PUKA_TOKEN not set, will not authenticate")
	}
	if origin == "" {
		origin = "http://localhost:8080"
		fmt.Printf("$ALLOW_ORIGIN not set, using %s\n", origin)
	}
}

func main() {
	bookmarkStorage, err := bookmark.NewMgoStorage(mongoURL)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	defer bookmarkStorage.Close()
	api := newAPI(bookmarkStorage, baseURL)
	api.UseMiddleware(middleware.CORS)
	if authToken != "" {
		api.UseMiddleware(middleware.NewAuthenticator(authToken))
	}
	fmt.Printf("Listening on :%s\n", port)
	fmt.Println(http.ListenAndServe(":"+port, api.Handler()))
}

func newAPI(st bookmark.Storage, base string) *api2go.API {
	api := api2go.NewAPIWithBaseURL("v0", base)
	api.AddResource(bookmark.Bookmark{}, bookmark.Resource{Storage: st})
	return api
}
<commit_msg>Removed unused config option.<commit_after>package main // import "jhhgo.us/pukaws"

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

	"github.com/manyminds/api2go"
	"jhhgo.us/pukaws/bookmark"
	"jhhgo.us/pukaws/middleware"
)

var (
	port      = os.Getenv("PORT")
	baseURL   = os.Getenv("BASE_URL")
	mongoURL  = os.Getenv("MONGODB_URI")
	authToken = os.Getenv("PUKA_TOKEN")
)

func init() {
	if port == "" {
		port = "8088"
		fmt.Println("$PORT not set, using: 8088")
	}
	if baseURL == "" {
		baseURL = "http://localhost:" + port
		fmt.Printf("$BASE_URL not set, using: %s\n", baseURL)
	}
	if mongoURL == "" {
		mongoURL = "mongodb://localhost/test"
		fmt.Printf("$MONGODB_URI not set, using: %s\n", mongoURL)
	}
	if authToken == "" {
		fmt.Println("$PUKA_TOKEN not set, will not authenticate")
	}
}

func main() {
	bookmarkStorage, err := bookmark.NewMgoStorage(mongoURL)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	defer bookmarkStorage.Close()
	api := newAPI(bookmarkStorage, baseURL)
	api.UseMiddleware(middleware.CORS)
	if authToken != "" {
		api.UseMiddleware(middleware.NewAuthenticator(authToken))
	}
	fmt.Printf("Listening on :%s\n", port)
	fmt.Println(http.ListenAndServe(":"+port, api.Handler()))
}

func newAPI(st bookmark.Storage, base string) *api2go.API {
	api := api2go.NewAPIWithBaseURL("v0", base)
	api.AddResource(bookmark.Bookmark{}, bookmark.Resource{Storage: st})
	return api
}
<|endoftext|>


<commit_before>// htwtxt – hosted twtxt server; see README for copyright and license info

package main

import "bufio"
import "errors"
import "flag"
import "github.com/gorilla/mux"
import "golang.org/x/crypto/bcrypt"
import "html/template"
import "io/ioutil"
import "log"
import "net/http"
import "os"
import "strconv"
import "strings"
import "time"

const loginsFile = "logins.txt"
const twtsDir = "feeds"

var dataDir string
var loginsPath string
var templ *template.Template

func createFileIfNotExists(path string) {
	if _, err := os.Stat(path); err != nil {
		file, err := os.Create(path)
		if err != nil {
			log.Fatal("Can't create file: ", err)
		}
		file.Close()
	}
}

func appendToFile(path string, msg string) {
	fileWrite, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0600)
	defer fileWrite.Close()
	if err != nil {
		log.Fatal("Can't open file for appending", err)
	}
	if _, err = fileWrite.WriteString(msg); err != nil {
		log.Fatal("Can't write to file", err)
	}
}

func onlyLegalRunes(str string) bool {
	alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +
		"0123456789_"
	for _, ru := range str {
		if !(strings.ContainsRune(alphabet, ru)) {
			return false
		}
	}
	return true
}

func execTemplate(w http.ResponseWriter, file string, input string) {
	type data struct{ Msg string }
	err := templ.ExecuteTemplate(w, file, data{Msg: input})
	if err != nil {
		log.Fatal("Trouble executing template", err)
	}
}

func login(w http.ResponseWriter, r *http.Request) (string, error) {
	name := r.FormValue("name")
	pw := r.FormValue("password")
	loginValid := false
	file, err := os.Open(loginsPath)
	defer file.Close()
	if err != nil {
		log.Fatal("Can't open file for reading", err)
	}
	scanner := bufio.NewScanner(bufio.NewReader(file))
	for {
		if !scanner.Scan() {
			break
		}
		line := scanner.Text()
		tokens := strings.Split(line, " ")
		if len(tokens) == 3 {
			if 0 == strings.Compare(tokens[0], name) &&
				nil == bcrypt.CompareHashAndPassword(
					[]byte(tokens[1]), []byte(pw)) {
				loginValid = true

			}
		}
	}
	if !loginValid {
		execTemplate(w, "error.html", "Bad login.")
		return name, errors.New("")
	}
	return name, nil
}

func accountLine(w http.ResponseWriter, r *http.Request,
	checkDupl bool) (string, error) {
	name := r.FormValue("name")
	pw := r.FormValue("new_password")
	pw2 := r.FormValue("new_password2")
	mail := r.FormValue("mail")
	if 0 != strings.Compare(pw, pw2) || 0 == strings.Compare("name", "") ||
		0 == strings.Compare(pw, "") || !onlyLegalRunes(name) ||
		len(name) > 140 {
		execTemplate(w, "error.html", "Invalid values.")
		return "", errors.New("")
	}
	if checkDupl {
		fileRead, err := os.Open(loginsPath)
		defer fileRead.Close()
		if err != nil {
			log.Fatal("Can't open file for reading", err)
		}
		scanner := bufio.NewScanner(bufio.NewReader(fileRead))
		for {
			if !scanner.Scan() {
				break
			}
			line := scanner.Text()
			tokens := strings.Split(line, " ")
			if 0 == strings.Compare(name, tokens[0]) {
				execTemplate(w, "error.html", "Username taken.")
				return "", errors.New("")
			}
		}
	}
	hash, err := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.DefaultCost)
	if err != nil {
		log.Fatal("Can't generate password hash", err)
	}
	return name + " " + string(hash) + " " + mail, nil
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	execTemplate(w, "index.html", "")
}

func signUpFormHandler(w http.ResponseWriter, r *http.Request) {
	execTemplate(w, "signupform.html", "")
}

func signUpHandler(w http.ResponseWriter, r *http.Request) {
	newLine, err := accountLine(w, r, true)
	if err != nil {
		return
	}
	appendToFile(loginsPath, newLine+"\n")
	execTemplate(w, "feedset.html", "")
}

func accountFormHandler(w http.ResponseWriter, r *http.Request) {
	execTemplate(w, "accountform.html", "")
}

func accountPostHandler(w http.ResponseWriter, r *http.Request) {
	name, err := login(w, r)
	if err != nil {
		return
	}
	newLine, err := accountLine(w, r, false)
	if err != nil {
		return
	}
	text, err := ioutil.ReadFile(loginsPath)
	if err != nil {
		log.Fatal("Can't read file", err)
	}
	lines := strings.Split(string(text), "\n")
	for i, line := range lines {
		tokens := strings.Split(line, " ")
		if 0 == strings.Compare(name, tokens[0]) {
			lines[i] = newLine
			break
		}
	}
	text = []byte(strings.Join(lines, "\n"))
	tmpFile := "tmp_" + loginsPath
	if err := ioutil.WriteFile(tmpFile, []byte(text), 0600); err != nil {
		log.Fatal("Trouble writing file", err)
	}
	if err := os.Rename(loginsPath, "_"+loginsFile); err != nil {
		log.Fatal("Trouble moving file", err)
	}
	if err := os.Rename(tmpFile, loginsPath); err != nil {
		log.Fatal("Trouble moving file", err)
	}
	if err := os.Remove("_" + loginsPath); err != nil {
		log.Fatal("Trouble removing file", err)
	}
	execTemplate(w, "feedset.html", "")
}

func listHandler(w http.ResponseWriter, r *http.Request) {
	file, err := os.Open(loginsPath)
	defer file.Close()
	if err != nil {
		log.Fatal("Can't open file for reading", err)
	}
	scanner := bufio.NewScanner(bufio.NewReader(file))
	var dir []string
	for {
		if !scanner.Scan() {
			break
		}
		line := scanner.Text()
		tokens := strings.Split(line, " ")
		if len(tokens) == 3 {
			dir = append(dir, tokens[0])
		}
	}
	type data struct{ Dir []string }
	err = templ.ExecuteTemplate(w, "list.html", data{Dir: dir})
	if err != nil {
		log.Fatal("Trouble executing template", err)
	}
}

func twtxtPostHandler(w http.ResponseWriter, r *http.Request) {
	name, err := login(w, r)
	if err != nil {
		return
	}
	text := r.FormValue("twt")
	twtsFile := twtsDir + "/" + name
	createFileIfNotExists(twtsFile)
	text = strings.Replace(text, "\n", " ", -1)
	appendToFile(twtsFile, time.Now().Format(time.RFC3339)+"\t"+text+"\n")
	http.Redirect(w, r, "/"+twtsFile, 302)
}

func twtxtHandler(w http.ResponseWriter, r *http.Request) {
	name := mux.Vars(r)["name"]
	if !onlyLegalRunes(name) {
		execTemplate(w, "error.html", "Bad path.")
		return
	}
	path := twtsDir + "/" + name
	if _, err := os.Stat(path); err != nil {
		execTemplate(w, "error.html", "Empty twtxt for user.")
		return
	}
	http.ServeFile(w, r, path)
}

func main() {
	var err error
	portPtr := flag.Int("port", 8000, "port to serve")
	keyPtr := flag.String("key", "", "SSL key file")
	certPtr := flag.String("cert", "", "SSL certificate file")
	templDirPtr := flag.String("templates",
		os.Getenv("GOPATH")+"/src/htwtxt/templates",
		"directory where to expect HTML templates")
	flag.StringVar(&dataDir, "dir", os.Getenv("HOME")+"/htwtxt",
		"directory to store feeds and login data")
	flag.Parse()
	log.Println("Using as templates dir:", *templDirPtr)
	log.Println("Using as data dir:", dataDir)
	loginsPath = dataDir + "/" + loginsFile
	if ("" == *keyPtr && "" != *certPtr) ||
		("" != *keyPtr && "" == *certPtr) {
		log.Fatal("Expect either both key and certificate or none.")
	}
	if "" != *keyPtr {
		log.Println("Using TLS.")
		if _, err := os.Stat(*certPtr); err != nil {
			log.Fatal("No certificate file found.")
		}
		if _, err := os.Stat(*keyPtr); err != nil {
			log.Fatal("No server key file found.")
		}
	}
	createFileIfNotExists(loginsPath)
	// TODO: Handle err here.
	_ = os.Mkdir(twtsDir, 0700)
	templ, err = template.New("main").ParseGlob(*templDirPtr + "/*.html")
	if err != nil {
		log.Fatal("Can't set up new template: ", err)
	}
	router := mux.NewRouter()
	router.HandleFunc("/", indexHandler)
	router.HandleFunc("/feeds", listHandler).Methods("GET")
	router.HandleFunc("/feeds/", listHandler)
	router.HandleFunc("/account", accountFormHandler).Methods("GET")
	router.HandleFunc("/account", accountPostHandler).Methods("POST")
	router.HandleFunc("/signup", signUpFormHandler).Methods("GET")
	router.HandleFunc("/signup", signUpHandler).Methods("POST")
	router.HandleFunc("/feeds", twtxtPostHandler).Methods("POST")
	router.HandleFunc("/feeds/{name}", twtxtHandler)
	http.Handle("/", router)
	log.Println("serving at port", *portPtr)
	if "" != *keyPtr {
		err = http.ListenAndServeTLS(":"+strconv.Itoa(*portPtr),
			*certPtr, *keyPtr, nil)
	} else {
		err = http.ListenAndServe(":"+strconv.Itoa(*portPtr), nil)
	}
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<commit_msg>Fix internal feeds path handling.<commit_after>// htwtxt – hosted twtxt server; see README for copyright and license info

package main

import "bufio"
import "errors"
import "flag"
import "github.com/gorilla/mux"
import "golang.org/x/crypto/bcrypt"
import "html/template"
import "io/ioutil"
import "log"
import "net/http"
import "os"
import "strconv"
import "strings"
import "time"

const loginsFile = "logins.txt"
const feedsDir = "feeds"

var dataDir string
var loginsPath string
var feedsPath string
var templ *template.Template

func createFileIfNotExists(path string) {
	if _, err := os.Stat(path); err != nil {
		file, err := os.Create(path)
		if err != nil {
			log.Fatal("Can't create file: ", err)
		}
		file.Close()
	}
}

func appendToFile(path string, msg string) {
	fileWrite, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0600)
	defer fileWrite.Close()
	if err != nil {
		log.Fatal("Can't open file for appending", err)
	}
	if _, err = fileWrite.WriteString(msg); err != nil {
		log.Fatal("Can't write to file", err)
	}
}

func onlyLegalRunes(str string) bool {
	alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +
		"0123456789_"
	for _, ru := range str {
		if !(strings.ContainsRune(alphabet, ru)) {
			return false
		}
	}
	return true
}

func execTemplate(w http.ResponseWriter, file string, input string) {
	type data struct{ Msg string }
	err := templ.ExecuteTemplate(w, file, data{Msg: input})
	if err != nil {
		log.Fatal("Trouble executing template", err)
	}
}

func login(w http.ResponseWriter, r *http.Request) (string, error) {
	name := r.FormValue("name")
	pw := r.FormValue("password")
	loginValid := false
	file, err := os.Open(loginsPath)
	defer file.Close()
	if err != nil {
		log.Fatal("Can't open file for reading", err)
	}
	scanner := bufio.NewScanner(bufio.NewReader(file))
	for {
		if !scanner.Scan() {
			break
		}
		line := scanner.Text()
		tokens := strings.Split(line, " ")
		if len(tokens) == 3 {
			if 0 == strings.Compare(tokens[0], name) &&
				nil == bcrypt.CompareHashAndPassword(
					[]byte(tokens[1]), []byte(pw)) {
				loginValid = true

			}
		}
	}
	if !loginValid {
		execTemplate(w, "error.html", "Bad login.")
		return name, errors.New("")
	}
	return name, nil
}

func accountLine(w http.ResponseWriter, r *http.Request,
	checkDupl bool) (string, error) {
	name := r.FormValue("name")
	pw := r.FormValue("new_password")
	pw2 := r.FormValue("new_password2")
	mail := r.FormValue("mail")
	if 0 != strings.Compare(pw, pw2) || 0 == strings.Compare("name", "") ||
		0 == strings.Compare(pw, "") || !onlyLegalRunes(name) ||
		len(name) > 140 {
		execTemplate(w, "error.html", "Invalid values.")
		return "", errors.New("")
	}
	if checkDupl {
		fileRead, err := os.Open(loginsPath)
		defer fileRead.Close()
		if err != nil {
			log.Fatal("Can't open file for reading", err)
		}
		scanner := bufio.NewScanner(bufio.NewReader(fileRead))
		for {
			if !scanner.Scan() {
				break
			}
			line := scanner.Text()
			tokens := strings.Split(line, " ")
			if 0 == strings.Compare(name, tokens[0]) {
				execTemplate(w, "error.html", "Username taken.")
				return "", errors.New("")
			}
		}
	}
	hash, err := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.DefaultCost)
	if err != nil {
		log.Fatal("Can't generate password hash", err)
	}
	return name + " " + string(hash) + " " + mail, nil
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	execTemplate(w, "index.html", "")
}

func signUpFormHandler(w http.ResponseWriter, r *http.Request) {
	execTemplate(w, "signupform.html", "")
}

func signUpHandler(w http.ResponseWriter, r *http.Request) {
	newLine, err := accountLine(w, r, true)
	if err != nil {
		return
	}
	appendToFile(loginsPath, newLine+"\n")
	execTemplate(w, "feedset.html", "")
}

func accountFormHandler(w http.ResponseWriter, r *http.Request) {
	execTemplate(w, "accountform.html", "")
}

func accountPostHandler(w http.ResponseWriter, r *http.Request) {
	name, err := login(w, r)
	if err != nil {
		return
	}
	newLine, err := accountLine(w, r, false)
	if err != nil {
		return
	}
	text, err := ioutil.ReadFile(loginsPath)
	if err != nil {
		log.Fatal("Can't read file", err)
	}
	lines := strings.Split(string(text), "\n")
	for i, line := range lines {
		tokens := strings.Split(line, " ")
		if 0 == strings.Compare(name, tokens[0]) {
			lines[i] = newLine
			break
		}
	}
	text = []byte(strings.Join(lines, "\n"))
	tmpFile := "tmp_" + loginsPath
	if err := ioutil.WriteFile(tmpFile, []byte(text), 0600); err != nil {
		log.Fatal("Trouble writing file", err)
	}
	if err := os.Rename(loginsPath, "_"+loginsFile); err != nil {
		log.Fatal("Trouble moving file", err)
	}
	if err := os.Rename(tmpFile, loginsPath); err != nil {
		log.Fatal("Trouble moving file", err)
	}
	if err := os.Remove("_" + loginsPath); err != nil {
		log.Fatal("Trouble removing file", err)
	}
	execTemplate(w, "feedset.html", "")
}

func listHandler(w http.ResponseWriter, r *http.Request) {
	file, err := os.Open(loginsPath)
	defer file.Close()
	if err != nil {
		log.Fatal("Can't open file for reading", err)
	}
	scanner := bufio.NewScanner(bufio.NewReader(file))
	var dir []string
	for {
		if !scanner.Scan() {
			break
		}
		line := scanner.Text()
		tokens := strings.Split(line, " ")
		if len(tokens) == 3 {
			dir = append(dir, tokens[0])
		}
	}
	type data struct{ Dir []string }
	err = templ.ExecuteTemplate(w, "list.html", data{Dir: dir})
	if err != nil {
		log.Fatal("Trouble executing template", err)
	}
}

func twtxtPostHandler(w http.ResponseWriter, r *http.Request) {
	name, err := login(w, r)
	if err != nil {
		return
	}
	text := r.FormValue("twt")
	twtsFile := feedsPath + "/" + name
	createFileIfNotExists(twtsFile)
	text = strings.Replace(text, "\n", " ", -1)
	appendToFile(twtsFile, time.Now().Format(time.RFC3339)+"\t"+text+"\n")
	http.Redirect(w, r, "/"+feedsDir+"/"+name, 302)
}

func twtxtHandler(w http.ResponseWriter, r *http.Request) {
	name := mux.Vars(r)["name"]
	if !onlyLegalRunes(name) {
		execTemplate(w, "error.html", "Bad path.")
		return
	}
	path := feedsPath + "/" + name
	if _, err := os.Stat(path); err != nil {
		execTemplate(w, "error.html", "Empty twtxt for user.")
		return
	}
	http.ServeFile(w, r, path)
}

func main() {
	var err error
	portPtr := flag.Int("port", 8000, "port to serve")
	keyPtr := flag.String("key", "", "SSL key file")
	certPtr := flag.String("cert", "", "SSL certificate file")
	templDirPtr := flag.String("templates",
		os.Getenv("GOPATH")+"/src/htwtxt/templates",
		"directory where to expect HTML templates")
	flag.StringVar(&dataDir, "dir", os.Getenv("HOME")+"/htwtxt",
		"directory to store feeds and login data")
	flag.Parse()
	log.Println("Using as templates dir:", *templDirPtr)
	log.Println("Using as data dir:", dataDir)
	loginsPath = dataDir + "/" + loginsFile
	feedsPath = dataDir + "/" + feedsDir
	if ("" == *keyPtr && "" != *certPtr) ||
		("" != *keyPtr && "" == *certPtr) {
		log.Fatal("Expect either both key and certificate or none.")
	}
	if "" != *keyPtr {
		log.Println("Using TLS.")
		if _, err := os.Stat(*certPtr); err != nil {
			log.Fatal("No certificate file found.")
		}
		if _, err := os.Stat(*keyPtr); err != nil {
			log.Fatal("No server key file found.")
		}
	}
	createFileIfNotExists(loginsPath)
	// TODO: Handle err here.
	_ = os.Mkdir(feedsPath, 0700)
	templ, err = template.New("main").ParseGlob(*templDirPtr + "/*.html")
	if err != nil {
		log.Fatal("Can't set up new template: ", err)
	}
	router := mux.NewRouter()
	router.HandleFunc("/", indexHandler)
	router.HandleFunc("/feeds", listHandler).Methods("GET")
	router.HandleFunc("/feeds/", listHandler)
	router.HandleFunc("/account", accountFormHandler).Methods("GET")
	router.HandleFunc("/account", accountPostHandler).Methods("POST")
	router.HandleFunc("/signup", signUpFormHandler).Methods("GET")
	router.HandleFunc("/signup", signUpHandler).Methods("POST")
	router.HandleFunc("/feeds", twtxtPostHandler).Methods("POST")
	router.HandleFunc("/feeds/{name}", twtxtHandler)
	http.Handle("/", router)
	log.Println("serving at port", *portPtr)
	if "" != *keyPtr {
		err = http.ListenAndServeTLS(":"+strconv.Itoa(*portPtr),
			*certPtr, *keyPtr, nil)
	} else {
		err = http.ListenAndServe(":"+strconv.Itoa(*portPtr), nil)
	}
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<|endoftext|>


<commit_before>package main

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

	"github.com/MyHomeworkSpace/api-server/api"
	"github.com/MyHomeworkSpace/api-server/auth"

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

type ErrorResponse struct {
	Status string `json:"status"`
	Error string `json:"error"`
}

func main() {
	log.Println("MyHomeworkSpace API Server")

	InitConfig()
	InitDatabase()
	InitRedis()

	api.AuthURLBase = config.Server.AuthURLBase
	api.DB = DB
	api.RedisClient = RedisClient
	api.WhitelistEnabled = config.Whitelist.Enabled
	api.WhitelistFile = config.Whitelist.WhitelistFile
	api.WhitelistBlockMsg = config.Whitelist.BlockMessage
	auth.DB = DB
	auth.RedisClient = RedisClient

	e := echo.New()
	e.Pre(middleware.RemoveTrailingSlash())
	e.Pre(func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if config.CORS.Enabled {
				c.Response().Header().Set("Access-Control-Allow-Origin", config.CORS.Origin)
				c.Response().Header().Set("Access-Control-Allow-Credentials", "true")
			}
			if strings.HasPrefix(c.Request().URL.Path, "/api_tester") {
				return next(c)
			}
			if strings.HasPrefix(c.Request().URL.Path, "/application/requestAuth") {
				return next(c)
			}
			_, err := c.Cookie("session")
			if err != nil {
				// user has no cookie, generate one
				cookie := new(http.Cookie)
				cookie.Name ="session"
				cookie.Path = "/"
				uid, err := auth.GenerateUID()
				if err != nil {
					return err
				}
				cookie.Value = uid
				cookie.Expires = time.Now().Add(7 * 24 * time.Hour)
				c.SetCookie(cookie)
			}

			csrfCookie, err := c.Cookie("csrfToken")
			if err != nil {
				// user has no cookie, generate one
				cookie := new(http.Cookie)
				cookie.Name = "csrfToken"
				cookie.Path = "/"
				uid, err := auth.GenerateRandomString(40)
				if err != nil {
					return err
				}
				cookie.Value = uid
				cookie.Expires = time.Now().Add(12 * 4 * 7 * 24 * time.Hour)
				c.SetCookie(cookie)
				jsonResp := ErrorResponse{"error", "csrfToken_created"}
				return c.JSON(http.StatusBadRequest, jsonResp)
			}

			// bypass csrf token for /auth/csrf
			if strings.HasPrefix(c.Request().URL.Path, "/auth/csrf") {
				return next(c)
			}

			// bypass csrf if they send an authorization header
			if c.Request().Header.Get("Authorization") != "" {
				return next(c)
			}

			if csrfCookie.Value != c.QueryParam("csrfToken") {
				jsonResp := ErrorResponse{"error", "csrfToken_invalid"}
				return c.JSON(http.StatusBadRequest, jsonResp)
			}

			return next(c)
		}
	})
	e.Static("/api_tester", "api_tester")
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "MyHomeworkSpace API Server")
	})

	api.Init(e) // API init delayed because router must be started first

	log.Printf("Listening on port %d", config.Server.Port)
	e.Start(fmt.Sprintf(":%d", config.Server.Port))
}
<commit_msg>fix bug where csrf tokens would be created when they aren't needed<commit_after>package main

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

	"github.com/MyHomeworkSpace/api-server/api"
	"github.com/MyHomeworkSpace/api-server/auth"

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

type ErrorResponse struct {
	Status string `json:"status"`
	Error string `json:"error"`
}

func main() {
	log.Println("MyHomeworkSpace API Server")

	InitConfig()
	InitDatabase()
	InitRedis()

	api.AuthURLBase = config.Server.AuthURLBase
	api.DB = DB
	api.RedisClient = RedisClient
	api.WhitelistEnabled = config.Whitelist.Enabled
	api.WhitelistFile = config.Whitelist.WhitelistFile
	api.WhitelistBlockMsg = config.Whitelist.BlockMessage
	auth.DB = DB
	auth.RedisClient = RedisClient

	e := echo.New()
	e.Pre(middleware.RemoveTrailingSlash())
	e.Pre(func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if config.CORS.Enabled {
				c.Response().Header().Set("Access-Control-Allow-Origin", config.CORS.Origin)
				c.Response().Header().Set("Access-Control-Allow-Credentials", "true")
			}
			if strings.HasPrefix(c.Request().URL.Path, "/api_tester") {
				return next(c)
			}
			if strings.HasPrefix(c.Request().URL.Path, "/application/requestAuth") {
				return next(c)
			}
			_, err := c.Cookie("session")
			if err != nil {
				// user has no cookie, generate one
				cookie := new(http.Cookie)
				cookie.Name ="session"
				cookie.Path = "/"
				uid, err := auth.GenerateUID()
				if err != nil {
					return err
				}
				cookie.Value = uid
				cookie.Expires = time.Now().Add(7 * 24 * time.Hour)
				c.SetCookie(cookie)
			}

			// bypass csrf if they send an authorization header
			if c.Request().Header.Get("Authorization") != "" {
				return next(c)
			}

			csrfCookie, err := c.Cookie("csrfToken")
			if err != nil {
				// user has no cookie, generate one
				cookie := new(http.Cookie)
				cookie.Name = "csrfToken"
				cookie.Path = "/"
				uid, err := auth.GenerateRandomString(40)
				if err != nil {
					return err
				}
				cookie.Value = uid
				cookie.Expires = time.Now().Add(12 * 4 * 7 * 24 * time.Hour)
				c.SetCookie(cookie)
				jsonResp := ErrorResponse{"error", "csrfToken_created"}
				return c.JSON(http.StatusBadRequest, jsonResp)
			}

			// bypass csrf token for /auth/csrf
			if strings.HasPrefix(c.Request().URL.Path, "/auth/csrf") {
				return next(c)
			}

			if csrfCookie.Value != c.QueryParam("csrfToken") {
				jsonResp := ErrorResponse{"error", "csrfToken_invalid"}
				return c.JSON(http.StatusBadRequest, jsonResp)
			}

			return next(c)
		}
	})
	e.Static("/api_tester", "api_tester")
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "MyHomeworkSpace API Server")
	})

	api.Init(e) // API init delayed because router must be started first

	log.Printf("Listening on port %d", config.Server.Port)
	e.Start(fmt.Sprintf(":%d", config.Server.Port))
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
	"runtime"

	"github.com/codegangsta/cli"
	"github.com/mitchellh/go-homedir"
	"github.com/skratchdot/open-golang/open"
)

var (
	// exitCode to terminate.
	exitCode = 0

	// Default endpoint.
	endpoint = "http://upload.gyazo.com/upload.cgi"
)

const usageText = `Gyazo command-line uploader

		EXAMPLE:

		$ gyazo foo.png
		$ gyazo ~/Downloads/bar.jpg`

func main() {
	defer os.Exit(exitCode)

	app := cli.NewApp()
	app.Name = "gyazo"
	app.Version = Version
	app.Usage = usageText
	app.Author = "Tomohiro TAIRA"
	app.Email = "tomohiro.t@gmail.com"
	app.Action = upload
	app.Run(os.Args)
}

// Set the endpoint of Gyazo API.
func init() {
	if os.Getenv("GYAZO_SERVER_URL") != "" {
		endpoint = os.Getenv("GYAZO_SERVER_URL")
	} else if os.Getenv("GYAZO_ACCESS_TOKEN") != "" {
		endpoint = "https://upload.gyazo.com/api/upload"
	}
}

// Image represents a uploaded image on the Gyazo server.
//
// Gyazo API docs: https://gyazo.com/api/docs/image
type Image struct {
	ID           string `json:"image_id"`
	PermalinkURL string `json:"permalink_url"`
	ThumbURL     string `json:"thumb_url"`
	URL          string `json:"url"`
	Type         string `json:"type"`
}

// Upload a new image to a Gyazo server from the specified local image file.
//
// Gyazo API docs: https://gyazo.com/api/docs/image
func upload(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Fprintln(os.Stderr, "Try `gyazo --help` for more information")
		exitCode = 1
		return
	}

	filename := c.Args().First()
	content, err := os.Open(filename)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open and read %s\n", filename)
		return
	}
	defer content.Close()

	// Create multipart/form-data
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)

	part, err := writer.CreateFormFile("imagedata", filename)
	if err != nil {
		exitCode = 1
		return
	}

	if _, err = io.Copy(part, content); err != nil {
		exitCode = 1
		return
	}

	if os.Getenv("GYAZO_ACCESS_TOKEN") != "" {
		writer.WriteField("access_token", os.Getenv("GYAZO_ACCESS_TOKEN"))
	} else {
		writer.WriteField("id", gyazoID())
	}

	err = writer.Close()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create multipart/data: %s\n", err)
		exitCode = 1
		return
	}

	res, err := http.Post(endpoint, writer.FormDataContentType(), body)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to upload: %s\n", err)
		exitCode = 1
		return
	}
	defer res.Body.Close()

	url, err := imageURL(res)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Response error: %s\n", err)
		exitCode = 1
		return
	}

	fmt.Println(url)
	err = open.Run(url)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open by default browser: %s\n", err)
	}
}

// imageURL returns url of uploaded image.
func imageURL(r *http.Response) (string, error) {
	var url = ""
	if os.Getenv("GYAZO_ACCESS_TOKEN") != "" {
		image := Image{}
		if err := json.NewDecoder(r.Body).Decode(&image); err != nil {
			return url, err
		}

		url = image.PermalinkURL
	} else {
		id := r.Header.Get("X-Gyazo-Id")
		if err := saveGyazoID(id); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to save Gyazo ID: %s\n", err)
		}

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

		url = string(body)
	}

	return url, nil
}

// getID returns ID
func gyazoID() string {
	var id = ""

	fp, err := os.Open(gyazoIDPath())
	if err != nil {
		return id
	}
	defer fp.Close()

	body, err := ioutil.ReadAll(fp)
	if err != nil {
		return id
	}

	id = string(body)
	return id
}

// saveGyazoID stores Gyazo ID to file.
func saveGyazoID(id string) error {
	return nil
}

// gyazoIDPath returns path of Gyazo ID file on local filesystem.
func gyazoIDPath() string {
	homedir, _ := homedir.Dir()

	var path = ""
	switch runtime.GOOS {
	case "darwin":
		path = fmt.Sprintf("%s/Library/Gyazo/id", homedir)
	case "linux":
		path = fmt.Sprintf("%s/.gyazo.id", homedir)
	}

	return path
}
<commit_msg>Fix usage<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
	"runtime"

	"github.com/codegangsta/cli"
	"github.com/mitchellh/go-homedir"
	"github.com/skratchdot/open-golang/open"
)

var (
	// exitCode to terminate.
	exitCode = 0

	// Default endpoint.
	endpoint = "http://upload.gyazo.com/upload.cgi"
)

func main() {
	defer os.Exit(exitCode)

	app := cli.NewApp()
	app.Name = "gyazo"
	app.Version = Version
	app.Usage = "Gyazo command-line uploader"
	app.Author = "Tomohiro TAIRA"
	app.Email = "tomohiro.t@gmail.com"
	app.Action = upload
	app.Run(os.Args)
}

// Set the endpoint of Gyazo API.
func init() {
	if os.Getenv("GYAZO_SERVER_URL") != "" {
		endpoint = os.Getenv("GYAZO_SERVER_URL")
	} else if os.Getenv("GYAZO_ACCESS_TOKEN") != "" {
		endpoint = "https://upload.gyazo.com/api/upload"
	}
}

// Image represents a uploaded image on the Gyazo server.
//
// Gyazo API docs: https://gyazo.com/api/docs/image
type Image struct {
	ID           string `json:"image_id"`
	PermalinkURL string `json:"permalink_url"`
	ThumbURL     string `json:"thumb_url"`
	URL          string `json:"url"`
	Type         string `json:"type"`
}

// Upload a new image to a Gyazo server from the specified local image file.
//
// Gyazo API docs: https://gyazo.com/api/docs/image
func upload(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Fprintln(os.Stderr, "Try `gyazo --help` for more information")
		exitCode = 1
		return
	}

	filename := c.Args().First()
	content, err := os.Open(filename)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open and read %s\n", filename)
		return
	}
	defer content.Close()

	// Create multipart/form-data
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)

	part, err := writer.CreateFormFile("imagedata", filename)
	if err != nil {
		exitCode = 1
		return
	}

	if _, err = io.Copy(part, content); err != nil {
		exitCode = 1
		return
	}

	if os.Getenv("GYAZO_ACCESS_TOKEN") != "" {
		writer.WriteField("access_token", os.Getenv("GYAZO_ACCESS_TOKEN"))
	} else {
		writer.WriteField("id", gyazoID())
	}

	err = writer.Close()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create multipart/data: %s\n", err)
		exitCode = 1
		return
	}

	res, err := http.Post(endpoint, writer.FormDataContentType(), body)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to upload: %s\n", err)
		exitCode = 1
		return
	}
	defer res.Body.Close()

	url, err := imageURL(res)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Response error: %s\n", err)
		exitCode = 1
		return
	}

	fmt.Println(url)
	err = open.Run(url)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open by default browser: %s\n", err)
	}
}

// imageURL returns url of uploaded image.
func imageURL(r *http.Response) (string, error) {
	var url = ""
	if os.Getenv("GYAZO_ACCESS_TOKEN") != "" {
		image := Image{}
		if err := json.NewDecoder(r.Body).Decode(&image); err != nil {
			return url, err
		}

		url = image.PermalinkURL
	} else {
		id := r.Header.Get("X-Gyazo-Id")
		if err := saveGyazoID(id); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to save Gyazo ID: %s\n", err)
		}

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

		url = string(body)
	}

	return url, nil
}

// getID returns ID
func gyazoID() string {
	var id = ""

	fp, err := os.Open(gyazoIDPath())
	if err != nil {
		return id
	}
	defer fp.Close()

	body, err := ioutil.ReadAll(fp)
	if err != nil {
		return id
	}

	id = string(body)
	return id
}

// saveGyazoID stores Gyazo ID to file.
func saveGyazoID(id string) error {
	return nil
}

// gyazoIDPath returns path of Gyazo ID file on local filesystem.
func gyazoIDPath() string {
	homedir, _ := homedir.Dir()

	var path = ""
	switch runtime.GOOS {
	case "darwin":
		path = fmt.Sprintf("%s/Library/Gyazo/id", homedir)
	case "linux":
		path = fmt.Sprintf("%s/.gyazo.id", homedir)
	}

	return path
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"net"
	"net/http"
	"os"
	"regexp"
	"strings"
	"time"
)

var regex = regexp.MustCompile("(?m)[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}")
var verbose = false

var urls = []string{
	"myipinfo.net",
	"myip.dnsomatic.com",
	"icanhazip.com",
	"checkip.dyndns.org",
	"www.myipnumber.com",
	"checkmyip.com",
	"myexternalip.com",
	"www.ipchicken.com",
	"ipecho.net/plain",
	"bot.whatismyipaddress.com",
	"ipv4.ipogre.com",
	"smart-ip.net/myip",
	"checkip.amazonaws.com",
	"www.checkip.org",
}

func main() {
	var interactive = false
	var currentIp net.IP = nil

	if len(os.Args) > 1 {
		for _, arg := range os.Args[1:] {
			switch arg {
			case "-v", "--version":
				verbose = true
			case "-i", "--interactive":
				interactive = true
			case "-h", "--help":
				fmt.Print(`
Usage: myip [options]
where options include:
	--local, -l		returns the local IP address(es)
	--verbose, -v		enable verbose output
	--interactive, -i	enable interactive mode
	--help, -h		print this help message
`)
				return
			case "-l", "--local":
				listLocalIP()
				return
			default:
				fmt.Print(`Invalid option: '` + arg + `'
`)
				return
			}
		}
	}

	if interactive {
		fmt.Println("Select a url from the list:")
		for i, url := range urls {
			fmt.Printf("	[%v] %v\n", i + 1, url)
		}
		fmt.Printf("	[%v] custom url\n", len(urls) + 1)

		var number int
		_, err := fmt.Scanln(&number)
		if err != nil || number <= 0 || number > (len(urls) + 1) {
			fmt.Println("Incorrect value has been entered.")
			return
		}

		var url string
		if number == len(urls) + 1 {
			fmt.Println("Enter url:")
			_, err := fmt.Scanln(&url)
			if err != nil {
				fmt.Println("Incorrect url has been entered.")
				return
			}
			if url == "" {
				return
			}

		} else {
			url = urls[number - 1]
		}
		currentIp = getExternalIPByURL(url)
	} else {
		rand.Seed(time.Now().UTC().UnixNano())
		currentIp = getExternalIP()
	}

	if currentIp == nil {
		fmt.Println("No external IP address found.")
		return
	}
	fmt.Println(currentIp.String())
}

func listLocalIP() {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		if verbose {
			fmt.Printf("%v\n", err)
		}

		return
	}

	for _, address := range addrs {
		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				fmt.Println(ipnet.IP.String())
			}
		}
	}
}

func getExternalIP() net.IP {
	var currentIp net.IP
	for _, i := range rand.Perm(len(urls)) {
		if verbose {
			fmt.Printf("Connecting to %v...\n", urls[i])
		}

		url := "http://" + urls[i]

		content, err := getResponse(url)
		if err != nil {
			if verbose {
				fmt.Printf("%v\n", err)
			}
			continue
		}

		ip := regex.FindString(content)

		currentIp = net.ParseIP(ip)

		if currentIp != nil {
			return currentIp
		}

		fmt.Println("No valid IP address could be parsed from response.")
	}

	return currentIp
}

func getExternalIPByURL(url string) net.IP {
	if verbose {
		fmt.Printf("Connecting to %v...\n", url)
	}

	if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
		url = "http://" + url
	}

	content, err := getResponse(url)
	if err != nil {
		if verbose {
			fmt.Printf("%v\n", err)
		}
		return nil
	}

	ip := regex.FindString(content)

	currentIp := net.ParseIP(ip)

	if currentIp != nil {
		return currentIp
	}

	return nil
}

func getResponse(url string) (string, error) {
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", err
	}

	client := &http.Client{
		Timeout: time.Duration(3 * time.Second),
	}
	response, err := client.Do(request)
	if err != nil {
		return "", err
	}
	defer response.Body.Close()

	content, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return "", err
	}

	return string(content), nil
}
<commit_msg>Changes recommended by Golint<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"net"
	"net/http"
	"os"
	"regexp"
	"strings"
	"time"
)

var regex = regexp.MustCompile("(?m)[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}")
var verbose = false

var urls = []string{
	"myipinfo.net",
	"myip.dnsomatic.com",
	"icanhazip.com",
	"checkip.dyndns.org",
	"www.myipnumber.com",
	"checkmyip.com",
	"myexternalip.com",
	"www.ipchicken.com",
	"ipecho.net/plain",
	"bot.whatismyipaddress.com",
	"ipv4.ipogre.com",
	"smart-ip.net/myip",
	"checkip.amazonaws.com",
	"www.checkip.org",
}

func main() {
	var interactive = false
	var currentIP net.IP

	if len(os.Args) > 1 {
		for _, arg := range os.Args[1:] {
			switch arg {
			case "-v", "--version":
				verbose = true
			case "-i", "--interactive":
				interactive = true
			case "-h", "--help":
				fmt.Print(`
Usage: myip [options]
where options include:
	--local, -l		returns the local IP address(es)
	--verbose, -v		enable verbose output
	--interactive, -i	enable interactive mode
	--help, -h		print this help message
`)
				return
			case "-l", "--local":
				listLocalIP()
				return
			default:
				fmt.Print(`Invalid option: '` + arg + `'
`)
				return
			}
		}
	}

	if interactive {
		fmt.Println("Select a url from the list:")
		for i, url := range urls {
			fmt.Printf("	[%v] %v\n", i + 1, url)
		}
		fmt.Printf("	[%v] custom url\n", len(urls) + 1)

		var number int
		_, err := fmt.Scanln(&number)
		if err != nil || number <= 0 || number > (len(urls) + 1) {
			fmt.Println("Incorrect value has been entered.")
			return
		}

		var url string
		if number == len(urls) + 1 {
			fmt.Println("Enter url:")
			_, err := fmt.Scanln(&url)
			if err != nil {
				fmt.Println("Incorrect url has been entered.")
				return
			}
			if url == "" {
				return
			}

		} else {
			url = urls[number - 1]
		}
		currentIP = getExternalIPByURL(url)
	} else {
		rand.Seed(time.Now().UTC().UnixNano())
		currentIP = getExternalIP()
	}

	if currentIP == nil {
		fmt.Println("No external IP address found.")
		return
	}
	fmt.Println(currentIP.String())
}

func listLocalIP() {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		if verbose {
			fmt.Printf("%v\n", err)
		}

		return
	}

	for _, address := range addrs {
		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				fmt.Println(ipnet.IP.String())
			}
		}
	}
}

func getExternalIP() net.IP {
	var currentIP net.IP
	for _, i := range rand.Perm(len(urls)) {
		if verbose {
			fmt.Printf("Connecting to %v...\n", urls[i])
		}

		url := "http://" + urls[i]

		content, err := getResponse(url)
		if err != nil {
			if verbose {
				fmt.Printf("%v\n", err)
			}
			continue
		}

		ip := regex.FindString(content)

		currentIP = net.ParseIP(ip)

		if currentIP != nil {
			return currentIP
		}

		fmt.Println("No valid IP address could be parsed from response.")
	}

	return currentIP
}

func getExternalIPByURL(url string) net.IP {
	if verbose {
		fmt.Printf("Connecting to %v...\n", url)
	}

	if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
		url = "http://" + url
	}

	content, err := getResponse(url)
	if err != nil {
		if verbose {
			fmt.Printf("%v\n", err)
		}
		return nil
	}

	ip := regex.FindString(content)

	currentIP := net.ParseIP(ip)

	if currentIP != nil {
		return currentIP
	}

	return nil
}

func getResponse(url string) (string, error) {
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", err
	}

	client := &http.Client{
		Timeout: time.Duration(3 * time.Second),
	}
	response, err := client.Do(request)
	if err != nil {
		return "", err
	}
	defer response.Body.Close()

	content, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return "", err
	}

	return string(content), nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/gob"
	"flag"
	"fmt"
	"github.com/neurodrone/aws-sqs/sqs"
	"log"
	"os"
)

var (
	awsAccessKey = flag.String("accesskey", "", "AWS Access Key")
	awsSecret    = flag.String("secret", "", "AWS Secret Key")

	regionId  = flag.String("region", "", "AWS Region ID")
	uuid      = flag.String("uuid", "", "AWS Unique ID")
	queueName = flag.String("queue", "", "AWS Queue Name")
)

type SampleMessageStruct struct {
	SomeStr string
	SomeInt int
}

func main() {
	flag.Parse()

	e := validateInputs()
	if e.hasErrors() {
		e.printErrors(os.Stderr)
		log.Fatalf("Aborting.")
	}

	sqsReq := &sqs.SQSRequest{
		*regionId,
		*uuid,
		*queueName,
		*awsAccessKey,
		*awsSecret,
	}

	qur, err := sqsReq.QueueURL()
	if err != nil {
		log.Fatalf("Unable to fetch queue url: %s", err)
	}
	log.Println(qur.QueueURL)

	qlr, err := sqsReq.ListQueues("stat")
	if err != nil {
		log.Fatalf("Unable to list queues: %s", err)
	}
	log.Println(qlr.QueueURLs)

	var buf bytes.Buffer
	var message string
	var m *SampleMessageStruct

	m = &SampleMessageStruct{"strVal", 7}
	gob.NewEncoder(&buf).Encode(m)

	message = buf.String()
	_, err = sqsReq.SendSQSMessage(message)
	if err != nil {
		log.Fatalf("Unable to enqueue message: %s", err)
	}
	log.Println("Message sent.")

	msgResp, err := sqsReq.ReceiveSQSMessage()
	if err != nil {
		log.Fatalf("Unable to receive message: %s", err)
	}

	log.Println(msgResp.MessageId, "received.")
	message = msgResp.MessageBody

	m = new(SampleMessageStruct)
	gob.NewDecoder(bytes.NewBufferString(message)).Decode(m)
	log.Println(m)

	_, err = sqsReq.DeleteSQSMessage(msgResp.ReceiptHandle)
	if err != nil {
		log.Fatalf("Unable to delete message: %s", msgResp.MessageId)
	}

	log.Println("Successfully received and deleted.")
}

func validateInputs() Errors {
	errs := make(Errors, 0)

	flag.VisitAll(func(fl *flag.Flag) {
		if fl.Value.String() == fl.DefValue {
			errs = append(errs, fmt.Errorf("%s needs to be set.", fl.Usage))
		}
	})

	return errs
}
<commit_msg>Don't fatal when you can panic<commit_after>package main

import (
	"bytes"
	"encoding/gob"
	"flag"
	"fmt"
	"github.com/neurodrone/aws-sqs/sqs"
	"log"
	"os"
)

var (
	awsAccessKey = flag.String("accesskey", "", "AWS Access Key")
	awsSecret    = flag.String("secret", "", "AWS Secret Key")

	regionId  = flag.String("region", "", "AWS Region ID")
	uuid      = flag.String("uuid", "", "AWS Unique ID")
	queueName = flag.String("queue", "", "AWS Queue Name")
)

type SampleMessageStruct struct {
	SomeStr string
	SomeInt int
}

func main() {
	flag.Parse()

	e := validateInputs()
	if e.hasErrors() {
		e.printErrors(os.Stderr)
		log.Panicf("Aborting.")
	}

	sqsReq := &sqs.SQSRequest{
		*regionId,
		*uuid,
		*queueName,
		*awsAccessKey,
		*awsSecret,
	}

	qur, err := sqsReq.QueueURL()
	if err != nil {
		log.Panicf("Unable to fetch queue url: %s", err)
	}
	log.Println(qur.QueueURL)

	qlr, err := sqsReq.ListQueues("stat")
	if err != nil {
		log.Panicf("Unable to list queues: %s", err)
	}
	log.Println(qlr.QueueURLs)

	var buf bytes.Buffer
	var message string
	var m *SampleMessageStruct

	m = &SampleMessageStruct{"strVal", 7}
	gob.NewEncoder(&buf).Encode(m)

	message = buf.String()
	_, err = sqsReq.SendSQSMessage(message)
	if err != nil {
		log.Panicf("Unable to enqueue message: %s", err)
	}
	log.Println("Message sent.")

	msgResp, err := sqsReq.ReceiveSQSMessage()
	if err != nil {
		log.Panicf("Unable to receive message: %s", err)
	}

	log.Println(msgResp.MessageId, "received.")
	message = msgResp.MessageBody

	m = new(SampleMessageStruct)
	gob.NewDecoder(bytes.NewBufferString(message)).Decode(m)
	log.Println(m)

	_, err = sqsReq.DeleteSQSMessage(msgResp.ReceiptHandle)
	if err != nil {
		log.Panicf("Unable to delete message: %s", msgResp.MessageId)
	}

	log.Println("Successfully received and deleted.")
}

func validateInputs() Errors {
	errs := make(Errors, 0)

	flag.VisitAll(func(fl *flag.Flag) {
		if fl.Value.String() == fl.DefValue {
			errs = append(errs, fmt.Errorf("%s needs to be set.", fl.Usage))
		}
	})

	return errs
}
<|endoftext|>


<commit_before>package blobstore

const (
	blobTypeSimpleStaticFile = 0x01
	blobTypeSimpleStaticDir  = 0x11

	maxSimpleFileDataSize = 16 * 1024 * 1024
	maxSimpleDirEntries   = 1024

	validationMethodHash = 0x01
)
<commit_msg>Add type bytes for split file and split dir<commit_after>package blobstore

const (
	blobTypeSimpleStaticFile = 0x01
	blobTypeSplitStaticFile  = 0x02
	blobTypeSimpleStaticDir  = 0x11
	blobTypeSplitStaticDir   = 0x12

	maxSimpleFileDataSize = 16 * 1024 * 1024
	maxSimpleDirEntries   = 1024

	validationMethodHash = 0x01
)
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", hello)
	fmt.Println("listening...")
	err := http.ListenAndServe(":80", nil)
	if err != nil {
		panic(err)
	}
}

func hello(res http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(res, "Hello World!")
}<commit_msg>initial commit<commit_after>package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", hello)
	fmt.Println("listening...")
	err := http.ListenAndServe(":80", nil)
	if err != nil {
		panic(err)
	}
}

func hello(res http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(res, "Hello Go!")
}<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"flag"
	"fmt"
	_ "github.com/lib/pq"
	"log"
	"net/http"
	"os"
	"runtime"
	"strconv"
	"encoding/json"
)

const version = "0.0.0"

var database string
var user string
var pass string
var port uint

func init() {
	const (
		databaseDefault = ""
		databaseUsage   = "database"
		userDefault     = ""
		userUsage       = "database user"
		passDefault     = ""
		passUsage       = "database password"
		portDefault     = 0
		portUsage       = "http serve port"
	)
	flag.StringVar(&database, "database", databaseDefault, databaseUsage)
	flag.StringVar(&database, "d", databaseDefault, databaseUsage+" (shorthand)")
	flag.StringVar(&user, "user", userDefault, userUsage)
	flag.StringVar(&user, "u", userDefault, userUsage+" (shorthand)")
	flag.StringVar(&pass, "password", passDefault, passUsage)
	flag.StringVar(&pass, "pass", passDefault, passUsage+" (shorthand)")
	flag.UintVar(&port, "port", portDefault, portUsage)
	flag.UintVar(&port, "p", portDefault, portUsage+" (shorthand)")
}

func printUsage() {
	exeName := os.Args[0]
	fmt.Println(exeName + " " + version + " usage: ")
	fmt.Println("\t" + exeName + " -d star-database -u database-user-name -pass database-user-password -p serve-port")
	fmt.Println("flags:")
	flag.PrintDefaults()
	fmt.Println("example:\n\t" + exeName + " -d hyg -u jimbob -p nascarrulez -p 8008")
}

type Star struct {
	Id                int64 `json:"id"`
	Name              string `json:"name"`
	X                 float64 `json:"x"`
	Y                 float64 `json:"y"`
	Z                 float64 `json:"z"`
	Color             float32 `json:"color"`
	AbsoluteMagnitude float32 `json:"absolute-magnitude"`
	Spectrum          string `json:"spectrum"`
}

func (star *Star) Json() []byte {
	bytes, err := json.Marshal(star);
	if err != nil {
		return nil ///< @todo fix to return JSON error
	}
	return bytes
}

type NullStar struct {
	Id                sql.NullInt64
	Name              sql.NullString
	X                 sql.NullFloat64
	Y                 sql.NullFloat64
	Z                 sql.NullFloat64
	Color             sql.NullFloat64
	AbsoluteMagnitude sql.NullFloat64
	Spectrum          sql.NullString
}

/// returns a Star, with zero values for any null values in the NullStar
func (nstar *NullStar) Star() Star {
	var star Star
	if nstar.Id.Valid {
		star.Id = nstar.Id.Int64
	}
	if nstar.Name.Valid {
		star.Name = nstar.Name.String
	}
	if nstar.X.Valid {
		star.X = nstar.X.Float64
	}
	if nstar.Y.Valid {
		star.Y = nstar.Y.Float64
	}
	if nstar.Z.Valid {
		star.Z = nstar.Z.Float64
	}
	if nstar.Color.Valid {
		star.Color = float32(nstar.Color.Float64)
	}
	if nstar.AbsoluteMagnitude.Valid {
		star.AbsoluteMagnitude = float32(nstar.AbsoluteMagnitude.Float64)
	}
	if nstar.Spectrum.Valid {
		star.Spectrum = nstar.Spectrum.String
	}
	return star
}

func dbManager(user string, pass string, getStar chan struct {
	id       int64
	callback chan Star
}) {
	fmt.Println("Opening " + "postgres://" + user + ":" + pass + "@localhost/")
	db, err := sql.Open("postgres", "postgres://"+user+":"+pass+"@localhost/"+database)
	if err != nil {
		log.Fatal(err)
	}

	sql := "select propername, x, y, z, colorindex, absmag, spectrum from hygxyz where starid = $1"
	stmt, err := db.Prepare(sql)
	if err != nil {
		log.Fatal(err)
	}

	for {
		request := <-getStar

		rows, err := stmt.Query(request.id)

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

		if !rows.Next() {
			request.callback <- Star{}
			continue
		}

		var nstar NullStar
		err = rows.Scan(&nstar.Name, &nstar.X, &nstar.Y, &nstar.Z, &nstar.Color, &nstar.AbsoluteMagnitude, &nstar.Spectrum)
		if err != nil {
			log.Fatal(err)
		}
		star := nstar.Star()
		star.Id = request.id
		request.callback <- star // return zero values for null fields

		rows.Close()
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.Parse()

	if database == "" || user == "" || pass == "" || port == 0 || port > 65535 {
		printUsage()
		return
	}

	getStar := make(chan struct {
		id       int64
		callback chan Star
	}, 100)

	go dbManager(user, pass, getStar)

	http.HandleFunc("/star/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("Serving request to " + r.URL.Path)

		getStarCallback := make(chan Star)

		staridStr := r.URL.Path[len("/star/"):]
		starid, err := strconv.Atoi(staridStr)
		if err != nil {
			fmt.Println("ignoring request for non-integral star id")
			return
		}

		getStar <- struct {
			id       int64
			callback chan Star
		}{int64(starid), getStarCallback}
		star := <-getStarCallback
		starjson := star.Json();

		w.Header().Add("Content-Type", "application/json")
		w.Header().Add("Content-Length", strconv.Itoa(len(starjson)))

		_, err = w.Write(starjson)
		if err != nil {
			fmt.Println(err)
		}
	})

	fmt.Println("Serving on " + strconv.Itoa(int(port)) + "...")
	http.ListenAndServe(":"+strconv.Itoa(int(port)), nil)
}
<commit_msg>gofmt<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"flag"
	"fmt"
	_ "github.com/lib/pq"
	"log"
	"net/http"
	"os"
	"runtime"
	"strconv"
)

const version = "0.0.0"

var database string
var user string
var pass string
var port uint

func init() {
	const (
		databaseDefault = ""
		databaseUsage   = "database"
		userDefault     = ""
		userUsage       = "database user"
		passDefault     = ""
		passUsage       = "database password"
		portDefault     = 0
		portUsage       = "http serve port"
	)
	flag.StringVar(&database, "database", databaseDefault, databaseUsage)
	flag.StringVar(&database, "d", databaseDefault, databaseUsage+" (shorthand)")
	flag.StringVar(&user, "user", userDefault, userUsage)
	flag.StringVar(&user, "u", userDefault, userUsage+" (shorthand)")
	flag.StringVar(&pass, "password", passDefault, passUsage)
	flag.StringVar(&pass, "pass", passDefault, passUsage+" (shorthand)")
	flag.UintVar(&port, "port", portDefault, portUsage)
	flag.UintVar(&port, "p", portDefault, portUsage+" (shorthand)")
}

func printUsage() {
	exeName := os.Args[0]
	fmt.Println(exeName + " " + version + " usage: ")
	fmt.Println("\t" + exeName + " -d star-database -u database-user-name -pass database-user-password -p serve-port")
	fmt.Println("flags:")
	flag.PrintDefaults()
	fmt.Println("example:\n\t" + exeName + " -d hyg -u jimbob -p nascarrulez -p 8008")
}

type Star struct {
	Id                int64   `json:"id"`
	Name              string  `json:"name"`
	X                 float64 `json:"x"`
	Y                 float64 `json:"y"`
	Z                 float64 `json:"z"`
	Color             float32 `json:"color"`
	AbsoluteMagnitude float32 `json:"absolute-magnitude"`
	Spectrum          string  `json:"spectrum"`
}

func (star *Star) Json() []byte {
	bytes, err := json.Marshal(star)
	if err != nil {
		return nil ///< @todo fix to return JSON error
	}
	return bytes
}

type NullStar struct {
	Id                sql.NullInt64
	Name              sql.NullString
	X                 sql.NullFloat64
	Y                 sql.NullFloat64
	Z                 sql.NullFloat64
	Color             sql.NullFloat64
	AbsoluteMagnitude sql.NullFloat64
	Spectrum          sql.NullString
}

/// returns a Star, with zero values for any null values in the NullStar
func (nstar *NullStar) Star() Star {
	var star Star
	if nstar.Id.Valid {
		star.Id = nstar.Id.Int64
	}
	if nstar.Name.Valid {
		star.Name = nstar.Name.String
	}
	if nstar.X.Valid {
		star.X = nstar.X.Float64
	}
	if nstar.Y.Valid {
		star.Y = nstar.Y.Float64
	}
	if nstar.Z.Valid {
		star.Z = nstar.Z.Float64
	}
	if nstar.Color.Valid {
		star.Color = float32(nstar.Color.Float64)
	}
	if nstar.AbsoluteMagnitude.Valid {
		star.AbsoluteMagnitude = float32(nstar.AbsoluteMagnitude.Float64)
	}
	if nstar.Spectrum.Valid {
		star.Spectrum = nstar.Spectrum.String
	}
	return star
}

func dbManager(user string, pass string, getStar chan struct {
	id       int64
	callback chan Star
}) {
	fmt.Println("Opening " + "postgres://" + user + ":" + pass + "@localhost/")
	db, err := sql.Open("postgres", "postgres://"+user+":"+pass+"@localhost/"+database)
	if err != nil {
		log.Fatal(err)
	}

	sql := "select propername, x, y, z, colorindex, absmag, spectrum from hygxyz where starid = $1"
	stmt, err := db.Prepare(sql)
	if err != nil {
		log.Fatal(err)
	}

	for {
		request := <-getStar

		rows, err := stmt.Query(request.id)

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

		if !rows.Next() {
			request.callback <- Star{}
			continue
		}

		var nstar NullStar
		err = rows.Scan(&nstar.Name, &nstar.X, &nstar.Y, &nstar.Z, &nstar.Color, &nstar.AbsoluteMagnitude, &nstar.Spectrum)
		if err != nil {
			log.Fatal(err)
		}
		star := nstar.Star()
		star.Id = request.id
		request.callback <- star // return zero values for null fields

		rows.Close()
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.Parse()

	if database == "" || user == "" || pass == "" || port == 0 || port > 65535 {
		printUsage()
		return
	}

	getStar := make(chan struct {
		id       int64
		callback chan Star
	}, 100)

	go dbManager(user, pass, getStar)

	http.HandleFunc("/star/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("Serving request to " + r.URL.Path)

		getStarCallback := make(chan Star)

		staridStr := r.URL.Path[len("/star/"):]
		starid, err := strconv.Atoi(staridStr)
		if err != nil {
			fmt.Println("ignoring request for non-integral star id")
			return
		}

		getStar <- struct {
			id       int64
			callback chan Star
		}{int64(starid), getStarCallback}
		star := <-getStarCallback
		starjson := star.Json()

		w.Header().Add("Content-Type", "application/json")
		w.Header().Add("Content-Length", strconv.Itoa(len(starjson)))

		_, err = w.Write(starjson)
		if err != nil {
			fmt.Println(err)
		}
	})

	fmt.Println("Serving on " + strconv.Itoa(int(port)) + "...")
	http.ListenAndServe(":"+strconv.Itoa(int(port)), nil)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/attilaolah/strict"
	"github.com/go-martini/martini"
	"github.com/martini-contrib/binding"
	"github.com/martini-contrib/gzip"
	"github.com/martini-contrib/render"
	"github.com/martini-contrib/sessions"
	"log"
)

func main() {
	m := martini.Classic()
	store := sessions.NewCookieStore([]byte("heartbleed"))
	m.Use(sessions.Sessions("user", store))
	m.Use(render.Renderer())
	m.Use(middleware())
	m.Use(strict.Strict)
	m.Use(gzip.All())
	m.Use(render.Renderer(render.Options{
		Layout: "layout",
	}))

	m.Get("/", func(r render.Render) {
		r.HTML(200, "home", nil)
	})

	m.Group("/post", func(r martini.Router) {

		// Please note that `/new` route has to be before the `/:title` route. Otherwise the program will try
		// to fetch for Post named "new".
		// For now I'll keep it this way to streamline route naming.
		r.Get("/new", ProtectedPage, func(res render.Render) {
			res.HTML(200, "post/new", nil)
		})
		r.Get("/:title", ReadPost)
		r.Post("/new", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Post{}), binding.ErrorHandler, CreatePost)

	})

	m.Group("/user", func(r martini.Router) {

		r.Get("", ProtectedPage, ReadUser)
		//r.Post("/delete", strict.ContentType("application/x-www-form-urlencoded"), ProtectedPage, binding.Form(Person{}), DeleteUser)

		r.Get("/register", SessionRedirect, func(res render.Render) {
			res.HTML(200, "user/register", nil)
		})
		r.Post("/register", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Person{}), binding.ErrorHandler, CreateUser)

		r.Get("/login", SessionRedirect, func(res render.Render) {
			res.HTML(200, "user/login", nil)
		})
		r.Post("/login", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Person{}), LoginUser)

		r.Get("/logout", func(s sessions.Session, res render.Render) {
			s.Delete("user")
			res.Redirect("/", 302)
		})

	})

	m.Group("/api", func(r martini.Router) {

		r.Get("/users", ReadUsers)
		r.Get("/user/:id", ReadUser)
		//r.Delete("/user", DeleteUser)
		r.Post("/user", strict.ContentType("application/json"), binding.Json(Person{}), binding.ErrorHandler, CreateUser)
		r.Post("/user/login", strict.ContentType("application/json"), binding.Json(Person{}), binding.ErrorHandler, LoginUser)

		r.Get("/posts", ReadPosts)
		r.Get("/post/:title", ReadPost)
		r.Post("/post", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, CreatePost)

	})

	m.Router.NotFound(strict.MethodNotAllowed, strict.NotFound)
	m.Run()

	log.Println("Server started.")
}
<commit_msg>routes: add template helpers to render HTML correctly, add homepage and API index route<commit_after>package main

import (
	"github.com/attilaolah/strict"
	"github.com/go-martini/martini"
	"github.com/martini-contrib/binding"
	"github.com/martini-contrib/gzip"
	"github.com/martini-contrib/render"
	"github.com/martini-contrib/sessions"
	"log"
	"html/template"
)

func main() {

	helpers := template.FuncMap{
		"unescape": func(s string) template.HTML {
			return template.HTML(s)
		},
	}

	m := martini.Classic()
	store := sessions.NewCookieStore([]byte("heartbleed"))
	m.Use(sessions.Sessions("user", store))
	m.Use(middleware())
	m.Use(strict.Strict)
	m.Use(gzip.All())
	m.Use(render.Renderer(render.Options{
		Layout: "layout",
		Funcs: []template.FuncMap{helpers}, // Specify helper function maps for templates to access.
	}))

	m.Get("/", Homepage)

	m.Group("/post", func(r martini.Router) {

		// Please note that `/new` route has to be before the `/:title` route. Otherwise the program will try
		// to fetch for Post named "new".
		// For now I'll keep it this way to streamline route naming.
		r.Get("/new", ProtectedPage, func(res render.Render) {
			res.HTML(200, "post/new", nil)
		})
		r.Get("/:title", ReadPost)
		r.Post("/new", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Post{}), binding.ErrorHandler, CreatePost)

	})

	m.Group("/user", func(r martini.Router) {

		r.Get("", ProtectedPage, ReadUser)
		//r.Post("/delete", strict.ContentType("application/x-www-form-urlencoded"), ProtectedPage, binding.Form(Person{}), DeleteUser)

		r.Get("/register", SessionRedirect, func(res render.Render) {
			res.HTML(200, "user/register", nil)
		})
		r.Post("/register", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Person{}), binding.ErrorHandler, CreateUser)

		r.Get("/login", SessionRedirect, func(res render.Render) {
			res.HTML(200, "user/login", nil)
		})
		r.Post("/login", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Person{}), LoginUser)

		r.Get("/logout", func(s sessions.Session, res render.Render) {
			s.Delete("user")
			res.Redirect("/", 302)
		})

	})

	m.Group("/api", func(r martini.Router) {

		r.Get("", func(res render.Render) {
			res.HTML(200, "api/index", nil)
		})
		r.Get("/users", ReadUsers)
		r.Get("/user/:id", ReadUser)
		//r.Delete("/user", DeleteUser)
		r.Post("/user", strict.ContentType("application/json"), binding.Json(Person{}), binding.ErrorHandler, CreateUser)
		r.Post("/user/login", strict.ContentType("application/json"), binding.Json(Person{}), binding.ErrorHandler, LoginUser)

		r.Get("/posts", ReadPosts)
		r.Get("/post/:title", ReadPost)
		r.Post("/post", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, CreatePost)

	})

	m.Router.NotFound(strict.MethodNotAllowed, strict.NotFound)
	m.Run()

	log.Println("Server started.")
}
<|endoftext|>


<commit_before>package main

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

func main() {

	clients := strings.Split(os.Getenv("XLANG_CLIENTS"), ",")
	servers := strings.Split(os.Getenv("XLANG_SERVERS"), ",")
	behaviors := strings.Split(os.Getenv("XLANG_BEHAVIORS"), ",")

	matrix := Matrix{
		Clients:   clients,
		Servers:   servers,
		Behaviors: behaviors,
	}

	beginMatrixTest(matrix)
}

type Matrix struct {
	Clients   []string
	Servers   []string
	Behaviors []string
}

func beginMatrixTest(matrix Matrix) {

	for _, client := range matrix.Clients {
		for _, server := range matrix.Servers {
			for _, behavior := range matrix.Behaviors {

				testCase := TestCase{
					Client:   client,
					Server:   server,
					Behavior: behavior,
				}

				executeTestCase(testCase)
			}
		}
	}
}

type TestCase struct {
	Client   string
	Server   string
	Behavior string
}

func executeTestCase(testCase TestCase) {

	// start with base url
	callUrl, err := url.Parse(fmt.Sprintf("http://%v:8080/", testCase.Client))
	if err != nil {
		log.Fatal(err)
	}

	// build query params
	params := url.Values{}
	params.Add("server", testCase.Server)
	params.Add("behavior", testCase.Behavior)
	callUrl.RawQuery = params.Encode()

	// make request to test client
	resp, err := http.Get(callUrl.String())
	if err != nil {
		log.Fatal(err)
	}

	log.Println(resp.StatusCode, callUrl.String())
}
<commit_msg>output response<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"strings"
)

func main() {

	clients := strings.Split(os.Getenv("XLANG_CLIENTS"), ",")
	servers := strings.Split(os.Getenv("XLANG_SERVERS"), ",")
	behaviors := strings.Split(os.Getenv("XLANG_BEHAVIORS"), ",")

	matrix := Matrix{
		Clients:   clients,
		Servers:   servers,
		Behaviors: behaviors,
	}

	beginMatrixTest(matrix)
}

type Matrix struct {
	Clients   []string
	Servers   []string
	Behaviors []string
}

func beginMatrixTest(matrix Matrix) {

	for _, client := range matrix.Clients {
		for _, server := range matrix.Servers {
			for _, behavior := range matrix.Behaviors {

				testCase := TestCase{
					Client:   client,
					Server:   server,
					Behavior: behavior,
				}

				executeTestCase(testCase)
			}
		}
	}
}

type TestCase struct {
	Client   string
	Server   string
	Behavior string
}

func executeTestCase(testCase TestCase) {

	callUrl, err := url.Parse(fmt.Sprintf("http://%v:8080/", testCase.Client))
	if err != nil {
		log.Fatal(err)
	}

	params := url.Values{}
	params.Add("server", testCase.Server)
	params.Add("behavior", testCase.Behavior)
	callUrl.RawQuery = params.Encode()

	resp, err := http.Get(callUrl.String())
	if err != nil {
		log.Fatal(err)
	}

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

	fmt.Println(fmt.Sprintf("%v - %v - %v", resp.StatusCode, callUrl.String(), string(body)))
}
<|endoftext|>


<commit_before>package main

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

	"github.com/kisielk/errcheck/lib"
	"github.com/kisielk/gotool"
)

// Err prints an error to Stderr
func Err(s string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "error: "+s+"\n", args...)
}

// Fatal calls Err followed by os.Exit(2)
func Fatalf(s string, args ...interface{}) {
	Err(s, args...)
	os.Exit(2)
}

type ignoreFlag map[string]*regexp.Regexp

func (f ignoreFlag) String() string {
	pairs := make([]string, 0, len(f))
	for pkg, re := range f {
		prefix := ""
		if pkg != "" {
			prefix = pkg + ":"
		}
		pairs = append(pairs, prefix+re.String())
	}
	return fmt.Sprintf("%q", strings.Join(pairs, ","))
}

func (f ignoreFlag) Set(s string) error {
	if s == "" {
		return nil
	}
	for _, pair := range strings.Split(s, ",") {
		colonIndex := strings.Index(pair, ":")
		var pkg, re string
		if colonIndex == -1 {
			pkg = ""
			re = pair
		} else {
			pkg = pair[:colonIndex]
			re = pair[colonIndex+1:]
		}
		regex, err := regexp.Compile(re)
		if err != nil {
			return err
		}
		f[pkg] = regex
	}
	return nil
}

var dotStar = regexp.MustCompile(".*")

func main() {
	ignore := ignoreFlag(map[string]*regexp.Regexp{
		"fmt": dotStar,
	})
	flag.Var(ignore, "ignore", "comma-separated list of pairs of the form pkg:regex\n"+
		"            the regex is used to ignore names within pkg")
	ignorePkg := flag.String("ignorepkg", "", "comma-separated list of package paths to ignore")
	blank := flag.Bool("blank", false, "if true, check for errors assigned to blank identifier")
	asserts := flag.Bool("asserts", false, "if true, check for ignored type assertion results")
	flag.Parse()

	for _, pkg := range strings.Split(*ignorePkg, ",") {
		if pkg != "" {
			ignore[pkg] = dotStar
		}
	}

	var exitStatus int
	for _, pkgPath := range gotool.ImportPaths(flag.Args()) {
		if err := errcheck.CheckPackage(pkgPath, ignore, *blank, *asserts); err != nil {
			if e, ok := err.(errcheck.UncheckedErrors); ok {
				for _, uncheckedError := range e.Errors {
					fmt.Println(uncheckedError)
				}
				exitStatus = 1
				continue
			} else if err == errcheck.ErrNoGoFiles {
				fmt.Fprintln(os.Stderr, err)
				continue
			}
			Fatalf("failed to check package %s: %s", pkgPath, err)
		}
	}
	os.Exit(exitStatus)
}
<commit_msg>Update imports.<commit_after>package main

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

	"github.com/alecthomas/errcheck/lib"
	"github.com/kisielk/gotool"
)

// Err prints an error to Stderr
func Err(s string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "error: "+s+"\n", args...)
}

// Fatal calls Err followed by os.Exit(2)
func Fatalf(s string, args ...interface{}) {
	Err(s, args...)
	os.Exit(2)
}

type ignoreFlag map[string]*regexp.Regexp

func (f ignoreFlag) String() string {
	pairs := make([]string, 0, len(f))
	for pkg, re := range f {
		prefix := ""
		if pkg != "" {
			prefix = pkg + ":"
		}
		pairs = append(pairs, prefix+re.String())
	}
	return fmt.Sprintf("%q", strings.Join(pairs, ","))
}

func (f ignoreFlag) Set(s string) error {
	if s == "" {
		return nil
	}
	for _, pair := range strings.Split(s, ",") {
		colonIndex := strings.Index(pair, ":")
		var pkg, re string
		if colonIndex == -1 {
			pkg = ""
			re = pair
		} else {
			pkg = pair[:colonIndex]
			re = pair[colonIndex+1:]
		}
		regex, err := regexp.Compile(re)
		if err != nil {
			return err
		}
		f[pkg] = regex
	}
	return nil
}

var dotStar = regexp.MustCompile(".*")

func main() {
	ignore := ignoreFlag(map[string]*regexp.Regexp{
		"fmt": dotStar,
	})
	flag.Var(ignore, "ignore", "comma-separated list of pairs of the form pkg:regex\n"+
		"            the regex is used to ignore names within pkg")
	ignorePkg := flag.String("ignorepkg", "", "comma-separated list of package paths to ignore")
	blank := flag.Bool("blank", false, "if true, check for errors assigned to blank identifier")
	asserts := flag.Bool("asserts", false, "if true, check for ignored type assertion results")
	flag.Parse()

	for _, pkg := range strings.Split(*ignorePkg, ",") {
		if pkg != "" {
			ignore[pkg] = dotStar
		}
	}

	var exitStatus int
	for _, pkgPath := range gotool.ImportPaths(flag.Args()) {
		if err := errcheck.CheckPackage(pkgPath, ignore, *blank, *asserts); err != nil {
			if e, ok := err.(errcheck.UncheckedErrors); ok {
				for _, uncheckedError := range e.Errors {
					fmt.Println(uncheckedError)
				}
				exitStatus = 1
				continue
			} else if err == errcheck.ErrNoGoFiles {
				fmt.Fprintln(os.Stderr, err)
				continue
			}
			Fatalf("failed to check package %s: %s", pkgPath, err)
		}
	}
	os.Exit(exitStatus)
}
<|endoftext|>


<commit_before>// Package main is an entry point of the application.
package main

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

	"github.com/alkchr/pp/routes"

	"github.com/goaltools/iniflag"
)

var (
	addr = flag.String("http.addr", ":8080", "HTTP address the app must listen on")

	// Parameters for using HTTPS mode.
	tls  = flag.Bool("tls.enable", false, "Start application using TLS")
	cert = flag.String("tls.cert", "", "Path to the TLS certificate file")
	key  = flag.String("tls.key", "", "Path to the TLS key file")
)

// main parses INI configuration files making their values
// available to the flags of the application, prepares a handler,
// and starts a new server.
func main() {
	// Parse INI configuration files to make their values
	// available as flags.
	err := iniflag.Parse("config/app.ini")
	assertNil(err)

	// Allocate and run a new server. Depending on the
	// configuration use either HTTP or HTTPS.
	s := &http.Server{
		Addr:    *addr,
		Handler: routes.Handler(),
	}
	log.Printf(`Listening on "%s"...`, s.Addr)
	switch *tls {
	case true:
		err = s.ListenAndServeTLS(*cert, *key)
	default:
		err = s.ListenAndServe()
	}
	assertNil(err)
}

// assertNil gets an error as an argument and makes sure
// it is nil. If it isn't, it terminates the program.
func assertNil(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Initialize handlers after parsing flags<commit_after>// Package main is an entry point of the application.
package main

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

	"github.com/alkchr/pp/handlers"
	"github.com/alkchr/pp/routes"

	"github.com/goaltools/iniflag"
)

var (
	addr = flag.String("http.addr", ":8080", "HTTP address the app must listen on")

	// Parameters for using HTTPS mode.
	tls  = flag.Bool("tls.enable", false, "Start application using TLS")
	cert = flag.String("tls.cert", "", "Path to the TLS certificate file")
	key  = flag.String("tls.key", "", "Path to the TLS key file")
)

// main parses INI configuration files making their values
// available to the flags of the application, prepares a handler,
// and starts a new server.
func main() {
	// Parse INI configuration files to make their values
	// available as flags.
	err := iniflag.Parse("config/app.ini")
	assertNil(err)

	// Initialize handlers.
	handlers.Init()

	// Allocate and run a new server. Depending on the
	// configuration use either HTTP or HTTPS.
	s := &http.Server{
		Addr:    *addr,
		Handler: routes.Handler(),
	}
	log.Printf(`Listening on "%s"...`, s.Addr)
	switch *tls {
	case true:
		err = s.ListenAndServeTLS(*cert, *key)
	default:
		err = s.ListenAndServe()
	}
	assertNil(err)
}

// assertNil gets an error as an argument and makes sure
// it is nil. If it isn't, it terminates the program.
func assertNil(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"html/template"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"regexp"
	"sync"
	"syscall"

	"github.com/gorilla/websocket"
	"github.com/hpcloud/tail"
	maxminddb "github.com/oschwald/maxminddb-golang"
)

type broadcaster struct {
	mu sync.Mutex
	cs []chan<- interface{}
}

func (b *broadcaster) sub(c chan<- interface{}) {
	b.mu.Lock()
	defer b.mu.Unlock()

	b.cs = append(b.cs, c)
}

func (b *broadcaster) usub(c chan<- interface{}) {
	b.mu.Lock()
	defer b.mu.Unlock()

	n := b.cs[:0]
	for _, x := range b.cs {
		if x != c {
			n = append(n, x)
		}
	}
	b.cs = n
}

func (b *broadcaster) pub(v interface{}) {
	b.mu.Lock()
	defer b.mu.Unlock()

	for _, c := range b.cs {
		c <- v
	}
}

func (b *broadcaster) close() {
	b.mu.Lock()
	defer b.mu.Unlock()

	for _, c := range b.cs {
		close(c)
	}
}

type mmrecord struct {
	Location struct {
		Latitude  float64 `maxminddb:"latitude"`
		Longitude float64 `maxminddb:"longitude"`
	} `maxminddb:"location"`
}

var b *broadcaster

func main() {
	logFilename := os.Getenv("LOG_FILENAME")
	if logFilename == "" {
		log.Fatal("LOG_FILENAME env variable is required")
	}

	gdb, err := maxminddb.Open("GeoLite2-City.mmdb")
	if err != nil {
		log.Fatalf("failed to open maxmind db: %v", err)
	}
	defer gdb.Close()

	t, err := tail.TailFile(logFilename, tail.Config{
		Follow:   true,
		Location: &tail.SeekInfo{Whence: os.SEEK_END},
	})
	if err != nil {
		log.Fatalf("failed to tail %s: %v", "ips.log", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/ws", ws)
	mux.HandleFunc("/", index)
	httpListenOn := os.Getenv("HTTP_LISTEN_ON")
	if httpListenOn == "" {
		httpListenOn = ":8080"
	}
	server := http.Server{Addr: httpListenOn, Handler: mux}

	wg := sync.WaitGroup{}
	go func() {
		wg.Add(1)
		defer wg.Done()

		if err := server.ListenAndServe(); err != nil {
			log.Println(err)
		}
		log.Println("server goroutine has exited")
	}()

	b = &broadcaster{}

	go func() {
		wg.Add(1)
		defer wg.Done()

		ipregexp := regexp.MustCompile(`\d+\.\d+\.\d+\.\d+`)

		for line := range t.Lines {
			ipstr := ipregexp.FindString(line.Text)
			if ipstr == "" {
				log.Printf("failed to find IP addres in: %s", line.Text)
				continue
			}
			ip := net.ParseIP(ipstr)

			res := mmrecord{}
			if err := gdb.Lookup(ip, &res); err != nil {
				log.Printf("failed to lookup ip %s location: %v", ipstr, err)
				continue
			}
			b.pub([]float64{res.Location.Latitude, res.Location.Longitude})
		}
		log.Println("log tailing goroutine has exited")
	}()

	sigs := make(chan os.Signal)
	signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
	<-sigs
	log.Println("interrupted, shutting down the server")
	if err := t.Stop(); err != nil {
		log.Println(err)
	}
	if err := server.Shutdown(context.Background()); err != nil {
		log.Println(err)
	}
	wg.Wait()
}

func index(w http.ResponseWriter, r *http.Request) {
	tmpl, err := template.ParseFiles("index.html")
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	data := struct{ Host string }{Host: r.Host}
	if err := tmpl.Execute(w, data); err != nil {
		http.Error(w, err.Error(), 500)
	}
}

var upgrader = websocket.Upgrader{}

func ws(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	defer conn.Close()

	c := make(chan interface{})
	b.sub(c)
	defer b.usub(c)

	for v := range c {
		if err := conn.WriteJSON(v); err != nil {
			log.Println(err)
			break
		}
	}
}
<commit_msg>More logs<commit_after>package main

import (
	"context"
	"html/template"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"regexp"
	"sync"
	"syscall"

	"github.com/gorilla/websocket"
	"github.com/hpcloud/tail"
	maxminddb "github.com/oschwald/maxminddb-golang"
)

type broadcaster struct {
	mu sync.Mutex
	cs []chan<- interface{}
}

func (b *broadcaster) sub(c chan<- interface{}) {
	b.mu.Lock()
	defer b.mu.Unlock()

	b.cs = append(b.cs, c)
}

func (b *broadcaster) usub(c chan<- interface{}) {
	b.mu.Lock()
	defer b.mu.Unlock()

	n := b.cs[:0]
	for _, x := range b.cs {
		if x != c {
			n = append(n, x)
		}
	}
	b.cs = n
}

func (b *broadcaster) pub(v interface{}) {
	b.mu.Lock()
	defer b.mu.Unlock()

	log.Printf("broadcasting %v to %d listeners\n", v, len(b.cs))
	for _, c := range b.cs {
		c <- v
	}
}

func (b *broadcaster) close() {
	b.mu.Lock()
	defer b.mu.Unlock()

	for _, c := range b.cs {
		close(c)
	}
}

type mmrecord struct {
	Location struct {
		Latitude  float64 `maxminddb:"latitude"`
		Longitude float64 `maxminddb:"longitude"`
	} `maxminddb:"location"`
}

var b *broadcaster

func main() {
	logFilename := os.Getenv("LOG_FILENAME")
	if logFilename == "" {
		log.Fatal("LOG_FILENAME env variable is required")
	}

	gdb, err := maxminddb.Open("GeoLite2-City.mmdb")
	if err != nil {
		log.Fatalf("failed to open maxmind db: %v", err)
	}
	defer gdb.Close()

	t, err := tail.TailFile(logFilename, tail.Config{
		Follow:   true,
		Location: &tail.SeekInfo{Whence: os.SEEK_END},
	})
	if err != nil {
		log.Fatalf("failed to tail %s: %v", "ips.log", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/ws", ws)
	mux.HandleFunc("/", index)
	httpListenOn := os.Getenv("HTTP_LISTEN_ON")
	if httpListenOn == "" {
		httpListenOn = ":8080"
	}
	server := http.Server{Addr: httpListenOn, Handler: mux}

	wg := sync.WaitGroup{}
	go func() {
		wg.Add(1)
		defer wg.Done()

		if err := server.ListenAndServe(); err != nil {
			log.Println(err)
		}
		log.Println("server goroutine has exited")
	}()

	b = &broadcaster{}

	go func() {
		wg.Add(1)
		defer wg.Done()

		ipregexp := regexp.MustCompile(`\d+\.\d+\.\d+\.\d+`)

		for line := range t.Lines {
			ipstr := ipregexp.FindString(line.Text)
			if ipstr == "" {
				log.Printf("failed to find IP addres in: %s", line.Text)
				continue
			}
			ip := net.ParseIP(ipstr)

			res := mmrecord{}
			if err := gdb.Lookup(ip, &res); err != nil {
				log.Printf("failed to lookup ip %s location: %v", ipstr, err)
				continue
			}
			b.pub([]float64{res.Location.Latitude, res.Location.Longitude})
		}
		log.Println("log tailing goroutine has exited")
	}()

	sigs := make(chan os.Signal)
	signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
	<-sigs
	log.Println("interrupted, shutting down the server")
	if err := t.Stop(); err != nil {
		log.Println(err)
	}
	if err := server.Shutdown(context.Background()); err != nil {
		log.Println(err)
	}
	wg.Wait()
}

func index(w http.ResponseWriter, r *http.Request) {
	tmpl, err := template.ParseFiles("index.html")
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	data := struct{ Host string }{Host: r.Host}
	if err := tmpl.Execute(w, data); err != nil {
		http.Error(w, err.Error(), 500)
	}
}

var upgrader = websocket.Upgrader{}

func ws(w http.ResponseWriter, r *http.Request) {
	log.Println("new websocket connection from " + r.RemoteAddr)
	defer log.Println("websocket connection with " + r.RemoteAddr + " is closed")

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	defer conn.Close()

	c := make(chan interface{})
	b.sub(c)
	defer b.usub(c)

	for v := range c {
		if err := conn.WriteJSON(v); err != nil {
			log.Println(err)
			break
		}
	}
}
<|endoftext|>