<commit_before>package docker

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/fileutils"
)

func createTarStream(srcPath string) (io.ReadCloser, error) {
	excludes, err := parseDockerignore(srcPath)
	if err != nil {
		return nil, err
	}

	if err := validateContextDirectory(srcPath, excludes); err != nil {
		return nil, err
	}
	tarOpts := &archive.TarOptions{
		Excludes:    excludes,
		Compression: archive.Uncompressed,
		NoLchown:    true,
	}
	return archive.TarWithOptions(srcPath, tarOpts)
}

// validateContextDirectory checks if all the contents of the directory
// can be read and returns an error if some files can't be read.
// Symlinks which point to non-existing files don't trigger an error
func validateContextDirectory(srcPath string, excludes []string) error {
	return filepath.Walk(filepath.Join(srcPath, "."), func(filePath string, f os.FileInfo, err error) error {
		// skip this directory/file if it's not in the path, it won't get added to the context
		if relFilePath, err := filepath.Rel(srcPath, filePath); err != nil {
			return err
		} else if skip, err := fileutils.Matches(relFilePath, excludes); err != nil {
			return err
		} else if skip {
			if f.IsDir() {
				return filepath.SkipDir
			}
			return nil
		}

		if err != nil {
			if os.IsPermission(err) {
				return fmt.Errorf("can't stat '%s'", filePath)
			}
			if os.IsNotExist(err) {
				return nil
			}
			return err
		}

		// skip checking if symlinks point to non-existing files, such symlinks can be useful
		// also skip named pipes, because they hanging on open
		if f.Mode()&(os.ModeSymlink|os.ModeNamedPipe) != 0 {
			return nil
		}

		if !f.IsDir() {
			currentFile, err := os.Open(filePath)
			if err != nil && os.IsPermission(err) {
				return fmt.Errorf("no permission to read from '%s'", filePath)
			}
			currentFile.Close()
		}
		return nil
	})
}

func parseDockerignore(root string) ([]string, error) {
	var excludes []string
	ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore"))
	if err != nil && !os.IsNotExist(err) {
		return excludes, fmt.Errorf("error reading .dockerignore: '%s'", err)
	}
	for _, pattern := range strings.Split(string(ignore), "\n") {
		matches, err := filepath.Match(pattern, "Dockerfile")
		if err != nil {
			return excludes, fmt.Errorf("bad .dockerignore pattern: '%s', error: %s", pattern, err)
		}
		if matches {
			return excludes, fmt.Errorf("dockerfile was excluded by .dockerignore pattern '%s'", pattern)
		}
		excludes = append(excludes, pattern)
	}

	return excludes, nil
}
<commit_msg>tar: add copyright banner<commit_after>// Copyright 2014 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/fileutils"
)

func createTarStream(srcPath string) (io.ReadCloser, error) {
	excludes, err := parseDockerignore(srcPath)
	if err != nil {
		return nil, err
	}

	if err := validateContextDirectory(srcPath, excludes); err != nil {
		return nil, err
	}
	tarOpts := &archive.TarOptions{
		Excludes:    excludes,
		Compression: archive.Uncompressed,
		NoLchown:    true,
	}
	return archive.TarWithOptions(srcPath, tarOpts)
}

// validateContextDirectory checks if all the contents of the directory
// can be read and returns an error if some files can't be read.
// Symlinks which point to non-existing files don't trigger an error
func validateContextDirectory(srcPath string, excludes []string) error {
	return filepath.Walk(filepath.Join(srcPath, "."), func(filePath string, f os.FileInfo, err error) error {
		// skip this directory/file if it's not in the path, it won't get added to the context
		if relFilePath, err := filepath.Rel(srcPath, filePath); err != nil {
			return err
		} else if skip, err := fileutils.Matches(relFilePath, excludes); err != nil {
			return err
		} else if skip {
			if f.IsDir() {
				return filepath.SkipDir
			}
			return nil
		}

		if err != nil {
			if os.IsPermission(err) {
				return fmt.Errorf("can't stat '%s'", filePath)
			}
			if os.IsNotExist(err) {
				return nil
			}
			return err
		}

		// skip checking if symlinks point to non-existing files, such symlinks can be useful
		// also skip named pipes, because they hanging on open
		if f.Mode()&(os.ModeSymlink|os.ModeNamedPipe) != 0 {
			return nil
		}

		if !f.IsDir() {
			currentFile, err := os.Open(filePath)
			if err != nil && os.IsPermission(err) {
				return fmt.Errorf("no permission to read from '%s'", filePath)
			}
			currentFile.Close()
		}
		return nil
	})
}

func parseDockerignore(root string) ([]string, error) {
	var excludes []string
	ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore"))
	if err != nil && !os.IsNotExist(err) {
		return excludes, fmt.Errorf("error reading .dockerignore: '%s'", err)
	}
	for _, pattern := range strings.Split(string(ignore), "\n") {
		matches, err := filepath.Match(pattern, "Dockerfile")
		if err != nil {
			return excludes, fmt.Errorf("bad .dockerignore pattern: '%s', error: %s", pattern, err)
		}
		if matches {
			return excludes, fmt.Errorf("dockerfile was excluded by .dockerignore pattern '%s'", pattern)
		}
		excludes = append(excludes, pattern)
	}

	return excludes, nil
}
<|endoftext|>


<commit_before>package medtronic

import (
	"fmt"
	"time"
)

const (
	TempBasal            Command = 0x98
	SetAbsoluteTempBasal Command = 0x4C
	SetPercentTempBasal  Command = 0x69
)

type TempBasalType byte

//go:generate stringer -type TempBasalType

const (
	Absolute TempBasalType = 0
	Percent  TempBasalType = 1
)

type TempBasalInfo struct {
	Duration time.Duration
	Type     TempBasalType
	Rate     *Insulin `json:",omitempty"`
	Percent  *uint8   `json:",omitempty"`
}

func (pump *Pump) TempBasal() TempBasalInfo {
	data := pump.Execute(TempBasal)
	if pump.Error() != nil {
		return TempBasalInfo{}
	}
	if len(data) < 7 || data[0] != 6 {
		pump.BadResponse(TempBasal, data)
		return TempBasalInfo{}
	}
	d := time.Duration(twoByteInt(data[5:7])) * time.Minute
	tempType := TempBasalType(data[1])
	info := TempBasalInfo{Duration: d, Type: tempType}
	switch TempBasalType(data[1]) {
	case Absolute:
		rate := twoByteInsulin(data[3:5], true)
		info.Rate = &rate
	case Percent:
		percent := data[2]
		info.Percent = &percent
	default:
		pump.BadResponse(TempBasal, data)
	}
	return info
}

func (pump *Pump) SetAbsoluteTempBasal(duration time.Duration, rate Insulin) {
	d := pump.halfHours(duration)
	if rate%25 != 0 {
		pump.SetError(fmt.Errorf("absolute temporary basal rate (%d) is not a multiple of 25 milliUnits per hour", rate))
	}
	pump.Execute(SetAbsoluteTempBasal, 0, byte(rate/25), d)
}

func (pump *Pump) SetPercentTempBasal(duration time.Duration, percent int) {
	d := pump.halfHours(duration)
	if percent < 0 || 100 < percent {
		pump.SetError(fmt.Errorf("percent temporary basal rate (%d) is not between 0 and 100", percent))
	}
	pump.Execute(SetPercentTempBasal, byte(percent), d)
}

func (pump *Pump) halfHours(duration time.Duration) uint8 {
	const halfHour = 30 * time.Minute
	if duration%halfHour != 0 {
		pump.SetError(fmt.Errorf("duration (%v) is not a multiple of 30 minutes", duration))
	}
	return uint8(duration / halfHour)
}
<commit_msg>Simplify switch expression<commit_after>package medtronic

import (
	"fmt"
	"time"
)

const (
	TempBasal            Command = 0x98
	SetAbsoluteTempBasal Command = 0x4C
	SetPercentTempBasal  Command = 0x69
)

type TempBasalType byte

//go:generate stringer -type TempBasalType

const (
	Absolute TempBasalType = 0
	Percent  TempBasalType = 1
)

type TempBasalInfo struct {
	Duration time.Duration
	Type     TempBasalType
	Rate     *Insulin `json:",omitempty"`
	Percent  *uint8   `json:",omitempty"`
}

func (pump *Pump) TempBasal() TempBasalInfo {
	data := pump.Execute(TempBasal)
	if pump.Error() != nil {
		return TempBasalInfo{}
	}
	if len(data) < 7 || data[0] != 6 {
		pump.BadResponse(TempBasal, data)
		return TempBasalInfo{}
	}
	d := time.Duration(twoByteInt(data[5:7])) * time.Minute
	tempType := TempBasalType(data[1])
	info := TempBasalInfo{Duration: d, Type: tempType}
	switch tempType {
	case Absolute:
		rate := twoByteInsulin(data[3:5], true)
		info.Rate = &rate
	case Percent:
		percent := data[2]
		info.Percent = &percent
	default:
		pump.BadResponse(TempBasal, data)
	}
	return info
}

func (pump *Pump) SetAbsoluteTempBasal(duration time.Duration, rate Insulin) {
	d := pump.halfHours(duration)
	if rate%25 != 0 {
		pump.SetError(fmt.Errorf("absolute temporary basal rate (%d) is not a multiple of 25 milliUnits per hour", rate))
	}
	pump.Execute(SetAbsoluteTempBasal, 0, byte(rate/25), d)
}

func (pump *Pump) SetPercentTempBasal(duration time.Duration, percent int) {
	d := pump.halfHours(duration)
	if percent < 0 || 100 < percent {
		pump.SetError(fmt.Errorf("percent temporary basal rate (%d) is not between 0 and 100", percent))
	}
	pump.Execute(SetPercentTempBasal, byte(percent), d)
}

func (pump *Pump) halfHours(duration time.Duration) uint8 {
	const halfHour = 30 * time.Minute
	if duration%halfHour != 0 {
		pump.SetError(fmt.Errorf("duration (%v) is not a multiple of 30 minutes", duration))
	}
	return uint8(duration / halfHour)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"strconv"
	"strings"
	"time"
)

const ucdFileName = "UnicodeData.txt"
const ucdBaseUrl = "http://www.unicode.org/Public/UCD/latest/ucd/"

func progress(done *bool) {
	for !*done {
		fmt.Print(".")
		time.Sleep(200 * time.Millisecond)
	}
	fmt.Println()
}

func getUcdFile(fileName string) {
	url := ucdBaseUrl + ucdFileName
	fmt.Printf("%s not found\nretrieving from %s\n", ucdFileName, url)
	response, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer response.Body.Close()
	file, err := os.Create(fileName)
	if err != nil {
		panic(err)
	}
	_, err = io.Copy(file, response.Body)
	if err != nil {
		panic(err)
	}
	file.Close()
}

func loadIndex(fileName string) (map[string][]rune, map[rune]string) {
	if _, err := os.Stat(fileName); os.IsNotExist(err) {
		done := false
		go progress(&done)
		getUcdFile(fileName)
		done = true
	}
	content, err := ioutil.ReadFile(fileName)
	if err != nil {
		panic(err)
	}

	lines := strings.Split(string(content), "\n")

	index := make(map[string][]rune)
	names := make(map[rune]string)

	for _, line := range lines {
		var uchar rune
		fields := strings.Split(line, ";")
		if len(fields) >= 2 {
			code64, _ := strconv.ParseInt(fields[0], 16, 0)
			uchar = rune(code64)
			names[uchar] = fields[1]
			for _, word := range strings.Split(fields[1], " ") {
				var entries []rune
				if len(index[word]) < 1 {
					entries = make([]rune, 0)
				} else {
					entries = index[word]
				}
				index[word] = append(entries, uchar)
			}
		}

	}
	return index, names
}

func main() {
	dir, _ := os.Getwd()
	path := path.Join(dir, ucdFileName)
	index, names := loadIndex(path)
	if len(os.Args) != 2 {
		fmt.Println("Usage:  runefinder <word>\texample: runefinder cat")
		os.Exit(1)
	}

	word := strings.ToUpper(os.Args[1])
	for _, uchar := range index[word] {
		fmt.Printf("U+%-5X %c\t%s\n", uchar, uchar, names[uchar])
	}

}
<commit_msg>minor output formatting tweak<commit_after>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"strconv"
	"strings"
	"time"
)

const ucdFileName = "UnicodeData.txt"
const ucdBaseUrl = "http://www.unicode.org/Public/UCD/latest/ucd/"

func progress(done *bool) {
	for !*done {
		fmt.Print(".")
		time.Sleep(200 * time.Millisecond)
	}
	fmt.Println()
}

func getUcdFile(fileName string) {
	url := ucdBaseUrl + ucdFileName
	fmt.Printf("%s not found\nretrieving from %s\n", ucdFileName, url)
	response, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer response.Body.Close()
	file, err := os.Create(fileName)
	if err != nil {
		panic(err)
	}
	_, err = io.Copy(file, response.Body)
	if err != nil {
		panic(err)
	}
	file.Close()
}

func loadIndex(fileName string) (map[string][]rune, map[rune]string) {
	if _, err := os.Stat(fileName); os.IsNotExist(err) {
		done := false
		go progress(&done)
		getUcdFile(fileName)
		done = true
	}
	content, err := ioutil.ReadFile(fileName)
	if err != nil {
		panic(err)
	}

	lines := strings.Split(string(content), "\n")

	index := make(map[string][]rune)
	names := make(map[rune]string)

	for _, line := range lines {
		var uchar rune
		fields := strings.Split(line, ";")
		if len(fields) >= 2 {
			code64, _ := strconv.ParseInt(fields[0], 16, 0)
			uchar = rune(code64)
			names[uchar] = fields[1]
			for _, word := range strings.Split(fields[1], " ") {
				var entries []rune
				if len(index[word]) < 1 {
					entries = make([]rune, 0)
				} else {
					entries = index[word]
				}
				index[word] = append(entries, uchar)
			}
		}

	}
	return index, names
}

