<commit_before>//A simple implementation of ETSN: https://raw.github.com/250bpm/nanomsg/master/rfc/etsn-01.txt
package etsn

import (
	"errors"
	"io"
	"net"
	"sync"
	"time"
)

var (
	ErrProtocolIdentifierTooLong  = errors.New("ETSN protocol identifier exceeds 255 bytes")
	ErrUnsupportedProtocolVersion = errors.New("Unsupported ETSN protocol version")
	ErrInvalidHeader              = errors.New("Invalid ETSN header")
)

func addrfix(laddr string) string {
	if len(laddr) > 0 && laddr[len(laddr)-1] == ':' {
		laddr += "5908"
	}
	return laddr
}

//Dial connects to the specified ETSN server and requests protocol proto.
//
//nett must be one of "tcp", "tcp4", "tcp6".
//
//laddr is standard Go networking address as used in the
//net package. If the laddr string ends in ":", the default
//port, 5908, is appended.
//
//If the server server does not speak the protocol proto, an error
//will be returned; otherwise a TCP connection is returned ready to use.
func Dial(nett, laddr, proto string) (*net.TCPConn, error) {
	if len(proto) > 255 {
		return nil, ErrProtocolIdentifierTooLong
	}
	conn, err := net.Dial(nett, addrfix(laddr))
	if err != nil {
		return nil, err
	}
	n, err := conn.Write(append([]byte{1, byte(len(proto))}, proto...))
	if err != nil || n != len(proto)+2 {
		conn.Close()
		switch {
		case err != nil:
			return nil, err
		case n != len(proto)+2:
			return nil, io.ErrShortWrite
		}
	}
	return conn.(*net.TCPConn), nil
}

//Server encapsulates the state of an ETSN server.
type Server struct {
	protos map[string]func(*net.TCPConn)
	lock   sync.Mutex
	log    func(error)
}

//New returns a new Server.
//
//logger is called whenever there's an error establishing
//a connection within Listen. If nil, a no op logger is used.
//The logger may be called by multiple goroutines.
func New(logger func(error)) *Server {
	if logger == nil {
		logger = func(error) {}
	}
	return &Server{
		protos: map[string]func(*net.TCPConn){},
		log:    logger,
	}
}

//Register registers a handler function for the protocol named proto.
//
//If there was already a protocol registered with identifier proto,
//handler will be used for any future connections. All existing
//connections of proto will remain with the previous handler until
//the connections are closed.
func (s *Server) Register(proto string, handler func(*net.TCPConn)) error {
	if len(proto) > 255 {
		return ErrProtocolIdentifierTooLong
	}
	s.lock.Lock()
	defer s.lock.Unlock()
	s.protos[proto] = handler
	return nil
}

//Unregister removes any handler associated with the identifier proto,
//if present.
//
//No existing connection will be effected.
func (s *Server) Unregister(proto string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	delete(s.protos, proto)
}

//Help is a local version of the TCPMUX HELP protocol.
//It returns a list of all the protocols the server
//implements. It is not exposed by the server, but can be
//made to do so trivially, if desired: (error handling elided
//for brevity)
//	server.Register("HELP", func(c *net.TCPConn) {
//		w := bufio.NewWriter(c)
//		for _, p := range server.Help() {
//			w.WriteString(p)
//			w.WriteByte('\n')
//		}
//		w.Flush()
//		c.Close()
//	})
func (s *Server) Help() (protos []string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	for p := range s.protos {
		protos = append(protos, p)
	}
	return
}

//Listen starts an ETSN server on port 5908.
//
//When connections are made they are dispatched,
//based on the client's requested protocol identifier,
//to any handler registered via Register, otherwise the
//request is dropped.
//
//If a logger was set with SetListenLogger, all errors
//during the ETSN handshake will be passed to it, there will
//be at most one error per goroutine.
//
//nett must be one of "tcp", "tcp4", "tcp6".
//
//laddr is standard Go networking address as used in the
//net package. If the laddr string ends in ":", the default
//port, 5908, is appended.
//
//If the server does not fail to start, it will take over
//the current goroutine until it is killed from another
//goroutine.
func (s *Server) Listen(nett, laddr string) error {
	Ln, err := net.Listen(nett, addrfix(laddr))
	if err != nil {
		return err
	}
	ln := Ln.(*net.TCPListener)
	for {
		conn, err := ln.AcceptTCP()
		if err != nil {
			s.log(err)
			//we assume that any error here means we don't care
			continue
		}
		go func() {
			conn.SetReadDeadline(time.Now().Add(time.Second))

			header := make([]byte, 2)
			n, err := conn.Read(header)
			if err != nil || n != 2 || header[0] != 1 {
				conn.Close()
				switch {
				case err != nil:
					s.log(err)
				case n != 2:
					s.log(ErrInvalidHeader)
				case header[0] != 1:
					s.log(ErrUnsupportedProtocolVersion)
				}
				return
			}
			length := int(header[1])
			proto := make([]byte, length)
			n, err = conn.Read(proto)
			if err != nil || n != length {
				conn.Close()
				switch {
				case err != nil:
					s.log(err)
				case n != length:
					s.log(ErrInvalidHeader)
				}
				return
			}

			s.lock.Lock()
			handler, ok := s.protos[string(proto)]
			s.lock.Unlock()
			if !ok {
				conn.Close()
				return
			}

			conn.SetReadDeadline(time.Time{})
			handler(conn)
		}()
	}
}
<commit_msg>added errors for handlers; added methodmissing<commit_after>//A simple implementation of ETSN: https://raw.github.com/250bpm/nanomsg/master/rfc/etsn-01.txt
package etsn

import (
	"errors"
	"io"
	"net"
	"sync"
	"time"
)

var (
	ErrProtocolIdentifierTooLong  = errors.New("ETSN protocol identifier exceeds 255 bytes")
	ErrUnsupportedProtocolVersion = errors.New("Unsupported ETSN protocol version")
	ErrInvalidHeader              = errors.New("Invalid ETSN header")
)

func addrfix(laddr string) string {
	if len(laddr) > 0 && laddr[len(laddr)-1] == ':' {
		laddr += "5908"
	}
	return laddr
}

//Dial connects to the specified ETSN server and requests protocol proto.
//
//nett must be one of "tcp", "tcp4", "tcp6".
//
//laddr is standard Go networking address as used in the
//net package. If the laddr string ends in ":", the default
//port, 5908, is appended.
//
//If the server server does not speak the protocol proto, an error
//will be returned; otherwise a TCP connection is returned ready to use.
func Dial(nett, laddr, proto string) (*net.TCPConn, error) {
	if len(proto) > 255 {
		return nil, ErrProtocolIdentifierTooLong
	}
	conn, err := net.Dial(nett, addrfix(laddr))
	if err != nil {
		return nil, err
	}
	n, err := conn.Write(append([]byte{1, byte(len(proto))}, proto...))
	if err != nil || n != len(proto)+2 {
		conn.Close()
		switch {
		case err != nil:
			return nil, err
		case n != len(proto)+2:
			return nil, io.ErrShortWrite
		}
	}
	return conn.(*net.TCPConn), nil
}

//Server encapsulates the state of an ETSN server.
type Server struct {
	protos  map[string]func(*net.TCPConn) error
	lock    sync.Mutex
	log     func(error)
	missing func(string, *net.TCPConn) error
}

//New returns a new Server.
//
//logger is called whenever there's an error establishing
//a connection within Listen. If nil, a no op logger is used.
//The logger may be called by multiple goroutines.
//Errors returned from handlers are passed to logger.
func New(logger func(error)) *Server {
	if logger == nil {
		logger = func(error) {}
	}
	return &Server{
		protos: map[string]func(*net.TCPConn){},
		log:    logger,
	}
}

//ProtocolMissing is called when no protocol is found.
//The first argument is the name of the unknown protocol, otherwise
//it behaves exactly like a regular handler.
//If no ProtocolMissing handler is set, or this is called with nil,
//requests will be closed and ignored.
func (s *Server) ProtocolMissing(pm func(string, *net.TCPConn) error) {
	lock.Lock()
	defer lock.Unlock()
	s.missing = pm
}

//Register registers a handler function for the protocol named proto.
//
//If there was already a protocol registered with identifier proto,
//handler will be used for any future connections. All existing
//connections of proto will remain with the previous handler until
//the connections are closed.
func (s *Server) Register(proto string, handler func(*net.TCPConn) error) error {
	if len(proto) > 255 {
		return ErrProtocolIdentifierTooLong
	}
	s.lock.Lock()
	defer s.lock.Unlock()
	s.protos[proto] = handler
	return nil
}

//Unregister removes any handler associated with the identifier proto,
//if present.
//
//No existing connection will be effected.
func (s *Server) Unregister(proto string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	delete(s.protos, proto)
}

//Help is a local version of the TCPMUX HELP protocol.
//It returns a list of all the protocols the server
//implements. It is not exposed by the server, but can be
//made to do so trivially, if desired: (error handling elided
//for brevity)
//	server.Register("HELP", func(c *net.TCPConn) {
//		w := bufio.NewWriter(c)
//		for _, p := range server.Help() {
//			w.WriteString(p)
//			w.WriteByte('\n')
//		}
//		w.Flush()
//		c.Close()
//	})
func (s *Server) Help() (protos []string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	for p := range s.protos {
		protos = append(protos, p)
	}
	return
}

//Listen starts an ETSN server on port 5908.
//
//When connections are made they are dispatched,
//based on the client's requested protocol identifier,
//to any handler registered via Register, otherwise the
//request is dropped.
//
//If a logger was set with SetListenLogger, all errors
//during the ETSN handshake will be passed to it, there will
//be at most one error per goroutine.
//
//nett must be one of "tcp", "tcp4", "tcp6".
//
//laddr is standard Go networking address as used in the
//net package. If the laddr string ends in ":", the default
//port, 5908, is appended.
//
//If the server does not fail to start, it will take over
//the current goroutine until it is killed from another
//goroutine.
func (s *Server) Listen(nett, laddr string) error {
	Ln, err := net.Listen(nett, addrfix(laddr))
	if err != nil {
		return err
	}
	ln := Ln.(*net.TCPListener)
	for {
		conn, err := ln.AcceptTCP()
		if err != nil {
			s.log(err)
			//we assume that any error here means we don't care
			continue
		}
		go func() {
			conn.SetReadDeadline(time.Now().Add(time.Second))

			header := make([]byte, 2)
			n, err := conn.Read(header)
			if err != nil || n != 2 || header[0] != 1 {
				conn.Close()
				switch {
				case err != nil:
					s.log(err)
				case n != 2:
					s.log(ErrInvalidHeader)
				case header[0] != 1:
					s.log(ErrUnsupportedProtocolVersion)
				}
				return
			}
			length := int(header[1])
			proto := make([]byte, length)
			n, err = conn.Read(proto)
			if err != nil || n != length {
				conn.Close()
				switch {
				case err != nil:
					s.log(err)
				case n != length:
					s.log(ErrInvalidHeader)
				}
				return
			}
			conn.SetReadDeadline(time.Time{})
			sproto := string(proto)

			s.lock.Lock()
			handler, ok := s.protos[sproto]
			missing := s.missing
			s.lock.Unlock()

			if !ok {
				conn.Close()
			} else if missing != nil {
				s.log(missing(proto, conn))
			} else {
				s.log(handler(conn))
			}
		}()
	}
}
<|endoftext|>