func main() {
	dir, _ := os.Getwd()
	path := path.Join(dir, ucdFileName)
	index, names := loadIndex(path)
	if len(os.Args) != 2 {
		fmt.Println("Usage:  runefinder <word>\texample: runefinder cat")
		os.Exit(1)
	}

	word := strings.ToUpper(os.Args[1])
	for _, uchar := range index[word] {
		fmt.Printf("U+%-5X %c \t%s\n", uchar, uchar, names[uchar])
	}

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"./cmd"
)

func main() {
	if err := cmd.RootCmd.Execute(); err != nil {
		fmt.Printf("%+v\n", err)
		os.Exit(-1)
	}
}
<commit_msg>fixed main import<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/uchimanajet7/tlc/cmd"
)

func main() {
	if err := cmd.RootCmd.Execute(); err != nil {
		fmt.Printf("%+v\n", err)
		os.Exit(-1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/dotcloud/docker/rcli"
	"github.com/dotcloud/docker/future"
	"io"
	"log"
	"os"
	"syscall"
	"unsafe"
)

type Termios struct {
	Iflag  uintptr
	Oflag  uintptr
	Cflag  uintptr
	Lflag  uintptr
	Cc     [20]byte
	Ispeed uintptr
	Ospeed uintptr
}

const (
	// Input flags
	inpck  = 0x010
	istrip = 0x020
	icrnl  = 0x100
	ixon   = 0x200

	// Output flags
	opost = 0x1

	// Control flags
	cs8 = 0x300

	// Local flags
	icanon = 0x100
	iexten = 0x400
)

const (
        HUPCL                             = 0x4000
        ICANON                            = 0x100
        ICRNL                             = 0x100
        IEXTEN                            = 0x400
        BRKINT                            = 0x2
        CFLUSH                            = 0xf
        CLOCAL                            = 0x8000
        CREAD                             = 0x800
        CS5                               = 0x0
        CS6                               = 0x100
        CS7                               = 0x200
        CS8                               = 0x300
        CSIZE                             = 0x300
        CSTART                            = 0x11
        CSTATUS                           = 0x14
        CSTOP                             = 0x13
        CSTOPB                            = 0x400
        CSUSP                             = 0x1a
        IGNBRK                            = 0x1
        IGNCR                             = 0x80
        IGNPAR                            = 0x4
        IMAXBEL                           = 0x2000
        INLCR                             = 0x40
        INPCK                             = 0x10
        ISIG                              = 0x80
        ISTRIP                            = 0x20
        IUTF8                             = 0x4000
        IXANY                             = 0x800
        IXOFF                             = 0x400
        IXON                              = 0x200
        NOFLSH                            = 0x80000000
        OCRNL                             = 0x10
        OFDEL                             = 0x20000
        OFILL                             = 0x80
        ONLCR                             = 0x2
        ONLRET                            = 0x40
        ONOCR                             = 0x20
        ONOEOT                            = 0x8
        OPOST                             = 0x1
RENB                            = 0x1000
        PARMRK                            = 0x8
        PARODD                            = 0x2000

        TOSTOP                            = 0x400000
        VDISCARD                          = 0xf
        VDSUSP                            = 0xb
        VEOF                              = 0x0
        VEOL                              = 0x1
        VEOL2                             = 0x2
        VERASE                            = 0x3
        VINTR                             = 0x8
        VKILL                             = 0x5
        VLNEXT                            = 0xe
        VMIN                              = 0x10
        VQUIT                             = 0x9
        VREPRINT                          = 0x6
        VSTART                            = 0xc
        VSTATUS                           = 0x12
        VSTOP                             = 0xd
        VSUSP                             = 0xa
        VT0                               = 0x0
        VT1                               = 0x10000
        VTDLY                             = 0x10000
        VTIME                             = 0x11
	ECHO				  = 0x00000008

        PENDIN                            = 0x20000000
)

type State struct {
       termios Termios
}

// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
        var termios Termios
        _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
        return err == 0
}

// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
        var oldState State
        if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
                return nil, err
        }

        newState := oldState.termios
        newState.Iflag &^= istrip | INLCR | ICRNL | IGNCR | IXON | IXOFF
        newState.Lflag &^= ECHO | ICANON | ISIG
        if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
                return nil, err
        }

        return &oldState, nil
}

// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
        _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
        return err
}

var oldState *State

func Fatal(err error) {
	if oldState != nil {
		Restore(0, oldState)
	}
	log.Fatal(err)
}

func main() {
	var err error
	if IsTerminal(0) && os.Getenv("NORAW") == "" {
		oldState, err = MakeRaw(0)
		if err != nil {
			panic(err)
		}
		defer Restore(0, oldState)
	}
	conn, err := rcli.CallTCP(os.Getenv("DOCKER"), os.Args[1:]...)
	if err != nil {
		Fatal(err)
	}
	receive_stdout := future.Go(func() error {
		_, err := io.Copy(os.Stdout, conn)
		return err
	})
	send_stdin := future.Go(func() error {
		_, err := io.Copy(conn, os.Stdin)
		if err := conn.CloseWrite(); err != nil {
			log.Printf("Couldn't send EOF: " + err.Error())
		}
		return err
	})
	if err := <-receive_stdout; err != nil {
		Fatal(err)
	}
	if IsTerminal(0) && os.Getenv("NORAW") == "" {
		Restore(0, oldState)
	} else {
		if err := <-send_stdin; err != nil {
			Fatal(err)
		}
	}
}
<commit_msg>Fix a bug which caused the client to never exit in interactive mode when NORAW is set.<commit_after>package main

import (
	"github.com/dotcloud/docker/rcli"
	"github.com/dotcloud/docker/future"
	"io"
	"log"
	"os"
	"syscall"
	"unsafe"
)

type Termios struct {
	Iflag  uintptr
	Oflag  uintptr
	Cflag  uintptr
	Lflag  uintptr
	Cc     [20]byte
	Ispeed uintptr
	Ospeed uintptr
}

const (
	// Input flags
	inpck  = 0x010
	istrip = 0x020
	icrnl  = 0x100
	ixon   = 0x200

	// Output flags
	opost = 0x1

	// Control flags
	cs8 = 0x300

	// Local flags
	icanon = 0x100
	iexten = 0x400
)

const (
        HUPCL                             = 0x4000
        ICANON                            = 0x100
        ICRNL                             = 0x100
        IEXTEN                            = 0x400
        BRKINT                            = 0x2
        CFLUSH                            = 0xf
        CLOCAL                            = 0x8000
        CREAD                             = 0x800
        CS5                               = 0x0
        CS6                               = 0x100
        CS7                               = 0x200
        CS8                               = 0x300
        CSIZE                             = 0x300
        CSTART                            = 0x11
        CSTATUS                           = 0x14
        CSTOP                             = 0x13
        CSTOPB                            = 0x400
        CSUSP                             = 0x1a
        IGNBRK                            = 0x1
        IGNCR                             = 0x80
        IGNPAR                            = 0x4
        IMAXBEL                           = 0x2000
        INLCR                             = 0x40
        INPCK                             = 0x10
        ISIG                              = 0x80
        ISTRIP                            = 0x20
        IUTF8                             = 0x4000
        IXANY                             = 0x800
        IXOFF                             = 0x400
        IXON                              = 0x200
        NOFLSH                            = 0x80000000
        OCRNL                             = 0x10
        OFDEL                             = 0x20000
        OFILL                             = 0x80
        ONLCR                             = 0x2
        ONLRET                            = 0x40
        ONOCR                             = 0x20
        ONOEOT                            = 0x8
        OPOST                             = 0x1
RENB                            = 0x1000
        PARMRK                            = 0x8
        PARODD                            = 0x2000

        TOSTOP                            = 0x400000
        VDISCARD                          = 0xf
        VDSUSP                            = 0xb
        VEOF                              = 0x0
        VEOL                              = 0x1
        VEOL2                             = 0x2
        VERASE                            = 0x3
        VINTR                             = 0x8
        VKILL                             = 0x5
        VLNEXT                            = 0xe
        VMIN                              = 0x10
        VQUIT                             = 0x9
        VREPRINT                          = 0x6
        VSTART                            = 0xc
        VSTATUS                           = 0x12
        VSTOP                             = 0xd
        VSUSP                             = 0xa
        VT0                               = 0x0
        VT1                               = 0x10000
        VTDLY                             = 0x10000
        VTIME                             = 0x11
	ECHO				  = 0x00000008

        PENDIN                            = 0x20000000
)

type State struct {
       termios Termios
}

// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
        var termios Termios
        _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
        return err == 0
}

// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
        var oldState State
        if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
                return nil, err
        }

        newState := oldState.termios
        newState.Iflag &^= istrip | INLCR | ICRNL | IGNCR | IXON | IXOFF
        newState.Lflag &^= ECHO | ICANON | ISIG
        if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
                return nil, err
        }

        return &oldState, nil
}

// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
        _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
        return err
}

var oldState *State

func Fatal(err error) {
	if oldState != nil {
		Restore(0, oldState)
	}
	log.Fatal(err)
}

func main() {
	var err error
	if IsTerminal(0) && os.Getenv("NORAW") == "" {
		oldState, err = MakeRaw(0)
		if err != nil {
			panic(err)
		}
		defer Restore(0, oldState)
	}
	conn, err := rcli.CallTCP(os.Getenv("DOCKER"), os.Args[1:]...)
	if err != nil {
		Fatal(err)
	}
	receive_stdout := future.Go(func() error {
		_, err := io.Copy(os.Stdout, conn)
		return err
	})
	send_stdin := future.Go(func() error {
		_, err := io.Copy(conn, os.Stdin)
		if err := conn.CloseWrite(); err != nil {
			log.Printf("Couldn't send EOF: " + err.Error())
		}
		return err
	})
	if err := <-receive_stdout; err != nil {
		Fatal(err)
	}
	if oldState != nil {
		Restore(0, oldState)
	}
	if !IsTerminal(0) {
		if err := <-send_stdin; err != nil {
			Fatal(err)
		}
	}
}
<|endoftext|>


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

// +build go1.2

package phoenix

import (
	"crypto/tls"
)

func setTLSMinVersion(config Config, section string, tlsConfig *tls.Config) {
	// Default to SSL3.
	minVersion := tls.VersionSSL30
	minVersionString, err := config.GetString(section, "minVersion")
	if err == nil {
		switch minVersionString {
		case "TLSv1":
			minVersion = tls.VersionTLS10
		case "TLSv1.1":
			minVersion = tls.VersionTLS11
		case "TLSv1.2":
			minVersion = tls.VersionTLS12
		}
	}
	tlsConfig.MinVersion = uint16(minVersion)
}

func makeDefaultCipherSuites() []uint16 {
	// Default cipher suites - no RC4.
	return []uint16{
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
		tls.TLS_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
		tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
	}
}
<commit_msg>Changed default TLS minimal version to TLSv1.2.<commit_after>// Copyright 2016 struktur AG. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build go1.2

package phoenix

import (
	"crypto/tls"
)

func setTLSMinVersion(config Config, section string, tlsConfig *tls.Config) {
	// Default to TLSv1.2.
	minVersion := tls.VersionTLS12
	minVersionString, err := config.GetString(section, "minVersion")
	if err == nil {
		switch minVersionString {
		case "SSLv3":
			minVersion = tls.VersionSSL30
		case "TLSv1":
			minVersion = tls.VersionTLS10
		case "TLSv1.1":
			minVersion = tls.VersionTLS11
		case "TLSv1.2":
			minVersion = tls.VersionTLS12
		}
	}
	tlsConfig.MinVersion = uint16(minVersion)
}

func makeDefaultCipherSuites() []uint16 {
	// Default cipher suites - no RC4.
	return []uint16{
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
		tls.TLS_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
		tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/dotcloud/docker"
	"github.com/dotcloud/docker/rcli"
	"github.com/dotcloud/docker/term"
	"io"
	"log"
	"os"
)

var GIT_COMMIT string

func main() {
	if docker.SelfPath() == "/sbin/init" {
		// Running in init mode
		docker.SysInit()
		return
	}
	// FIXME: Switch d and D ? (to be more sshd like)
	flDaemon := flag.Bool("d", false, "Daemon mode")
	flDebug := flag.Bool("D", false, "Debug mode")
	bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge")
	flag.Parse()
	if *bridgeName != "" {
		docker.NetworkBridgeIface = *bridgeName
	} else {
		docker.NetworkBridgeIface = docker.DefaultNetworkBridge
	}
	if *flDebug {
		os.Setenv("DEBUG", "1")
	}
	docker.GIT_COMMIT = GIT_COMMIT
	if *flDaemon {
		if flag.NArg() != 0 {
			flag.Usage()
			return
		}
		if err := daemon(); err != nil {
			log.Fatal(err)
		}
	} else {
		if err := runCommand(flag.Args()); err != nil {
			log.Fatal(err)
		}
	}
}

func daemon() error {
	service, err := docker.NewServer()
	if err != nil {
		return err
	}
	return rcli.ListenAndServe("tcp", "127.0.0.1:4242", service)
}

func runCommand(args []string) error {
	// FIXME: we want to use unix sockets here, but net.UnixConn doesn't expose
	// CloseWrite(), which we need to cleanly signal that stdin is closed without
	// closing the connection.
	// See http://code.google.com/p/go/issues/detail?id=3345
	if conn, err := rcli.Call("tcp", "127.0.0.1:4242", args...); err == nil {
		options := conn.GetOptions()
		if options.RawTerminal &&
			term.IsTerminal(int(os.Stdin.Fd())) &&
			os.Getenv("NORAW") == "" {
			if oldState, err := rcli.SetRawTerminal(); err != nil {
				return err
			} else {
				defer rcli.RestoreTerminal(oldState)
			}
		}
		receiveStdout := docker.Go(func() error {
			_, err := io.Copy(os.Stdout, conn)
			return err
		})
		sendStdin := docker.Go(func() error {
			_, err := io.Copy(conn, os.Stdin)
			if err := conn.CloseWrite(); err != nil {
				log.Printf("Couldn't send EOF: " + err.Error())
			}
			return err
		})
		if err := <-receiveStdout; err != nil {
			return err
		}
		if !term.IsTerminal(int(os.Stdin.Fd())) {
			if err := <-sendStdin; err != nil {
				return err
			}
		}
	} else {
		service, err := docker.NewServer()
		if err != nil {
			return err
		}
		dockerConn := rcli.NewDockerLocalConn(os.Stdout)
		defer dockerConn.Close()
		if err := rcli.LocalCall(service, os.Stdin, dockerConn, args...); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>docker daemon: create file containing PID<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/dotcloud/docker"
	"github.com/dotcloud/docker/rcli"
	"github.com/dotcloud/docker/term"
	"io"
	"log"
	"os"
	"os/signal"
	"syscall"
)

var GIT_COMMIT string

func main() {
	if docker.SelfPath() == "/sbin/init" {
		// Running in init mode
		docker.SysInit()
		return
	}
	// FIXME: Switch d and D ? (to be more sshd like)
	flDaemon := flag.Bool("d", false, "Daemon mode")
	flDebug := flag.Bool("D", false, "Debug mode")
	bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge")
	pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID")
	flag.Parse()
	if *bridgeName != "" {
		docker.NetworkBridgeIface = *bridgeName
	} else {
		docker.NetworkBridgeIface = docker.DefaultNetworkBridge
	}
	if *flDebug {
		os.Setenv("DEBUG", "1")
	}
	docker.GIT_COMMIT = GIT_COMMIT
	if *flDaemon {
		if flag.NArg() != 0 {
			flag.Usage()
			return
		}
		if err := daemon(*pidfile); err != nil {
			log.Fatal(err)
		}
	} else {
		if err := runCommand(flag.Args()); err != nil {
			log.Fatal(err)
		}
	}
}

func createPidFile(pidfile string) error {
	if _, err := os.Stat(pidfile); err == nil {
		return fmt.Errorf("pid file found, ensure docker is not running or delete %s", pidfile)
	}

	file, err := os.Create(pidfile)
	if err != nil {
		return err
	}

	defer file.Close()

	_, err = fmt.Fprintf(file, "%d", os.Getpid())
	return err
}

func removePidFile(pidfile string) {
	if err := os.Remove(pidfile); err != nil {
		log.Printf("Error removing %s: %s", pidfile, err)
	}
}

func daemon(pidfile string) error {
		if err := createPidFile(pidfile); err != nil {
			log.Fatal(err)
		}
		defer removePidFile(pidfile)

		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM))
		go func() {
			sig := <-c
			log.Printf("Received signal '%v', exiting\n", sig)
			removePidFile(pidfile)
			os.Exit(0)
		}()

	service, err := docker.NewServer()
	if err != nil {
		return err
	}
	return rcli.ListenAndServe("tcp", "127.0.0.1:4242", service)
}

func runCommand(args []string) error {
	// FIXME: we want to use unix sockets here, but net.UnixConn doesn't expose
	// CloseWrite(), which we need to cleanly signal that stdin is closed without
	// closing the connection.
	// See http://code.google.com/p/go/issues/detail?id=3345
	if conn, err := rcli.Call("tcp", "127.0.0.1:4242", args...); err == nil {
		options := conn.GetOptions()
		if options.RawTerminal &&
			term.IsTerminal(int(os.Stdin.Fd())) &&
			os.Getenv("NORAW") == "" {
			if oldState, err := rcli.SetRawTerminal(); err != nil {
				return err
			} else {
				defer rcli.RestoreTerminal(oldState)
			}
		}
		receiveStdout := docker.Go(func() error {
			_, err := io.Copy(os.Stdout, conn)
			return err
		})
		sendStdin := docker.Go(func() error {
			_, err := io.Copy(conn, os.Stdin)
			if err := conn.CloseWrite(); err != nil {
				log.Printf("Couldn't send EOF: " + err.Error())
			}
			return err
		})
		if err := <-receiveStdout; err != nil {
			return err
		}
		if !term.IsTerminal(int(os.Stdin.Fd())) {
			if err := <-sendStdin; err != nil {
				return err
			}
		}
	} else {
		service, err := docker.NewServer()
		if err != nil {
			return err
		}
		dockerConn := rcli.NewDockerLocalConn(os.Stdout)
		defer dockerConn.Close()
		if err := rcli.LocalCall(service, os.Stdin, dockerConn, args...); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/hex"
	"io/ioutil"
)

func main() {
	b := "0047FF6F0564206A6F6221"
	bits, err := hex.DecodeString(b)
	if err != nil {
		panic(err)
	}
	ioutil.WriteFile("rides/hello.td4", bits, 0644)
}
<commit_msg>remove temp file<commit_after><|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/dotcloud/docker"
	"github.com/dotcloud/docker/rcli"
	"github.com/dotcloud/docker/term"
	"io"
	"log"
	"os"
)

var GIT_COMMIT string

func main() {
	if docker.SelfPath() == "/sbin/init" {
		// Running in init mode
		docker.SysInit()
		return
	}
	// FIXME: Switch d and D ? (to be more sshd like)
	flDaemon := flag.Bool("d", false, "Daemon mode")
	flDebug := flag.Bool("D", false, "Debug mode")
	bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge")
	flag.Parse()
	if *bridgeName != "" {
		docker.NetworkBridgeIface = *bridgeName
	} else {
		docker.NetworkBridgeIface = docker.DefaultNetworkBridge
	}
	if *flDebug {
		os.Setenv("DEBUG", "1")
	}
	docker.GIT_COMMIT = GIT_COMMIT
	if *flDaemon {
		if flag.NArg() != 0 {
			flag.Usage()
			return
		}
		if err := daemon(); err != nil {
			log.Fatal(err)
		}
	} else {
		if err := runCommand(flag.Args()); err != nil {
			log.Fatal(err)
		}
	}
}

func daemon() error {
	service, err := docker.NewServer()
	if err != nil {
		return err
	}
	return rcli.ListenAndServe("tcp", "127.0.0.1:4242", service)
}

func runCommand(args []string) error {
	var oldState *term.State
	var err error
	if term.IsTerminal(int(os.Stdin.Fd())) && os.Getenv("NORAW") == "" {
		oldState, err = term.MakeRaw(int(os.Stdin.Fd()))
		if err != nil {
			return err
		}
		defer term.Restore(int(os.Stdin.Fd()), oldState)
	}
	// FIXME: we want to use unix sockets here, but net.UnixConn doesn't expose
	// CloseWrite(), which we need to cleanly signal that stdin is closed without
	// closing the connection.
	// See http://code.google.com/p/go/issues/detail?id=3345
	if conn, err := rcli.Call("tcp", "127.0.0.1:4242", args...); err == nil {
		options := conn.GetOptions()
		if options.RawTerminal &&
			term.IsTerminal(int(os.Stdin.Fd())) &&
			os.Getenv("NORAW") == "" {
			if oldState, err := rcli.SetRawTerminal(); err != nil {
				return err
			} else {
				defer rcli.RestoreTerminal(oldState)
			}
		}
		receiveStdout := docker.Go(func() error {
			_, err := io.Copy(os.Stdout, conn)
			return err
		})
		sendStdin := docker.Go(func() error {
			_, err := io.Copy(conn, os.Stdin)
			if err := conn.CloseWrite(); err != nil {
				log.Printf("Couldn't send EOF: " + err.Error())
			}
			return err
		})
		if err := <-receiveStdout; err != nil {
			return err
		}
		if !term.IsTerminal(int(os.Stdin.Fd())) {
			if err := <-sendStdin; err != nil {
				return err
			}
		}
	} else {
		service, err := docker.NewServer()
		if err != nil {
			return err
		}
		dockerConn := rcli.NewDockerLocalConn(os.Stdout)
		defer dockerConn.Close()
		if err := rcli.LocalCall(service, os.Stdin, dockerConn, args...); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Fix merge issue<commit_after>package main

import (
	"flag"
	"github.com/dotcloud/docker"
	"github.com/dotcloud/docker/rcli"
	"github.com/dotcloud/docker/term"
	"io"
	"log"
	"os"
)

var GIT_COMMIT string

func main() {
	if docker.SelfPath() == "/sbin/init" {
		// Running in init mode
		docker.SysInit()
		return
	}
	// FIXME: Switch d and D ? (to be more sshd like)
	flDaemon := flag.Bool("d", false, "Daemon mode")
	flDebug := flag.Bool("D", false, "Debug mode")
	bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge")
	flag.Parse()
	if *bridgeName != "" {
		docker.NetworkBridgeIface = *bridgeName
	} else {
		docker.NetworkBridgeIface = docker.DefaultNetworkBridge
	}
	if *flDebug {
		os.Setenv("DEBUG", "1")
	}
	docker.GIT_COMMIT = GIT_COMMIT
	if *flDaemon {
		if flag.NArg() != 0 {
			flag.Usage()
			return
		}
		if err := daemon(); err != nil {
			log.Fatal(err)
		}
	} else {
		if err := runCommand(flag.Args()); err != nil {
			log.Fatal(err)
		}
	}
}

func daemon() error {
	service, err := docker.NewServer()
	if err != nil {
		return err
	}
	return rcli.ListenAndServe("tcp", "127.0.0.1:4242", service)
}

func runCommand(args []string) error {
	// FIXME: we want to use unix sockets here, but net.UnixConn doesn't expose
	// CloseWrite(), which we need to cleanly signal that stdin is closed without
	// closing the connection.
	// See http://code.google.com/p/go/issues/detail?id=3345
	if conn, err := rcli.Call("tcp", "127.0.0.1:4242", args...); err == nil {
		options := conn.GetOptions()
		if options.RawTerminal &&
			term.IsTerminal(int(os.Stdin.Fd())) &&
			os.Getenv("NORAW") == "" {
			if oldState, err := rcli.SetRawTerminal(); err != nil {
				return err
			} else {
				defer rcli.RestoreTerminal(oldState)
			}
		}
		receiveStdout := docker.Go(func() error {
			_, err := io.Copy(os.Stdout, conn)
			return err
		})
		sendStdin := docker.Go(func() error {
			_, err := io.Copy(conn, os.Stdin)
			if err := conn.CloseWrite(); err != nil {
				log.Printf("Couldn't send EOF: " + err.Error())
			}
			return err
		})
		if err := <-receiveStdout; err != nil {
			return err
		}
		if !term.IsTerminal(int(os.Stdin.Fd())) {
			if err := <-sendStdin; err != nil {
				return err
			}
		}
	} else {
		service, err := docker.NewServer()
		if err != nil {
			return err
		}
		dockerConn := rcli.NewDockerLocalConn(os.Stdout)
		defer dockerConn.Close()
		if err := rcli.LocalCall(service, os.Stdin, dockerConn, args...); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"
)

type downloadResult struct {
	Page  []byte
	Error error
}

type releaseView struct {
	DownloadUrl string
	Version     string
	Md5         string
	Path        string
}

var rePackageUrl = regexp.MustCompile(`(?i)<a href=\"(?P<url>.+?)#md5=.+?\">(?P<filename>.+?)</a>`)
var reDownloadUrl = regexp.MustCompile(`(?i)<a href=\"(?P<url>.+?)\"\s+rel=\"download">(?P<version>.+?) download_url</a>`)

func simpleIndexHandler(w http.ResponseWriter, r *http.Request) {
	renderTemplate(w, "index", nil)
}

func getPage(url string) downloadResult {
	log.Println("Downloading page: " + url)
	res, err := http.Get(url)
	if err != nil {
		return downloadResult{Page: []byte(""), Error: err}
	}
	page, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return downloadResult{Page: []byte(""), Error: err}
	}
	return downloadResult{Page: page, Error: err}
}

func updateProxyCache(pkg Package) error {
	log.Println("Updating proxy cache for: " + pkg.Name)
	url := Config.PypiMirror + "/simple/" + pkg.Name + "/"

	result := getPage(url)

	if result.Error != nil {
		// We'll try next time
		return result.Error
	}

	finalizeCache(pkg, result.Page)
	return nil
}

func finalizeCache(pkg Package, data []byte) {
	log.Println("Finalizing cache for: " + pkg.Name)
	returnData := string(data)
	// Replace the local package links with links to a local proxy
	// so we can cache that result as well.
	packageUris := rePackageUrl.FindAllSubmatch(data, -1)
	for _, line := range packageUris {
		uri := line[1]
		filename := line[2]
		// TODO: This most certainly has edge cases that aren't addressed here.
		// Specifically: ".tar.gz" can't be the only filetype uploaded...
		versionSplit := strings.Split(string(uri), "-")
		almostVersion := versionSplit[len(versionSplit)-1]
		version := strings.Replace(almostVersion, ".tar.gz", "", -1)
		quoteduri := url.QueryEscape(Config.PypiMirror + "/a/b/" + string(uri))
		replaceuri := "/fondu/cached-file/" + string(filename) + "?package=" + pkg.Name + "&release=" + version + "&original=" + quoteduri + "&name=" + url.QueryEscape(string(filename))
		returnData = strings.Replace(returnData, string(uri), replaceuri, -1)
	}

	// Replace the download links with links to a local proxy so that
	// we can cache the downloads as well.
	downloadUrls := reDownloadUrl.FindAllSubmatch(data, -1)
	for _, line := range downloadUrls {
		uri := line[1]
		version := line[2]
		filename := pkg.Name + "-" + string(version) + ".tar.gz"
		quotedUri := url.QueryEscape(string(uri))
		replaceUri := "/fondu/cached-file/" + filename + "?package=" + pkg.Name + "&release=" + string(version) + "&original=" + quotedUri + "&name=" + url.QueryEscape(filename)
		returnData = strings.Replace(returnData, string(uri), replaceUri, -1)
	}

	pkg.SetProxy([]byte(returnData))
}

func renderProxy(w http.ResponseWriter, pkg Package) {
	log.Println("Rendering proxy for: " + pkg.Name)
	data := string(pkg.ProxyData())
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.Header().Set("Content-Length", strconv.Itoa(len(data)))
	w.Header().Set("Connection", "keep-alive")
	io.WriteString(w, data)
}

func buildReleaseMap(pkg Package) []releaseView {
	releaseMap := []releaseView{}
	for _, rel := range pkg.Releases() {
		metadata, err := rel.Metadata()
		if err != nil {
			break
		}
		md5Json, err := metadata.Get("md5_digest").Array()
		if err != nil {
			continue
		}
		md5 := md5Json[0]

		releaseMap = append(releaseMap, releaseView{
			DownloadUrl: rel.DownloadUrl(),
			Version:     rel.Version,
			Md5:         md5.(string),
			Path:        rel.Path(),
		})
	}
	return releaseMap
}

func simpleHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("SIMPLE: " + r.URL.Path)
	paths := strings.Split(r.URL.Path, "/")
	name := paths[2]
	pkg := Package{Name: name, DataDir: Config.DataDir}

	// The package is ours, so we serve it ourselves.
	if pkg.Exists() && !pkg.Proxied() {
		log.Print("Private package: " + name + ". Serving it.")
		releaseMap := buildReleaseMap(pkg)
		renderTemplate(w, "single", &releaseMap)
		return
	}

	// Public package, so just render the proxy
	if pkg.Proxied() {
		log.Print("Proxied package: " + name + ". Sending cached data.")
		go updateProxyCache(pkg)
		renderProxy(w, pkg)
		return
	}

	if err := updateProxyCache(pkg); err != nil {
		http.Error(w, "Unable to update proxy", http.StatusInternalServerError)
		return
	}

	renderProxy(w, pkg)
}
<commit_msg>Only respond to a single path here<commit_after>package main

import (
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"
)

type downloadResult struct {
	Page  []byte
	Error error
}

type releaseView struct {
	DownloadUrl string
	Version     string
	Md5         string
	Path        string
}

var rePackageUrl = regexp.MustCompile(`(?i)<a href=\"(?P<url>.+?)#md5=.+?\">(?P<filename>.+?)</a>`)
var reDownloadUrl = regexp.MustCompile(`(?i)<a href=\"(?P<url>.+?)\"\s+rel=\"download">(?P<version>.+?) download_url</a>`)

func simpleIndexHandler(w http.ResponseWriter, r *http.Request) {
	renderTemplate(w, "index", nil)
}

func getPage(url string) downloadResult {
	log.Println("Downloading page: " + url)
	res, err := http.Get(url)
	if err != nil {
		return downloadResult{Page: []byte(""), Error: err}
	}
	page, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return downloadResult{Page: []byte(""), Error: err}
	}
	return downloadResult{Page: page, Error: err}
}