<commit_before>//A simple implementation of ETSN: https://raw.github.com/250bpm/nanomsg/master/rfc/etsn-01.txt
package etsn

import (
	"errors"
	"io"
	"net"
	"sync"
	"time"
)

var (
	ErrProtocolIdentifierTooLong  = errors.New("ETSN protocol identifier exceeds 255 bytes")
	ErrUnsupportedProtocolVersion = errors.New("Unsupported ETSN protocol version")
	ErrInvalidHeader              = errors.New("Invalid ETSN header")
)

func addrfix(laddr string) string {
	if len(laddr) > 0 && laddr[len(laddr)-1] == ":" {
		laddr += "5908"
	}
	return laddr
}

//Dial connects to the specified ETSN server and requests protocol proto.
//
//nett must be one of "tcp", "tcp4", "tcp6".
//laddr is standard Go networking address as used in the
//net package. If the laddr string ends in ":", the default
//port, 5908, is appended.
//
//If the server server does not speak the protocol proto, an error
//will be returned; otherwise a TCP connection is returned ready to use.
func Dial(nett, laddr, proto string) (*net.TCPConn, error) {
	if len(proto) > 255 {
		return nil, ErrProtocolIdentifierTooLong
	}
	conn, err := net.Dial(nett, addrfix(laddr))
	if err != nil {
		return nil, err
	}
	n, err := conn.Write(append([]byte{1, byte(len(proto))}, proto...))
	if err != nil {
		conn.Close()
		return nil, err
	}
	if n != len(proto)+2 {
		conn.Close()
		return nil, io.ErrShortWrite
	}
	return conn.(*net.TCPConn), nil
}

//Server encapsulates the state of an ETSN server.
type Server struct {
	protos  map[string]func(*net.TCPConn)
	lock    sync.Mutex
	running bool
	done    chan bool
	log     func(error)
}

//New returns a new Server.
//
//logger is called whenever there's an error establishing
//a connection within Listen. If nil, a no op logger is used.
//The logger may be called by multiple goroutines.
func New(logger func(error)) *Server {
	if logger == nil {
		logger = func(error) {}
	}
	return &Server{
		done:   make(chan bool),
		protos: map[string]func(*net.TCPConn){},
	}
}

//Register registers a handler function for the protocol named proto.
//
//If there was already a protocol registered with identifier proto,
//handler will be used for any future connections. All existing
//connections of proto will remain with the previous handler until
//the connections are closed.
func (s *Server) Register(proto string, handler func(*net.TCPConn)) error {
	if len(proto) > 255 {
		return ErrProtocolIdentifierTooLong
	}
	s.lock.Lock()
	defer s.lock.Unlock()
	s.protos[proto] = handler
	return nil
}

//Unregister removes any handler associated with the identifier proto,
//if present.
//
//No existing connection will be effected.
func (s *Server) Unregister(proto string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	delete(s.protos, proto)
}

//Kill makes the server die. It will accept no more incoming requests.
//Open connections will continue to run.
func (s *Server) Kill() {
	s.lock.Lock()
	defer s.lock.Unlock()
	if s.running {
		done <- true
		s.running = false
	}
}

//Listen starts an ETSN server on port 5908.
//
//When connections are made they are dispatched,
//based on the client's requested protocol identifier,
//to any handler registered via Register, otherwise the
//request is dropped.
//
//If a logger was set with SetListenLogger, all errors
//during the ETSN handshake will be passed to it.
//
//nett must be one of "tcp", "tcp4", "tcp6".
//laddr is standard Go networking address as used in the
//net package. If the laddr string ends in ":", the default
//port, 5908, is appended.
//
//If the server does not fail to start, it will take over
//the current goroutine until it is killed from another
//goroutine.
func (s *Server) Listen(nett, laddr string) error {
	s.lock.Lock()
	defer s.lock.Unlock()
	if s.running {
		return errors.New("Already running")
	}
	Ln, err := net.Listen(nett, addrfix(laddr))
	if err != nil {
		return err
	}
	s.running = true
	ln := Ln.(*net.TCPListener)
	for {
		select {
		case <-done:
			return
		default:
		}
		conn, err := ln.AcceptTCP()
		if err != nil {
			//we assume that any error here means we don't care
			continue
		}
		go func() {
			conn.SetReadDeadline(time.Now().Add(time.Second))

			header := make([]byte, 0, 2)
			n, err := conn.Read(header)
			if err != nil || n != 2 || header[0] != 1 {
				conn.Close()
				switch {
				case err != nil:
					s.log(err)
				case n != 2:
					s.log(ErrInvalidHeader)
				case header[0] != 1:
					s.log(ErrUnsupportedProtocolVersion)
				}
			}
			length := int(header[1])
			proto := make([]byte, 0, length)
			n, err = conn.Read(proto)
			if err != nil || n != length {
				conn.Close()
				switch {
				case err != nil:
					s.log(err)
				case n != length:
					s.log(ErrInvalidHeader)
				}
				return
			}

			s.lock.Lock()
			handler, ok := s.protos[string(proto)]
			s.lock.Unlock()
			if !ok {
				conn.Close()
				return
			}

			conn.SetReadDeadline(time.Time{})
			handler(conn)
		}()
	}
}
<commit_msg>clean up api, actually attached logger to server, add Help<commit_after>//A simple implementation of ETSN: https://raw.github.com/250bpm/nanomsg/master/rfc/etsn-01.txt
package etsn

import (
	"errors"
	"io"
	"net"
	"sync"
	"time"
)

var (
	ErrProtocolIdentifierTooLong  = errors.New("ETSN protocol identifier exceeds 255 bytes")
	ErrUnsupportedProtocolVersion = errors.New("Unsupported ETSN protocol version")
	ErrInvalidHeader              = errors.New("Invalid ETSN header")
)

func addrfix(laddr string) string {
	if len(laddr) > 0 && laddr[len(laddr)-1] == ':' {
		laddr += "5908"
	}
	return laddr
}

//Dial connects to the specified ETSN server and requests protocol proto.
//
//nett must be one of "tcp", "tcp4", "tcp6".
//
//laddr is standard Go networking address as used in the
//net package. If the laddr string ends in ":", the default
//port, 5908, is appended.
//
//If the server server does not speak the protocol proto, an error
//will be returned; otherwise a TCP connection is returned ready to use.
func Dial(nett, laddr, proto string) (*net.TCPConn, error) {
	if len(proto) > 255 {
		return nil, ErrProtocolIdentifierTooLong
	}
	conn, err := net.Dial(nett, addrfix(laddr))
	if err != nil {
		return nil, err
	}
	n, err := conn.Write(append([]byte{1, byte(len(proto))}, proto...))
	if err != nil {
		conn.Close()
		return nil, err
	}
	if n != len(proto)+2 {
		conn.Close()
		return nil, io.ErrShortWrite
	}
	return conn.(*net.TCPConn), nil
}

//Server encapsulates the state of an ETSN server.
type Server struct {
	protos map[string]func(*net.TCPConn)
	lock   sync.Mutex
	log    func(error)
}

//New returns a new Server.
//
//logger is called whenever there's an error establishing
//a connection within Listen. If nil, a no op logger is used.
//The logger may be called by multiple goroutines.
func New(logger func(error)) *Server {
	if logger == nil {
		logger = func(error) {}
	}
	return &Server{
		protos: map[string]func(*net.TCPConn){},
		log:    logger,
	}
}

//Register registers a handler function for the protocol named proto.
//
//If there was already a protocol registered with identifier proto,
//handler will be used for any future connections. All existing
//connections of proto will remain with the previous handler until
//the connections are closed.
func (s *Server) Register(proto string, handler func(*net.TCPConn)) error {
	if len(proto) > 255 {
		return ErrProtocolIdentifierTooLong
	}
	s.lock.Lock()
	defer s.lock.Unlock()
	s.protos[proto] = handler
	return nil
}

//Unregister removes any handler associated with the identifier proto,
//if present.
//
//No existing connection will be effected.
func (s *Server) Unregister(proto string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	delete(s.protos, proto)
}

//Help is a local version of the TCPMUX HELP protocol.
//It returns a list of all the protocols the server
//implements. It is not exposed by the server, but can be
//made to do so trivially, if desired: (error handling elided
//for brevity)
//	server.Register("HELP", func(c *net.TCPConn) {
//		w := bufio.NewWriter(c)
//		for _, p := range server.Help() {
//			w.WriteString(p)
//			w.WriteByte('\n')
//		}
//		w.Flush()
//		c.Close()
//	})
func (s *Server) Help() (protos []string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	for p := range s.protos {
		protos = append(protos, p)
	}
	return
}