func updateProxyCache(pkg Package) error {
	log.Println("Updating proxy cache for: " + pkg.Name)
	url := Config.PypiMirror + "/simple/" + pkg.Name + "/"

	result := getPage(url)

	if result.Error != nil {
		// We'll try next time
		return result.Error
	}

	finalizeCache(pkg, result.Page)
	return nil
}

func finalizeCache(pkg Package, data []byte) {
	log.Println("Finalizing cache for: " + pkg.Name)
	returnData := string(data)
	// Replace the local package links with links to a local proxy
	// so we can cache that result as well.
	packageUris := rePackageUrl.FindAllSubmatch(data, -1)
	for _, line := range packageUris {
		uri := line[1]
		filename := line[2]
		// TODO: This most certainly has edge cases that aren't addressed here.
		// Specifically: ".tar.gz" can't be the only filetype uploaded...
		versionSplit := strings.Split(string(uri), "-")
		almostVersion := versionSplit[len(versionSplit)-1]
		version := strings.Replace(almostVersion, ".tar.gz", "", -1)
		quoteduri := url.QueryEscape(Config.PypiMirror + "/a/b/" + string(uri))
		replaceuri := "/fondu/cached-file/" + string(filename) + "?package=" + pkg.Name + "&release=" + version + "&original=" + quoteduri + "&name=" + url.QueryEscape(string(filename))
		returnData = strings.Replace(returnData, string(uri), replaceuri, -1)
	}

	// Replace the download links with links to a local proxy so that
	// we can cache the downloads as well.
	downloadUrls := reDownloadUrl.FindAllSubmatch(data, -1)
	for _, line := range downloadUrls {
		uri := line[1]
		version := line[2]
		filename := pkg.Name + "-" + string(version) + ".tar.gz"
		quotedUri := url.QueryEscape(string(uri))
		replaceUri := "/fondu/cached-file/" + filename + "?package=" + pkg.Name + "&release=" + string(version) + "&original=" + quotedUri + "&name=" + url.QueryEscape(filename)
		returnData = strings.Replace(returnData, string(uri), replaceUri, -1)
	}

	pkg.SetProxy([]byte(returnData))
}

func renderProxy(w http.ResponseWriter, pkg Package) {
	log.Println("Rendering proxy for: " + pkg.Name)
	data := string(pkg.ProxyData())
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.Header().Set("Content-Length", strconv.Itoa(len(data)))
	w.Header().Set("Connection", "keep-alive")
	io.WriteString(w, data)
}

func buildReleaseMap(pkg Package) []releaseView {
	releaseMap := []releaseView{}
	for _, rel := range pkg.Releases() {
		metadata, err := rel.Metadata()
		if err != nil {
			break
		}
		md5Json, err := metadata.Get("md5_digest").Array()
		if err != nil {
			continue
		}
		md5 := md5Json[0]

		releaseMap = append(releaseMap, releaseView{
			DownloadUrl: rel.DownloadUrl(),
			Version:     rel.Version,
			Md5:         md5.(string),
			Path:        rel.Path(),
		})
	}
	return releaseMap
}

func simpleHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("SIMPLE: " + r.URL.Path)
	paths := strings.Split(r.URL.Path, "/")

	if len(paths) != 4 || paths[len(paths)-1] != "" {
		http.NotFound(w, r)
		return
	}

	name := paths[2]

	pkg := Package{Name: name, DataDir: Config.DataDir}

	// The package is ours, so we serve it ourselves.
	if pkg.Exists() && !pkg.Proxied() {
		log.Print("Private package: " + name + ". Serving it.")
		releaseMap := buildReleaseMap(pkg)
		renderTemplate(w, "single", &releaseMap)
		return
	}

	// Public package, so just render the proxy
	if pkg.Proxied() {
		log.Print("Proxied package: " + name + ". Sending cached data.")
		go updateProxyCache(pkg)
		renderProxy(w, pkg)
		return
	}

	if err := updateProxyCache(pkg); err != nil {
		http.Error(w, "Unable to update proxy", http.StatusInternalServerError)
		return
	}

	renderProxy(w, pkg)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"time"
	term "github.com/nsf/termbox-go"
	"io/ioutil"
	"strings"
)

// we use line, offset style. termbox use o, l style.
func SetCursor(l, o int) {
	term.SetCursor(o, l)
}

func SetCell(l, o int, ch rune, fg, bg term.Attribute) {
	term.SetCell(o, l, ch, fg, bg)
}

func SetTermboxCursor(c *Cursor, w *Window, l *Layout) {
	view := l.MainViewerBound()
	p := c.PositionInWindow(w)
	SetCursor(view.min.l+p.l, view.min.o+p.o)
}

func clearScreen(l *Layout) {
	viewer := l.MainViewerBound()
	for l := viewer.min.l ; l < viewer.max.l ; l++ {
		for o := viewer.min.o ; o < viewer.max.o ; o++ {
			SetCell(l, o, ' ', term.ColorDefault, term.ColorDefault)
		}
	}
}

// draw text inside of window at mainviewer
func drawScreen(l *Layout, w *Window, t *Text, sel *Selection) {
	viewer := l.MainViewerBound()
	for l , ln := range t.lines {
		if l < w.min.l || l >= w.max.l {
			continue
		}
		o := 0 // we cannot use index of line([]rune) because some rune have multiple-visible length. ex) tab, korean
		for _, ch := range ln.data {
			if o >= w.max.o {
				break
			}
			bgColor := term.ColorDefault
			if sel.on && sel.Contains(Point{l,o}) {
				bgColor = term.ColorGreen
			}
			// append cell to buffer
			if ch == '\t' {
				for i:=0 ; i<taboffset ; i++ {
					if o >= w.min.o {
						SetCell(l-w.min.l+viewer.min.l, o-w.min.o+viewer.min.o, rune(' '), term.ColorWhite, bgColor)
					}
					o += 1
				}
			} else {
				if o >= w.min.o {
					SetCell(l-w.min.l+viewer.min.l, o-w.min.o+viewer.min.o, rune(ch), term.ColorWhite, bgColor)
				}
				o += 1
			}
		}
	}
}

func printStatus(status string) {
	termw, termh := term.Size()
	statusLine := termh - 1
	for off:=0 ; off<termw ; off++ {
		SetCell(statusLine, off, ' ', term.ColorBlack, term.ColorWhite)
	}
	for off, ch := range status {
		SetCell(statusLine, off, rune(ch), term.ColorBlack, term.ColorWhite)
	}
}

func parseEvent(ev term.Event, sel *Selection) []*Action {
	if ev.Type != term.EventKey {
		panic(fmt.Sprintln("what the..", ev.Type, "event?"))
	}

	switch ev.Key {
	case term.KeyCtrlW:
		return []*Action{&Action{kind:"exit"}}
	case term.KeyCtrlS:
		return []*Action{&Action{kind:"save"}}
	// move
	case term.KeyArrowLeft:
		return []*Action{&Action{kind:"move", value:"left"}}
	case term.KeyArrowRight:
		return []*Action{&Action{kind:"move", value:"right"}}
	case term.KeyArrowUp:
		return []*Action{&Action{kind:"move", value:"up"}}
	case term.KeyArrowDown:
		return []*Action{&Action{kind:"move", value:"down"}}
	// insert
	case term.KeyEnter:
		return []*Action{&Action{kind:"insert", value:"\n"}}
	case term.KeySpace:
		return []*Action{&Action{kind:"insert", value:" "}}
	case term.KeyTab:
		return []*Action{&Action{kind:"insert", value:"\t"}}
	// delete : value will added after actual deletion.
	case term.KeyDelete:
		if sel.on {
			return []*Action{&Action{kind:"deleteSelection"}}
		} else {
			return []*Action{&Action{kind:"delete"}}
		}
	case term.KeyBackspace, term.KeyBackspace2:
		if sel.on {
			return []*Action{&Action{kind:"deleteSelection"}}
		} else {
			return []*Action{&Action{kind:"backspace"}}
		}
	// undo, redo
	case term.KeyCtrlZ:
		return []*Action{&Action{kind:"undo"}}
	case term.KeyCtrlY:
		return []*Action{&Action{kind:"redo"}}
	// copy, paste
	case term.KeyCtrlC:
		return []*Action{&Action{kind:"copy"}}
	case term.KeyCtrlV:
		return []*Action{&Action{kind:"paste"}}
	default:
		if ev.Ch == 0 {
			return []*Action{&Action{kind:"unknown"}}
		}
		if ev.Mod & term.ModAlt != 0 {
			kind := "move"
			if withShift(ev.Ch) {
				kind = "select"
			}
			switch ev.Ch {
			case 'j', 'J':
				return []*Action{&Action{kind:kind, value:"left"}}
			case 'l', 'L':
				return []*Action{&Action{kind:kind, value:"right"}}
			case 'i', 'I':
				return []*Action{&Action{kind:kind, value:"up"}}
			case 'k', 'K':
				return []*Action{&Action{kind:kind, value:"down"}}
			case 'm', 'M':
				return []*Action{&Action{kind:kind, value:"bow"}}
			case '.', '>':
				return []*Action{&Action{kind:kind, value:"eow"}}
			case 'u', 'U':
				return []*Action{&Action{kind:kind, value:"bol"}}
			case 'o', 'O':
				return []*Action{&Action{kind:kind, value:"eol"}}
			case 'h', 'H':
				return []*Action{&Action{kind:kind, value:"pageup"}}
			case 'n', 'N':
				return []*Action{&Action{kind:kind, value:"pagedown"}}
			case 'a', 'A':
				return []*Action{&Action{kind:kind, value:"bof"}}
			case 'z', 'Z':
				return []*Action{&Action{kind:kind, value:"eof"}}
			default:
				return []*Action{&Action{kind:"none"}}
			}
		}
		if sel.on {
			return []*Action{&Action{kind:"deleteSelection"}, &Action{kind:"insert", value:string(ev.Ch)}}
		} else {
			return []*Action{&Action{kind:"insert", value:string(ev.Ch)}}
		}
	}
}

func do(a *Action, c *Cursor, sel *Selection, history *History) {
	switch a.kind {
	case "none":
		return
	case "move", "select":
		if a.kind == "select" && !sel.on {
			sel.on = true
			sel.SetStart(c)
		}
		switch a.value {
		case "left":
			c.MoveLeft()
		case "right":
			c.MoveRight()
		case "up":
			c.MoveUp()
		case "down":
			c.MoveDown()
		case "bow":
			c.MoveBow()
		case "eow":
			c.MoveEow()
		case "bol":
			c.MoveBol()
		case "eol":
			c.MoveEol()
		case "pageup":
			c.PageUp()
		case "pagedown":
			c.PageDown()
		case "bof":
			c.MoveBof()
		case "eof":
			c.MoveEof()
		default:
			panic(fmt.Sprintln("what the..", a.value, "move?"))
		}
		if a.kind == "select" {
				sel.SetEnd(c)
		}
	case "insert":
		c.Insert(a.value)
	case "delete":
		a.value = c.Delete()
	case "backspace":
		a.value = c.Backspace()
	case "deleteSelection":
		a.value = c.DeleteSelection(sel)
	case "undo":
		if history.head == 0 {
			return
		}
		history.head--
		action := history.At(history.head)
		// status = fmt.Sprintf("undo : %v", action)
		// holdStatus = true
		switch action.kind {
		case "insert":
			c.Copy(action.afterCursor)
			for range action.value {
				c.Backspace()
			}
		case "backspace":
			c.Copy(action.afterCursor)
			for _, r := range action.value {
				c.Insert(string(r))
			}
		case "delete", "deleteSelection":
			c.Copy(action.afterCursor)
			for _, r := range action.value {
				c.Insert(string(r))
			}
		default:
			panic(fmt.Sprintln("what the..", action.kind, "history?"))
		}
	case "redo":
		if history.head == history.Len() {
			return
		}
		action := history.At(history.head)
		// status = fmt.Sprintf("redo : %v", action)
		// holdStatus = true
		history.head++
		switch action.kind {
		case "insert":
			c.Copy(action.beforeCursor)
			for _, r := range action.value {
				c.Insert(string(r))
			}
		case "backspace":
			c.Copy(action.beforeCursor)
			for range action.value {
				c.Backspace()
			}
		case "delete", "deleteSelection":
			c.Copy(action.beforeCursor)
			for range action.value {
				c.Delete()
			}
		default:
			panic(fmt.Sprintln("what the..", action.kind, "history?"))
		}
	default:
		panic(fmt.Sprintln("what the..", a.kind, "action?"))
	}
}

func main() {
	// check there is an destination file. ex)tor some.file
	args := os.Args[1:]
	if len(args)==0 {
		fmt.Println("please, set text file")
		return
	}
	f := args[0]

	text, err := open(f)
	if err != nil {
		fmt.Println(err)
		return
	}

	err = term.Init()
	if err != nil {
		panic(err)
	}
	defer term.Close()
	term.SetInputMode(term.InputAlt)
	term.Clear(term.ColorDefault, term.ColorDefault)
	term.Flush()

	layout := NewLayout()
	mainview := layout.MainViewerBound()
	win := NewWindow(layout)
	// drawbuf := textToDrawBuffer(text, selection)
	cursor := NewCursor(text)
	selection := NewSelection()
	history := newHistory()
	SetCursor(mainview.min.l, mainview.min.o)

	status := ""
	holdStatus := false
	lastActStr := ""
	copied := ""
	events := make(chan term.Event, 20)
	go func() {
		for {
			events <- term.PollEvent()
		}
	}()
	for {
		win.Follow(cursor)
		clearScreen(layout)
		drawScreen(layout, win, text, selection)

		if !holdStatus {
			if selection.on {
				status = "selection on - " + fmt.Sprintf("(%v, %v) - (%v, %v)", selection.start.l, selection.start.o, selection.end.l, selection.end.o)
			} else {
				status = fmt.Sprintf("linenum:%v, byteoff:%v, visoff:%v, cursoroff:%v, vpos:(%v,%v, %v,%v)", cursor.l, cursor.b, cursor.v, cursor.o, win.min.l, win.min.o, win.max.l, win.max.o)
			}
		}
		printStatus(status)
		holdStatus = false

		SetTermboxCursor(cursor, win, layout)
		term.Flush()

		// wait for keyboard input
		select {
		case ev := <-events:
			switch ev.Type {
			case term.EventKey:
				actions := parseEvent(ev, selection)
				for _, a := range actions {
					// keepSelection := false
					beforeCursor := *cursor

					if a.kind != "select" {
						selection.on=false
					}

					if a.kind == "exit" {
						return
					} else if a.kind == "save" {
						err := save(f, text)
						if err != nil {
							panic(err)
						}
						status = fmt.Sprintf("successfully saved : %v", f)
						holdStatus = true
					} else if a.kind == "copy" {
						minc, maxc := selection.MinMax()
						copied = text.DataInside(minc, maxc)
					} else if a.kind == "paste" {
						plines := strings.Split(copied, "\n")
						plen := len(plines)
						for i, l := range plines {
							cursor.Insert(l)
							if i != plen-1 {
								cursor.SplitLine()
							}
						}
					} else {
						do(a, cursor, selection, history)
					}
					switch a.kind {
					case "insert", "delete", "backspace", "deleteSelection":
						// remember the action.
						nc := history.Cut(history.head)
						if nc != 0 {
							lastActStr = ""
						}
						if a.kind == lastActStr {
							lastAct, err := history.Pop()
							if err != nil {
								panic(err)
							}
							history.head--
							beforeCursor = lastAct.beforeCursor
							if a.kind == "insert" || a.kind == "delete" {
								a.value = lastAct.value + a.value
							} else if a.kind == "backspace" {
								a.value = a.value + lastAct.value
							}
						}
						a.beforeCursor = beforeCursor
						if a.kind == "deleteSelection" {
							a.beforeCursor, _ = selection.MinMax();
						}
						a.afterCursor = *cursor
						history.Add(a)
						history.head++
					}
					lastActStr = a.kind
					lastAct := history.Last()
					if lastAct != nil {
						historyFileString := ""
						for i, a := range history.actions {
							if i != 0 {
								historyFileString += "\n"
							}
							historyFileString += fmt.Sprintf("%v, %v", a, history.head)
						}
						ioutil.WriteFile(extendFileName(f, ".history"), []byte(historyFileString), 0755)
					}
				}
			}
		case <-time.After(time.Second):
			holdStatus = true
		// case term.EventResize:
		//	win.resize()
		//	win.clear()
		//	win.draw()
		}
	}
}
<commit_msg>undo, redo for paste<commit_after>package main

import (
	"fmt"
	"os"
	"time"
	term "github.com/nsf/termbox-go"
	"io/ioutil"
	"strings"
)

// we use line, offset style. termbox use o, l style.
func SetCursor(l, o int) {
	term.SetCursor(o, l)
}

func SetCell(l, o int, ch rune, fg, bg term.Attribute) {
	term.SetCell(o, l, ch, fg, bg)
}

func SetTermboxCursor(c *Cursor, w *Window, l *Layout) {
	view := l.MainViewerBound()
	p := c.PositionInWindow(w)
	SetCursor(view.min.l+p.l, view.min.o+p.o)
}

func clearScreen(l *Layout) {
	viewer := l.MainViewerBound()
	for l := viewer.min.l ; l < viewer.max.l ; l++ {
		for o := viewer.min.o ; o < viewer.max.o ; o++ {
			SetCell(l, o, ' ', term.ColorDefault, term.ColorDefault)
		}
	}
}

// draw text inside of window at mainviewer
func drawScreen(l *Layout, w *Window, t *Text, sel *Selection) {
	viewer := l.MainViewerBound()
	for l , ln := range t.lines {
		if l < w.min.l || l >= w.max.l {
			continue
		}
		o := 0 // we cannot use index of line([]rune) because some rune have multiple-visible length. ex) tab, korean
		for _, ch := range ln.data {
			if o >= w.max.o {
				break
			}
			bgColor := term.ColorDefault
			if sel.on && sel.Contains(Point{l,o}) {
				bgColor = term.ColorGreen
			}
			// append cell to buffer
			if ch == '\t' {
				for i:=0 ; i<taboffset ; i++ {
					if o >= w.min.o {
						SetCell(l-w.min.l+viewer.min.l, o-w.min.o+viewer.min.o, rune(' '), term.ColorWhite, bgColor)
					}
					o += 1
				}
			} else {
				if o >= w.min.o {
					SetCell(l-w.min.l+viewer.min.l, o-w.min.o+viewer.min.o, rune(ch), term.ColorWhite, bgColor)
				}
				o += 1
			}
		}
	}
}

func printStatus(status string) {
	termw, termh := term.Size()
	statusLine := termh - 1
	for off:=0 ; off<termw ; off++ {
		SetCell(statusLine, off, ' ', term.ColorBlack, term.ColorWhite)
	}
	for off, ch := range status {
		SetCell(statusLine, off, rune(ch), term.ColorBlack, term.ColorWhite)
	}
}

func parseEvent(ev term.Event, sel *Selection) []*Action {
	if ev.Type != term.EventKey {
		panic(fmt.Sprintln("what the..", ev.Type, "event?"))
	}

	switch ev.Key {
	case term.KeyCtrlW:
		return []*Action{&Action{kind:"exit"}}
	case term.KeyCtrlS:
		return []*Action{&Action{kind:"save"}}
	// move
	case term.KeyArrowLeft:
		return []*Action{&Action{kind:"move", value:"left"}}
	case term.KeyArrowRight:
		return []*Action{&Action{kind:"move", value:"right"}}
	case term.KeyArrowUp:
		return []*Action{&Action{kind:"move", value:"up"}}
	case term.KeyArrowDown:
		return []*Action{&Action{kind:"move", value:"down"}}
	// insert
	case term.KeyEnter:
		return []*Action{&Action{kind:"insert", value:"\n"}}
	case term.KeySpace:
		return []*Action{&Action{kind:"insert", value:" "}}
	case term.KeyTab:
		return []*Action{&Action{kind:"insert", value:"\t"}}
	// delete : value will added after actual deletion.
	case term.KeyDelete:
		if sel.on {
			return []*Action{&Action{kind:"deleteSelection"}}
		} else {
			return []*Action{&Action{kind:"delete"}}
		}
	case term.KeyBackspace, term.KeyBackspace2:
		if sel.on {
			return []*Action{&Action{kind:"deleteSelection"}}
		} else {
			return []*Action{&Action{kind:"backspace"}}
		}
	// undo, redo
	case term.KeyCtrlZ:
		return []*Action{&Action{kind:"undo"}}
	case term.KeyCtrlY:
		return []*Action{&Action{kind:"redo"}}
	// copy, paste
	case term.KeyCtrlC:
		return []*Action{&Action{kind:"copy"}}
	case term.KeyCtrlV:
		return []*Action{&Action{kind:"paste"}}
	default:
		if ev.Ch == 0 {
			return []*Action{&Action{kind:"unknown"}}
		}
		if ev.Mod & term.ModAlt != 0 {
			kind := "move"
			if withShift(ev.Ch) {
				kind = "select"
			}
			switch ev.Ch {
			case 'j', 'J':
				return []*Action{&Action{kind:kind, value:"left"}}
			case 'l', 'L':
				return []*Action{&Action{kind:kind, value:"right"}}
			case 'i', 'I':
				return []*Action{&Action{kind:kind, value:"up"}}
			case 'k', 'K':
				return []*Action{&Action{kind:kind, value:"down"}}
			case 'm', 'M':
				return []*Action{&Action{kind:kind, value:"bow"}}
			case '.', '>':
				return []*Action{&Action{kind:kind, value:"eow"}}
			case 'u', 'U':
				return []*Action{&Action{kind:kind, value:"bol"}}
			case 'o', 'O':
				return []*Action{&Action{kind:kind, value:"eol"}}
			case 'h', 'H':
				return []*Action{&Action{kind:kind, value:"pageup"}}
			case 'n', 'N':
				return []*Action{&Action{kind:kind, value:"pagedown"}}
			case 'a', 'A':
				return []*Action{&Action{kind:kind, value:"bof"}}
			case 'z', 'Z':
				return []*Action{&Action{kind:kind, value:"eof"}}
			default:
				return []*Action{&Action{kind:"none"}}
			}
		}
		if sel.on {
			return []*Action{&Action{kind:"deleteSelection"}, &Action{kind:"insert", value:string(ev.Ch)}}
		} else {
			return []*Action{&Action{kind:"insert", value:string(ev.Ch)}}
		}
	}
}

func do(a *Action, c *Cursor, sel *Selection, history *History) {
	switch a.kind {
	case "none":
		return
	case "move", "select":
		if a.kind == "select" && !sel.on {
			sel.on = true
			sel.SetStart(c)
		}
		switch a.value {
		case "left":
			c.MoveLeft()
		case "right":
			c.MoveRight()
		case "up":
			c.MoveUp()
		case "down":
			c.MoveDown()
		case "bow":
			c.MoveBow()
		case "eow":
			c.MoveEow()
		case "bol":
			c.MoveBol()
		case "eol":
			c.MoveEol()
		case "pageup":
			c.PageUp()
		case "pagedown":
			c.PageDown()
		case "bof":
			c.MoveBof()
		case "eof":
			c.MoveEof()
		default:
			panic(fmt.Sprintln("what the..", a.value, "move?"))
		}
		if a.kind == "select" {
				sel.SetEnd(c)
		}
	case "insert":
		c.Insert(a.value)
	case "delete":
		a.value = c.Delete()
	case "backspace":
		a.value = c.Backspace()
	case "deleteSelection":
		a.value = c.DeleteSelection(sel)
	case "undo":
		if history.head == 0 {
			return
		}
		history.head--
		action := history.At(history.head)
		// status = fmt.Sprintf("undo : %v", action)
		// holdStatus = true
		switch action.kind {
		case "insert":
			c.Copy(action.afterCursor)
			for range action.value {
				c.Backspace()
			}
		case "paste":
			c.Copy(action.beforeCursor)
			for range action.value {
				c.Delete()
			}
		case "backspace":
			c.Copy(action.afterCursor)
			for _, r := range action.value {
				c.Insert(string(r))
			}
		case "delete", "deleteSelection":
			c.Copy(action.afterCursor)
			for _, r := range action.value {
				c.Insert(string(r))
			}
		default:
			panic(fmt.Sprintln("what the..", action.kind, "history?"))
		}
	case "redo":
		if history.head == history.Len() {
			return
		}
		action := history.At(history.head)
		// status = fmt.Sprintf("redo : %v", action)
		// holdStatus = true
		history.head++
		switch action.kind {
		case "insert":
			c.Copy(action.beforeCursor)
			for _, r := range action.value {
				c.Insert(string(r))
			}
		case "paste":
			c.Copy(action.beforeCursor)
			for _, r := range action.value {
				c.Insert(string(r))
			}
		case "backspace":
			c.Copy(action.beforeCursor)
			for range action.value {
				c.Backspace()
			}
		case "delete", "deleteSelection":
			c.Copy(action.beforeCursor)
			for range action.value {
				c.Delete()
			}
		default:
			panic(fmt.Sprintln("what the..", action.kind, "history?"))
		}
	default:
		panic(fmt.Sprintln("what the..", a.kind, "action?"))
	}
}