//Listen starts an ETSN server on port 5908.
//
//When connections are made they are dispatched,
//based on the client's requested protocol identifier,
//to any handler registered via Register, otherwise the
//request is dropped.
//
//If a logger was set with SetListenLogger, all errors
//during the ETSN handshake will be passed to it, there will
//be at most one error per goroutine.
//
//nett must be one of "tcp", "tcp4", "tcp6".
//
//laddr is standard Go networking address as used in the
//net package. If the laddr string ends in ":", the default
//port, 5908, is appended.
//
//If the server does not fail to start, it will take over
//the current goroutine until it is killed from another
//goroutine.
func (s *Server) Listen(nett, laddr string) error {
	Ln, err := net.Listen(nett, addrfix(laddr))
	if err != nil {
		return err
	}
	ln := Ln.(*net.TCPListener)
	for {
		conn, err := ln.AcceptTCP()
		if err != nil {
			//we assume that any error here means we don't care
			continue
		}
		go func() {
			conn.SetReadDeadline(time.Now().Add(time.Second))

			header := make([]byte, 0, 2)
			n, err := conn.Read(header)
			if err != nil || n != 2 || header[0] != 1 {
				conn.Close()
				switch {
				case err != nil:
					s.log(err)
				case n != 2:
					s.log(ErrInvalidHeader)
				case header[0] != 1:
					s.log(ErrUnsupportedProtocolVersion)
				}
			}
			length := int(header[1])
			proto := make([]byte, 0, length)
			n, err = conn.Read(proto)
			if err != nil || n != length {
				conn.Close()
				switch {
				case err != nil:
					s.log(err)
				case n != length:
					s.log(ErrInvalidHeader)
				}
				return
			}

			s.lock.Lock()
			handler, ok := s.protos[string(proto)]
			s.lock.Unlock()
			if !ok {
				conn.Close()
				return
			}

			conn.SetReadDeadline(time.Time{})
			handler(conn)
		}()
	}
}
<|endoftext|>


<commit_before>package coreutils

import (
	"os"
	"os/exec"
)

// ExecCommand executes a utility with args and returning the stringified output
func ExecCommand(utility string, args []string, liveOutput bool) string {
	var output []byte
	runner := exec.Command(utility, args...)

	if liveOutput { // If we should immediately output the results of the command
		runner.Stdout = os.Stdout
		runner.Stderr = os.Stderr
		runner.Start()
	} else { // If we should redirect output to var
		output, _ = runner.CombinedOutput() // Combine the output of stderr and stdout
	}

	return string(output[:])
}

// ExecutableExists checks if an executable exists
func ExecutableExists(executableName string) bool {
	_, existsErr := exec.LookPath(executableName)
	return (existsErr == nil)
}
<commit_msg>Check if the provided command in ExecCommand exists before attempting execution.<commit_after>package coreutils

import (
	"os"
	"os/exec"
)

// ExecCommand executes a command with args and returning the stringified output
func ExecCommand(command string, args []string, liveOutput bool) string {
	if ExecutableExists(command) { // If the executable exists
		var output []byte
		runner := exec.Command(command, args...)

		if liveOutput { // If we should immediately output the results of the command
			runner.Stdout = os.Stdout
			runner.Stderr = os.Stderr
			runner.Start()
		} else { // If we should redirect output to var
			output, _ = runner.CombinedOutput() // Combine the output of stderr and stdout
		}

		return string(output[:])
	} else { // If the executable doesn't exist
		return command + " is not an executable."
	}
}

// ExecutableExists checks if an executable exists
func ExecutableExists(executableName string) bool {
	_, existsErr := exec.LookPath(executableName)
	return (existsErr == nil)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"testing"

	"github.com/kataras/iris/httptest"
)

func TestI18n(t *testing.T) {
	app := newApp()

	expectedf := "From the language %s translated output: %s"
	var (
		elgr = fmt.Sprintf(expectedf, "el-GR", "γεια, iris")
		enus = fmt.Sprintf(expectedf, "en-US", "hello, iris")
		zhcn = fmt.Sprintf(expectedf, "zh-CN", "您好，iris")
	)

	e := httptest.New(t, app)
	// default is en-US
	e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal(enus)
	// default is en-US if lang query unable to be found
	e.GET("/").WithQueryString("lang=un-EX").Expect().Status(httptest.StatusOK).Body().Equal(enus)

	e.GET("/").WithQueryString("lang=el-GR").Expect().Status(httptest.StatusOK).Body().Equal(elgr)
	e.GET("/").WithQueryString("lang=en-US").Expect().Status(httptest.StatusOK).Body().Equal(enus)
	e.GET("/").WithQueryString("lang=zh-CN").Expect().Status(httptest.StatusOK).Body().Equal(zhcn)
}
<commit_msg>update test to cover the multi files per language new feature - requested at: https://github.com/kataras/iris/issues/815<commit_after>package main

import (
	"fmt"
	"testing"

	"github.com/kataras/iris/httptest"
)

func TestI18n(t *testing.T) {
	app := newApp()

	expectedf := "From the language %s translated output: %s"
	var (
		elgr = fmt.Sprintf(expectedf, "el-GR", "γεια, iris")
		enus = fmt.Sprintf(expectedf, "en-US", "hello, iris")
		zhcn = fmt.Sprintf(expectedf, "zh-CN", "您好，iris")

		elgrMulti = fmt.Sprintf("From the language: %s, translated output:\n%s=%s\n%s=%s", "el-GR",
			"key1",
			"αυτό είναι μια τιμή από το πρώτο αρχείο: locale_multi_first",
			"key2",
			"αυτό είναι μια τιμή από το δεύτερο αρχείο μετάφρασης: locale_multi_second")
		enusMulti = fmt.Sprintf("From the language: %s, translated output:\n%s=%s\n%s=%s", "en-US",
			"key1",
			"this is a value from the first file: locale_multi_first",
			"key2",
			"this is a value from the second file: locale_multi_second")
	)

	e := httptest.New(t, app)
	// default is en-US
	e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal(enus)
	// default is en-US if lang query unable to be found
	e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal(enus)

	e.GET("/").WithQueryString("lang=el-GR").Expect().Status(httptest.StatusOK).
		Body().Equal(elgr)
	e.GET("/").WithQueryString("lang=en-US").Expect().Status(httptest.StatusOK).
		Body().Equal(enus)
	e.GET("/").WithQueryString("lang=zh-CN").Expect().Status(httptest.StatusOK).
		Body().Equal(zhcn)

	e.GET("/multi").WithQueryString("lang=el-GR").Expect().Status(httptest.StatusOK).
		Body().Equal(elgrMulti)
	e.GET("/multi").WithQueryString("lang=en-US").Expect().Status(httptest.StatusOK).
		Body().Equal(enusMulti)

}
<|endoftext|>


<commit_before>package main

import "fmt"
import "time"

func startOfMonth(t time.Time) time.Time {
	return t.AddDate(0, 0, 1-t.Day())
}

func endOfMonth(t time.Time) time.Time {
	return startOfMonth(t).AddDate(0, 1, -1)
}

func datesBetween(start, end time.Time) []time.Time {
	var dates []time.Time
	curr := start

	for curr.Before(end.AddDate(0, 0, 1)) {
		dates = append(dates, curr)
		curr = curr.AddDate(0, 0, 1)
	}

	return dates
}

func main() {
	now := time.Now()
	//now := time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
	fmt.Println(now.String())

	thisMonth := now.Month()

	fmt.Println(thisMonth.String())
	fmt.Println(now.Weekday().String())
	fmt.Println(now.Weekday())

	dates := datesBetween(startOfMonth(now), endOfMonth(now))
	for _, date := range dates {
		fmt.Println(date)
	}
}
<commit_msg>Print this month's calendar<commit_after>package main

import "fmt"
import "time"
import "bytes"

func startOfMonth(t time.Time) time.Time {
	return t.AddDate(0, 0, 1-t.Day())
}

func endOfMonth(t time.Time) time.Time {
	return startOfMonth(t).AddDate(0, 1, -1)
}

func datesBetween(start, end time.Time) []time.Time {
	var dates []time.Time
	curr := start

	for curr.Before(end.AddDate(0, 0, 1)) {
		dates = append(dates, curr)
		curr = curr.AddDate(0, 0, 1)
	}

	return dates
}

func breakIntoWeeks(dates []time.Time) [][]time.Time {
	var weeks [][]time.Time
	currWeek := []time.Time{}

	for _, date := range dates {
		currWeek = append(currWeek, date)
		if int(date.Weekday()) == 6 {
			weeks = append(weeks, currWeek)
			currWeek = []time.Time{}
		}
	}
	weeks = append(weeks, currWeek)

	return weeks
}

func main() {
	now := time.Now()
	header := fmt.Sprintf("%s %d", now.Month(), now.Year())
	fmt.Printf("%*s\n", 10+len(header)/2, header)
	fmt.Println("Su Mo Tu We Th Fr Sa")

	dates := datesBetween(startOfMonth(now), endOfMonth(now))
	weeks := breakIntoWeeks(dates)
	for j, week := range weeks {
		var buffer bytes.Buffer

		if j == 0 {
			for i := 0; i <= 6-len(week); i++ {
				buffer.WriteString("   ")
			}
		}

		for _, date := range week {
			buffer.WriteString(fmt.Sprintf("%2d ", date.Day()))
		}

		fmt.Println(buffer.String())
	}
}
<|endoftext|>


<commit_before>// 1 september 2012
package main

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