func main() {
	// check there is an destination file. ex)tor some.file
	args := os.Args[1:]
	if len(args)==0 {
		fmt.Println("please, set text file")
		return
	}
	f := args[0]

	text, err := open(f)
	if err != nil {
		fmt.Println(err)
		return
	}

	err = term.Init()
	if err != nil {
		panic(err)
	}
	defer term.Close()
	term.SetInputMode(term.InputAlt)
	term.Clear(term.ColorDefault, term.ColorDefault)
	term.Flush()

	layout := NewLayout()
	mainview := layout.MainViewerBound()
	win := NewWindow(layout)
	// drawbuf := textToDrawBuffer(text, selection)
	cursor := NewCursor(text)
	selection := NewSelection()
	history := newHistory()
	SetCursor(mainview.min.l, mainview.min.o)

	status := ""
	holdStatus := false
	lastActStr := ""
	copied := ""
	events := make(chan term.Event, 20)
	go func() {
		for {
			events <- term.PollEvent()
		}
	}()
	for {
		win.Follow(cursor)
		clearScreen(layout)
		drawScreen(layout, win, text, selection)

		if !holdStatus {
			if selection.on {
				status = "selection on - " + fmt.Sprintf("(%v, %v) - (%v, %v)", selection.start.l, selection.start.o, selection.end.l, selection.end.o)
			} else {
				status = fmt.Sprintf("linenum:%v, byteoff:%v, visoff:%v, cursoroff:%v, vpos:(%v,%v, %v,%v)", cursor.l, cursor.b, cursor.v, cursor.o, win.min.l, win.min.o, win.max.l, win.max.o)
			}
		}
		printStatus(status)
		holdStatus = false

		SetTermboxCursor(cursor, win, layout)
		term.Flush()

		// wait for keyboard input
		select {
		case ev := <-events:
			switch ev.Type {
			case term.EventKey:
				actions := parseEvent(ev, selection)
				for _, a := range actions {
					// keepSelection := false
					beforeCursor := *cursor

					if a.kind != "select" {
						selection.on=false
					}

					if a.kind == "exit" {
						return
					} else if a.kind == "save" {
						err := save(f, text)
						if err != nil {
							panic(err)
						}
						status = fmt.Sprintf("successfully saved : %v", f)
						holdStatus = true
					} else if a.kind == "copy" {
						minc, maxc := selection.MinMax()
						copied = text.DataInside(minc, maxc)
					} else if a.kind == "paste" {
						plines := strings.Split(copied, "\n")
						plen := len(plines)
						for i, l := range plines {
							cursor.Insert(l)
							if i != plen-1 {
								cursor.SplitLine()
							}
						}
						cursor.Copy(beforeCursor)
						a.value = copied
					} else {
						do(a, cursor, selection, history)
					}
					switch a.kind {
					case "insert", "delete", "backspace", "deleteSelection", "paste":
						// remember the action.
						nc := history.Cut(history.head)
						if nc != 0 {
							lastActStr = ""
						}
						if a.kind == "insert" || a.kind == "backspace" || a.kind == "backspace" {
							if a.kind == lastActStr {
								lastAct, err := history.Pop()
								if err != nil {
									panic(err)
								}
								history.head--
								beforeCursor = lastAct.beforeCursor
								if a.kind == "insert" || a.kind == "delete" {
									a.value = lastAct.value + a.value
								} else if a.kind == "backspace" {
									a.value = a.value + lastAct.value
								}
							}
						}
						a.beforeCursor = beforeCursor
						if a.kind == "deleteSelection" {
							a.beforeCursor, _ = selection.MinMax();
						}
						a.afterCursor = *cursor
						history.Add(a)
						history.head++
					}
					lastActStr = a.kind
					lastAct := history.Last()
					if lastAct != nil {
						historyFileString := ""
						for i, a := range history.actions {
							if i != 0 {
								historyFileString += "\n"
							}
							historyFileString += fmt.Sprintf("%v, %v", a, history.head)
						}
						ioutil.WriteFile(extendFileName(f, ".history"), []byte(historyFileString), 0755)
					}
				}
			}
		case <-time.After(time.Second):
			holdStatus = true
		// case term.EventResize:
		//	win.resize()
		//	win.clear()
		//	win.draw()
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"gohg"
	"fmt"
	"os"
	// "time"
)

func main() {
	var repo string
	if len(os.Args) > 1 {
		repo = os.Args[1]
	} else {
		repo = "."
	}
	a := make([]string, 1)
	// err := gohg.Connect("M:\\DEV\\hg-stable\\hg", "C:\\DEV\\go\\src\\golout", a)
	// err := gohg.Connect("M:\\DEV\\hg-stable\\hg", ".", a)
	err := gohg.Connect("M:\\DEV\\hg-stable\\hg", repo, a)
	if err != nil {
		fmt.Print(err)
		err = gohg.Close()
		if err != nil {
			fmt.Print("from Close():", err)
		}
		os.Exit(1)
	}

	// // keeping the gohg lib 'open' for a while
	// fmt.Println("sleeping 5 seconds ...")
	// time.Sleep(5 * time.Second)

	// fmt.Println("before Close()")
	err = gohg.Close()
	if err != nil {
		fmt.Print("from Close():", err)
		os.Exit(1)
	}
	// fmt.Println("after Close()")
	os.Exit(0)
}
<commit_msg>cleanup the test program<commit_after>package main

import (
	"gohg"
	"fmt"
	"os"
)

func main() {
	var repo = "."
	if len(os.Args) > 1 {
		repo = os.Args[1]
	}
	a := make([]string, 1)
	err := gohg.Connect("M:\\DEV\\hg-stable\\hg", repo, a)
	if err != nil {
		fmt.Println("from Connect():", err)
		err = gohg.Close()
		if err != nil {
			fmt.Println("from Close():", err)
		}
		os.Exit(1)
	}
	err = gohg.Close()
	if err != nil {
		fmt.Println("from Close():", err)
		os.Exit(1)
	}
	os.Exit(0)
}
<|endoftext|>


<commit_before>// +build !windows

package scard

// BUG(mg): Does not work on darwin. (older/different libpcsclite?)

// #cgo pkg-config: libpcsclite
// #include <stdlib.h>
// #include <winscard.h>
import "C"

import (
	"unsafe"
)

func (e Error) Error() string {
	return "scard: " + C.GoString(C.pcsc_stringify_error(C.LONG(e)))
}

// Version returns the libpcsclite version string
func Version() string {
	return C.PCSCLITE_VERSION_NUMBER
}

func scardEstablishContext(scope Scope, reserved1, reserved2 uintptr) (uintptr, Error) {
	var ctx C.SCARDCONTEXT
	r := C.SCardEstablishContext(C.DWORD(scope), C.LPCVOID(reserved1), C.LPCVOID(reserved2), &ctx)
	return uintptr(ctx), Error(r)
}

func scardIsValidContext(ctx uintptr) Error {
	r := C.SCardIsValidContext(C.SCARDCONTEXT(ctx))
	return Error(r)
}

func scardCancel(ctx uintptr) Error {
	r := C.SCardCancel(C.SCARDCONTEXT(ctx))
	return Error(r)
}

func scardReleaseContext(ctx uintptr) Error {
	r := C.SCardReleaseContext(C.SCARDCONTEXT(ctx))
	return Error(r)
}

func scardListReaders(ctx uintptr, groups, buf unsafe.Pointer, bufLen uint32) (uint32, Error) {
	dwBufLen := C.DWORD(bufLen)
	r := C.SCardListReaders(C.SCARDCONTEXT(ctx), (C.LPCSTR)(groups), (C.LPSTR)(buf), &dwBufLen)
	return uint32(dwBufLen), Error(r)
}

func scardListReaderGroups(ctx uintptr, buf unsafe.Pointer, bufLen uint32) (uint32, Error) {
	dwBufLen := C.DWORD(bufLen)
	r := C.SCardListReaderGroups(C.SCARDCONTEXT(ctx), (C.LPSTR)(buf), &dwBufLen)
	return uint32(dwBufLen), Error(r)
}

func scardGetStatusChange(ctx uintptr, timeout uint32, states []scardReaderState) Error {
	r := C.SCardGetStatusChange(C.SCARDCONTEXT(ctx), C.DWORD(timeout), (C.LPSCARD_READERSTATE)(unsafe.Pointer(&states[0])), C.DWORD(len(states)))
	return Error(r)
}

func scardConnect(ctx uintptr, reader unsafe.Pointer, shareMode ShareMode, proto Protocol) (uintptr, Protocol, Error) {
	var handle C.SCARDHANDLE
	var activeProto C.DWORD

	r := C.SCardConnect(C.SCARDCONTEXT(ctx), C.LPCSTR(reader), C.DWORD(shareMode), C.DWORD(proto), &handle, &activeProto)

	return uintptr(handle), Protocol(activeProto), Error(r)
}

func scardDisconnect(card uintptr, d Disposition) Error {
	r := C.SCardDisconnect(C.SCARDHANDLE(card), C.DWORD(d))
	return Error(r)
}

func scardReconnect(card uintptr, mode ShareMode, proto Protocol, disp Disposition) (Protocol, Error) {
	var activeProtocol C.DWORD
	r := C.SCardReconnect(C.SCARDHANDLE(card), C.DWORD(mode), C.DWORD(proto), C.DWORD(disp), &activeProtocol)
	return Protocol(activeProtocol), Error(r)
}

func scardBeginTransaction(card uintptr) Error {
	r := C.SCardBeginTransaction(C.SCARDHANDLE(card))
	return Error(r)
}

func scardEndTransaction(card uintptr, disp Disposition) Error {
	r := C.SCardEndTransaction(C.SCARDHANDLE(card), C.DWORD(disp))
	return Error(r)
}

func scardCardStatus(card uintptr) (string, State, Protocol, []byte, Error) {
	var readerBuf [C.MAX_READERNAME + 1]byte
	var readerLen = C.DWORD(len(readerBuf))
	var state, proto C.DWORD
	var atr [maxAtrSize]byte
	var atrLen = C.DWORD(len(atr))

	r := C.SCardStatus(C.SCARDHANDLE(card), (C.LPSTR)(unsafe.Pointer(&readerBuf[0])), &readerLen, &state, &proto, (*C.BYTE)(&atr[0]), &atrLen)

	return decodestr(readerBuf[:readerLen]), State(state), Protocol(proto), atr[:atrLen], Error(r)
}

func scardTransmit(card uintptr, proto Protocol, cmd []byte, rsp []byte) (uint32, Error) {
	var sendpci C.SCARD_IO_REQUEST
	var recvpci C.SCARD_IO_REQUEST
	var rspLen = C.DWORD(len(rsp))

	switch proto {
	case ProtocolT0, ProtocolT1:
		sendpci.dwProtocol = C.ulong(proto)
	default:
		panic("unknown protocol")
	}
	sendpci.cbPciLength = C.sizeof_SCARD_IO_REQUEST

	r := C.SCardTransmit(C.SCARDHANDLE(card), &sendpci, (*C.BYTE)(&cmd[0]), C.DWORD(len(cmd)), &recvpci, (*C.BYTE)(&rsp[0]), &rspLen)

	return uint32(rspLen), Error(r)
}

func scardControl(card uintptr, ioctl uint32, in, out []byte) (uint32, Error) {
	var ptrIn C.LPCVOID
	var outLen = C.DWORD(len(out))

	if len(in) != 0 {
		ptrIn = C.LPCVOID(unsafe.Pointer(&in[0]))
	}

	r := C.SCardControl(C.SCARDHANDLE(card), C.DWORD(ioctl), ptrIn, C.DWORD(len(in)), (C.LPVOID)(unsafe.Pointer(&out[0])), C.DWORD(len(out)), &outLen)
	return uint32(outLen), Error(r)
}

func scardGetAttrib(card uintptr, id Attrib, buf []byte) (uint32, Error) {
	var ptr C.LPBYTE

	if len(buf) != 0 {
		ptr = C.LPBYTE(unsafe.Pointer(&buf[0]))
	}

	bufLen := C.DWORD(len(buf))
	r := C.SCardGetAttrib(C.SCARDHANDLE(card), C.DWORD(id), ptr, &bufLen)

	return uint32(bufLen), Error(r)
}

func scardSetAttrib(card uintptr, id Attrib, buf []byte) Error {
	r := C.SCardSetAttrib(C.SCARDHANDLE(card), C.DWORD(id), (C.LPBYTE)(unsafe.Pointer(&buf[0])), C.DWORD(len(buf)))
	return Error(r)
}

type strbuf []byte

func encodestr(s string) (strbuf, error) {
	buf := strbuf(s + "\x00")
	return buf, nil
}

func decodestr(buf strbuf) string {
	if len(buf) == 0 {
		return ""
	}

	if buf[len(buf)-1] == 0 {
		buf = buf[:len(buf)-1]
	}

	return string(buf)
}

type scardReaderState C.SCARD_READERSTATE

func (rs *ReaderState) toSys() (scardReaderState, error) {
	var sys scardReaderState

	creader, err := encodestr(rs.Reader)
	if err != nil {
		return scardReaderState{}, err
	}
	sys.szReader = (*C.char)(creader.ptr())
	sys.dwCurrentState = C.DWORD(rs.CurrentState)
	sys.cbAtr = C.DWORD(len(rs.Atr))
	for i, v := range rs.Atr {
		sys.rgbAtr[i] = C.uchar(v)
	}
	return sys, nil
}

func (rs *ReaderState) update(sys *scardReaderState) {
	rs.EventState = StateFlag(sys.dwEventState)
	if sys.cbAtr > 0 {
		rs.Atr = make([]byte, int(sys.cbAtr))
		for i := 0; i < int(sys.cbAtr); i++ {
			rs.Atr[i] = byte(sys.rgbAtr[i])
		}
	}
}
<commit_msg>inline scardReaderState struct definition<commit_after>// +build !windows

package scard

// BUG(mg): Does not work on darwin. (older/different libpcsclite?)

// #cgo pkg-config: libpcsclite
// #include <stdlib.h>
// #include <winscard.h>
import "C"

import (
	"unsafe"
)

func (e Error) Error() string {
	return "scard: " + C.GoString(C.pcsc_stringify_error(C.LONG(e)))
}

// Version returns the libpcsclite version string
func Version() string {
	return C.PCSCLITE_VERSION_NUMBER
}

func scardEstablishContext(scope Scope, reserved1, reserved2 uintptr) (uintptr, Error) {
	var ctx C.SCARDCONTEXT
	r := C.SCardEstablishContext(C.DWORD(scope), C.LPCVOID(reserved1), C.LPCVOID(reserved2), &ctx)
	return uintptr(ctx), Error(r)
}

func scardIsValidContext(ctx uintptr) Error {
	r := C.SCardIsValidContext(C.SCARDCONTEXT(ctx))
	return Error(r)
}

func scardCancel(ctx uintptr) Error {
	r := C.SCardCancel(C.SCARDCONTEXT(ctx))
	return Error(r)
}

func scardReleaseContext(ctx uintptr) Error {
	r := C.SCardReleaseContext(C.SCARDCONTEXT(ctx))
	return Error(r)
}

func scardListReaders(ctx uintptr, groups, buf unsafe.Pointer, bufLen uint32) (uint32, Error) {
	dwBufLen := C.DWORD(bufLen)
	r := C.SCardListReaders(C.SCARDCONTEXT(ctx), (C.LPCSTR)(groups), (C.LPSTR)(buf), &dwBufLen)
	return uint32(dwBufLen), Error(r)
}

func scardListReaderGroups(ctx uintptr, buf unsafe.Pointer, bufLen uint32) (uint32, Error) {
	dwBufLen := C.DWORD(bufLen)
	r := C.SCardListReaderGroups(C.SCARDCONTEXT(ctx), (C.LPSTR)(buf), &dwBufLen)
	return uint32(dwBufLen), Error(r)
}

func scardGetStatusChange(ctx uintptr, timeout uint32, states []scardReaderState) Error {
	r := C.SCardGetStatusChange(C.SCARDCONTEXT(ctx), C.DWORD(timeout), (C.LPSCARD_READERSTATE)(unsafe.Pointer(&states[0])), C.DWORD(len(states)))
	return Error(r)
}

func scardConnect(ctx uintptr, reader unsafe.Pointer, shareMode ShareMode, proto Protocol) (uintptr, Protocol, Error) {
	var handle C.SCARDHANDLE
	var activeProto C.DWORD

	r := C.SCardConnect(C.SCARDCONTEXT(ctx), C.LPCSTR(reader), C.DWORD(shareMode), C.DWORD(proto), &handle, &activeProto)

	return uintptr(handle), Protocol(activeProto), Error(r)
}

func scardDisconnect(card uintptr, d Disposition) Error {
	r := C.SCardDisconnect(C.SCARDHANDLE(card), C.DWORD(d))
	return Error(r)
}

func scardReconnect(card uintptr, mode ShareMode, proto Protocol, disp Disposition) (Protocol, Error) {
	var activeProtocol C.DWORD
	r := C.SCardReconnect(C.SCARDHANDLE(card), C.DWORD(mode), C.DWORD(proto), C.DWORD(disp), &activeProtocol)
	return Protocol(activeProtocol), Error(r)
}

func scardBeginTransaction(card uintptr) Error {
	r := C.SCardBeginTransaction(C.SCARDHANDLE(card))
	return Error(r)
}

func scardEndTransaction(card uintptr, disp Disposition) Error {
	r := C.SCardEndTransaction(C.SCARDHANDLE(card), C.DWORD(disp))
	return Error(r)
}

func scardCardStatus(card uintptr) (string, State, Protocol, []byte, Error) {
	var readerBuf [C.MAX_READERNAME + 1]byte
	var readerLen = C.DWORD(len(readerBuf))
	var state, proto C.DWORD
	var atr [maxAtrSize]byte
	var atrLen = C.DWORD(len(atr))

	r := C.SCardStatus(C.SCARDHANDLE(card), (C.LPSTR)(unsafe.Pointer(&readerBuf[0])), &readerLen, &state, &proto, (*C.BYTE)(&atr[0]), &atrLen)

	return decodestr(readerBuf[:readerLen]), State(state), Protocol(proto), atr[:atrLen], Error(r)
}

func scardTransmit(card uintptr, proto Protocol, cmd []byte, rsp []byte) (uint32, Error) {
	var sendpci C.SCARD_IO_REQUEST
	var recvpci C.SCARD_IO_REQUEST
	var rspLen = C.DWORD(len(rsp))

	switch proto {
	case ProtocolT0, ProtocolT1:
		sendpci.dwProtocol = C.ulong(proto)
	default:
		panic("unknown protocol")
	}
	sendpci.cbPciLength = C.sizeof_SCARD_IO_REQUEST

	r := C.SCardTransmit(C.SCARDHANDLE(card), &sendpci, (*C.BYTE)(&cmd[0]), C.DWORD(len(cmd)), &recvpci, (*C.BYTE)(&rsp[0]), &rspLen)

	return uint32(rspLen), Error(r)
}

func scardControl(card uintptr, ioctl uint32, in, out []byte) (uint32, Error) {
	var ptrIn C.LPCVOID
	var outLen = C.DWORD(len(out))

	if len(in) != 0 {
		ptrIn = C.LPCVOID(unsafe.Pointer(&in[0]))
	}

	r := C.SCardControl(C.SCARDHANDLE(card), C.DWORD(ioctl), ptrIn, C.DWORD(len(in)), (C.LPVOID)(unsafe.Pointer(&out[0])), C.DWORD(len(out)), &outLen)
	return uint32(outLen), Error(r)
}

func scardGetAttrib(card uintptr, id Attrib, buf []byte) (uint32, Error) {
	var ptr C.LPBYTE

	if len(buf) != 0 {
		ptr = C.LPBYTE(unsafe.Pointer(&buf[0]))
	}

	bufLen := C.DWORD(len(buf))
	r := C.SCardGetAttrib(C.SCARDHANDLE(card), C.DWORD(id), ptr, &bufLen)

	return uint32(bufLen), Error(r)
}

func scardSetAttrib(card uintptr, id Attrib, buf []byte) Error {
	r := C.SCardSetAttrib(C.SCARDHANDLE(card), C.DWORD(id), (C.LPBYTE)(unsafe.Pointer(&buf[0])), C.DWORD(len(buf)))
	return Error(r)
}

type strbuf []byte

func encodestr(s string) (strbuf, error) {
	buf := strbuf(s + "\x00")
	return buf, nil
}

func decodestr(buf strbuf) string {
	if len(buf) == 0 {
		return ""
	}

	if buf[len(buf)-1] == 0 {
		buf = buf[:len(buf)-1]
	}

	return string(buf)
}

type scardReaderState struct {
	szReader       uintptr
	pvUserData     uintptr
	dwCurrentState uint32
	dwEventState   uint32
	cbAtr          uint32
	rgbAtr         [33]byte
}

func (rs *ReaderState) toSys() (scardReaderState, error) {
	var sys scardReaderState

	creader, err := encodestr(rs.Reader)
	if err != nil {
		return scardReaderState{}, err
	}
	sys.szReader = uintptr(creader.ptr())
	sys.dwCurrentState = uint32(rs.CurrentState)
	sys.cbAtr = uint32(len(rs.Atr))
	for i, v := range rs.Atr {
		sys.rgbAtr[i] = byte(v)
	}
	return sys, nil
}

func (rs *ReaderState) update(sys *scardReaderState) {
	rs.EventState = StateFlag(sys.dwEventState)
	if sys.cbAtr > 0 {
		rs.Atr = make([]byte, int(sys.cbAtr))
		for i := 0; i < int(sys.cbAtr); i++ {
			rs.Atr[i] = byte(sys.rgbAtr[i])
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"text/template"
)

var header string = `// Code generated by ModelQ
// {{.TableName}}.go contains model for the database table [{{.DbName}}.{{.TableName}}]

package {{.PkgName}}

import (
	"encoding/json"
	"encoding/gob"
	"fmt"
	"strings"
	"github.com/mijia/modelq/gmq"
	"database/sql"
	{{if .ImportTime}}"time"{{end}}
)
`

var modelStruct string = `type {{.Name}} struct {
	{{range .Fields}}{{.Name}} {{.Type}} {{.JsonMeta}}{{if .Comment}} // {{.Comment}}{{end}}
	{{end}}
}
`

var objApi string = `
// Start of the {{.Name}} APIs.

func (obj {{.Name}}) String() string {
	if data, err := json.Marshal(obj); err != nil {
		{{if .PrimaryFields}}return fmt.Sprintf({{ call .PrimaryFields.FormatObject .Name }}){{else}}return "<{{.Name}}>"{{end}}
	} else {
		return string(data)
	}
}

func (obj {{.Name}}) Insert(dbtx gmq.DbTx) ({{.Name}}, error) {
	{{if .HasAutoIncrementPrimaryKey}}if result, err := {{.Name}}Objs.Insert(obj).Run(dbtx); err != nil {
		return obj, err
	}else {
		if dbtx.DriverName() != "postgres" {
			if id, err := result.LastInsertId(); err != nil {
				return obj, err
			} else {
				{{ call .PrimaryFields.FormatIncrementId }}
				return obj, err
			}
		}
		return obj, nil
	}{{else}}_, err := {{.Name}}Objs.Insert(obj).Run(dbtx)
	return obj, err{{end}}
}

func (obj {{.Name}}) Update(dbtx gmq.DbTx) (int64, error) {
	{{if .PrimaryFields}}fields := []string{ {{.UpdatableFields}} }
	{{ call .PrimaryFields.FormatFilters .Name }}
	if result, err := {{.Name}}Objs.Update(obj, fields...).Where(filter).Run(dbtx); err != nil {
		return 0, err
	} else {
		return result.RowsAffected()
	}{{else}}return 0, gmq.ErrNoPrimaryKeyDefined{{end}}
}

func (obj {{.Name}}) Delete(dbtx gmq.DbTx) (int64, error) {
	{{if .PrimaryFields}}{{ call .PrimaryFields.FormatFilters .Name }}
	if result, err := {{.Name}}Objs.Delete().Where(filter).Run(dbtx); err != nil {
		return 0, err
	} else {
		return result.RowsAffected()
	}{{else}}return 0, gmq.ErrNoPrimaryKeyDefined{{end}}
}
`

var queryApi string = `
// Start of the inner Query Api

type _{{.Name}}Query struct {
	gmq.Query
}

func (q _{{.Name}}Query) Where(f gmq.Filter) _{{.Name}}Query {
	q.Query = q.Query.Where(f)
	return q
}

func (q _{{.Name}}Query) OrderBy(by ...string) _{{.Name}}Query {
	tBy := make([]string, 0, len(by))
	for _, b := range by {
		sortDir := ""
		if b[0] == '-' || b[0] == '+' {
			sortDir = string(b[0])
			b = b[1:]
		}
		if col, ok := {{.Name}}Objs.fcMap[b]; ok {
			tBy = append(tBy, sortDir+col)
		}
	}
	q.Query = q.Query.OrderBy(tBy...)
	return q
}

func (q _{{.Name}}Query) GroupBy(by ...string) _{{.Name}}Query {
	tBy := make([]string, 0, len(by))
	for _, b := range by {
		if col, ok := {{.Name}}Objs.fcMap[b]; ok {
			tBy = append(tBy, col)
		}
	}
	q.Query = q.Query.GroupBy(tBy...)
	return q
}

func (q _{{.Name}}Query) Limit(offsets ...int64) _{{.Name}}Query {
	q.Query = q.Query.Limit(offsets...)
	return q
}

func (q _{{.Name}}Query) Page(number, size int) _{{.Name}}Query {
	q.Query = q.Query.Page(number, size)
	return q
}

func (q _{{.Name}}Query) Run(dbtx gmq.DbTx) (sql.Result, error) {
	return q.Query.Exec(dbtx)
}

type {{.Name}}RowVisitor func(obj {{.Name}}) bool

func (q _{{.Name}}Query) Iterate(dbtx gmq.DbTx, functor {{.Name}}RowVisitor) error {
	return q.Query.SelectList(dbtx, func(columns []gmq.Column, rb []sql.RawBytes) bool {
		obj := {{.Name}}Objs.to{{.Name}}(columns, rb)
		return functor(obj)
	})
}

func (q _{{.Name}}Query) One(dbtx gmq.DbTx) ({{.Name}}, error) {
	var obj {{.Name}}
	err := q.Query.SelectOne(dbtx, func(columns []gmq.Column, rb []sql.RawBytes) bool {
		obj = {{.Name}}Objs.to{{.Name}}(columns, rb)
		return true
	})
	return obj, err
}

func (q _{{.Name}}Query) List(dbtx gmq.DbTx) ([]{{.Name}}, error) {
	result := make([]{{.Name}}, 0, 10)
	err := q.Query.SelectList(dbtx, func(columns []gmq.Column, rb []sql.RawBytes) bool {
		obj := {{.Name}}Objs.to{{.Name}}(columns, rb)
		result = append(result, obj)
		return true
	})
	return result, err
}
`

var managedApi string = `
// Start of the model facade Apis.

type _{{.Name}}Objs struct {
	fcMap map[string]string
}

func (o _{{.Name}}Objs) Names() (schema, tbl, alias string) {
	return "{{.DbName}}", "{{.TableName}}", "{{.Name}}"
}

func (o _{{.Name}}Objs) Select(fields ...string) _{{.Name}}Query {
	q := _{{.Name}}Query{}
	if len(fields) == 0 {
		fields = []string{ {{.AllFields}} }
	}
	q.Query = gmq.Select(o, o.columns(fields...))
	return q
}

func (o _{{.Name}}Objs) Insert(obj {{.Name}}) _{{.Name}}Query {
	q := _{{.Name}}Query{}
	q.Query = gmq.Insert(o, o.columnsWithData(obj, {{.InsertableFields}}))
	return q
}

func (o _{{.Name}}Objs) Update(obj {{.Name}}, fields ...string) _{{.Name}}Query {
	q := _{{.Name}}Query{}
	q.Query = gmq.Update(o, o.columnsWithData(obj, fields...))
	return q
}

func (o _{{.Name}}Objs) Delete() _{{.Name}}Query {
	q := _{{.Name}}Query{}
	q.Query = gmq.Delete(o)
	return q
}

{{$ModelName := .Name }}
///// Managed Objects Filters definition
{{range .Fields}}
func (o _{{$ModelName}}Objs) Filter{{.Name}}(op string, p {{.Type}}, ps ...{{.Type}}) gmq.Filter {
	params := make([]interface{}, 1+len(ps))
	params[0] = p
	for i := range ps {
		params[i+1] = ps[i]
	}
	return o.newFilter("{{.ColumnName}}", op, params...)
}

{{end}}

///// Managed Objects Columns definition
{{range .Fields}}
func (o _{{$ModelName}}Objs) Column{{.Name}}(p ...{{.Type}}) gmq.Column {
	var value interface{}
	if len(p) > 0 {
		value = p[0]
	}
	return gmq.Column{"{{.ColumnName}}", value}
}
{{end}}

////// Internal helper funcs

func (o _{{.Name}}Objs) newFilter(name, op string, params ...interface{}) gmq.Filter {
	if strings.ToUpper(op) == "IN" {
		return gmq.InFilter(name, params)
	}
	return gmq.UnitFilter(name, op, params[0])
}

func (o _{{.Name}}Objs) to{{.Name}}(columns []gmq.Column, rb []sql.RawBytes) {{.Name}} {
	obj := {{.Name}}{}
	if len(columns) == len(rb) {
		for i := range columns {
			switch columns[i].Name {
			{{range .Fields}}case "{{.ColumnName}}":
				obj.{{.Name}} = gmq.{{.ConverterFuncName}}(rb[i])
			{{end}} }
		}
	}
	return obj
}

func (o _{{.Name}}Objs) columns(fields ...string) []gmq.Column {
	data := make([]gmq.Column, 0, len(fields))
	for _, f := range fields {
		switch f {
		{{range .Fields}}case "{{.Name}}":
			data = append(data, o.Column{{.Name}}())
		{{end}} }
	}
	return data
}

func (o _{{.Name}}Objs) columnsWithData(obj {{.Name}}, fields ...string) []gmq.Column {
	data := make([]gmq.Column, 0, len(fields))
	for _, f := range fields {
		switch f {
		{{range .Fields}}case "{{.Name}}":
			data = append(data, o.Column{{.Name}}(obj.{{.Name}}))
		{{end}} }
	}
	return data
}

var {{.Name}}Objs _{{.Name}}Objs

func init() {
	{{.Name}}Objs.fcMap = map[string]string{
		{{range .Fields}}"{{.Name}}": "{{.ColumnName}}",
		{{end}} }
	gob.Register({{.Name}}{})
}
`

var (
	tmHeader        *template.Template
	tmStruct        *template.Template
	tmObjApi        *template.Template
	tmQueryApi      *template.Template
	tmManagedObjApi *template.Template
)

func init() {
	tmHeader = template.Must(template.New("header").Parse(header))
	tmStruct = template.Must(template.New("modelStruct").Parse(modelStruct))
	tmObjApi = template.Must(template.New("objApi").Parse(objApi))
	tmQueryApi = template.Must(template.New("queryApi").Parse(queryApi))
	tmManagedObjApi = template.Must(template.New("managedApi").Parse(managedApi))
}
<commit_msg>Adding the Get method for model<commit_after>package main

import (
	"text/template"
)

var header string = `// Code generated by ModelQ
// {{.TableName}}.go contains model for the database table [{{.DbName}}.{{.TableName}}]

package {{.PkgName}}

import (
	"encoding/json"
	"encoding/gob"
	"fmt"
	"strings"
	"github.com/mijia/modelq/gmq"
	"database/sql"
	{{if .ImportTime}}"time"{{end}}
)
`

var modelStruct string = `type {{.Name}} struct {
	{{range .Fields}}{{.Name}} {{.Type}} {{.JsonMeta}}{{if .Comment}} // {{.Comment}}{{end}}
	{{end}}
}
`

var objApi string = `
// Start of the {{.Name}} APIs.

func (obj {{.Name}}) String() string {
	if data, err := json.Marshal(obj); err != nil {
		{{if .PrimaryFields}}return fmt.Sprintf({{ call .PrimaryFields.FormatObject .Name }}){{else}}return "<{{.Name}}>"{{end}}
	} else {
		return string(data)
	}
}

func (obj {{.Name}}) Get(dbtx gmq.DbTx) ({{.Name}}, error) {
	{{if .PrimaryFields}}{{ call .PrimaryFields.FormatFilters .Name }}
	if result, err := {{.Name}}Objs.Select().Where(filter).One(dbtx); err != nil {
		return obj, err
	} else {
		return result, nil
	}{{else}}return 0, gmq.ErrNoPrimaryKeyDefined{{end}}
}

func (obj {{.Name}}) Insert(dbtx gmq.DbTx) ({{.Name}}, error) {
	{{if .HasAutoIncrementPrimaryKey}}if result, err := {{.Name}}Objs.Insert(obj).Run(dbtx); err != nil {
		return obj, err
	}else {
		if dbtx.DriverName() != "postgres" {
			if id, err := result.LastInsertId(); err != nil {
				return obj, err
			} else {
				{{ call .PrimaryFields.FormatIncrementId }}
				return obj, err
			}
		}
		return obj, nil
	}{{else}}_, err := {{.Name}}Objs.Insert(obj).Run(dbtx)
	return obj, err{{end}}
}

func (obj {{.Name}}) Update(dbtx gmq.DbTx) (int64, error) {
	{{if .PrimaryFields}}fields := []string{ {{.UpdatableFields}} }
	{{ call .PrimaryFields.FormatFilters .Name }}
	if result, err := {{.Name}}Objs.Update(obj, fields...).Where(filter).Run(dbtx); err != nil {
		return 0, err
	} else {
		return result.RowsAffected()
	}{{else}}return 0, gmq.ErrNoPrimaryKeyDefined{{end}}
}

func (obj {{.Name}}) Delete(dbtx gmq.DbTx) (int64, error) {
	{{if .PrimaryFields}}{{ call .PrimaryFields.FormatFilters .Name }}
	if result, err := {{.Name}}Objs.Delete().Where(filter).Run(dbtx); err != nil {
		return 0, err
	} else {
		return result.RowsAffected()
	}{{else}}return 0, gmq.ErrNoPrimaryKeyDefined{{end}}
}
`

var queryApi string = `
// Start of the inner Query Api

type _{{.Name}}Query struct {
	gmq.Query
}

func (q _{{.Name}}Query) Where(f gmq.Filter) _{{.Name}}Query {
	q.Query = q.Query.Where(f)
	return q
}

func (q _{{.Name}}Query) OrderBy(by ...string) _{{.Name}}Query {
	tBy := make([]string, 0, len(by))
	for _, b := range by {
		sortDir := ""
		if b[0] == '-' || b[0] == '+' {
			sortDir = string(b[0])
			b = b[1:]
		}
		if col, ok := {{.Name}}Objs.fcMap[b]; ok {
			tBy = append(tBy, sortDir+col)
		}
	}
	q.Query = q.Query.OrderBy(tBy...)
	return q
}

func (q _{{.Name}}Query) GroupBy(by ...string) _{{.Name}}Query {
	tBy := make([]string, 0, len(by))
	for _, b := range by {
		if col, ok := {{.Name}}Objs.fcMap[b]; ok {
			tBy = append(tBy, col)
		}
	}
	q.Query = q.Query.GroupBy(tBy...)
	return q
}

func (q _{{.Name}}Query) Limit(offsets ...int64) _{{.Name}}Query {
	q.Query = q.Query.Limit(offsets...)
	return q
}

func (q _{{.Name}}Query) Page(number, size int) _{{.Name}}Query {
	q.Query = q.Query.Page(number, size)
	return q
}

func (q _{{.Name}}Query) Run(dbtx gmq.DbTx) (sql.Result, error) {
	return q.Query.Exec(dbtx)
}

type {{.Name}}RowVisitor func(obj {{.Name}}) bool

func (q _{{.Name}}Query) Iterate(dbtx gmq.DbTx, functor {{.Name}}RowVisitor) error {
	return q.Query.SelectList(dbtx, func(columns []gmq.Column, rb []sql.RawBytes) bool {
		obj := {{.Name}}Objs.to{{.Name}}(columns, rb)
		return functor(obj)
	})
}

func (q _{{.Name}}Query) One(dbtx gmq.DbTx) ({{.Name}}, error) {
	var obj {{.Name}}
	err := q.Query.SelectOne(dbtx, func(columns []gmq.Column, rb []sql.RawBytes) bool {
		obj = {{.Name}}Objs.to{{.Name}}(columns, rb)
		return true
	})
	return obj, err
}

func (q _{{.Name}}Query) List(dbtx gmq.DbTx) ([]{{.Name}}, error) {
	result := make([]{{.Name}}, 0, 10)
	err := q.Query.SelectList(dbtx, func(columns []gmq.Column, rb []sql.RawBytes) bool {
		obj := {{.Name}}Objs.to{{.Name}}(columns, rb)
		result = append(result, obj)
		return true
	})
	return result, err
}
`

var managedApi string = `
// Start of the model facade Apis.

type _{{.Name}}Objs struct {
	fcMap map[string]string
}

func (o _{{.Name}}Objs) Names() (schema, tbl, alias string) {
	return "{{.DbName}}", "{{.TableName}}", "{{.Name}}"
}

func (o _{{.Name}}Objs) Select(fields ...string) _{{.Name}}Query {
	q := _{{.Name}}Query{}
	if len(fields) == 0 {
		fields = []string{ {{.AllFields}} }
	}
	q.Query = gmq.Select(o, o.columns(fields...))
	return q
}

func (o _{{.Name}}Objs) Insert(obj {{.Name}}) _{{.Name}}Query {
	q := _{{.Name}}Query{}
	q.Query = gmq.Insert(o, o.columnsWithData(obj, {{.InsertableFields}}))
	return q
}

func (o _{{.Name}}Objs) Update(obj {{.Name}}, fields ...string) _{{.Name}}Query {
	q := _{{.Name}}Query{}
	q.Query = gmq.Update(o, o.columnsWithData(obj, fields...))
	return q
}

func (o _{{.Name}}Objs) Delete() _{{.Name}}Query {
	q := _{{.Name}}Query{}
	q.Query = gmq.Delete(o)
	return q
}

{{$ModelName := .Name }}
///// Managed Objects Filters definition
{{range .Fields}}
func (o _{{$ModelName}}Objs) Filter{{.Name}}(op string, p {{.Type}}, ps ...{{.Type}}) gmq.Filter {
	params := make([]interface{}, 1+len(ps))
	params[0] = p
	for i := range ps {
		params[i+1] = ps[i]
	}
	return o.newFilter("{{.ColumnName}}", op, params...)
}

{{end}}

///// Managed Objects Columns definition
{{range .Fields}}
func (o _{{$ModelName}}Objs) Column{{.Name}}(p ...{{.Type}}) gmq.Column {
	var value interface{}
	if len(p) > 0 {
		value = p[0]
	}
	return gmq.Column{"{{.ColumnName}}", value}
}
{{end}}

////// Internal helper funcs

func (o _{{.Name}}Objs) newFilter(name, op string, params ...interface{}) gmq.Filter {
	if strings.ToUpper(op) == "IN" {
		return gmq.InFilter(name, params)
	}
	return gmq.UnitFilter(name, op, params[0])
}

func (o _{{.Name}}Objs) to{{.Name}}(columns []gmq.Column, rb []sql.RawBytes) {{.Name}} {
	obj := {{.Name}}{}
	if len(columns) == len(rb) {
		for i := range columns {
			switch columns[i].Name {
			{{range .Fields}}case "{{.ColumnName}}":
				obj.{{.Name}} = gmq.{{.ConverterFuncName}}(rb[i])
			{{end}} }
		}
	}
	return obj
}

func (o _{{.Name}}Objs) columns(fields ...string) []gmq.Column {
	data := make([]gmq.Column, 0, len(fields))
	for _, f := range fields {
		switch f {
		{{range .Fields}}case "{{.Name}}":
			data = append(data, o.Column{{.Name}}())
		{{end}} }
	}
	return data
}

func (o _{{.Name}}Objs) columnsWithData(obj {{.Name}}, fields ...string) []gmq.Column {
	data := make([]gmq.Column, 0, len(fields))
	for _, f := range fields {
		switch f {
		{{range .Fields}}case "{{.Name}}":
			data = append(data, o.Column{{.Name}}(obj.{{.Name}}))
		{{end}} }
	}
	return data
}

var {{.Name}}Objs _{{.Name}}Objs

func init() {
	{{.Name}}Objs.fcMap = map[string]string{
		{{range .Fields}}"{{.Name}}": "{{.ColumnName}}",
		{{end}} }
	gob.Register({{.Name}}{})
}
`

var (
	tmHeader        *template.Template
	tmStruct        *template.Template
	tmObjApi        *template.Template
	tmQueryApi      *template.Template
	tmManagedObjApi *template.Template
)

func init() {
	tmHeader = template.Must(template.New("header").Parse(header))
	tmStruct = template.Must(template.New("modelStruct").Parse(modelStruct))
	tmObjApi = template.Must(template.New("objApi").Parse(objApi))
	tmQueryApi = template.Must(template.New("queryApi").Parse(queryApi))
	tmManagedObjApi = template.Must(template.New("managedApi").Parse(managedApi))
}
<|endoftext|>