// TODO NoScans
func listotherconsoles(w http.ResponseWriter, r *http.Request) error {
	fmt.Fprintln(w, "<title>[extra consoles]</title>")

	var consoles = map[string]bool{}
	catlist, err := sql_getconsoles(filterConsole)
	if err != nil { panic(err) }
	for _, c := range catlist {
		consoles[c] = true
	}

	sbl, err := globsql.db_scanbox.Query(
		`SELECT _page, console
			FROM Scanbox;`)
	if err != nil { panic(err) }
	defer sbl.Close()

	var n = map[string]int{}
	var pg = map[string][]string{}

	for sbl.Next() {
		var page string
		var console string

		err = sbl.Scan(&page, &console)
		if err != nil { panic(err) }
		if consoles[console] {		// skip consoles we have
			continue
		}
		n[console]++
		if len(pg[console]) < 5 {
			pg[console] = append(pg[console], `<a href="http://segaretro.org/` + page + `">` + page + `</a>`)
		}
	}

	fmt.Fprintln(w, "
")
	for console := range pg {
		fmt.Fprintf(w, "%20s %s", console, strings.Join(pg[console], ", "))
		if n[console] > 5 {
			fmt.Fprintf(w, ", %d more", n[console] - 5)
		}
		fmt.Fprintln(w)
	}
	fmt.Fprintln(w, "
")
	return nil
}

func listcompare(w http.ResponseWriter, r *http.Request) error {
	fmt.Fprintln(w, "<title>[missing pages]</title>")

	p := func(f string, a ...interface{}){panic(fmt.Sprintf(f,a...))}

	type S struct{}
	var s = S(struct{}{})

	categorylist := map[string]S{}
	clscan := map[string]S{}
	consoles, err := sql_getconsoles(filterConsole)
	if err != nil {
		p("Error getting list of consoles: %v", err)
	}
	for i := range consoles {
		consoles[i] = consoles[i] + " games"
	}
	consoles = append(consoles, "albums")
	for _, category := range consoles {
		games, err := GetGameList(category)
		if err != nil {
			p("error getting %s list: %v", category, err)
		}
		for _, g := range games {
			categorylist[g] = s
			clscan[g] = s
		}
	}

	scanboxlist := map[string]S{}
	sbl, err := globsql.db_scanbox.Query(
		`SELECT _page
			FROM Scanbox
		UNION SELECT _page
			FROM NoScans;`)
	if err != nil {
		p("could not run scanbox list query (for scan list): %v", err)
	}
	defer sbl.Close()

	for sbl.Next() {
		var d string

		err := sbl.Scan(&d)
		if err != nil {
			p("error reading entry in scanbox list query (for scan list): %v", err)
		}
		scanboxlist[d] = s
	}

	for g := range clscan {
		if _, ok := scanboxlist[g]; ok {
			delete(scanboxlist, g)
			delete(categorylist, g)
		}
	}

	fmt.Fprintln(w, `<pre>Only in category list:`)
	for g := range categorylist {
		fmt.Fprintf(w, "%s\n", g, g)
	}
	fmt.Fprintln(w)
	fmt.Fprintln(w, `Only in scanbox db:`)
	for g := range scanboxlist {
		fmt.Fprintln(w, g)
	}
	fmt.Fprintln(w, "
")

	return nil
}

func showAllMissing(w http.ResponseWriter, r *http.Request) error {
	consoles, err := sql_getconsoles(filterConsole)
	if err != nil {
		return fmt.Errorf("Error getting list of consoles: %v", err)
	}
	fmt.Fprintln(w, "<title>[missing pages]</title>")
	for _, s := range consoles {
		ss, err := GetConsoleScans(s)
		fmt.Fprintf(w, "
%s
", s)
		if err != nil {
			fmt.Fprintf(w,  "
Error: %v
\n", err)
			continue
		}
		fmt.Fprintf(w,  "
\n")
		for _, g := range ss {
			if g.HasNoScans {
				fmt.Fprintf(w, `<li><a href="http://segaretro.org/%s">%s</a>`, g.Name, g.Name)
			}
		}
		fmt.Fprintf(w, "
\n")
	}
	return nil
}

func showAllInvalid(w http.ResponseWriter, r *http.Request) error {
	consoles, err := sql_getconsoles(filterConsole)
	if err != nil {
		return fmt.Errorf("Error getting list of consoles: %v", err)
	}
	fmt.Fprintln(w, "<title>[invalid scanboxes]</title>")
	for _, s := range consoles {
		games, err := GetGameList(s)
		if err != nil {
			fmt.Fprintf(w,  "
Error getting game list: %v
\n", err)
			continue
		}
		for _, g := range games {
			scans, err := GetScans(g, s)
			if err == ErrGameNoScans {		// omit games for this console that will not have scans
				continue
			}
			if err != nil {
				fmt.Fprintf(w,  "
Error getting scans for %s: %v
\n", g, err)
				continue
			}
			fmt.Fprintf(w, "
\n")
			for _, v := range scans {
				if v.Console == "" || v.Region == "" {
					fmt.Fprintf(w, `<li><a href="http://segaretro.org/%s">%s</a></li>`, g, g)
					break
				}
			}
			fmt.Fprintf(w, "
\n")
		}
	}
	return nil
}

<commit_msg>Altered the code to show consoles that we don't have covered to remove duplicate URLs in the results.<commit_after>// 1 september 2012
package main

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

// TODO NoScans
func listotherconsoles(w http.ResponseWriter, r *http.Request) error {
	fmt.Fprintln(w, "<title>[extra consoles]</title>")

	var consoles = map[string]bool{}
	catlist, err := sql_getconsoles(filterConsole)
	if err != nil { panic(err) }
	for _, c := range catlist {
		consoles[c] = true
	}

	sbl, err := globsql.db_scanbox.Query(
		`SELECT _page, console
			FROM Scanbox;`)
	if err != nil { panic(err) }
	defer sbl.Close()

	var n = map[string]int{}
	var pg = map[string][]string{}

	for sbl.Next() {
		var page string
		var console string

		err = sbl.Scan(&page, &console)
		if err != nil { panic(err) }
		if consoles[console] {		// skip consoles we have
			continue
		}
		what := `<a href="http://segaretro.org/` + page + `">` + page + `</a>`
		in := false
		for i := 0; i < len(pg[console]); i++ {
			if pg[console][i] == what {
				in = true
			}
		}
		if !in {
			n[console]++
			if len(pg[console]) < 5 {
				pg[console] = append(pg[console], what)
			}
		}
	}

	fmt.Fprintln(w, "
")
	for console := range pg {
		fmt.Fprintf(w, "%20s %s", console, strings.Join(pg[console], ", "))
		if n[console] > 5 {
			fmt.Fprintf(w, ", %d more", n[console] - 5)
		}
		fmt.Fprintln(w)
	}
	fmt.Fprintln(w, "
")
	return nil
}

func listcompare(w http.ResponseWriter, r *http.Request) error {
	fmt.Fprintln(w, "<title>[missing pages]</title>")

	p := func(f string, a ...interface{}){panic(fmt.Sprintf(f,a...))}

	type S struct{}
	var s = S(struct{}{})

	categorylist := map[string]S{}
	clscan := map[string]S{}
	consoles, err := sql_getconsoles(filterConsole)
	if err != nil {
		p("Error getting list of consoles: %v", err)
	}
	for i := range consoles {
		consoles[i] = consoles[i] + " games"
	}
	consoles = append(consoles, "albums")
	for _, category := range consoles {
		games, err := GetGameList(category)
		if err != nil {
			p("error getting %s list: %v", category, err)
		}
		for _, g := range games {
			categorylist[g] = s
			clscan[g] = s
		}
	}

	scanboxlist := map[string]S{}
	sbl, err := globsql.db_scanbox.Query(
		`SELECT _page
			FROM Scanbox
		UNION SELECT _page
			FROM NoScans;`)
	if err != nil {
		p("could not run scanbox list query (for scan list): %v", err)
	}
	defer sbl.Close()

	for sbl.Next() {
		var d string

		err := sbl.Scan(&d)
		if err != nil {
			p("error reading entry in scanbox list query (for scan list): %v", err)
		}
		scanboxlist[d] = s
	}

	for g := range clscan {
		if _, ok := scanboxlist[g]; ok {
			delete(scanboxlist, g)
			delete(categorylist, g)
		}
	}

	fmt.Fprintln(w, `<pre>Only in category list:`)
	for g := range categorylist {
		fmt.Fprintf(w, "%s\n", g, g)
	}
	fmt.Fprintln(w)
	fmt.Fprintln(w, `Only in scanbox db:`)
	for g := range scanboxlist {
		fmt.Fprintln(w, g)
	}
	fmt.Fprintln(w, "
")

	return nil
}

func showAllMissing(w http.ResponseWriter, r *http.Request) error {
	consoles, err := sql_getconsoles(filterConsole)
	if err != nil {
		return fmt.Errorf("Error getting list of consoles: %v", err)
	}
	fmt.Fprintln(w, "<title>[missing pages]</title>")
	for _, s := range consoles {
		ss, err := GetConsoleScans(s)
		fmt.Fprintf(w, "
%s
", s)
		if err != nil {
			fmt.Fprintf(w,  "
Error: %v
\n", err)
			continue
		}
		fmt.Fprintf(w,  "
\n")
		for _, g := range ss {
			if g.HasNoScans {
				fmt.Fprintf(w, `<li><a href="http://segaretro.org/%s">%s</a>`, g.Name, g.Name)
			}
		}
		fmt.Fprintf(w, "
\n")
	}
	return nil
}

func showAllInvalid(w http.ResponseWriter, r *http.Request) error {
	consoles, err := sql_getconsoles(filterConsole)
	if err != nil {
		return fmt.Errorf("Error getting list of consoles: %v", err)
	}
	fmt.Fprintln(w, "<title>[invalid scanboxes]</title>")
	for _, s := range consoles {
		games, err := GetGameList(s)
		if err != nil {
			fmt.Fprintf(w,  "
Error getting game list: %v
\n", err)
			continue
		}
		for _, g := range games {
			scans, err := GetScans(g, s)
			if err == ErrGameNoScans {		// omit games for this console that will not have scans
				continue
			}
			if err != nil {
				fmt.Fprintf(w,  "
Error getting scans for %s: %v
\n", g, err)
				continue
			}
			fmt.Fprintf(w, "
\n")
			for _, v := range scans {
				if v.Console == "" || v.Region == "" {
					fmt.Fprintf(w, `<li><a href="http://segaretro.org/%s">%s</a></li>`, g, g)
					break
				}
			}
			fmt.Fprintf(w, "
\n")
		}
	}
	return nil
}

<|endoftext|>


<commit_before>package skiplist

import (
	"bytes"
)

type byteKeyItem []byte

func (itm *byteKeyItem) String() string {
	return string(*itm)
}

func NewByteKeyItem(k []byte) Item {
	itm := byteKeyItem(k)
	return &itm
}

func (itm *byteKeyItem) Compare(other Item) int {
	var otherItem *byteKeyItem
	var ok bool

	if other == nil {
		return 1
	}

	if otherItem, ok = other.(*byteKeyItem); !ok {
		return 1
	}

	return bytes.Compare([]byte(*itm), []byte(*otherItem))
}

type nilItem struct {
	cmp int
}

func (i *nilItem) Compare(itm Item) int {
	return i.cmp
}
<commit_msg>skiplist: Add int item type<commit_after>package skiplist

import (
	"bytes"
	"fmt"
)

type nilItem struct {
	cmp int
}

func (i *nilItem) Compare(itm Item) int {
	return i.cmp
}

type byteKeyItem []byte

func (itm *byteKeyItem) String() string {
	return string(*itm)
}

func NewByteKeyItem(k []byte) Item {
	itm := byteKeyItem(k)
	return &itm
}

func (itm *byteKeyItem) Compare(other Item) int {
	var otherItem *byteKeyItem
	var ok bool

	if other == nil {
		return 1
	}

	if otherItem, ok = other.(*byteKeyItem); !ok {
		return 1
	}

	return bytes.Compare([]byte(*itm), []byte(*otherItem))
}

type intKeyItem int

func (itm *intKeyItem) String() string {
	return fmt.Sprint(*itm)
}

func (itm *intKeyItem) Compare(other Item) int {
	var otherItem *intKeyItem
	var ok bool

	if other == nil {
		return 1
	}

	if otherItem, ok = other.(*intKeyItem); !ok {
		return 1
	}

	return int(*itm) - int(*otherItem)
}
<|endoftext|>


<commit_before>package xj2go

import (
	"errors"
	"log"
	"os"
	"os/exec"
	"path"
	"strings"
)

func checkFile(filename, pkg string) (string, error) {
	if ok, err := pathExists(pkg); !ok {
		os.Mkdir(pkg, 0755)
		if err != nil {
			return "", err
		}
	}

	filename = path.Base(filename)
	if filename[:1] == "." {
		return "", errors.New("File could not start with '.'")
	}

	filename = pkg + "/" + filename + ".go"
	if ok, _ := pathExists(filename); ok {
		if err := os.Remove(filename); err != nil {
			log.Fatal(err)
			return "", err
		}
	}

	return filename, nil
}

func writeStruct(filename, pkg string, strcts *[]strctMap) error {
	file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatal(err)
		return err
	}

	defer file.Close()

	pkgLines := make(map[string]string)
	strctLines := []string{}
	for _, strct := range *strcts {
		for root, sns := range strct {
			strctLines = append(strctLines, "type "+strings.Title(root)+" struct {\n")
			for i := 0; i < len(sns); i++ {
				if sns[i].Type == "time.Time" {
					pkgLines["time.Time"] = "import \"time\"\n"
				}
				strctLines = append(strctLines, "\t"+strings.Title(sns[i].Name)+"\t"+sns[i].Type+"\t"+sns[i].Tag+"\n")
			}
			strctLines = append(strctLines, "}\n")
		}
	}
	strctLines = append(strctLines, "\n")

	file.WriteString("package " + pkg + "\n\n")
	for _, pl := range pkgLines {
		file.WriteString(pl)
	}
	for _, sl := range strctLines {
		file.WriteString(sl)
	}

	ft := exec.Command("go", "fmt", filename)
	if err := ft.Run(); err != nil {
		log.Fatal(err)
		return err
	}

	vt := exec.Command("go", "vet", filename)
	if err := vt.Run(); err != nil {
		log.Fatal(err)
		return err
	}

	return nil
}
<commit_msg>update file.go<commit_after>package xj2go

import (
	"errors"
	"log"
	"os"
	"os/exec"
	"path"
	"strings"
)

func checkFile(filename, pkg string) (string, error) {
	if ok, err := pathExists(pkg); !ok {
		os.Mkdir(pkg, 0755)
		if err != nil {
			return "", err
		}
	}

	filename = path.Base(filename)
	if filename[:1] == "." {
		return "", errors.New("File could not start with '.'")
	}

	filename = pkg + "/" + filename + ".go"
	if ok, _ := pathExists(filename); ok {
		if err := os.Remove(filename); err != nil {
			log.Fatal(err)
			return "", err
		}
	}

	return filename, nil
}

func writeStruct(filename, pkg string, strcts *[]strctMap) error {
	file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	defer file.Close()
	if err != nil {
		log.Fatal(err)
		return err
	}

	pkgLines := make(map[string]string)
	strctLines := []string{}
	for _, strct := range *strcts {
		for root, sns := range strct {
			strctLines = append(strctLines, "type "+strings.Title(root)+" struct {\n")
			for i := 0; i < len(sns); i++ {
				if sns[i].Type == "time.Time" {
					pkgLines["time.Time"] = "import \"time\"\n"
				}
				strctLines = append(strctLines, "\t"+strings.Title(sns[i].Name)+"\t"+sns[i].Type+"\t"+sns[i].Tag+"\n")
			}
			strctLines = append(strctLines, "}\n")
		}
	}
	strctLines = append(strctLines, "\n")

	file.WriteString("package " + pkg + "\n\n")
	for _, pl := range pkgLines {
		file.WriteString(pl)
	}
	for _, sl := range strctLines {
		file.WriteString(sl)
	}

	ft := exec.Command("go", "fmt", filename)
	if err := ft.Run(); err != nil {
		log.Fatal(err)
		return err
	}

	vt := exec.Command("go", "vet", filename)
	if err := vt.Run(); err != nil {
		log.Fatal(err)
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"log"
	"os"
	"path"
)

// tryReadFile takes a _filename_ as an argument and tries to read that file
// from cwd and then configDir. If it doesn't find the file in any of them it
// will return an empty byte slice.
func tryReadFile(fn string) []byte {
	var dirs []string
	cwd, err := os.Getwd()
	if err == nil {
		dirs = append(dirs, cwd)
	} else {
		log.Println("could not get working directory")
	}
	dirs = append(dirs, configDir)
	for _, dir := range dirs {
		contents, err := ioutil.ReadFile(path.Join(dir, fn))
		if err == nil {
			log.Printf("found %s in %s\n", fn, dir)
			return contents
		}
	}
	log.Println("could not find", fn)
	return []byte{}
}
<commit_msg>split tryReadFile() in two parts<commit_after>package main

import (
	"io/ioutil"
	"log"
	"os"
	"path"
)

// tryFile takes a _filename_ and uses tryFile() to find the file and
// eventually return its contents. If the files was not found or is unreadable
// returns an empty byte slice.
func tryReadFile(fn string) []byte {
	pn := tryFile(fn)
	contents, err := ioutil.ReadFile(pn)
	if err == nil {
		return contents
	}
	return []byte{}
}

// tryFile takes a _filename_ as an argument and tries several directories to
// find this file. In the case of success it returns the full path name,
// otherwise it returns the empty string.
func tryFile(fn string) string {
	var dirs []string
	cwd, err := os.Getwd()
	if err == nil {
		dirs = append(dirs, cwd)
	} else {
		log.Println("could not get working directory")
	}
	dirs = append(dirs, configDir)
	for _, dir := range dirs {
		pn := path.Join(dir, fn)
		f, err := os.Open(pn)
		if err == nil {
			log.Printf("found %s in %s\n", fn, dir)
			f.Close()
			return pn
		}
	}
	log.Println("could not find", fn)
	return ""
}
<|endoftext|>


<commit_before>package configr

import (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"path/filepath"
	"strings"

	"github.com/BurntSushi/toml"
)

type Encoding int

const (
	Unknown Encoding = iota - 1
	JSON
	TOML
)

type FileSource struct {
	filePath string
	encoding Encoding
}

var SupportedFileExtensions = []string{"json", "toml"}
var ErrUnknownEncoding = errors.New("configr: Unable to determine file encoding, please set manually")

var f *FileSource = NewFileSource("")

func NewFileSource(filePath string) *FileSource {
	f := &FileSource{encoding: Unknown}
	f.SetFilePath(filePath)

	return f
}

// SetFilePath sets the file path of the configuration file and try to determine
// the encoding of the file using its extension. See SupportedFileExtensions for
// a list of supported extensions
func SetFilePath(path string) {
	f.SetFilePath(path)
}
func (f *FileSource) SetFilePath(path string) {
	f.filePath = path

	fileExt := getFileExtension(path)
	switch fileExt {
	case SupportedFileExtensions[TOML]:
		f.SetEncoding(TOML)
	case SupportedFileExtensions[JSON]:
		f.SetEncoding(JSON)
	}
}

func FilePath() string {
	return f.FilePath()
}

func (f *FileSource) FilePath() string {
	return f.filePath
}

// SetEncoding allows the caller to override the infered file encoding format
func SetEncoding(encoding Encoding) {
	f.SetEncoding(encoding)
}
func (f *FileSource) SetEncoding(encoding Encoding) {
	f.encoding = encoding
}

func Unmarshal() (map[string]interface{}, error) {
	return f.Unmarshal()
}
func (f *FileSource) Unmarshal() (map[string]interface{}, error) {
	var unmarshaller func([]byte, interface{}) error
	values := make(map[string]interface{})

	switch f.encoding {
	case JSON:
		unmarshaller = json.Unmarshal
	case TOML:
		unmarshaller = toml.Unmarshal
	default:
		return values, ErrUnknownEncoding
	}

	fileBytes, err := ioutil.ReadFile(f.filePath)
	if err != nil {
		return values, err
	}

	err = unmarshaller(fileBytes, &values)
	if err != nil {
		return values, err
	}

	return values, nil
}

func Marshal(v interface{}) ([]byte, error) {
	return f.Marshal(v)
}
func (f *FileSource) Marshal(v interface{}) ([]byte, error) {
	switch f.encoding {
	case JSON:
		return json.MarshalIndent(v, "", "	")
	case TOML:
		var tomlBytes bytes.Buffer
		tomlEncoder := toml.NewEncoder(bufio.NewWriter(&tomlBytes))
		err := tomlEncoder.Encode(v)
		if err != nil {
			return tomlBytes.Bytes(), err
		}

		return tomlBytes.Bytes(), nil
	default:
		return []byte{}, ErrUnknownEncoding
	}
}

func getFileExtension(filePath string) string {
	return strings.ToLower(strings.TrimPrefix(filepath.Ext(filePath), "."))
}
<commit_msg>Renaming f->globalFileSource<commit_after>package configr

import (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"path/filepath"
	"strings"

	"github.com/BurntSushi/toml"
)

type Encoding int

const (
	Unknown Encoding = iota - 1
	JSON
	TOML
)

type FileSource struct {
	filePath string
	encoding Encoding
}

var SupportedFileExtensions = []string{"json", "toml"}
var ErrUnknownEncoding = errors.New("configr: Unable to determine file encoding, please set manually")

var globalFileSource *FileSource = NewFileSource("")

func NewFileSource(filePath string) *FileSource {
	f := &FileSource{encoding: Unknown}
	f.SetFilePath(filePath)

	return f
}

// SetFilePath sets the file path of the configuration file and try to determine
// the encoding of the file using its extension. See SupportedFileExtensions for
// a list of supported extensions
func SetFilePath(path string) {
	globalFileSource.SetFilePath(path)
}
func (f *FileSource) SetFilePath(path string) {
	f.filePath = path

	fileExt := getFileExtension(path)
	switch fileExt {
	case SupportedFileExtensions[TOML]:
		f.SetEncoding(TOML)
	case SupportedFileExtensions[JSON]:
		f.SetEncoding(JSON)
	}
}

func FilePath() string {
	return globalFileSource.FilePath()
}
func (f *FileSource) FilePath() string {
	return f.filePath
}

// SetEncoding allows the caller to override the infered file encoding format
func SetEncoding(encoding Encoding) {
	globalFileSource.SetEncoding(encoding)
}
func (f *FileSource) SetEncoding(encoding Encoding) {
	f.encoding = encoding
}

func Unmarshal() (map[string]interface{}, error) {
	return globalFileSource.Unmarshal()
}
func (f *FileSource) Unmarshal() (map[string]interface{}, error) {
	var unmarshaller func([]byte, interface{}) error
	values := make(map[string]interface{})

	switch f.encoding {
	case JSON:
		unmarshaller = json.Unmarshal
	case TOML:
		unmarshaller = toml.Unmarshal
	default:
		return values, ErrUnknownEncoding
	}

	fileBytes, err := ioutil.ReadFile(f.filePath)
	if err != nil {
		return values, err
	}

	err = unmarshaller(fileBytes, &values)
	if err != nil {
		return values, err
	}

	return values, nil
}

func Marshal(v interface{}) ([]byte, error) {
	return globalFileSource.Marshal(v)
}
func (f *FileSource) Marshal(v interface{}) ([]byte, error) {
	switch f.encoding {
	case JSON:
		return json.MarshalIndent(v, "", "	")
	case TOML:
		var tomlBytes bytes.Buffer
		tomlEncoder := toml.NewEncoder(bufio.NewWriter(&tomlBytes))
		err := tomlEncoder.Encode(v)
		if err != nil {
			return tomlBytes.Bytes(), err
		}

		return tomlBytes.Bytes(), nil
	default:
		return []byte{}, ErrUnknownEncoding
	}
}

func getFileExtension(filePath string) string {
	return strings.ToLower(strings.TrimPrefix(filepath.Ext(filePath), "."))
}
<|endoftext|>


<commit_before>package abide

import (
	"fmt"
	"net/http"
	"net/http/httputil"
	"testing"

	"github.com/sergi/go-diff/diffmatchpatch"
)

// AssertHTTPResponse asserts the value of an http.Response.
func AssertHTTPResponse(t *testing.T, id string, w *http.Response) {
	snapshot := getSnapshot(snapshotID(id))

	body, err := httputil.DumpResponse(w, true)
	if err != nil {
		t.Fatal(err)
	}

	if snapshot == nil {
		fmt.Printf("Creating snapshot `%s`\n", id)
		_, err = createSnapshot(snapshotID(id), string(body))
		if err != nil {
			t.Fatal(err)
		}
		return
	}

	if snapshot != nil && args.shouldUpdate {
		fmt.Printf("Updating snapshot `%s`\n", id)
		_, err = createSnapshot(snapshotID(id), string(body))
		if err != nil {
			t.Fatal(err)
		}
		return
	}

	compareResults(t, string(body), snapshot.value)
}

func compareResults(t *testing.T, new, existing string) {
	dmp := diffmatchpatch.New()
	dmp.PatchMargin = 20
	allDiffs := dmp.DiffMain(new, existing, false)
	nonEqualDiffs := []diffmatchpatch.Diff{}
	for _, diff := range allDiffs {
		if diff.Type != diffmatchpatch.DiffEqual {
			nonEqualDiffs = append(nonEqualDiffs, diff)
		}
	}
	if len(nonEqualDiffs) > 0 {
		msg := "\n\nExisting snapshot does not match results...\n\n"
		msg += dmp.DiffPrettyText(allDiffs)
		msg += "\n\n"
		msg += "If this change was intentional, run tests again, $ go test -v -- -u\n"

		t.Error(msg)
	}
}
<commit_msg>fix assertion order<commit_after>package abide

import (
	"fmt"
	"net/http"
	"net/http/httputil"
	"testing"

	"github.com/sergi/go-diff/diffmatchpatch"
)

// AssertHTTPResponse asserts the value of an http.Response.
func AssertHTTPResponse(t *testing.T, id string, w *http.Response) {
	snapshot := getSnapshot(snapshotID(id))

	body, err := httputil.DumpResponse(w, true)
	if err != nil {
		t.Fatal(err)
	}

	if snapshot == nil {
		fmt.Printf("Creating snapshot `%s`\n", id)
		_, err = createSnapshot(snapshotID(id), string(body))
		if err != nil {
			t.Fatal(err)
		}
		return
	}

	if snapshot != nil && args.shouldUpdate {
		fmt.Printf("Updating snapshot `%s`\n", id)
		_, err = createSnapshot(snapshotID(id), string(body))
		if err != nil {
			t.Fatal(err)
		}
		return
	}

	compareResults(t, snapshot.value, string(body))
}

func compareResults(t *testing.T, existing, new string) {
	dmp := diffmatchpatch.New()
	dmp.PatchMargin = 20
	allDiffs := dmp.DiffMain(existing, new, false)
	nonEqualDiffs := []diffmatchpatch.Diff{}
	for _, diff := range allDiffs {
		if diff.Type != diffmatchpatch.DiffEqual {
			nonEqualDiffs = append(nonEqualDiffs, diff)
		}
	}
	if len(nonEqualDiffs) > 0 {
		msg := "\n\nExisting snapshot does not match results...\n\n"
		msg += dmp.DiffPrettyText(allDiffs)
		msg += "\n\n"
		msg += "If this change was intentional, run tests again, $ go test -v -- -u\n"

		t.Error(msg)
	}
}
<|endoftext|>


<commit_before>package simplecsv

import (
	"strings"
)

// FindInColumn returns a slice with the rownumbers where the "word" is in the  columnPosition
// If the column is not valid it returns an empty slice and a second false value
func (s SimpleCsv) FindInColumn(columnPosition int, word string) ([]int, bool) {
	var validColumn bool
	results := []int{}

	if columnPosition < 0 || columnPosition >= len(s[0]) {
		validColumn = false
		return results, validColumn
	}

	validColumn = true
	numberOfRows := len(s)
	for i := 0; i < numberOfRows; i++ {
		if strings.ToLower(s[i][columnPosition]) == strings.ToLower(word) {
			results = append(results, i)
		}
	}

	return results, validColumn

}

// FindInField returns a slice with the rownumbers where the "word" is in the column name
// If the column is not valid it returns an empty slice and a second false value
func (s SimpleCsv) FindInField(columnName string, word string) ([]int, bool) {

	columnPosition := s.GetHeaderPosition(columnName)

	var validColumn bool
	results := []int{}

	if columnPosition == -1 {
		validColumn = false
		return results, validColumn
	}

	validColumn = true
	numberOfRows := len(s)
	for i := 1; i < numberOfRows; i++ {
		if strings.ToLower(s[i][columnPosition]) == strings.ToLower(word) {
			results = append(results, i)
		}
	}

	return results, validColumn

}
<commit_msg>Code for MatchInColumn<commit_after>package simplecsv

import (
	"regexp"
	"strings"
)

// FindInColumn returns a slice with the rownumbers where the "word" is in the  columnPosition
// If the column is not valid it returns an empty slice and a second false value
func (s SimpleCsv) FindInColumn(columnPosition int, word string) ([]int, bool) {
	var validColumn bool
	results := []int{}

	if columnPosition < 0 || columnPosition >= len(s[0]) {
		validColumn = false
		return results, validColumn
	}

	validColumn = true
	numberOfRows := len(s)
	for i := 0; i < numberOfRows; i++ {
		if strings.ToLower(s[i][columnPosition]) == strings.ToLower(word) {
			results = append(results, i)
		}
	}

	return results, validColumn

}

// FindInField returns a slice with the rownumbers where the "word" is in the column name
// If the column is not valid it returns an empty slice and a second false value
func (s SimpleCsv) FindInField(columnName string, word string) ([]int, bool) {

	columnPosition := s.GetHeaderPosition(columnName)

	var validColumn bool
	results := []int{}

	if columnPosition == -1 {
		validColumn = false
		return results, validColumn
	}

	validColumn = true
	numberOfRows := len(s)
	for i := 1; i < numberOfRows; i++ {
		if strings.ToLower(s[i][columnPosition]) == strings.ToLower(word) {
			results = append(results, i)
		}
	}

	return results, validColumn

}

// MatchInColumn returns a slice with the rownumbers where the regular expression applies in the  columnPosition
// If the column or regular expression are not valid it returns an empty slice and a second false value
func (s SimpleCsv) MatchInColumn(columnPosition int, regularexpression string) ([]int, bool) {
	var ok bool
	results := []int{}

	r, u := regexp.Compile(regularexpression)

	if u != nil {
		ok = false
		return results, ok
	}
	if columnPosition < 0 || columnPosition >= len(s[0]) {
		ok = false
		return results, ok
	}

	ok = true
	numberOfRows := len(s)
	for i := 0; i < numberOfRows; i++ {
		if r.MatchString(s[i][columnPosition]) {
			results = append(results, i)
		}
	}

	return results, ok

}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"io"
	"log"
	"fmt"
	"flag"
	"strings"
	"net/http"
	"os/exec"
	"text/template"
	"html"
	"sync"
	"regexp"
)

type TemplateData struct {
	Name string
	Link string
	Content string
}

const (
	TemplateName = ".tmpl"
	RulesName = ".rules"
)

var siteRoot *string = flag.String("r", ".",
	"Path to serve.")

var siteName *string = flag.String("n", "Asthum Site",
	"Site name.")

var nameFormat *string = flag.String("f", "%s - %s",
	"String used by fmt to get name to give to template." +
	"The first substitution is the page name, second the site name.")

var serverPortNormal *string = flag.String("p", "80",
	"Port to listen on for normal connections. Set to 0 to disable.")

var serverPortTLS *string = flag.String("t", "0",
	"Port to listen on for TLS connections. Set to 0 to disable.")

var certFilePath *string = flag.String("c", "/dev/null",
	"TLS certificate.")

var keyFilePath *string = flag.String("k", "/dev/null",
	"TLS key file.")

var maxBytes *int = flag.Int("m", 2 * 1024 * 1024,
	"Max file size that will be given to templates. Also the chunk size " +
	"that is read in before writing to the stream")

func splitSuffix(s string, pattern string) (string, string) {
	l := strings.LastIndex(s, pattern)
	if l > 0 {
		return s[:l], s[l+1:]
	} else {
		return "", s
	}
}

func findFile(path string, name string) string {
	for {
		path, _ = splitSuffix(path, "/")

		p := "./" + path + "/" + name

		_, err := os.Stat(p)
		if err == nil {
			return p
		}

		if path == "" {
			return ""
		}
	}
}

func readLine(file *os.File, bytes []byte) (int, error) {
	var i int
	b := make([]byte, 1)
	escaped := false

	for i = 0; i < len(bytes); i++ {
		_, err := file.Read(b)
		if err != nil {
			return i, err
		}

		if rune(b[0]) == '\\' {
			escaped = true
		} else if rune(b[0]) == '\n' {
			if escaped {
				escaped = false
				i -= 2
				continue
			} else {
				break
			}
		} else {
			escaped = false
		}

		bytes[i] = b[0]
	}

	return i, nil
}

func parseRule(strings []string) (bool, bool, []string) {
	i := 0
	templated := false

	if strings[i] == "hidden" {
		return true, false, []string{}
	} else if strings[i] == "templated" {
		templated = true
		i++
	}

	return false, templated, strings[i:]
}

func findApplicableRule(file *os.File, name string) ([]string, error) {
	bytes := make([]byte, 256)

	for {
		n, err := readLine(file, bytes)
		if err != nil {
			return []string{}, err
		} else if n < 1 {
			continue
		}

		line := strings.Split(string(bytes[:n]), " ")

		if len(line) == 0 || line[0][0] == '#' {
			continue
		}

		matched, err := regexp.MatchString(line[0], name)

		if matched {
			return line[1:], nil
		}
	}
}

func readRules(path string) (bool, bool, []string) {
	var file *os.File = nil
	hidden, templated := false, false
	interpreter := []string{}

	parts := strings.Split(path, "/")

	spath := "./"

	for _, part := range parts {
		_, err := os.Stat(spath + RulesName)
		if err == nil {
			if file != nil {
				file.Close()
			}

			file, err = os.Open(spath + RulesName)
			if err != nil {
				panic(err)
			}
		}

		if file != nil {
			file.Seek(0, 0)

			rule, _ := findApplicableRule(file, part)
			if len(rule) > 0 {
				hidden, templated, interpreter = parseRule(rule)
				/* If any parent directories are hidden then it will be hidden. */
				if hidden {
					break
				}
			}
		}

		spath += path + "/"
	}

	if file != nil {
		file.Close()
	}

	return hidden, templated, interpreter
}

func runInterpreter(interpreter []string,
		values map[string][]string, file *os.File) ([]byte, error) {
	dir, base := splitSuffix(file.Name(), "/")

	cmd := exec.Command(interpreter[0])
	cmd.Args = append(interpreter, base)
	cmd.Dir = "./" + dir

	l := len(cmd.Env) + len(values) + 1
	env := make([]string, l)
	copy(env, cmd.Env)

	i := len(cmd.Env) + 1
	for name, value := range values {
		env[i] = name + "=" + value[0]
		i++
	}

	cmd.Env = env
	return cmd.Output()
}

func processFile(w http.ResponseWriter, req *http.Request,
		data *TemplateData, file *os.File, fi os.FileInfo) {
	var err error
	var bytes []byte

	hidden, templated, interpreter := readRules(file.Name())

	if hidden {
		log.Print("Hidden file requested:", req.URL.Path)
		w.WriteHeader(http.StatusNotFound)
		io.WriteString(w, "404")
		return
	}

	if len(interpreter) > 0 {
		bytes, err = runInterpreter(interpreter,
				req.URL.Query(), file)
	} else {
		bytes = make([]byte, fi.Size())
		_, err = file.Read(bytes)
	}

	if err != nil {
		log.Print("Error: ", err)
		io.WriteString(w,
			"An error occured. " +
			"Please contact the administrator.")
		return
	}

	if templated {
		processTemplatedData(w, req, data, bytes)
	} else {
		processRawData(w, req, bytes)
	}
}

func processTemplatedData(w http.ResponseWriter, req *http.Request,
		data *TemplateData, bytes []byte) {

	tmplPath := findFile(req.URL.Path[1:], TemplateName)

	if tmplPath == "" {
		log.Print("Error: No template found!!")
		io.WriteString(w,
			"An error occured. " +
			"Please contact the administrator.")
		return
	}

	tmpl, err := template.ParseFiles(tmplPath)
	if err == nil {
		data.Content = string(bytes)
		tmpl.Execute(w, data)
	}
}

func processRawData(w http.ResponseWriter, req *http.Request, bytes []byte) {
	req.ContentLength = int64(len(bytes))
	w.Write(bytes)
}

func findDirIndex(req string) string {
	file, err := os.Open("." + req)
	if err != nil {
		log.Print("Error finding index: ", err)
		return ""
	}
	defer file.Close()

	names, err := file.Readdirnames(0)
	if err != nil {
		log.Print("Error: ", err)
		return ""
	}

	if !strings.HasSuffix(req, "/") {
		req += "/"
	}

	for _, name := range names {
		if strings.HasPrefix(name, "index") {
			return req + name
		}
	}

	return ""
}

func handleDir(w http.ResponseWriter, req *http.Request) {
	index := findDirIndex(req.URL.Path)

	if index == "" {
		log.Print("Error:", req.URL.Path, "has no index")
		w.WriteHeader(http.StatusNotFound)
		io.WriteString(w, "404")
		return
	}

	url := index + req.URL.RawQuery
	log.Print("Redirect to: ", url)
	http.Redirect(w, req, url, http.StatusMovedPermanently)
}

func handler(w http.ResponseWriter, req *http.Request) {
	var file *os.File
	var err error
	var name string

	log.Print(req.RemoteAddr, " requested: ", req.URL.String())

	path := html.EscapeString(req.URL.Path[1:])

	if len(path) == 0 {
		handleDir(w, req)
		return
	}

	file, err = os.Open(path)
	if err != nil {
		log.Print("Error: ", err)
		w.WriteHeader(http.StatusNotFound)
		io.WriteString(w, "404")
		return
	}
	defer file.Close()

	fi, err := file.Stat()
	if err != nil {
		log.Print("Error: ", err)
		return
	}

	if fi.IsDir() {
		handleDir(w, req)
		return
	}

	data := new(TemplateData)
	data.Link = req.URL.String()

	if strings.HasPrefix(fi.Name(), "index") {
		path, _ = splitSuffix(path, "/")
		_, name = splitSuffix(path, "/")
		path += "/"
	} else {
		name, _ = splitSuffix(fi.Name(), ".")
	}

	if path == "/" {
		data.Name = *siteName
	} else {
		data.Name = fmt.Sprintf(*nameFormat, name, *siteName)
	}

	processFile(w, req, data, file, fi)
}

func main() {
	var wg sync.WaitGroup

	flag.Parse()

	err := os.Chdir(*siteRoot)
	if err != nil {
		panic(err)
	}

	http.HandleFunc("/", handler)

	wg.Add(2)

	go func() {
		defer wg.Done()

		if *serverPortNormal == "0" {
			return
		}

		err := http.ListenAndServe(":" + *serverPortNormal, nil)
		if err != nil {
			log.Fatal("ListenAndServe: ", err)
		}
	}()

	go func() {
		defer wg.Done()

		if *serverPortTLS == "0" {
			return
		}

		err := http.ListenAndServeTLS(":" + *serverPortTLS,
			*certFilePath, *keyFilePath, nil)
		if err != nil {
			log.Fatal("ListenAndServeTLS: ", err)
		}
	}()

	wg.Wait()
}
<commit_msg>upload files in chuncks again<commit_after>package main

import (
	"os"
	"io"
	"log"
	"fmt"
	"flag"
	"strings"
	"net/http"
	"os/exec"
	"text/template"
	"html"
	"sync"
	"regexp"
)

type TemplateData struct {
	Name string
	Link string
	Content string
}

const (
	TemplateName = ".tmpl"
	RulesName = ".rules"
)

var siteRoot *string = flag.String("r", ".",
	"Path to serve.")

var siteName *string = flag.String("n", "Asthum Site",
	"Site name.")

var nameFormat *string = flag.String("f", "%s - %s",
	"String used by fmt to get name to give to template." +
	"The first substitution is the page name, second the site name.")

var serverPortNormal *string = flag.String("p", "80",
	"Port to listen on for normal connections. Set to 0 to disable.")

var serverPortTLS *string = flag.String("t", "0",
	"Port to listen on for TLS connections. Set to 0 to disable.")

var certFilePath *string = flag.String("c", "/dev/null",
	"TLS certificate.")

var keyFilePath *string = flag.String("k", "/dev/null",
	"TLS key file.")

var maxBytes *int = flag.Int("m", 1024 * 1024,
	"Max file size that will be given to templates. Also the chunk size " +
	"that is read in before writing to the stream")

func splitSuffix(s string, pattern string) (string, string) {
	l := strings.LastIndex(s, pattern)
	if l > 0 {
		return s[:l], s[l+1:]
	} else {
		return "", s
	}
}

func findFile(path string, name string) string {
	for {
		path, _ = splitSuffix(path, "/")

		p := "./" + path + "/" + name

		_, err := os.Stat(p)
		if err == nil {
			return p
		}

		if path == "" {
			return ""
		}
	}
}

func readLine(file *os.File, bytes []byte) (int, error) {
	var i int
	b := make([]byte, 1)
	escaped := false

	for i = 0; i < len(bytes); i++ {
		_, err := file.Read(b)
		if err != nil {
			return i, err
		}

		if rune(b[0]) == '\\' {
			escaped = true
		} else if rune(b[0]) == '\n' {
			if escaped {
				escaped = false
				i -= 2
				continue
			} else {
				break
			}
		} else {
			escaped = false
		}

		bytes[i] = b[0]
	}

	return i, nil
}

func parseRule(strings []string) (bool, bool, []string) {
	i := 0
	templated := false

	if strings[i] == "hidden" {
		return true, false, []string{}
	} else if strings[i] == "templated" {
		templated = true
		i++
	}

	return false, templated, strings[i:]
}

func findApplicableRule(file *os.File, name string) ([]string, error) {
	bytes := make([]byte, 256)

	for {
		n, err := readLine(file, bytes)
		if err != nil {
			return []string{}, err
		} else if n < 1 {
			continue
		}

		line := strings.Split(string(bytes[:n]), " ")

		if len(line) == 0 || line[0][0] == '#' {
			continue
		}

		matched, err := regexp.MatchString(line[0], name)

		if matched {
			return line[1:], nil
		}
	}
}

func readRules(path string) (bool, bool, []string) {
	var file *os.File = nil
	hidden, templated := false, false
	interpreter := []string{}

	parts := strings.Split(path, "/")

	spath := "./"

	for _, part := range parts {
		_, err := os.Stat(spath + RulesName)
		if err == nil {
			if file != nil {
				file.Close()
			}

			file, err = os.Open(spath + RulesName)
			if err != nil {
				panic(err)
			}
		}

		if file != nil {
			file.Seek(0, 0)

			rule, _ := findApplicableRule(file, part)
			if len(rule) > 0 {
				hidden, templated, interpreter = parseRule(rule)
				/* If any parent directories are hidden then it will be hidden. */
				if hidden {
					break
				}
			}
		}

		spath += path + "/"
	}

	if file != nil {
		file.Close()
	}

	return hidden, templated, interpreter
}

func runInterpreter(interpreter []string,
		values map[string][]string, file *os.File) ([]byte, error) {
	dir, base := splitSuffix(file.Name(), "/")

	cmd := exec.Command(interpreter[0])
	cmd.Args = append(interpreter, base)
	cmd.Dir = "./" + dir

	l := len(cmd.Env) + len(values) + 1
	env := make([]string, l)
	copy(env, cmd.Env)

	i := len(cmd.Env) + 1
	for name, value := range values {
		env[i] = name + "=" + value[0]
		i++
	}

	cmd.Env = env
	return cmd.Output()
}

func processFile(w http.ResponseWriter, req *http.Request,
		data *TemplateData, file *os.File, fi os.FileInfo) {
	var err error
	var bytes []byte
	var n int

	hidden, templated, interpreter := readRules(file.Name())

	if hidden {
		log.Print("Hidden file requested:", req.URL.Path)
		w.WriteHeader(http.StatusNotFound)
		io.WriteString(w, "404")
		return
	}

	if len(interpreter) > 0 {
		bytes, err = runInterpreter(interpreter,
				req.URL.Query(), file)
		n = len(bytes)
	} else {
		bytes = make([]byte, *maxBytes)
		n, err = file.Read(bytes)
	}

	if err != nil {
		log.Print("Error: ", err)
		io.WriteString(w,
			"An error occured. " +
			"Please contact the administrator.")
		return
	}

	if templated {
		processTemplatedData(w, req, data, bytes[:n])
	} else {
		processRawData(w, req, bytes, n, fi.Size(), file)
	}
}

func processTemplatedData(w http.ResponseWriter, req *http.Request,
		data *TemplateData, bytes []byte) {

	tmplPath := findFile(req.URL.Path[1:], TemplateName)

	if tmplPath == "" {
		log.Print("Error: No template found!!")
		io.WriteString(w,
			"An error occured. " +
			"Please contact the administrator.")
		return
	}

	tmpl, err := template.ParseFiles(tmplPath)
	if err == nil {
		data.Content = string(bytes)
		tmpl.Execute(w, data)
	}
}

func processRawData(w http.ResponseWriter, req *http.Request,
		bytes []byte, n int, size int64, file *os.File) {
	var err error
	req.ContentLength = size

	for {
		_, err = w.Write(bytes[:n])
		if err != nil {
			break
		}
		n, err = file.Read(bytes)
		if err != nil {
			break
		}
	}
}

func findDirIndex(req string) string {
	file, err := os.Open("." + req)
	if err != nil {
		log.Print("Error finding index: ", err)
		return ""
	}
	defer file.Close()

	names, err := file.Readdirnames(0)
	if err != nil {
		log.Print("Error: ", err)
		return ""
	}

	if !strings.HasSuffix(req, "/") {
		req += "/"
	}

	for _, name := range names {
		if strings.HasPrefix(name, "index") {
			return req + name
		}
	}

	return ""
}

func handleDir(w http.ResponseWriter, req *http.Request) {
	index := findDirIndex(req.URL.Path)

	if index == "" {
		log.Print("Error:", req.URL.Path, "has no index")
		w.WriteHeader(http.StatusNotFound)
		io.WriteString(w, "404")
		return
	}

	url := index + req.URL.RawQuery
	log.Print("Redirect to: ", url)
	http.Redirect(w, req, url, http.StatusMovedPermanently)
}

func handler(w http.ResponseWriter, req *http.Request) {
	var file *os.File
	var err error
	var name string

	log.Print(req.RemoteAddr, " requested: ", req.URL.String())

	path := html.EscapeString(req.URL.Path[1:])

	if len(path) == 0 {
		handleDir(w, req)
		return
	}

	file, err = os.Open(path)
	if err != nil {
		log.Print("Error: ", err)
		w.WriteHeader(http.StatusNotFound)
		io.WriteString(w, "404")
		return
	}
	defer file.Close()

	fi, err := file.Stat()
	if err != nil {
		log.Print("Error: ", err)
		return
	}

	if fi.IsDir() {
		handleDir(w, req)
		return
	}

	data := new(TemplateData)
	data.Link = req.URL.String()

	if strings.HasPrefix(fi.Name(), "index") {
		path, _ = splitSuffix(path, "/")
		_, name = splitSuffix(path, "/")
		path += "/"
	} else {
		name, _ = splitSuffix(fi.Name(), ".")
	}

	if path == "/" {
		data.Name = *siteName
	} else {
		data.Name = fmt.Sprintf(*nameFormat, name, *siteName)
	}

	processFile(w, req, data, file, fi)
}

func main() {
	var wg sync.WaitGroup

	flag.Parse()

	err := os.Chdir(*siteRoot)
	if err != nil {
		panic(err)
	}

	http.HandleFunc("/", handler)

	wg.Add(2)

	go func() {
		defer wg.Done()

		if *serverPortNormal == "0" {
			return
		}

		err := http.ListenAndServe(":" + *serverPortNormal, nil)
		if err != nil {
			log.Fatal("ListenAndServe: ", err)
		}
	}()

	go func() {
		defer wg.Done()

		if *serverPortTLS == "0" {
			return
		}

		err := http.ListenAndServeTLS(":" + *serverPortTLS,
			*certFilePath, *keyFilePath, nil)
		if err != nil {
			log.Fatal("ListenAndServeTLS: ", err)
		}
	}()

	wg.Wait()
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 - Max Ekman <max@looplab.se>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package domain

import (
	eh "github.com/looplab/eventhorizon"
)

func init() {
	eh.RegisterEvent(func() eh.Event { return &InviteCreated{} })
	eh.RegisterEvent(func() eh.Event { return &InviteAccepted{} })
	eh.RegisterEvent(func() eh.Event { return &InviteDeclined{} })
}

const (
	InviteCreatedEvent eh.EventType = "InviteCreated"

	InviteAcceptedEvent eh.EventType = "InviteAccepted"
	InviteDeclinedEvent eh.EventType = "InviteDeclined"

	InviteConfirmedEvent eh.EventType = "InviteConfirmed"
	InviteDeniedEvent    eh.EventType = "InviteDenied"
)

// InviteCreated is an event for when an invite has been created.
type InviteCreated struct {
	InvitationID eh.UUID `bson:"invitation_id"`
	Name         string  `bson:"name"`
	Age          int     `bson:"age"`
}

func (c InviteCreated) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteCreated) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteCreated) EventType() eh.EventType         { return InviteCreatedEvent }

// InviteAccepted is an event for when an invite has been accepted.
type InviteAccepted struct {
	InvitationID eh.UUID `bson:"invitation_id"`
}

func (c InviteAccepted) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteAccepted) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteAccepted) EventType() eh.EventType         { return InviteAcceptedEvent }

// InviteDeclined is an event for when an invite has been declined.
type InviteDeclined struct {
	InvitationID eh.UUID `bson:"invitation_id"`
}

func (c InviteDeclined) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteDeclined) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteDeclined) EventType() eh.EventType         { return InviteDeclinedEvent }

// InviteConfirmed is an event for when an invite has been confirmed as booked.
type InviteConfirmed struct {
	InvitationID eh.UUID `bson:"invitation_id"`
}

func (c InviteConfirmed) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteConfirmed) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteConfirmed) EventType() eh.EventType         { return InviteConfirmedEvent }

// InviteDenied is an event for when an invite has been denied to book.
type InviteDenied struct {
	InvitationID eh.UUID `bson:"invitation_id"`
}

func (c InviteDenied) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteDenied) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteDenied) EventType() eh.EventType         { return InviteDeniedEvent }
<commit_msg>Fix bug where not all events in the example where reigstered<commit_after>// Copyright (c) 2014 - Max Ekman <max@looplab.se>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package domain

import (
	eh "github.com/looplab/eventhorizon"
)

func init() {
	eh.RegisterEvent(func() eh.Event { return &InviteCreated{} })
	eh.RegisterEvent(func() eh.Event { return &InviteAccepted{} })
	eh.RegisterEvent(func() eh.Event { return &InviteDeclined{} })
	eh.RegisterEvent(func() eh.Event { return &InviteConfirmedEvent{} })
	eh.RegisterEvent(func() eh.Event { return &InviteDeniedEvent{} })
}

const (
	InviteCreatedEvent eh.EventType = "InviteCreated"

	InviteAcceptedEvent eh.EventType = "InviteAccepted"
	InviteDeclinedEvent eh.EventType = "InviteDeclined"

	InviteConfirmedEvent eh.EventType = "InviteConfirmed"
	InviteDeniedEvent    eh.EventType = "InviteDenied"
)

// InviteCreated is an event for when an invite has been created.
type InviteCreated struct {
	InvitationID eh.UUID `bson:"invitation_id"`
	Name         string  `bson:"name"`
	Age          int     `bson:"age"`
}

func (c InviteCreated) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteCreated) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteCreated) EventType() eh.EventType         { return InviteCreatedEvent }

// InviteAccepted is an event for when an invite has been accepted.
type InviteAccepted struct {
	InvitationID eh.UUID `bson:"invitation_id"`
}

func (c InviteAccepted) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteAccepted) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteAccepted) EventType() eh.EventType         { return InviteAcceptedEvent }

// InviteDeclined is an event for when an invite has been declined.
type InviteDeclined struct {
	InvitationID eh.UUID `bson:"invitation_id"`
}

func (c InviteDeclined) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteDeclined) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteDeclined) EventType() eh.EventType         { return InviteDeclinedEvent }

// InviteConfirmed is an event for when an invite has been confirmed as booked.
type InviteConfirmed struct {
	InvitationID eh.UUID `bson:"invitation_id"`
}

func (c InviteConfirmed) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteConfirmed) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteConfirmed) EventType() eh.EventType         { return InviteConfirmedEvent }

// InviteDenied is an event for when an invite has been denied to book.
type InviteDenied struct {
	InvitationID eh.UUID `bson:"invitation_id"`
}

func (c InviteDenied) AggregateID() eh.UUID            { return c.InvitationID }
func (c InviteDenied) AggregateType() eh.AggregateType { return InvitationAggregateType }
func (c InviteDenied) EventType() eh.EventType         { return InviteDeniedEvent }
<|endoftext|>