<commit_before>// A gozmq server that responds to requests in a specified manner,
// allowing you to mock ZMQ servers.

package main

import (
	"flag"
	zmq "github.com/alecthomas/gozmq"
	poller "github.com/tchap/gozmq-poller"
	"log"
	"os"
	"os/signal"
	"time"
)

func main() {
	var (
		socketUrl string
		replyText string
		verbose   bool
		delay     int
		nreplies  int
	)

	flag.StringVar(&socketUrl, "socket", "", "the mock server socket: ipc:///tmp/foo.sock, tcp://1.2.3.4:9999, etc")
	flag.StringVar(&replyText, "reply", "", "the text to return whenever any request is made")
	flag.BoolVar(&verbose, "verbose", false, "set true to log all input")
	flag.IntVar(&delay, "delay", 0, "the number of milliseconds to sleep before replying to requests")
	flag.IntVar(&nreplies, "n", 0, "the number of replies to return (default: 0 = unlimited)")
	flag.Parse()

	if socketUrl == "" {
		log.Println("main", "you must specify a socket")
		flag.PrintDefaults()
		os.Exit(1)
	}

	if replyText == "" {
		log.Println("main", "you must specify reply text")
		flag.PrintDefaults()
		os.Exit(1)
	}

	if nreplies < 0 {
		nreplies = 0
	}

	// OK, we're all set. Get ready to start the server and to wait for
	// a signal to end it.

	done := make(chan bool, 1)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		<-c
		log.Println("main", "caught signal, going down")
		done <- true
		<-done
		os.Exit(0)
	}()

	err := startServerRep(socketUrl, replyText, verbose, delay, done, nreplies)
	if err != nil {
		log.Fatalln("startServer", err.Error())
		os.Exit(1)
	}
	<-done
}

type zmqMessage struct {
	Payload []byte
}

func startServerRep(socketUrl string, replyText string, verbose bool, delay int, done chan bool, nreplies int) (err error) {
	zmqContext, err := zmq.NewContext()
	if err != nil {
		return
	}

	zmqSocket, err := zmqContext.NewSocket(zmq.REP)
	if err != nil {
		return
	}

	err = zmqSocket.Bind(socketUrl)
	if err != nil {
		return
	}

	pf := poller.NewFactory(zmqContext)

	zmqPoller, err := pf.NewPoller(zmq.PollItems{
		0: zmq.PollItem{Socket: zmqSocket, Events: zmq.POLLIN},
	})
	if err != nil {
		return
	}

	n := 0

	go func() {
		input := make(chan zmqMessage, 1)
		output := make(chan zmqMessage, 1)
		pollCh := zmqPoller.Poll()

		doneFunc := func() {
			zmqPoller.Close()
			zmqSocket.Close()
			zmqContext.Close()
			done <- true
		}

		for {
			select {
			case <-done:
				doneFunc()
				break

			case <-pollCh:
				msg, _ := zmqSocket.Recv(0)

				input <- zmqMessage{Payload: msg}
				// Reset the poller so it can accept more requests
				pollCh = zmqPoller.Poll()

			case inputMessage := <-input:
				if verbose {
					log.Println("input", string(inputMessage.Payload))
				}

				// Read the request from the caller, reply to the request
				// as expected.

				output <- zmqMessage{Payload: []byte(replyText)}

			case outputMessage := <-output:
				time.Sleep(time.Duration(delay) * time.Millisecond)
				err := zmqSocket.Send(outputMessage.Payload, 0)
				if err != nil {
					log.Println("zmqSocket.Send", err.Error())
				}

				n++
				if nreplies > 0 && n >= nreplies {
					doneFunc()
					break
				}
			}
		}
	}()

	return
}
<commit_msg>Implement REQ server. Reduce complexity of simple REP server, fixing blocking issue.<commit_after>// A gozmq server that either responds to requests (REP) with static
// data or makes repeated requests (REQ) with static data to a
// specified ZMQ server.

package main

import (
	"flag"
	zmq "github.com/alecthomas/gozmq"
	poller "github.com/tchap/gozmq-poller"
	"log"
	"os"
	"os/signal"
	"time"
)

func main() {
	var (
		socketUrl  string
		socketType string
		replyText  string
		verbose    bool
		delay      int
		nreplies   int
	)

	flag.StringVar(&socketUrl, "socket", "", "the mock server socket: ipc:///tmp/foo.sock, tcp://1.2.3.4:9999, etc")
	flag.StringVar(&socketType, "type", "REP", "the type of socket (currently supported: REP (default), REQ)")
	flag.StringVar(&replyText, "reply", "", "the text to return whenever any request is made")
	flag.BoolVar(&verbose, "verbose", false, "set true to log all input (REP) or output (REQ)")
	flag.IntVar(&delay, "delay", 0, "the number of milliseconds to sleep between messages")
	flag.IntVar(&nreplies, "n", 0, "the number of replies or requests to send (default: 0 = unlimited)")
	flag.Parse()

	if socketUrl == "" {
		log.Println("main", "you must specify a socket")
		flag.PrintDefaults()
		os.Exit(1)
	}

	if replyText == "" {
		log.Println("main", "you must specify reply text")
		flag.PrintDefaults()
		os.Exit(1)
	}

	if nreplies < 0 {
		nreplies = 0
	}

	// OK, we're all set. Get ready to start the server and to wait for
	// a signal to end it.

	done := make(chan bool, 1)
	finishedClosing := make(chan bool, 1)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		<-c
		log.Println("main", "caught signal, going down")
		done <- true
		<-done
		os.Exit(0)
	}()

	var err error
	switch socketType {
	case "REP":
		err = startServerRep(socketUrl, replyText, verbose, delay, done, finishedClosing, nreplies)
	case "REQ":
		err = startServerReq(socketUrl, replyText, verbose, delay, done, finishedClosing, nreplies)
	default:
		log.Println("main", "only supports REP and REQ")
		flag.PrintDefaults()
		os.Exit(1)
	}

	if err != nil {
		log.Fatalln("startServer", err.Error())
		os.Exit(1)
	}
	<-finishedClosing
}

type zmqMessage struct {
	Payload []byte
}

// Start a simple "request" sender. This just sends the same request
// payload repeatedly to a server at the specified socketUrl until
// a value is passed to the done channel or the number of requests
// exceeds nrequests. (nrequests = 0 means unlimited requests).
func startServerReq(socketUrl string, payload string, verbose bool, delay int, done chan bool, finishedClosing chan bool, nrequests int) (err error) {
	zmqContext, err := zmq.NewContext()
	if err != nil {
		return
	}

	zmqSocket, err := zmqContext.NewSocket(zmq.REQ)
	if err != nil {
		return
	}

	err = zmqSocket.Connect(socketUrl)
	if err != nil {
		return
	}

	go func() {
		ticker := time.Tick(time.Duration(delay) * time.Millisecond)

		n := 0

		for {
			select {
			case <-done:
				zmqSocket.Close()
				zmqContext.Close()
				finishedClosing <- true
				return

			case <-ticker:
				err := zmqSocket.Send([]byte(payload), 0)
				if err != nil {
					log.Println("zmqSocket.Send", err.Error())
					done <- true
					break
				}

				if verbose {
					log.Println("> request", string(payload))
				}

				reply, err := zmqSocket.Recv(0)
				if err != nil {
					log.Println("zmqSocket.Recv", err.Error())
					done <- true
					break
				}

				if verbose {
					log.Println("< reply", string(reply))
				}

				n++
				if nrequests > 0 && n >= nrequests {
					done <- true
					ticker = nil
				}
			}
		}
	}()

	return
}

// Start a simple "reply" server. This responds to every incoming
// request at the specified socket with the reply payload until
// a value is passed to the done channel or there have been at least
// nreplies sent.
func startServerRep(socketUrl string, replyText string, verbose bool, delay int, done chan bool, finishedClosing chan bool, nreplies int) (err error) {
	zmqContext, err := zmq.NewContext()
	if err != nil {
		return
	}

	zmqSocket, err := zmqContext.NewSocket(zmq.REP)
	if err != nil {
		return
	}

	err = zmqSocket.Bind(socketUrl)
	if err != nil {
		return
	}

	pf := poller.NewFactory(zmqContext)

	zmqPoller, err := pf.NewPoller(zmq.PollItems{
		0: zmq.PollItem{Socket: zmqSocket, Events: zmq.POLLIN},
	})
	if err != nil {
		return
	}

	n := 0

	go func() {
		pollCh := zmqPoller.Poll()

		for {
			select {
			case <-done:
				zmqPoller.Close()
				zmqSocket.Close()
				zmqContext.Close()
				finishedClosing <- true
				return

			case <-pollCh:
				inputPayload, err := zmqSocket.Recv(0)
				if err != nil {
					log.Println("zmqSocket.Recv", err.Error())
					done <- true
					break
				}

				if verbose {
					log.Println("< request", string(inputPayload))
				}

				time.Sleep(time.Duration(delay) * time.Millisecond)
				zmqSocket.Send([]byte(replyText), 0)

				if verbose {
					log.Println("> reply", string(replyText))
				}

				n++
				if nreplies > 0 && n >= nreplies {
					done <- true
				}

				pollCh = zmqPoller.Poll()
			}
		}
	}()

	return
}
<|endoftext|>


<commit_before>package main

import (
	glfw    "github.com/go-gl/glfw3"
	gl      "github.com/polyfloyd/gl"
	irix    "polyfloyd/irix"
	input   "polyfloyd/irix/input"
	matreex "polyfloyd/irix/math/matreex"
	mesh    "polyfloyd/irix/res/mesh"
	shader  "polyfloyd/irix/res/shader"
	util    "polyfloyd/irix/util"
)

const (
	CUBE_WIDTH  = 16
	CUBE_LENGTH = 16
	CUBE_HEIGHT = 16

	BACKGROUND   = 0.12
	LED_DISTANCE = 8

	ZOOM_ACCELERATION = 8
	FOVY              = 45.0
)

const (
	CUBE_TOTAL_VOXELS = CUBE_WIDTH * CUBE_LENGTH * CUBE_HEIGHT
)

var (
	cam       = NewCubeCamera()
	sphere    *mesh.Mesh
	ledShader *shader.Program

	projection    = matreex.NewElement()
	center        = matreex.NewElement()
	ledTransforms = make([]matreex.Element, CUBE_TOTAL_VOXELS)

	frontBuffer = make([]float32, CUBE_TOTAL_VOXELS * 3)

	matrixUniformLocation gl.UniformLocation
	colorUniformLocation  gl.UniformLocation
)

func main() {
	irix.MustGLExt("GL_ARB_vertex_buffer_object")

	irix.FrameCap = 60
	irix.ShowFPS = true

	input.OnKeyPress(glfw.KeyF4, func(_ glfw.ModifierKey) {
		irix.Wireframe = !irix.Wireframe
	})

	input.OnMouseScroll(func(dx, dy float64) {
		cam.Zoom += float32(dy) * ZOOM_ACCELERATION
	})
	input.OnMouseDrag(glfw.MouseButtonLeft, func(x, y float64) {
		cam.RotX += float32(x / 10)
		cam.RotY += float32(y / 10)
	})

	colors := [][]float32{
		{ 0, 0, 1 },
		{ 0, 1, 0 },
		{ 0, 1, 1 },
		{ 1, 0, 0 },
		{ 1, 0, 1 },
	}
	for i := 0; i < CUBE_TOTAL_VOXELS*3; i += 3 {
		c := colors[(i/3) % len(colors)]
		frontBuffer[i+0] = c[0]
		frontBuffer[i+1] = c[1]
		frontBuffer[i+2] = c[2]
	}

	camMat := cam.MatElement()
	center.Translate(
		-(1 + LED_DISTANCE*CUBE_WIDTH /2),
		-(1 + LED_DISTANCE*CUBE_LENGTH/2),
		-(1 + LED_DISTANCE*CUBE_HEIGHT/2),
		nil,
	);
	camMat.AddChild(center)
	for x := 0; x < CUBE_WIDTH; x++ {
		for y := 0; y < CUBE_LENGTH; y++ {
			for z := 0; z < CUBE_HEIGHT; z++ {
				mat := &ledTransforms[x*CUBE_LENGTH*CUBE_HEIGHT + y*CUBE_HEIGHT + z]
				mat.LoadIdentity()
				mat.Translate(
					float32(x * LED_DISTANCE),
					float32(y * LED_DISTANCE),
					float32(z * LED_DISTANCE),
					nil,
				)
				center.AddChild(mat)
			}
		}
	}
	projection.AddChild(camMat)

	util.RunGLAsync(InitGL)
	util.Check(irix.OpenWindow(1280, 768, false))
	irix.WindowTitle("A Simulator For LED Cubes")
	irix.Main(Cycle)
}

func InitGL() {
	gl.ClearColor(BACKGROUND, BACKGROUND, BACKGROUND, 1.0)

	sphereBuilder := mesh.GenIcosahedron(2)
	sphere, _ = sphereBuilder.Build(nil)
	sphere.Load()

	vert, err := shader.CreateVertexObject(`
		#version 330 core

		{{.vert_position  }}
		{{.vert_normal    }}
		{{.vert_tex2      }}
		{{.vert_color     }}
		uniform mat4 mat_modviewproj;

		out vec3 frag_normal;
		out vec2 frag_tex2;
		out vec3 frag_color;

		void main() {
			frag_normal = vert_normal;
			frag_tex2   = vert_tex2;
			frag_color  = vert_color;
			gl_Position = mat_modviewproj * vec4(vert_position, 1.0);
		}
	`)
	util.Check(err)
	util.Check(vert.Load())
	frag, err := shader.CreateFragmentObject(`
		#version 330 core

		in vec3 frag_normal;
		in vec2 frag_tex2;
		in vec3 frag_color;
		uniform vec3 color_led;

		out vec3 color;

		vec3 LIGHT_VEC   = normalize(vec3(1, 1, 1));
		vec3 LIGHT_COLOR = vec3(0.5, 0.5, 0.5);

		void main() {
			float cosTheta = clamp(dot(frag_normal, LIGHT_VEC), 0, 1);
			color = color_led + LIGHT_COLOR * cosTheta;
		}
	`)
	util.Check(err)
	util.Check(frag.Load())
	ledShader, err = shader.Link(true, vert, frag)
	util.Check(err)

	matrixUniformLocation = ledShader.UniLoc("mat_modviewproj")
	colorUniformLocation  = ledShader.UniLoc("color_led")

	ledShader.Enable()
}

func Cycle(delta float32) {
	projection.LoadProjection(
		cam.GetFovy(),
		irix.WindowAspect(),
		cam.GetZNear(),
		cam.GetZFar(),
	)
	projection.Update()
	cam.UpdateLogic(delta)

	c := 0
	for _, mat := range ledTransforms {
		matrixUniformLocation.UniformMatrix4f(false, (*[16]float32)(&mat.Abs))
		colorUniformLocation.Uniform3f(
			frontBuffer[c],
			frontBuffer[c + 1],
			frontBuffer[c + 2],
		)
		c += 3
		sphere.RenderGL()
	}
}
<commit_msg>Update to new mesh API<commit_after>package main

import (
	glfw    "github.com/go-gl/glfw3"
	gl      "github.com/polyfloyd/gl"
	irix    "polyfloyd/irix"
	input   "polyfloyd/irix/input"
	matreex "polyfloyd/irix/math/matreex"
	mesh    "polyfloyd/irix/res/mesh"
	shader  "polyfloyd/irix/res/shader"
	util    "polyfloyd/irix/util"
)

const (
	CUBE_WIDTH  = 16
	CUBE_LENGTH = 16
	CUBE_HEIGHT = 16

	BACKGROUND   = 0.12
	LED_DISTANCE = 8

	ZOOM_ACCELERATION = 8
	FOVY              = 45.0
)

const (
	CUBE_TOTAL_VOXELS = CUBE_WIDTH * CUBE_LENGTH * CUBE_HEIGHT
)

var (
	cam       = NewCubeCamera()
	sphere    *mesh.Mesh
	ledShader *shader.Program

	projection    = matreex.NewElement()
	center        = matreex.NewElement()
	ledTransforms = make([]matreex.Element, CUBE_TOTAL_VOXELS)

	frontBuffer = make([]float32, CUBE_TOTAL_VOXELS * 3)

	matrixUniformLocation gl.UniformLocation
	colorUniformLocation  gl.UniformLocation
)

func main() {
	irix.MustGLExt("GL_ARB_vertex_buffer_object")

	irix.FrameCap = 60
	irix.ShowFPS = true

	input.OnKeyPress(glfw.KeyF4, func(_ glfw.ModifierKey) {
		irix.Wireframe = !irix.Wireframe
	})

	input.OnMouseScroll(func(dx, dy float64) {
		cam.Zoom += float32(dy) * ZOOM_ACCELERATION
	})
	input.OnMouseDrag(glfw.MouseButtonLeft, func(x, y float64) {
		cam.RotX += float32(x / 10)
		cam.RotY += float32(y / 10)
	})

	colors := [][]float32{
		{ 0, 0, 1 },
		{ 0, 1, 0 },
		{ 0, 1, 1 },
		{ 1, 0, 0 },
		{ 1, 0, 1 },
	}
	for i := 0; i < CUBE_TOTAL_VOXELS*3; i += 3 {
		c := colors[(i/3) % len(colors)]
		frontBuffer[i+0] = c[0]
		frontBuffer[i+1] = c[1]
		frontBuffer[i+2] = c[2]
	}

	camMat := cam.MatElement()
	center.Translate(
		-(1 + LED_DISTANCE*CUBE_WIDTH /2),
		-(1 + LED_DISTANCE*CUBE_LENGTH/2),
		-(1 + LED_DISTANCE*CUBE_HEIGHT/2),
		nil,
	);
	camMat.AddChild(center)
	for x := 0; x < CUBE_WIDTH; x++ {
		for y := 0; y < CUBE_LENGTH; y++ {
			for z := 0; z < CUBE_HEIGHT; z++ {
				mat := &ledTransforms[x*CUBE_LENGTH*CUBE_HEIGHT + y*CUBE_HEIGHT + z]
				mat.LoadIdentity()
				mat.Translate(
					float32(x * LED_DISTANCE),
					float32(y * LED_DISTANCE),
					float32(z * LED_DISTANCE),
					nil,
				)
				center.AddChild(mat)
			}
		}
	}
	projection.AddChild(camMat)

	util.RunGLAsync(InitGL)
	util.Check(irix.OpenWindow(1280, 768, false))
	irix.WindowTitle("A Simulator For LED Cubes")
	irix.Main(Cycle)
}

func InitGL() {
	gl.ClearColor(BACKGROUND, BACKGROUND, BACKGROUND, 1.0)

	sphereBuilder := mesh.GenIcosahedron(2)
	m, err := mesh.Build(sphereBuilder)
	util.Check(err)
	sphere = m[0]
	sphere.Load()

	vert, err := shader.CreateVertexObject(`
		#version 330 core

		{{.vert_position  }}
		{{.vert_normal    }}
		{{.vert_tex2      }}
		{{.vert_color     }}
		uniform mat4 mat_modviewproj;

		out vec3 frag_normal;
		out vec2 frag_tex2;
		out vec3 frag_color;

		void main() {
			frag_normal = vert_normal;
			frag_tex2   = vert_tex2;
			frag_color  = vert_color;
			gl_Position = mat_modviewproj * vec4(vert_position, 1.0);
		}
	`)
	util.Check(err)
	util.Check(vert.Load())
	frag, err := shader.CreateFragmentObject(`
		#version 330 core

		in vec3 frag_normal;
		in vec2 frag_tex2;
		in vec3 frag_color;
		uniform vec3 color_led;

		out vec3 color;

		vec3 LIGHT_VEC   = normalize(vec3(1, 1, 1));
		vec3 LIGHT_COLOR = vec3(0.5, 0.5, 0.5);

		void main() {
			float cosTheta = clamp(dot(frag_normal, LIGHT_VEC), 0, 1);
			color = color_led + LIGHT_COLOR * cosTheta;
		}
	`)
	util.Check(err)
	util.Check(frag.Load())
	ledShader, err = shader.Link(true, vert, frag)
	util.Check(err)

	matrixUniformLocation = ledShader.UniLoc("mat_modviewproj")
	colorUniformLocation  = ledShader.UniLoc("color_led")

	sphere.Enable()
	ledShader.Enable()
}

func Cycle(delta float32) {
	projection.LoadProjection(
		cam.GetFovy(),
		irix.WindowAspect(),
		cam.GetZNear(),
		cam.GetZFar(),
	)
	projection.Update()
	cam.UpdateLogic(delta)

	c := 0
	for _, mat := range ledTransforms {
		matrixUniformLocation.UniformMatrix4f(false, (*[16]float32)(&mat.Abs))
		colorUniformLocation.Uniform3f(
			frontBuffer[c],
			frontBuffer[c + 1],
			frontBuffer[c + 2],
		)
		c += 3
		sphere.RenderGL()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strings"

	"github.com/boltdb/bolt"
	"github.com/elgs/gojq"
	homedir "github.com/mitchellh/go-homedir"
	kingpin "gopkg.in/alecthomas/kingpin.v2"
)

var (
	verbose = kingpin.Flag("verbose", "Verbose mode").Short('v').Bool()

	dbFile string

	scheme     string
	usedScheme bool

	host     string
	usedHost bool

	port     int
	usedPort bool

	service    string
	path       string
	data       string
	noHeaders  bool
	headers    map[string]string
	filter     string
	parameters map[string]string
)

func init() {
	headers = make(map[string]string)
	parameters = make(map[string]string)

	use.Arg("service", "the service to use").Required().StringVar(&service)

	dir, err := homedir.Dir()
	if err != nil {
		panic(err)
	}
	dbFile = fmt.Sprintf("%s/%s", dir, ".rest.db")

	kingpin.Flag("db", "which config database to use").Default(dbFile).StringVar(&dbFile)
}

func main() {
	command := kingpin.Parse()

	switch command {
	case "init":
		if err := setValues(); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	case "use":
		if err := useService(); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	case "config":
		if err := displayConfig(); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

	case "get", "post", "put", "delete":
		resp, err := makeRequest(command)
		if err != nil {
			fmt.Println("error making request:", err)
			os.Exit(1)
		}

		if *verbose {
			fmt.Println(resp.Status)
		}

		if err := showRequest(resp); err != nil {
			fmt.Println("error displaying result:", err)
			os.Exit(1)
		}
	}
}

func useService() error {
	db, err := bolt.Open(dbFile, 0600, nil)
	if err != nil {
		return err
	}
	defer db.Close()

	err = db.Update(func(tx *bolt.Tx) error {
		serviceBucket := tx.Bucket([]byte("services"))
		if serviceBucket == nil {
			return ErrNoServicesBucket
		}

		if b := serviceBucket.Bucket([]byte(service)); b == nil {
			return ErrNoService{Name: service}
		}

		info, err := tx.CreateBucketIfNotExists([]byte("info"))
		if err != nil {
			return err
		}

		err = info.Put([]byte("current"), []byte(service))
		if err != nil {
			return err
		}

		return nil
	})

	return err
}

func getValues() (*url.URL, error) {
	db, err := bolt.Open(dbFile, 0600, nil)
	if err != nil {
		return nil, err
	}
	defer db.Close()

	u := &url.URL{}
	err = db.View(func(tx *bolt.Tx) error {
		info := tx.Bucket([]byte("info"))
		if info == nil {
			return ErrNoInfoBucket
		}

		current := info.Get([]byte("current"))
		if current == nil {
			return ErrNoServiceSet
		}

		serviceBucket := tx.Bucket([]byte("services"))
		if serviceBucket == nil {
			return ErrNoServicesBucket
		}

		b := serviceBucket.Bucket(current)
		if b == nil {
			return ErrNoService{Name: string(current)}
		}

		if usedScheme {
			u.Scheme = scheme
		} else {
			u.Scheme = string(b.Get([]byte("scheme")))

		}

		hostname := host
		if !usedHost {
			hostname = string(b.Get([]byte("host")))
		}

		if !usedPort {
			p, err := binary.ReadVarint(bytes.NewReader(b.Get([]byte("port"))))
			if err != nil {
				return err
			}
			port = int(p)
		}

		u.Host = fmt.Sprintf("%s:%d", hostname, port)

		bucketMap(b.Bucket([]byte("headers")), &headers)
		bucketMap(b.Bucket([]byte("parameters")), &parameters)

		return nil
	})

	return u, err
}

func makeRequest(reqType string) (*http.Response, error) {
	u, err := getValues()
	if err != nil {
		return nil, err
	}

	params := paramReplacer(parameters)
	u.Path = params.Replace(path)
	data = params.Replace(data)
	if *verbose {
		fmt.Println(u)
	}

	client := &http.Client{}

	req, err := http.NewRequest(strings.ToUpper(reqType), u.String(), strings.NewReader(data))
	if err != nil {
		return nil, err
	}

	if !noHeaders {
		for key, value := range headers {
			req.Header.Set(key, value)
		}
	}

	return client.Do(req)
}

func usedFlag(b *bool) func(*kingpin.ParseContext) error {
	return func(*kingpin.ParseContext) error {
		*b = true
		return nil
	}
}

func showRequest(r *http.Response) error {
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}

	if filter == "" {
		fmt.Println(string(body))
		return nil
	}

	parser, err := gojq.NewStringQuery(string(body))
	if err != nil {
		return err
	}

	result, err := parser.Query(filter)
	if err != nil {
		return err
	}

	out, err := json.Marshal(result)
	if err != nil {
		return err
	}

	fmt.Println(string(out))
	return nil
}

func paramReplacer(parameters map[string]string) *strings.Replacer {
	rep := make([]string, 0, len(parameters))
	for key, value := range parameters {
		rep = append(rep, ":"+key)
		rep = append(rep, value)
	}
	return strings.NewReplacer(rep...)
}
<commit_msg>Have non zero returns for http errors<commit_after>package main

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strings"

	"github.com/boltdb/bolt"
	"github.com/elgs/gojq"
	homedir "github.com/mitchellh/go-homedir"
	kingpin "gopkg.in/alecthomas/kingpin.v2"
)

var (
	verbose = kingpin.Flag("verbose", "Verbose mode").Short('v').Bool()

	dbFile string

	scheme     string
	usedScheme bool

	host     string
	usedHost bool

	port     int
	usedPort bool

	service    string
	path       string
	data       string
	noHeaders  bool
	headers    map[string]string
	filter     string
	parameters map[string]string
)

func init() {
	headers = make(map[string]string)
	parameters = make(map[string]string)

	use.Arg("service", "the service to use").Required().StringVar(&service)

	dir, err := homedir.Dir()
	if err != nil {
		panic(err)
	}
	dbFile = fmt.Sprintf("%s/%s", dir, ".rest.db")

	kingpin.Flag("db", "which config database to use").Default(dbFile).StringVar(&dbFile)
}

func main() {
	command := kingpin.Parse()

	switch command {
	case "init":
		if err := setValues(); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	case "use":
		if err := useService(); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	case "config":
		if err := displayConfig(); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

	case "get", "post", "put", "delete":
		resp, err := makeRequest(command)
		if err != nil {
			fmt.Println("error making request:", err)
			os.Exit(1)
		}

		if *verbose {
			fmt.Println(resp.Status)
		}

		if err := showRequest(resp); err != nil {
			fmt.Println("error displaying result:", err)
			os.Exit(1)
		}

		// exit non zero if not a 200 response
		if resp.StatusCode < 200 || resp.StatusCode > 300 {
			// if the exit value gets too high it gets mangled
			// so only keep the hundreds
			os.Exit(resp.StatusCode / 100)
		}
	}
}

func useService() error {
	db, err := bolt.Open(dbFile, 0600, nil)
	if err != nil {
		return err
	}
	defer db.Close()

	err = db.Update(func(tx *bolt.Tx) error {
		serviceBucket := tx.Bucket([]byte("services"))
		if serviceBucket == nil {
			return ErrNoServicesBucket
		}

		if b := serviceBucket.Bucket([]byte(service)); b == nil {
			return ErrNoService{Name: service}
		}

		info, err := tx.CreateBucketIfNotExists([]byte("info"))
		if err != nil {
			return err
		}

		err = info.Put([]byte("current"), []byte(service))
		if err != nil {
			return err
		}

		return nil
	})

	return err
}

func getValues() (*url.URL, error) {
	db, err := bolt.Open(dbFile, 0600, nil)
	if err != nil {
		return nil, err
	}
	defer db.Close()

	u := &url.URL{}
	err = db.View(func(tx *bolt.Tx) error {
		info := tx.Bucket([]byte("info"))
		if info == nil {
			return ErrNoInfoBucket
		}

		current := info.Get([]byte("current"))
		if current == nil {
			return ErrNoServiceSet
		}

		serviceBucket := tx.Bucket([]byte("services"))
		if serviceBucket == nil {
			return ErrNoServicesBucket
		}

		b := serviceBucket.Bucket(current)
		if b == nil {
			return ErrNoService{Name: string(current)}
		}

		if usedScheme {
			u.Scheme = scheme
		} else {
			u.Scheme = string(b.Get([]byte("scheme")))

		}

		hostname := host
		if !usedHost {
			hostname = string(b.Get([]byte("host")))
		}

		if !usedPort {
			p, err := binary.ReadVarint(bytes.NewReader(b.Get([]byte("port"))))
			if err != nil {
				return err
			}
			port = int(p)
		}

		u.Host = fmt.Sprintf("%s:%d", hostname, port)

		bucketMap(b.Bucket([]byte("headers")), &headers)
		bucketMap(b.Bucket([]byte("parameters")), &parameters)

		return nil
	})

	return u, err
}

func makeRequest(reqType string) (*http.Response, error) {
	u, err := getValues()
	if err != nil {
		return nil, err
	}

	params := paramReplacer(parameters)
	u.Path = params.Replace(path)
	data = params.Replace(data)
	if *verbose {
		fmt.Println(u)
	}

	client := &http.Client{}

	req, err := http.NewRequest(strings.ToUpper(reqType), u.String(), strings.NewReader(data))
	if err != nil {
		return nil, err
	}

	if !noHeaders {
		for key, value := range headers {
			req.Header.Set(key, value)
		}
	}

	return client.Do(req)
}

func usedFlag(b *bool) func(*kingpin.ParseContext) error {
	return func(*kingpin.ParseContext) error {
		*b = true
		return nil
	}
}

func showRequest(r *http.Response) error {
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}

	if filter == "" {
		fmt.Println(string(body))
		return nil
	}

	parser, err := gojq.NewStringQuery(string(body))
	if err != nil {
		return err
	}

	result, err := parser.Query(filter)
	if err != nil {
		return err
	}

	out, err := json.Marshal(result)
	if err != nil {
		return err
	}

	fmt.Println(string(out))
	return nil
}

func paramReplacer(parameters map[string]string) *strings.Replacer {
	rep := make([]string, 0, len(parameters))
	for key, value := range parameters {
		rep = append(rep, ":"+key)
		rep = append(rep, value)
	}
	return strings.NewReplacer(rep...)
}
<|endoftext|>


<commit_before>// gzvis is a tool to assist you visualising the operation of
// the go runtime garbage collector.
//
// usage:
//
//     gcvis program [arguments]...
package main

import (
	"bufio"
	"fmt"
	"html/template"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"github.com/pkg/browser"
)

var subprocessDone = make(chan struct{})
var parserDone = make(chan struct{})

func startSubprocess(w io.Writer) {
	defer close(subprocessDone)
	env := os.Environ()
	env = append(env, "GODEBUG=gctrace=1")
	args := os.Args[1:]
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Env = env
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = w // os.Stderr

	if err := cmd.Run(); err != nil {
		log.Fatal(err)
	}
}

type gctrace struct {
	NumGC       int
	Nproc       int
	t1          int
	t2          int
	t3          int
	t4          int
	Heap0       int // heap size before, in megabytes
	Heap1       int // heap size after, in megabytes
	Obj         int
	NMalloc     int
	NFree       int
	NSpan       int
	NBGSweep    int
	NPauseSweep int
	NHandoff    int
	NHandoffCnt int
	NSteal      int
	NStealCnt   int
	NProcYield  int
	NOsYield    int
	NSleep      int
}

type graphPoints [2]int

var heapuse, scvginuse, scvgidle, scvgsys, scvgreleased, scvgconsumed []graphPoints

func index(w http.ResponseWriter, req *http.Request) {
	visTmpl.Execute(w, struct {
		HeapUse, ScvgInuse, ScvgIdle, ScvgSys, ScvgReleased, ScvgConsumed []graphPoints
		Title                                                             string
	}{
		HeapUse:      heapuse,
		ScvgInuse:    scvginuse,
		ScvgIdle:     scvgidle,
		ScvgSys:      scvgsys,
		ScvgReleased: scvgreleased,
		ScvgConsumed: scvgconsumed,
		Title:        strings.Join(os.Args[1:], " "),
	})

}

var visTmpl = template.Must(template.New("vis").Parse(`

{{ .Title }}

Legend

gc.heapinuse: heap in use after gc
scvg.inuse: heap considered in use by the scavenger
scvg.idle: heap considered unused by the scavenger
scvg.sys: heap requested from the operating system
scvg.released: heap returned to the operating system by the scavenger
scvg.consumed: total heap size (should roughly match process VSS)

`))

var (
	gcre   = regexp.MustCompile(`gc\d+\(\d+\): \d+\+\d+\+\d+\+\d+ us, \d+ -> \d+ MB, \d+ \(\d+-\d+\) objects, \d+\/\d+\/\d+ sweeps, \d+\(\d+\) handoff, \d+\(\d+\) steal, \d+\/\d+\/\d+ yields`)
	scvgre = regexp.MustCompile(`scvg\d+: inuse: \d+, idle: \d+, sys: \d+, released: \d+, consumed: \d+ \(MB\)`)
)

type scvgtrace struct {
	inuse    int
	idle     int
	sys      int
	released int
	consumed int
}

func startParser(r io.Reader, gcc chan *gctrace, scvgc chan *scvgtrace) {

	defer close(parserDone)

	sc := bufio.NewScanner(r)
	for sc.Scan() {
		line := sc.Text()
		// try to parse as a gc trace line
		if gcre.MatchString(line) {
			var gc gctrace
			_, err := fmt.Sscanf(line, "gc%d(%d): %d+%d+%d+%d us, %d -> %d MB, %d (%d-%d) objects, %d/%d/%d sweeps, %d(%d) handoff, %d(%d) steal, %d/%d/%d yields\n",
				&gc.NumGC, &gc.Nproc, &gc.t1, &gc.t2, &gc.t3, &gc.t4, &gc.Heap0, &gc.Heap1, &gc.Obj, &gc.NMalloc, &gc.NFree,
				&gc.NSpan, &gc.NBGSweep, &gc.NPauseSweep, &gc.NHandoff, &gc.NHandoffCnt, &gc.NSteal, &gc.NStealCnt, &gc.NProcYield, &gc.NOsYield, &gc.NSleep)
			if err != nil {
				log.Printf("corrupt gctrace: %v: %s", err, line)
				continue
			}
			gcc <- &gc
			continue
		}
		// try to parse as a scavenger line
		if scvgre.MatchString(line) {
			var scvg scvgtrace
			var n int
			_, err := fmt.Sscanf(line, "scvg%d: inuse: %d, idle: %d, sys: %d, released: %d, consumed: %d (MB)\n",
				&n, &scvg.inuse, &scvg.idle, &scvg.sys, &scvg.released, &scvg.consumed)
			if err != nil {
				log.Printf("corrupt scvgtrace: %v: %s", err, line)
				continue
			}
			scvgc <- &scvg
			continue
		}
		// nope ? oh well, print it out
		fmt.Println(line)
	}
	if err := sc.Err(); err != nil {
		log.Fatal(err)
	}
}

func main() {
	if len(os.Args) < 2 {
		log.Fatalf("usage: %s command <args>...", os.Args[0])
	}
	pr, pw, _ := os.Pipe()
	gc := make(chan *gctrace, 1)
	scvg := make(chan *scvgtrace, 1)

	go startSubprocess(pw)
	go startParser(pr, gc, scvg)

	l, err := net.Listen("tcp4", "127.0.0.1:0")
	if err != nil {
		log.Fatal(err)
	}
	http.HandleFunc("/", index)
	go http.Serve(l, nil)

	addr := l.Addr()
	browser.OpenURL(fmt.Sprintf("http://%s/", addr))

	for {
		select {
		case gc := <-gc:
			ts := int(time.Now().UnixNano() / 1e6)
			heapuse = append(heapuse, graphPoints{ts, gc.Heap1})
		case scvg := <-scvg:
			ts := int(time.Now().UnixNano() / 1e6)
			scvginuse = append(scvginuse, graphPoints{ts, scvg.inuse})
			scvgidle = append(scvgidle, graphPoints{ts, scvg.idle})
			scvgsys = append(scvgsys, graphPoints{ts, scvg.sys})
			scvgreleased = append(scvgreleased, graphPoints{ts, scvg.released})
			scvgconsumed = append(scvgconsumed, graphPoints{ts, scvg.consumed})
		}
	}

	<-parserDone
	<-subprocessDone
}
<commit_msg>cleanups and expose the http url<commit_after>// gzvis is a tool to assist you visualising the operation of
// the go runtime garbage collector.
//
// usage:
//
//     gcvis program [arguments]...
package main

import (
	"bufio"
	"fmt"
	"html/template"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"sync"
	"time"

	"github.com/pkg/browser"
)

func startSubprocess(w io.Writer) {
	env := os.Environ()
	env = append(env, "GODEBUG=gctrace=1")
	args := os.Args[1:]
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Env = env
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = w // os.Stderr

	if err := cmd.Run(); err != nil {
		log.Fatal(err)
	}
}

type gctrace struct {
	NumGC       int
	Nproc       int
	t1          int
	t2          int
	t3          int
	t4          int
	Heap0       int // heap size before, in megabytes
	Heap1       int // heap size after, in megabytes
	Obj         int
	NMalloc     int
	NFree       int
	NSpan       int
	NBGSweep    int
	NPauseSweep int
	NHandoff    int
	NHandoffCnt int
	NSteal      int
	NStealCnt   int
	NProcYield  int
	NOsYield    int
	NSleep      int
}

type scvgtrace struct {
	inuse    int
	idle     int
	sys      int
	released int
	consumed int
}

type graphPoints [2]int

var heapuse, scvginuse, scvgidle, scvgsys, scvgreleased, scvgconsumed []graphPoints

var mu sync.RWMutex

func index(w http.ResponseWriter, req *http.Request) {
	mu.RLock()
	defer mu.RUnlock()
	visTmpl.Execute(w, struct {
		HeapUse, ScvgInuse, ScvgIdle, ScvgSys, ScvgReleased, ScvgConsumed []graphPoints
		Title                                                             string
	}{
		HeapUse:      heapuse,
		ScvgInuse:    scvginuse,
		ScvgIdle:     scvgidle,
		ScvgSys:      scvgsys,
		ScvgReleased: scvgreleased,
		ScvgConsumed: scvgconsumed,
		Title:        strings.Join(os.Args[1:], " "),
	})

}

var visTmpl = template.Must(template.New("vis").Parse(`

<title>gcvis - {{ .Title }}</title>

{{ .Title }}

Legend

gc.heapinuse: heap in use after gc
scvg.inuse: virtual memory considered in use by the scavenger
scvg.idle: virtual memory considered unused by the scavenger
scvg.sys: virtual memory requested from the operating system (should aproximate VSS)
scvg.released: virtual memory returned to the operating system by the scavenger
scvg.consumed: virtual memory in use (should roughly match process RSS)

`))

var (
	gcre   = regexp.MustCompile(`gc\d+\(\d+\): \d+\+\d+\+\d+\+\d+ us, \d+ -> \d+ MB, \d+ \(\d+-\d+\) objects, \d+\/\d+\/\d+ sweeps, \d+\(\d+\) handoff, \d+\(\d+\) steal, \d+\/\d+\/\d+ yields`)
	scvgre = regexp.MustCompile(`scvg\d+: inuse: \d+, idle: \d+, sys: \d+, released: \d+, consumed: \d+ \(MB\)`)
)

func startParser(r io.Reader, gcc chan *gctrace, scvgc chan *scvgtrace) {
	sc := bufio.NewScanner(r)
	for sc.Scan() {
		line := sc.Text()
		// try to parse as a gc trace line
		if gcre.MatchString(line) {
			var gc gctrace
			_, err := fmt.Sscanf(line, "gc%d(%d): %d+%d+%d+%d us, %d -> %d MB, %d (%d-%d) objects, %d/%d/%d sweeps, %d(%d) handoff, %d(%d) steal, %d/%d/%d yields\n",
				&gc.NumGC, &gc.Nproc, &gc.t1, &gc.t2, &gc.t3, &gc.t4, &gc.Heap0, &gc.Heap1, &gc.Obj, &gc.NMalloc, &gc.NFree,
				&gc.NSpan, &gc.NBGSweep, &gc.NPauseSweep, &gc.NHandoff, &gc.NHandoffCnt, &gc.NSteal, &gc.NStealCnt, &gc.NProcYield, &gc.NOsYield, &gc.NSleep)
			if err != nil {
				log.Printf("corrupt gctrace: %v: %s", err, line)
				continue
			}
			gcc <- &gc
			continue
		}
		// try to parse as a scavenger line
		if scvgre.MatchString(line) {
			var scvg scvgtrace
			var n int
			_, err := fmt.Sscanf(line, "scvg%d: inuse: %d, idle: %d, sys: %d, released: %d, consumed: %d (MB)\n",
				&n, &scvg.inuse, &scvg.idle, &scvg.sys, &scvg.released, &scvg.consumed)
			if err != nil {
				log.Printf("corrupt scvgtrace: %v: %s", err, line)
				continue
			}
			scvgc <- &scvg
			continue
		}
		// nope ? oh well, print it out
		fmt.Println(line)
	}
	if err := sc.Err(); err != nil {
		log.Fatal(err)
	}
}

func main() {
	if len(os.Args) < 2 {
		log.Fatalf("usage: %s command <args>...", os.Args[0])
	}
	pr, pw, _ := os.Pipe()
	gc := make(chan *gctrace, 1)
	scvg := make(chan *scvgtrace, 1)

	go startSubprocess(pw)
	go startParser(pr, gc, scvg)

	l, err := net.Listen("tcp4", "127.0.0.1:0")
	if err != nil {
		log.Fatal(err)
	}
	http.HandleFunc("/", index)
	go http.Serve(l, nil)

	url := fmt.Sprintf("http://%s/", l.Addr())
	log.Printf("opening browser window, if this fails, navigate to %s", url)
	browser.OpenURL(url)

	for {
		select {
		case gc := <-gc:
			mu.Lock()
			ts := int(time.Now().UnixNano() / 1e6)
			heapuse = append(heapuse, graphPoints{ts, gc.Heap1})
			mu.Unlock()
		case scvg := <-scvg:
			mu.Lock()
			ts := int(time.Now().UnixNano() / 1e6)
			scvginuse = append(scvginuse, graphPoints{ts, scvg.inuse})
			scvgidle = append(scvgidle, graphPoints{ts, scvg.idle})
			scvgsys = append(scvgsys, graphPoints{ts, scvg.sys})
			scvgreleased = append(scvgreleased, graphPoints{ts, scvg.released})
			scvgconsumed = append(scvgconsumed, graphPoints{ts, scvg.consumed})
			mu.Unlock()
		}
	}
}
<|endoftext|>


<commit_before>// --
// Copyright (c) 2014 Thaniyarasu Kannusamy <thaniyarasu@gmail.com> & Arasu Research , Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ++

package main

import (
	"github.com/arasuresearch/arasu/app"
	"github.com/arasuresearch/arasu/cmd/arasu_without_app"
	"github.com/arasuresearch/arasu/lib"
	"log"
	"reflect"
	"strings"
)

func main() {
	if app.Ok {
		app.Runtime.Build()
		if len(app.Runtime.Args) > 0 && app.Runtime.Args[0] == "serve" {
			mode := lib.ParseFlag([]string{"m", "mode"}, "debug", app.Runtime.Args)
			app.Runtime.Args[0] = mode
		}
		//fmt.Println(app.Runtime.CmdBin, app.Runtime.Args)
		cmdLine := app.Runtime.CmdBin + " " + strings.Join(app.Runtime.Args, " ")
		err := app.Runtime.Cmd(cmdLine).Run()
		if err != nil {
			log.Fatal(err)
		}
	} else {
		args := app.Runtime.Args
		awa := struct {
			ArasuWithoutApp arasu_without_app.ArasuWithoutApp
		}{}
		cmd := reflect.ValueOf(&awa).Elem().Field(0)
		index := 0
		for _, e := range args {
			if c := cmd.FieldByName(strings.Title(e)); c.IsValid() {
				cmd = c
				index++
			} else {
				break
			}
		}
		args = args[index:]
		cmd = reflect.New(cmd.Type())
		cmd.MethodByName("Init").Call(app.Rvs{reflect.ValueOf(args)})
		cmd.MethodByName("Run").Call(app.Rvs{})
	}
}
<commit_msg>App package dependencies have added as void import into main arasu command<commit_after>// --
// Copyright (c) 2014 Thaniyarasu Kannusamy <thaniyarasu@gmail.com> & Arasu Research , Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ++

package main

import (
	_ "bitbucket.org/pkg/inflect"
	_ "git.apache.org/thrift.git/lib/go/thrift"
	"github.com/arasuresearch/arasu/app"
	"github.com/arasuresearch/arasu/cmd/arasu_without_app"
	"github.com/arasuresearch/arasu/lib"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/jinzhu/gorm"

	"log"
	"reflect"
	"strings"
)

func main() {
	if app.Ok {
		app.Runtime.Build()
		if len(app.Runtime.Args) > 0 && app.Runtime.Args[0] == "serve" {
			mode := lib.ParseFlag([]string{"m", "mode"}, "debug", app.Runtime.Args)
			app.Runtime.Args[0] = mode
		}
		//fmt.Println(app.Runtime.CmdBin, app.Runtime.Args)
		cmdLine := app.Runtime.CmdBin + " " + strings.Join(app.Runtime.Args, " ")
		err := app.Runtime.Cmd(cmdLine).Run()
		if err != nil {
			log.Fatal(err)
		}
	} else {
		args := app.Runtime.Args
		awa := struct {
			ArasuWithoutApp arasu_without_app.ArasuWithoutApp
		}{}
		cmd := reflect.ValueOf(&awa).Elem().Field(0)
		index := 0
		for _, e := range args {
			if c := cmd.FieldByName(strings.Title(e)); c.IsValid() {
				cmd = c
				index++
			} else {
				break
			}
		}
		args = args[index:]
		cmd = reflect.New(cmd.Type())
		cmd.MethodByName("Init").Call(app.Rvs{reflect.ValueOf(args)})
		cmd.MethodByName("Run").Call(app.Rvs{})
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"regexp"
)

type Redirect struct {
	URI          string `json:"uri"`
	Android      string `json:"android"`
	IPhone       string `json:"iphone"`
	IPod         string `json:"ipod"`
	IPad         string `json:"ipad"`
	BlackBerry   string `json:"bb"`
	WindowsPhone string `json:"wp"`
	WinXin       string `json:"wx"`
	Unknown      string `json:"unknown"`
}

type Config struct {
	Address   string      `json:"address"`
	Port      uint16      `json:"port"`
	Redirects []*Redirect `json:"redirect"`
}

var (
	config *Config = new(Config)
)

func handler(w http.ResponseWriter, r *http.Request) {
	var redirect *Redirect = nil
	for _, v := range config.Redirects {
		if v.URI == r.RequestURI {
			redirect = v
			break
		}
	}
	if redirect != nil {
		userAgent := r.UserAgent()
		matched := regexp.MustCompile("Android").MatchString(userAgent)
		if matched {
			log.Println(redirect.Android)
			http.Redirect(w, r, redirect.Android, 302)
			return
		}
		matched = regexp.MustCompile("iPod").MatchString(userAgent)
		if matched {
			log.Println(redirect.IPod)
			http.Redirect(w, r, redirect.IPod, 302)
			return
		}
		matched = regexp.MustCompile("iPhone").MatchString(userAgent)
		if matched {
			log.Println(redirect.IPhone)
			http.Redirect(w, r, redirect.IPhone, 302)
			return
		}
		matched = regexp.MustCompile("iPad").MatchString(userAgent)
		if matched {
			log.Println(redirect.IPad)
			http.Redirect(w, r, redirect.IPad, 302)
			return
		}
		matched = regexp.MustCompile("BlackBerry").MatchString(userAgent)
		if matched {
			log.Println(redirect.BlackBerry)
			http.Redirect(w, r, redirect.BlackBerry, 302)
			return
		}
		matched = regexp.MustCompile("IEMobile").MatchString(userAgent)
		if matched {
			log.Println(redirect.WindowsPhone)
			http.Redirect(w, r, redirect.WindowsPhone, 302)
			return
		}
		matched = regexp.MustCompile("MQQBrowser").MatchString(userAgent)
		if matched {
			log.Println(redirect.WinXin)
			http.Redirect(w, r, redirect.WinXin, 302)
			return
		}
		matched = regexp.MustCompile("TBS").MatchString(userAgent)
		if matched {
			log.Println(redirect.WinXin)
			http.Redirect(w, r, redirect.WinXin, 302)
			return
		}
	}
	log.Println(redirect.Unknown)
	http.Redirect(w, r, redirect.Unknown, 302)
}

func main() {
	fh, err := os.Open("config.json")
	if err != nil {
		log.Fatal("opening config.json failed")
		return
	}
	defer fh.Close()
	configcontent, err := ioutil.ReadAll(fh)
	if err != nil {
		log.Fatal("reading config.json failed")
		return
	}

	if err = json.Unmarshal(configcontent, config); err != nil {
		log.Fatal("parsing config.json failed")
		return
	}

	http.HandleFunc("/", handler)
	log.Fatal(
		http.ListenAndServe(
			fmt.Sprintf("%s:%d", config.Address, config.Port),
			nil))
}
<commit_msg>(*)fixed default case<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"regexp"
)

type Redirect struct {
	URI          string `json:"uri"`
	Android      string `json:"android"`
	IPhone       string `json:"iphone"`
	IPod         string `json:"ipod"`
	IPad         string `json:"ipad"`
	BlackBerry   string `json:"bb"`
	WindowsPhone string `json:"wp"`
	WinXin       string `json:"wx"`
	Unknown      string `json:"unknown"`
}

type Config struct {
	Address   string      `json:"address"`
	Port      uint16      `json:"port"`
	Redirects []*Redirect `json:"redirect"`
}

var (
	config *Config = new(Config)
)

func handler(w http.ResponseWriter, r *http.Request) {
	var redirect *Redirect = nil
	for _, v := range config.Redirects {
		if v.URI == r.RequestURI {
			redirect = v
			break
		}
	}
	if redirect != nil {
		userAgent := r.UserAgent()
		matched := regexp.MustCompile("Android").MatchString(userAgent)
		if matched {
			log.Println("android", redirect.Android)
			http.Redirect(w, r, redirect.Android, 302)
			return
		}
		matched = regexp.MustCompile("iPod").MatchString(userAgent)
		if matched {
			log.Println("ipod", redirect.IPod)
			http.Redirect(w, r, redirect.IPod, 302)
			return
		}
		matched = regexp.MustCompile("iPhone").MatchString(userAgent)
		if matched {
			log.Println("iphone", redirect.IPhone)
			http.Redirect(w, r, redirect.IPhone, 302)
			return
		}
		matched = regexp.MustCompile("iPad").MatchString(userAgent)
		if matched {
			log.Println("ipad", redirect.IPad)
			http.Redirect(w, r, redirect.IPad, 302)
			return
		}
		matched = regexp.MustCompile("BlackBerry").MatchString(userAgent)
		if matched {
			log.Println("bb", redirect.BlackBerry)
			http.Redirect(w, r, redirect.BlackBerry, 302)
			return
		}
		matched = regexp.MustCompile("IEMobile").MatchString(userAgent)
		if matched {
			log.Println("wp", redirect.WindowsPhone)
			http.Redirect(w, r, redirect.WindowsPhone, 302)
			return
		}
		matched = regexp.MustCompile("MQQBrowser").MatchString(userAgent)
		if matched {
			log.Println("wx", redirect.WinXin)
			http.Redirect(w, r, redirect.WinXin, 302)
			return
		}
		matched = regexp.MustCompile("TBS").MatchString(userAgent)
		if matched {
			log.Println("wx", redirect.WinXin)
			http.Redirect(w, r, redirect.WinXin, 302)
			return
		}

		log.Println("unknown", redirect.Unknown)
		http.Redirect(w, r, redirect.Unknown, 302)
		return
	}
	log.Println("unmatched", config.Redirects[0].Unknown)
	http.Redirect(w, r, config.Redirects[0].Unknown, 302)
}

func main() {
	fh, err := os.Open("config.json")
	if err != nil {
		log.Fatal("opening config.json failed")
		return
	}
	defer fh.Close()
	configcontent, err := ioutil.ReadAll(fh)
	if err != nil {
		log.Fatal("reading config.json failed")
		return
	}

	if err = json.Unmarshal(configcontent, config); err != nil {
		log.Fatal("parsing config.json failed")
		return
	}

	http.HandleFunc("/", handler)
	log.Fatal(
		http.ListenAndServe(
			fmt.Sprintf("%s:%d", config.Address, config.Port),
			nil))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/shopspring/decimal"
)

func init() {
	flag.Parse()
}

var (
	pt = fmt.Printf
	sp = fmt.Sprintf
)

func main() {
	args := flag.Args()
	if len(args) < 1 {
		pt("usage: %s [file]\n", os.Args[0])
		return
	}

	checkErr := func(msg string, err error) {
		if err != nil {
			log.Fatalf("%s: %v", msg, err)
		}
	}

	type Entry struct {
		Account  string
		Currency string
		Amount   decimal.Decimal
	}
	type Transaction struct {
		When    time.Time
		What    string
		Entries []Entry
	}

	// parse
	location, err := time.LoadLocation("Asia/Hong_Kong")
	checkErr("load location", err)
	transactions := []Transaction{}
	bs, err := ioutil.ReadFile(args[0])
	checkErr("read file", err)
	entries := strings.Split(string(bs), "\n\n")
	for _, bs := range entries {
		lines := strings.Split(bs, "\n")
		if len(lines) == 0 {
			continue
		}
		when, what := spaceSplit(strings.TrimSpace(lines[0]))
		if len(when) == 0 {
			continue
		}
		parts := strings.Split(when, "-")
		year, err := strconv.Atoi(parts[0])
		checkErr("parse year", err)
		if year < 100 {
			year += 2000
		}
		month, err := strconv.Atoi(parts[1])
		checkErr("parse month", err)
		day, err := strconv.Atoi(parts[2])
		checkErr("parse day", err)
		transaction := Transaction{
			When: time.Date(year, time.Month(month), day, 0, 0, 0, 0, location),
			What: what,
		}
		for _, line := range lines[1:] {
			line = strings.TrimSpace(line)
			if len(line) == 0 {
				continue
			}
			account, res := spaceSplit(line)
			entry := Entry{
				Account: account,
			}
			if len(res) == 0 {
				log.Fatalf("invalid entry %s", line)
			}
			runes := []rune(res)
			currency := string(runes[0])
			entry.Currency = currency
			amount, err := decimal.NewFromString(string(runes[1:]))
			checkErr(sp("parse amount %v", string(runes[1:])), err)
			entry.Amount = amount
			transaction.Entries = append(transaction.Entries, entry)
		}
		transactions = append(transactions, transaction)
	}

	// calculate balance
	zero := decimal.New(0, 0)
	for _, transaction := range transactions {
		balance := make(map[string]decimal.Decimal)
		for _, entry := range transaction.Entries {
			balance[entry.Currency].Add(entry.Amount)
		}
		for _, n := range balance {
			if n.Cmp(zero) != 0 {
				log.Fatalf("not balance: %s", transaction.What)
			}
		}
	}

	// account summaries
	accounts := make(map[string]map[string]decimal.Decimal)
	sum := func(name, currency string, n decimal.Decimal) {
		var account map[string]decimal.Decimal
		var ok bool
		if account, ok = accounts[name]; !ok {
			account = make(map[string]decimal.Decimal)
			accounts[name] = account
		}
		var amount decimal.Decimal
		amount = amount.Add(n)
		account[currency] = amount
	}
	for _, transaction := range transactions {
		for _, entry := range transaction.Entries {
			var name []rune
			for _, r := range entry.Account {
				if r == '：' {
					sum(string(name), entry.Currency, entry.Amount)
				}
				name = append(name, r)
			}
			sum(string(name), entry.Currency, entry.Amount)
		}
	}
	names := []string{}
	for name := range accounts {
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		account := accounts[name]
		n := []rune{}
		level := 0
		for _, r := range name {
			if r == '：' {
				n = n[0:0]
				level++
			} else {
				n = append(n, r)
			}
		}
		pt("%s%s", strings.Repeat("\t", level), string(n))
		for currency, amount := range account {
			pt(" %s%s", currency, amount.String())
		}
		pt("\n")
	}

}

var spaceSplitPattern = regexp.MustCompile(`\s+`)

func spaceSplit(s string) (string, string) {
	ss := spaceSplitPattern.Split(s, 2)
	if len(ss) == 1 {
		return ss[0], ""
	}
	return ss[0], ss[1]
}
<commit_msg>Revert "use github.com/shopspring/decimal instead of math/big.Rat"<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"math/big"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
)

func init() {
	flag.Parse()
}

var (
	pt = fmt.Printf
	sp = fmt.Sprintf
)

func main() {
	args := flag.Args()
	if len(args) < 1 {
		pt("usage: %s [file]\n", os.Args[0])
		return
	}

	checkErr := func(msg string, err error) {
		if err != nil {
			log.Fatalf("%s: %v", msg, err)
		}
	}

	type Entry struct {
		Account  string
		Currency string
		Amount   *big.Rat
	}
	type Transaction struct {
		When    time.Time
		What    string
		Entries []Entry
	}

	// parse
	location, err := time.LoadLocation("Asia/Hong_Kong")
	checkErr("load location", err)
	transactions := []Transaction{}
	bs, err := ioutil.ReadFile(args[0])
	checkErr("read file", err)
	entries := strings.Split(string(bs), "\n\n")
	for _, bs := range entries {
		lines := strings.Split(bs, "\n")
		if len(lines) == 0 {
			continue
		}
		when, what := spaceSplit(strings.TrimSpace(lines[0]))
		if len(when) == 0 {
			continue
		}
		parts := strings.Split(when, "-")
		year, err := strconv.Atoi(parts[0])
		checkErr("parse year", err)
		if year < 100 {
			year += 2000
		}
		month, err := strconv.Atoi(parts[1])
		checkErr("parse month", err)
		day, err := strconv.Atoi(parts[2])
		checkErr("parse day", err)
		transaction := Transaction{
			When: time.Date(year, time.Month(month), day, 0, 0, 0, 0, location),
			What: what,
		}
		for _, line := range lines[1:] {
			line = strings.TrimSpace(line)
			if len(line) == 0 {
				continue
			}
			account, res := spaceSplit(line)
			entry := Entry{
				Account: account,
			}
			if len(res) == 0 {
				log.Fatalf("invalid entry %s", line)
			}
			runes := []rune(res)
			currency := string(runes[0])
			entry.Currency = currency
			amount := new(big.Rat)
			_, err := fmt.Sscan(string(runes[1:]), amount)
			checkErr(sp("parse amount %v", string(runes[1:])), err)
			entry.Amount = amount
			transaction.Entries = append(transaction.Entries, entry)
		}
		transactions = append(transactions, transaction)
	}

	// calculate balance
	zero := new(big.Rat)
	for _, transaction := range transactions {
		balance := make(map[string]*big.Rat)
		for _, entry := range transaction.Entries {
			if _, ok := balance[entry.Currency]; !ok {
				balance[entry.Currency] = new(big.Rat)
			}
			balance[entry.Currency].Add(balance[entry.Currency], entry.Amount)
		}
		for _, n := range balance {
			if n.Cmp(zero) != 0 {
				log.Fatalf("not balance: %s", transaction.What)
			}
		}
	}

	// account summaries
	accounts := make(map[string]map[string]*big.Rat)
	sum := func(name, currency string, n *big.Rat) {
		var account map[string]*big.Rat
		var ok bool
		if account, ok = accounts[name]; !ok {
			account = make(map[string]*big.Rat)
			accounts[name] = account
		}
		var amount *big.Rat
		if amount, ok = account[currency]; !ok {
			amount = new(big.Rat)
		}
		amount.Add(amount, n)
		account[currency] = amount
	}
	for _, transaction := range transactions {
		for _, entry := range transaction.Entries {
			var name []rune
			for _, r := range entry.Account {
				if r == '：' {
					sum(string(name), entry.Currency, entry.Amount)
				}
				name = append(name, r)
			}
			sum(string(name), entry.Currency, entry.Amount)
		}
	}
	names := []string{}
	for name := range accounts {
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		account := accounts[name]
		n := []rune{}
		level := 0
		for _, r := range name {
			if r == '：' {
				n = n[0:0]
				level++
			} else {
				n = append(n, r)
			}
		}
		pt("%s%s", strings.Repeat("\t", level), string(n))
		for currency, amount := range account {
			pt(" %s%s", currency, amount.FloatString(2))
		}
		pt("\n")
	}

}

var spaceSplitPattern = regexp.MustCompile(`\s+`)

func spaceSplit(s string) (string, string) {
	ss := spaceSplitPattern.Split(s, 2)
	if len(ss) == 1 {
		return ss[0], ""
	}
	return ss[0], ss[1]
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"syscall"
	"strings"

	"github.com/jaxxstorm/flexvolume"
	"github.com/kolyshkin/goploop-cli"
	"github.com/urfave/cli"
	"github.com/virtuozzo/ploop-flexvol/vstorage"

	"github.com/golang/glog"
)

func setupJournld() ([]string, *exec.Cmd, error) {
	fd, err := syscall.Dup(syscall.Stdout)
	if err != nil {
		return nil, nil, err
	}

	syscall.CloseOnExec(fd)

	flexvolume.SetRespFile(os.NewFile((uintptr)(fd), "RespFile"))

	if err := flag.CommandLine.Parse([]string{"-logtostderr"}); err != nil {
		return nil, nil, err
	}

	cmd := exec.Command("systemd-cat", "--identifier", "ploop-flexvol")
	if err != nil {
		return nil, nil, err
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, nil, fmt.Errorf("Unable to create a pipe: %v", err)
	}
	cmd.Stdin = pr
	defer pr.Close()
	defer pw.Close()

	if err := syscall.Dup2(int(pw.Fd()), syscall.Stdout); err != nil {
		return nil, nil, fmt.Errorf("Unable to redirect stdout: %v", err)
	}
	if err := syscall.Dup2(syscall.Stdout, syscall.Stderr); err != nil {
		return nil, nil, fmt.Errorf("Unable to redirect stderr: %v", err)
	}
	if err := cmd.Start(); err != nil {
		return nil, nil, fmt.Errorf("Unable to start systemd-cat: %v", err)
	}
	return os.Args, cmd, nil
}

func setupWrapperLogging() ([]string, *exec.Cmd, error) {
	syscall.CloseOnExec(3)
	flexvolume.SetRespFile(os.NewFile((uintptr)(3), "RespFile"))
	if err := flag.CommandLine.Parse(os.Args[2:]); err != nil {
		return nil, nil, err
	}
	return flag.CommandLine.Args(), nil, nil
}

func setupLogging() ([]string, *exec.Cmd, error) {
	if os.Args[1] == "wrapper" {
		return setupWrapperLogging()
	}

	return setupJournld()
}

func main() {
	args, cmd, err := setupLogging()
	if err != nil {
		panic(err)
	}
	if cmd != nil {
		defer func() {
			syscall.Close(syscall.Stdout)
			syscall.Close(syscall.Stderr)
			cmd.Wait()
		}()
	}

	app := cli.NewApp()
	app.Name = "ploop flexvolume"
	app.Usage = "Mount ploop volumes in kubernetes using the flexvolume driver"
	app.Commands = flexvolume.Commands(Ploop{})
	app.CommandNotFound = flexvolume.CommandNotFound
	app.Authors = []cli.Author{
		cli.Author{
			Name: "Lee Briggs",
		},
		cli.Author{
			Name: "Virtuozzo",
		},
	}
	app.Version = "0.2a"

	if glog.V(4) {
		glog.Infof("Request: %v", args)
	}
	app.Run(args)
}

type Ploop struct{}

const workingDir = "/var/run/ploop-flexvol/"

func (p Ploop) Init() (*flexvolume.Response, error) {
	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Ploop is available",
	}, nil
}

func (p Ploop) path(options map[string]string) string {
	path := "/"
	if options["volumePath"] != "" {
		path += options["volumePath"] + "/"
	}
	path += options["volumeID"]
	return path
}

func (p Ploop) GetVolumeName(options map[string]string) (*flexvolume.Response, error) {
	if options["volumeID"] == "" {
		return nil, fmt.Errorf("Must specify a volume id")
	}

	return &flexvolume.Response{
		Status:     flexvolume.StatusSuccess,
		VolumeName: options["clusterName"] + "|" + p.path(options),
	}, nil
}

func prepareVstorage(clusterName, clusterPasswd string, mount string) error {
	mounted, _ := vstorage.IsVstorage(mount)
	if mounted {
		return nil
	}

	// not mounted in proper place, prepare mount place and check other
	// mounts
	if err := os.MkdirAll(mount, 0700); err != nil {
		return err
	}

	v := vstorage.Vstorage{clusterName}
	p, _ := v.Mountpoint()
	if p != "" {
		return syscall.Mount(p, mount, "", syscall.MS_BIND, "")
	}

	if clusterPasswd == "" {
		return errors.New("Please provide vstorage credentials")
	}

	if err := v.Auth(clusterPasswd); err != nil {
		return err
	}
	if err := v.Mount(mount); err != nil {
		return err
	}

	return nil
}

func (p Ploop) Mount(target string, options map[string]string) (*flexvolume.Response, error) {
	// make the target directory we're going to mount to
	err := os.MkdirAll(target, 0700)
	if err != nil {
		return nil, err
	}

	path := p.path(options)

	if options["kubernetes.io/secret/clusterName"] != "" {
		_cluster, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterName"])
		if err != nil {
			return nil, fmt.Errorf("Unable to decode a cluster name: %v", err.Error())
		}
		cluster := string(_cluster)

		_passwd, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterPassword"])
		if err != nil {
			return nil, fmt.Errorf("Unable to decode a cluster password: %v", err.Error())
		}
		passwd := string(_passwd)

		mount := workingDir + cluster
		if err := prepareVstorage(cluster, passwd, mount); err != nil {
			return nil, err
		}
		path = mount + path
	}
	// open the disk descriptor first
	volume, err := ploop.Open(path + "/" + "DiskDescriptor.xml")
	if err != nil {
		return nil, err
	}
	defer volume.Close()

	if m, _ := volume.IsMounted(); !m {
		// If it's mounted, let's mount it!

		readonly := false
		if options["kubernetes.io/readwrite"] == "ro" {
			readonly = true
		}

		mp := ploop.MountParam{Target: target, Readonly: readonly}

		_, err := volume.Mount(&mp)
		if err != nil {
			return nil, err
		}

		return &flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Successfully mounted the ploop volume",
		}, nil
	} else {

		return &flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Ploop volume already mounted",
		}, nil

	}
}

func (p Ploop) Unmount(mount string) (*flexvolume.Response, error) {
	if err := ploop.UmountByMount(mount); err != nil {
		return nil, err
	}

	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully unmounted the ploop volume",
	}, nil
}

func (p Ploop) Attach(nodename string, options map[string]string) (*flexvolume.Response, error) {
	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully attached the ploop volume",
	}, nil
}

func (p Ploop) Detach(device string, nodename string) (*flexvolume.Response, error) {
	token := strings.Split(device, "|")
	v := vstorage.Vstorage{token[0]}
	if err := v.Revoke(token[1]); err != nil {
		return nil, err
	}

	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully detached the ploop volume",
	}, nil
}
<commit_msg>Move vstorage revoke from detach to mount operation<commit_after>package main

import (
	"encoding/base64"
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"syscall"

	"github.com/jaxxstorm/flexvolume"
	"github.com/kolyshkin/goploop-cli"
	"github.com/urfave/cli"
	"github.com/virtuozzo/ploop-flexvol/vstorage"

	"github.com/golang/glog"
)

func setupJournld() ([]string, *exec.Cmd, error) {
	fd, err := syscall.Dup(syscall.Stdout)
	if err != nil {
		return nil, nil, err
	}

	syscall.CloseOnExec(fd)

	flexvolume.SetRespFile(os.NewFile((uintptr)(fd), "RespFile"))

	if err := flag.CommandLine.Parse([]string{"-logtostderr"}); err != nil {
		return nil, nil, err
	}

	cmd := exec.Command("systemd-cat", "--identifier", "ploop-flexvol")
	if err != nil {
		return nil, nil, err
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, nil, fmt.Errorf("Unable to create a pipe: %v", err)
	}
	cmd.Stdin = pr
	defer pr.Close()
	defer pw.Close()

	if err := syscall.Dup2(int(pw.Fd()), syscall.Stdout); err != nil {
		return nil, nil, fmt.Errorf("Unable to redirect stdout: %v", err)
	}
	if err := syscall.Dup2(syscall.Stdout, syscall.Stderr); err != nil {
		return nil, nil, fmt.Errorf("Unable to redirect stderr: %v", err)
	}
	if err := cmd.Start(); err != nil {
		return nil, nil, fmt.Errorf("Unable to start systemd-cat: %v", err)
	}
	return os.Args, cmd, nil
}

func setupWrapperLogging() ([]string, *exec.Cmd, error) {
	syscall.CloseOnExec(3)
	flexvolume.SetRespFile(os.NewFile((uintptr)(3), "RespFile"))
	if err := flag.CommandLine.Parse(os.Args[2:]); err != nil {
		return nil, nil, err
	}
	return flag.CommandLine.Args(), nil, nil
}

func setupLogging() ([]string, *exec.Cmd, error) {
	if os.Args[1] == "wrapper" {
		return setupWrapperLogging()
	}

	return setupJournld()
}

func main() {
	args, cmd, err := setupLogging()
	if err != nil {
		panic(err)
	}
	if cmd != nil {
		defer func() {
			syscall.Close(syscall.Stdout)
			syscall.Close(syscall.Stderr)
			cmd.Wait()
		}()
	}

	app := cli.NewApp()
	app.Name = "ploop flexvolume"
	app.Usage = "Mount ploop volumes in kubernetes using the flexvolume driver"
	app.Commands = flexvolume.Commands(Ploop{})
	app.CommandNotFound = flexvolume.CommandNotFound
	app.Authors = []cli.Author{
		cli.Author{
			Name: "Lee Briggs",
		},
		cli.Author{
			Name: "Virtuozzo",
		},
	}
	app.Version = "0.2a"

	if glog.V(4) {
		glog.Infof("Request: %v", args)
	}
	app.Run(args)
}

type Ploop struct{}

const workingDir = "/var/run/ploop-flexvol/"

func (p Ploop) Init() (*flexvolume.Response, error) {
	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Ploop is available",
	}, nil
}

func (p Ploop) path(options map[string]string) string {
	path := "/"
	if options["volumePath"] != "" {
		path += options["volumePath"] + "/"
	}
	path += options["volumeID"]
	return path
}

func (p Ploop) GetVolumeName(options map[string]string) (*flexvolume.Response, error) {
	if options["volumeID"] == "" {
		return nil, fmt.Errorf("Must specify a volume id")
	}

	return &flexvolume.Response{
		Status:     flexvolume.StatusSuccess,
		VolumeName: options["clusterName"] + "|" + p.path(options),
	}, nil
}

func prepareVstorage(clusterName, clusterPasswd string, mount string) error {
	mounted, _ := vstorage.IsVstorage(mount)
	if mounted {
		return nil
	}

	// not mounted in proper place, prepare mount place and check other
	// mounts
	if err := os.MkdirAll(mount, 0700); err != nil {
		return err
	}

	v := vstorage.Vstorage{clusterName}
	p, _ := v.Mountpoint()
	if p != "" {
		return syscall.Mount(p, mount, "", syscall.MS_BIND, "")
	}

	if clusterPasswd == "" {
		return errors.New("Please provide vstorage credentials")
	}

	if err := v.Auth(clusterPasswd); err != nil {
		return err
	}
	if err := v.Mount(mount); err != nil {
		return err
	}

	return nil
}

func (p Ploop) Mount(target string, options map[string]string) (*flexvolume.Response, error) {
	// make the target directory we're going to mount to
	err := os.MkdirAll(target, 0700)
	if err != nil {
		return nil, err
	}

	path := p.path(options)

	readonly := false
	if options["kubernetes.io/readwrite"] == "ro" {
		readonly = true
	}

	if options["kubernetes.io/secret/clusterName"] != "" {
		_cluster, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterName"])
		if err != nil {
			return nil, fmt.Errorf("Unable to decode a cluster name: %v", err.Error())
		}
		cluster := string(_cluster)

		_passwd, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterPassword"])
		if err != nil {
			return nil, fmt.Errorf("Unable to decode a cluster password: %v", err.Error())
		}
		passwd := string(_passwd)

		mount := workingDir + cluster
		if err := prepareVstorage(cluster, passwd, mount); err != nil {
			return nil, err
		}
		path = mount + path

		if !readonly {
			// Node denial may lead to vstorage freezes. vstorage revoke operation before writing
			// data will prevent this cases. Detach method is more suitable for it, but currently
			// volume name is auto generated and does not include all neccessary credentials to
			// perform volume revoke. It should be fixed when k8s community fixed getvolumename call
			v := vstorage.Vstorage{cluster}
			if err := v.Revoke(path); err != nil {
				return nil, err
			}
		}
	}
	// open the disk descriptor first
	volume, err := ploop.Open(path + "/" + "DiskDescriptor.xml")
	if err != nil {
		return nil, err
	}
	defer volume.Close()

	if m, _ := volume.IsMounted(); !m {
		// If it's mounted, let's mount it!

		mp := ploop.MountParam{Target: target, Readonly: readonly}

		_, err := volume.Mount(&mp)
		if err != nil {
			return nil, err
		}

		return &flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Successfully mounted the ploop volume",
		}, nil
	} else {

		return &flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Ploop volume already mounted",
		}, nil

	}
}

func (p Ploop) Unmount(mount string) (*flexvolume.Response, error) {
	if err := ploop.UmountByMount(mount); err != nil {
		return nil, err
	}

	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully unmounted the ploop volume",
	}, nil
}

func (p Ploop) Attach(nodename string, options map[string]string) (*flexvolume.Response, error) {
	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully attached the ploop volume",
	}, nil
}

func (p Ploop) Detach(device string, nodename string) (*flexvolume.Response, error) {
	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully detached the ploop volume",
	}, nil
}
<|endoftext|>


<commit_before>// Hermes, a distributed backup system (DBS)

package main

import (
	"hermes/client"
	"hermes/server"
	"os"
	"io"
	"flag"
	"fmt"
	"bytes"
)

const (
	blockSize = 1048576
	tempDir = "temp"
)

type vault struct {
	Key string
}

func generate(file string) {//, pass string) {
	creds := server.NewCredentials()
    f, err := os.Create(file)
    defer f.Close()
    if err != nil {
        fmt.Println(err)
    }
    n, err := io.WriteString(f, creds.String())
    if err != nil {
        fmt.Println(n, err)
    }
	fmt.Println("Keep key secret, and safe.")
	fmt.Println("Vault Key: " + creds.String())
}

func load(file string) {//, pass string) {
    f, _ := os.Open(file)
	defer f.Close()
	buf := new(bytes.Buffer)
	buf.ReadFrom(f)
	s := buf.String()
	fmt.Println("Vault Key: " + s + " loaded")
}

func update() {
	// server code
	fmt.Println("Vault update successful")
}

func pull(file string) {
	//server code
	/*d := client.Join(files)
	d = client.Decrypt(d, "password")
	d = client.Decompress(d)
	file, _ := os.Create("../bench-files/test1.zip")
	io.Copy(file, d)*/
}

func push(file string) {
	in, _ := os.Open(file)
	defer in.Close()
	i := client.Compress(in)
	i = client.Encrypt(i, "password")
	client.Split(i, blockSize, tempDir)
	// server code
}

func lock() {
	fmt.Println("lock")
}

func main() {

	// check if temp dir exists / make it

	flag.Parse()
	flags := flag.Args()
	if client.ValidateFlags(flags) {
		switch flags[0] {
			case "update": update()
			case "generate": generate(flags[1])//, flags[2])
			case "load": load(flags[1]) //, flags[2])
			case "pull": pull(flags[1])
			case "push": push(flags[1])
			case "lock": lock()
			default: fmt.Println("Error: Invalid Flags")
		}
	} else {
		fmt.Println("Error: Invalid Flags")
	}

}<commit_msg>Command line interface improvements<commit_after>// Hermes, a distributed backup system (DBS)

package main

import (
	"hermes/client"
	"hermes/server"
	"os"
	"io"
	"flag"
	"fmt"
	"bytes"
)

const (
	blockSize = 1048576
	tempDir = "temp"
)

type vault struct {
	Key string
}

func generate(file string) {//, pass string) {
	creds := server.NewCredentials()
    f, err := os.Create(file)
    defer f.Close()
    if err != nil {
        fmt.Println(err)
    }
    n, err := io.WriteString(f, creds.String())
    if err != nil {
        fmt.Println(n, err)
    }
	fmt.Println("Keep key secret, and safe.")
	fmt.Println("Vault Key: " + creds.String())
}

func load(file string) {//, pass string) {
    f, _ := os.Open(file)
	defer f.Close()

	fo, err := os.Create("vault.dat")
    defer fo.Close()
    if err != nil {
        fmt.Println(err)
    } else {
    	io.Copy(fo, f)
    }

	buf := new(bytes.Buffer)
	buf.ReadFrom(f)
	s := buf.String()
	fmt.Println("Vault Key: " + s + " loaded")
}

func (v vault) update() {
	// server code
	fmt.Println(v.Key)
	fmt.Println("Vault update successful")
}

func (v vault) pull(file string) {
	//server code
	/*d := client.Join(files)
	d = client.Decrypt(d, "password")
	d = client.Decompress(d)
	file, _ := os.Create("../bench-files/test1.zip")
	io.Copy(file, d)*/
}

func (v vault) push(file string) {
	in, _ := os.Open(file)
	defer in.Close()
	i := client.Compress(in)
	i = client.Encrypt(i, "password")
	client.Split(i, blockSize, tempDir)
	// server code
}

func lock() {
	err := os.Remove("vault.dat")
	if err != nil {
		fmt.Println("No active vault to lock")
	} else {
		fmt.Println("Vault has been locked")
	}
}

func main() {

	// check if temp dir exists / make it

	var v vault

	flag.Parse()
	flags := flag.Args()
	if client.ValidateFlags(flags) {

		vaultfile, err := os.Open("vault.dat")
		if err != nil && flags[0] != "generate" && flags[0] != "load" {
	        fmt.Println("Failed to load vault")
	        return
		} else if err == nil {
			defer vaultfile.Close()
			buf := new(bytes.Buffer)
			buf.ReadFrom(vaultfile)
			s := buf.String()
			v.Key = s
		}

		switch flags[0] {
			case "generate": generate(flags[1])//, flags[2])
			case "load": load(flags[1]) //, flags[2])
			case "lock": lock()
			case "update": v.update()
			case "pull": v.pull(flags[1])
			case "push": v.push(flags[1])
			default: fmt.Println("Error: Invalid Flags")
		}
	} else {
		fmt.Println("Error: Invalid Flags")
	}

}<|endoftext|>


<commit_before>package main

import (
	"time"
	"encoding/json"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"net/http/httputil"
	"log"
	"os"
	//"io"
	"fmt"
	"database/sql"
	_ "github.com/lib/pq"
	"gopkg.in/antage/eventsource.v1"
)

var conn *sql.DB
var es eventsource.EventSource

func SetHeaders(w *http.ResponseWriter) {
	(*w).Header().Set("Access-Control-Allow-Origin", "*")
	(*w).Header().Set("Content-Type", "application/json")
}

func GetBlog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM blog")
	data := []BlogPost{}
	for rows.Next() {
		post := BlogPost{}
		rows.Scan(&post.Id, &post.Titel, &post.Text, &post.Auteur, &post.Img_url, &post.Ctime, &post.Image)
		data = append(data, post)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT * FROM blog WHERE id = $1 LIMIT 1", ps.ByName("id"))
	data := BlogPost{}
	row.Scan(&data.Id, &data.Titel, &data.Text, &data.Auteur, &data.Img_url, &data.Ctime, &data.Image)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM spindata ORDER BY tijd DESC LIMIT 1")
	spin := SpinData{}
	rows.Next()
	rows.Scan(&spin.Id, &spin.Tijd, &spin.Mode, &spin.Hellingsgraad, &spin.Snelheid, &spin.Batterij, &spin.BallonCount)
	buf,_ := json.Marshal(spin)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinBatterij(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT batterij FROM spindata ORDER BY tijd DESC LIMIT 1")
	var data int
	row.Scan(&data)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinMode(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT mode FROM spindata ORDER BY tijd DESC LIMIT 1")
	var data string
	row.Scan(&data)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM spindata")
	data := []SpinData{}
	for rows.Next() {
		spin := SpinData{}
		rows.Scan(&spin.Id, &spin.Tijd, &spin.Mode, &spin.Hellingsgraad, &spin.Snelheid, &spin.Batterij, &spin.BallonCount)
		data = append(data, spin)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinBatterij(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT batterij FROM spindata")
	data := make([]int, 0)
	var scanInt int
	for rows.Next() {
		rows.Scan(&scanInt)
		data = append(data, scanInt)
	}
	buf,_ := json.Marshal(data)
	fmt.Printf(string(buf))
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinMode(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT mode FROM spindata")
	data := make([]string, 0)
	var scanStr string
	for rows.Next() {
		rows.Scan(&scanStr)
		data = append(data, scanStr)
	}
	buf,_ := json.Marshal(data)
	fmt.Printf(string(buf))
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT * FROM servodata ORDER BY tijd DESC LIMIT 1")
	servo := ServoData{}
	row.Scan(&servo.Id, &servo.ServoId, &servo.Tijd, &servo.Voltage, &servo.Positie, &servo.Load, &servo.Temperatuur)
	buf,_ := json.Marshal(servo)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM servodata")
	data := []ServoData{}
	for rows.Next() {
		servo := ServoData{}
		rows.Scan(&servo.Id, &servo.ServoId, &servo.Tijd, &servo.Voltage, &servo.Positie, &servo.Load, &servo.Temperatuur)
		data = append(data, servo)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLogs(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM logs")
	data := []LogData{}
	for rows.Next() {
		log := LogData{}
		rows.Scan(&log.Id, &log.Log)
		data = append(data, log)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestGyroData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT hellingsgraad FROM spindata ORDER BY tijd DESC LIMIT 1")
	var helling int
	row.Scan(&helling)
	buf,_ := json.Marshal(helling)
	SetHeaders(&w)
	w.Write(buf)
}

func Test(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	buf,_ := json.Marshal("test")
	SetHeaders(&w)
	w.Write(buf)
}

func PostBlog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	//r.ParseMultipartForm(32 << 20)
	/*file, handler, err := r.FormFile("uploadfile")
	defer file.Close()
	if err == nil {
		fmt.Fprintf(w, "%v", handler.Header)
		f, err := os.OpenFile("./img/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			w.WriteHeader(500)
			return
		}
		defer f.Close()
		io.Copy(f, file)
	}

	err = nil*/

	//_,err := conn.Query("INSERT INTO blog (titel, text, auteur, ctime, image) VALUES ($1, $2, $3, $4, $5)", r.FormValue("titel"), r.FormValue("text"), r.FormValue("auteur"), time.Now(), "http://idp-api.herokuapp.com/img/"+handler.Filename)
	_,err := conn.Query("INSERT INTO blog (titel, text, auteur, ctime) VALUES ($1, $2, $3, $4)", r.FormValue("onderwerp"), r.FormValue("bericht"), r.FormValue("naam"), time.Now())
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	w.Header().Set("Content-Type", "text/html")
	w.WriteHeader(201)
	w.Write([]byte("<meta http-equiv=\"refresh\" content=\"1; url=http://knightspider.herokuapp.com/#/blog\">successful"))
}

func PostSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// buf := make([]byte,100)
	// r.Body.Read(buf)
	// w.Write(buf)
	//reqStr, _ := httputil.DumpRequest(r, true)
	//w.Write(reqStr)
	r.ParseForm()
	_,err := conn.Query("INSERT INTO spindata (mode, hellingsgraad, snelheid, batterij, balloncount) VALUES ($1, $2, $3, $4, $5)",
		r.PostFormValue("mode"), r.PostFormValue("hellingsgraad"), r.PostFormValue("snelheid"), r.PostFormValue("batterij"), r.PostFormValue("ballonCount"))
		//"manueel", 0, 300, 50, 0)
		//r.FormValue("mode"),
		//r.FormValue("hellingsgraad"),
		//300,50,0)
		//r.FormValue("batterij"),
		//r.FormValue("ballonCount"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))

		return
	}
	w.WriteHeader(201)
	//w.Write([]byte(fmt.Sprintf("mode = %s, hellingsgraad = %s, snelheid = %s, batterij = %s, balloncount = %s", mode, hellingsgraad, snelheid, batterij, balloncount)))
	w.Write([]byte("successful"))
}

func PostServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	_,err := conn.Query("INSERT INTO servodata (servo_id, tijd, voltage, positie, load, temperatuur) VALUES ($1, $2, $3, $4, $5, $6)",
		r.FormValue("servo_id"), time.Now(), r.FormValue("voltage"), r.FormValue("positie"), r.FormValue("load"), r.FormValue("Temperatuur"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	w.WriteHeader(201)
	w.Write([]byte("successful"))
}

func PostLog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	_,err := conn.Query("INSERT INTO logs (log) VALUES ($1)",
		r.FormValue("log"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	es.SendEventMessage(r.FormValue("log"), "log", "")
	w.WriteHeader(201)
	w.Write([]byte(r.FormValue("log")))
}

func Head(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	SetHeaders(&w)
	w.WriteHeader(204)
}

func main() {
	conn,_ = sql.Open("postgres", os.Getenv("DATABASE_URL"))
	defer conn.Close()

	es = eventsource.New(
		&eventsource.Settings{
			Timeout: 5 * time.Second,
			CloseOnTimeout: false,
			IdleTimeout: 30 * time.Minute,
		},
		func(req *http.Request) [][]byte {
			return [][]byte{
				[]byte("X-Accel-Buffering: no"),
				[]byte("Access-Control-Allow-Origin: *"),
			}
		},
	)
	defer es.Close()

	router := httprouter.New()
	router.HEAD("/*path", Head)
	router.GET("/test", Test)
	router.GET("/blog", GetBlog)
	router.GET("/blog/:id", GetPost)
	router.GET("/spin/latest", GetLatestSpinData)
	router.GET("/spin/latest/batterij", GetLatestSpinBatterij)
	router.GET("/spin/latest/mode", GetLatestSpinMode)
	router.GET("/spin/latest/helling", GetLatestGyroData)
	router.GET("/spin/archive", GetArchivedSpinData)
	router.GET("/spin/archive/batterij", GetArchivedSpinBatterij)
	router.GET("/spin/archive/mode", GetArchivedSpinMode)
	router.GET("/servo/latest", GetLatestServoData)
	router.GET("/servo/archive", GetArchivedServoData)
	router.GET("/log", GetLogs)
	router.POST("/blog", PostBlog)
	router.POST("/spin", PostSpinData)
	router.POST("/servo", PostServoData)
	router.POST("/log", PostLog)

	http.Handle("/subscribe", es)
	http.Handle("/", router)

	port := os.Getenv("PORT")
	if port == "" {
		port = "3000"
	}
	fmt.Printf("Starting server at localhost:%s...", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}<commit_msg>removed debug code<commit_after>package main

import (
	"time"
	"encoding/json"
	"github.com/julienschmidt/httprouter"
	"net/http"
	//"net/http/httputil"
	"log"
	"os"
	//"io"
	"fmt"
	"database/sql"
	_ "github.com/lib/pq"
	"gopkg.in/antage/eventsource.v1"
)

var conn *sql.DB
var es eventsource.EventSource

func SetHeaders(w *http.ResponseWriter) {
	(*w).Header().Set("Access-Control-Allow-Origin", "*")
	(*w).Header().Set("Content-Type", "application/json")
}

func GetBlog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM blog")
	data := []BlogPost{}
	for rows.Next() {
		post := BlogPost{}
		rows.Scan(&post.Id, &post.Titel, &post.Text, &post.Auteur, &post.Img_url, &post.Ctime, &post.Image)
		data = append(data, post)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT * FROM blog WHERE id = $1 LIMIT 1", ps.ByName("id"))
	data := BlogPost{}
	row.Scan(&data.Id, &data.Titel, &data.Text, &data.Auteur, &data.Img_url, &data.Ctime, &data.Image)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM spindata ORDER BY tijd DESC LIMIT 1")
	spin := SpinData{}
	rows.Next()
	rows.Scan(&spin.Id, &spin.Tijd, &spin.Mode, &spin.Hellingsgraad, &spin.Snelheid, &spin.Batterij, &spin.BallonCount)
	buf,_ := json.Marshal(spin)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinBatterij(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT batterij FROM spindata ORDER BY tijd DESC LIMIT 1")
	var data int
	row.Scan(&data)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestSpinMode(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT mode FROM spindata ORDER BY tijd DESC LIMIT 1")
	var data string
	row.Scan(&data)
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM spindata")
	data := []SpinData{}
	for rows.Next() {
		spin := SpinData{}
		rows.Scan(&spin.Id, &spin.Tijd, &spin.Mode, &spin.Hellingsgraad, &spin.Snelheid, &spin.Batterij, &spin.BallonCount)
		data = append(data, spin)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinBatterij(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT batterij FROM spindata")
	data := make([]int, 0)
	var scanInt int
	for rows.Next() {
		rows.Scan(&scanInt)
		data = append(data, scanInt)
	}
	buf,_ := json.Marshal(data)
	fmt.Printf(string(buf))
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedSpinMode(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT mode FROM spindata")
	data := make([]string, 0)
	var scanStr string
	for rows.Next() {
		rows.Scan(&scanStr)
		data = append(data, scanStr)
	}
	buf,_ := json.Marshal(data)
	fmt.Printf(string(buf))
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT * FROM servodata ORDER BY tijd DESC LIMIT 1")
	servo := ServoData{}
	row.Scan(&servo.Id, &servo.ServoId, &servo.Tijd, &servo.Voltage, &servo.Positie, &servo.Load, &servo.Temperatuur)
	buf,_ := json.Marshal(servo)
	SetHeaders(&w)
	w.Write(buf)
}

func GetArchivedServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM servodata")
	data := []ServoData{}
	for rows.Next() {
		servo := ServoData{}
		rows.Scan(&servo.Id, &servo.ServoId, &servo.Tijd, &servo.Voltage, &servo.Positie, &servo.Load, &servo.Temperatuur)
		data = append(data, servo)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLogs(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	rows,_ := conn.Query("SELECT * FROM logs")
	data := []LogData{}
	for rows.Next() {
		log := LogData{}
		rows.Scan(&log.Id, &log.Log)
		data = append(data, log)
	}
	buf,_ := json.Marshal(data)
	SetHeaders(&w)
	w.Write(buf)
}

func GetLatestGyroData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	row := conn.QueryRow("SELECT hellingsgraad FROM spindata ORDER BY tijd DESC LIMIT 1")
	var helling int
	row.Scan(&helling)
	buf,_ := json.Marshal(helling)
	SetHeaders(&w)
	w.Write(buf)
}

func Test(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	buf,_ := json.Marshal("test")
	SetHeaders(&w)
	w.Write(buf)
}

func PostBlog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	//r.ParseMultipartForm(32 << 20)
	/*file, handler, err := r.FormFile("uploadfile")
	defer file.Close()
	if err == nil {
		fmt.Fprintf(w, "%v", handler.Header)
		f, err := os.OpenFile("./img/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			w.WriteHeader(500)
			return
		}
		defer f.Close()
		io.Copy(f, file)
	}

	err = nil*/

	//_,err := conn.Query("INSERT INTO blog (titel, text, auteur, ctime, image) VALUES ($1, $2, $3, $4, $5)", r.FormValue("titel"), r.FormValue("text"), r.FormValue("auteur"), time.Now(), "http://idp-api.herokuapp.com/img/"+handler.Filename)
	_,err := conn.Query("INSERT INTO blog (titel, text, auteur, ctime) VALUES ($1, $2, $3, $4)", r.FormValue("onderwerp"), r.FormValue("bericht"), r.FormValue("naam"), time.Now())
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	w.Header().Set("Content-Type", "text/html")
	w.WriteHeader(201)
	w.Write([]byte("<meta http-equiv=\"refresh\" content=\"1; url=http://knightspider.herokuapp.com/#/blog\">successful"))
}

func PostSpinData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// buf := make([]byte,100)
	// r.Body.Read(buf)
	// w.Write(buf)
	//reqStr, _ := httputil.DumpRequest(r, true)
	//w.Write(reqStr)
	r.ParseForm()
	_,err := conn.Query("INSERT INTO spindata (mode, hellingsgraad, snelheid, batterij, balloncount) VALUES ($1, $2, $3, $4, $5)",
		r.PostFormValue("mode"), r.PostFormValue("hellingsgraad"), r.PostFormValue("snelheid"), r.PostFormValue("batterij"), r.PostFormValue("ballonCount"))
		//"manueel", 0, 300, 50, 0)
		//r.FormValue("mode"),
		//r.FormValue("hellingsgraad"),
		//300,50,0)
		//r.FormValue("batterij"),
		//r.FormValue("ballonCount"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))

		return
	}
	w.WriteHeader(201)
	//w.Write([]byte(fmt.Sprintf("mode = %s, hellingsgraad = %s, snelheid = %s, batterij = %s, balloncount = %s", mode, hellingsgraad, snelheid, batterij, balloncount)))
	w.Write([]byte("successful"))
}

func PostServoData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	_,err := conn.Query("INSERT INTO servodata (servo_id, tijd, voltage, positie, load, temperatuur) VALUES ($1, $2, $3, $4, $5, $6)",
		r.FormValue("servo_id"), time.Now(), r.FormValue("voltage"), r.FormValue("positie"), r.FormValue("load"), r.FormValue("Temperatuur"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	w.WriteHeader(201)
	w.Write([]byte("successful"))
}

func PostLog(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	_,err := conn.Query("INSERT INTO logs (log) VALUES ($1)",
		r.FormValue("log"))
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte(err.Error()))
		return
	}
	es.SendEventMessage(r.FormValue("log"), "log", "")
	w.WriteHeader(201)
	w.Write([]byte(r.FormValue("log")))
}

func Head(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	SetHeaders(&w)
	w.WriteHeader(204)
}

func main() {
	conn,_ = sql.Open("postgres", os.Getenv("DATABASE_URL"))
	defer conn.Close()

	es = eventsource.New(
		&eventsource.Settings{
			Timeout: 5 * time.Second,
			CloseOnTimeout: false,
			IdleTimeout: 30 * time.Minute,
		},
		func(req *http.Request) [][]byte {
			return [][]byte{
				[]byte("X-Accel-Buffering: no"),
				[]byte("Access-Control-Allow-Origin: *"),
			}
		},
	)
	defer es.Close()

	router := httprouter.New()
	router.HEAD("/*path", Head)
	router.GET("/test", Test)
	router.GET("/blog", GetBlog)
	router.GET("/blog/:id", GetPost)
	router.GET("/spin/latest", GetLatestSpinData)
	router.GET("/spin/latest/batterij", GetLatestSpinBatterij)
	router.GET("/spin/latest/mode", GetLatestSpinMode)
	router.GET("/spin/latest/helling", GetLatestGyroData)
	router.GET("/spin/archive", GetArchivedSpinData)
	router.GET("/spin/archive/batterij", GetArchivedSpinBatterij)
	router.GET("/spin/archive/mode", GetArchivedSpinMode)
	router.GET("/servo/latest", GetLatestServoData)
	router.GET("/servo/archive", GetArchivedServoData)
	router.GET("/log", GetLogs)
	router.POST("/blog", PostBlog)
	router.POST("/spin", PostSpinData)
	router.POST("/servo", PostServoData)
	router.POST("/log", PostLog)

	http.Handle("/subscribe", es)
	http.Handle("/", router)

	port := os.Getenv("PORT")
	if port == "" {
		port = "3000"
	}
	fmt.Printf("Starting server at localhost:%s...", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"time"
	"strings"
	"regexp"

	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

var db *sql.DB
var err error

type UrlResponse struct {
	OriginalURL interface{} `json:"original_url"`
	ShortURL    interface{} `json:"short_url"`
}

type ErrorResponse struct {
	Error interface{} `json:"error"`
}

type Config struct {
    Database struct {
        User     string `json:"user"`
        Password string `json:"password"`
    } `json:"database"`
    Host string `json:"host"`
    Port string `json:"port"`
		Name string `json:"name"`
}

func main() {
	var config = loadConfig("config.json")

	db, err = sql.Open("mysql", "" + config.Database.User + ":" + config.Database.Password + "@tcp(" + config.Host + ":" + config.Port + ")/" + config.Name + "")
	check(err)
	defer db.Close()

	err = db.Ping()
	check(err)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	router := mux.NewRouter()
	router.HandleFunc("/new/", index)
	router.HandleFunc("/", index)
	http.ListenAndServe(":"+port, router)
}

func loadConfig(file string) Config {
    var config Config
    configFile, err := os.Open(file)
    if err != nil {
        fmt.Println(err.Error())
    }
    jsonParser := json.NewDecoder(configFile)
    jsonParser.Decode(&config)
    configFile.Close()
    return config
}

func index(res http.ResponseWriter, req *http.Request) {
	req.URL.Path = strings.Replace(req.URL.Path, ":/", "://", -1)
	fmt.Println(req.URL.Path)
	param := strings.Split(req.URL.Path, "/")
	if len(param) > 4 {
		createURL(res, req, param)
	} else {
		fmt.Fprint(res, "Welcome to the URL Shortener Service!\n")
	}
}

func createURL(res http.ResponseWriter, req *http.Request, param []string) {

	fmt.Println("createURL")

	posURL := strings.Split(req.URL.Path, "new/")
	originalUrl := posURL[1]

	reg, _ := regexp.Compile(`https?:\/\/(www\.)[a-zA-Z0-9_\-]+\.[(com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)]\/?[/a-zA-Z0-9_\-]+$`)

	if reg.MatchString(originalUrl) {
		idNum := random(0, 9999)
		idStr := strconv.Itoa(idNum)
		check(err)
		shortUrl := "https://morning-retreat-24523.herokuapp.com/" + idStr
		_, err := db.Exec("INSERT INTO urls(id, original_url, short_url) VALUES(?, ?, ?)", idNum, originalUrl, shortUrl)
		check(err)
		response := UrlResponse{OriginalURL: originalUrl, ShortURL: shortUrl}
		js, err := json.Marshal(response)
		check(err)
		res.Header().Set("Content-Type", "application/json")
		res.Write(js)
	} else {
		response := ErrorResponse{Error: "Wrong url format, make sure you have a valid protocol and real site."}
		js, err := json.Marshal(response)
		check(err)
		res.Header().Set("Content-Type", "application/json")
		res.Write(js)
	}

}

func getURL(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	var idStr string = vars["id"]
	var idNum, err = strconv.Atoi(idStr)
	var originalUrl string
	err = db.QueryRow("SELECT original_url FROM urls WHERE id = ?", idNum).Scan(&originalUrl)
	check(err)

	http.Redirect(w, r, originalUrl, 301) //This needs to have a protocol: http or https
}

func random(min, max int) int {
	rand.Seed(time.Now().Unix())
	return rand.Intn(max-min) + min
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}
<commit_msg>added SkipClean method<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"time"
	"regexp"

	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

var db *sql.DB
var err error

type UrlResponse struct {
	OriginalURL interface{} `json:"original_url"`
	ShortURL    interface{} `json:"short_url"`
}

type ErrorResponse struct {
	Error interface{} `json:"error"`
}

type Config struct {
    Database struct {
        User     string `json:"user"`
        Password string `json:"password"`
    } `json:"database"`
    Host string `json:"host"`
    Port string `json:"port"`
		Name string `json:"name"`
}

func main() {
	var config = loadConfig("config.json")

	db, err = sql.Open("mysql", "" + config.Database.User + ":" + config.Database.Password + "@tcp(" + config.Host + ":" + config.Port + ")/" + config.Name + "")
	check(err)
	defer db.Close()

	err = db.Ping()
	check(err)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	router := mux.NewRouter()
	router.SkipClean(true)
	router.HandleFunc("/new/", createURL)
	router.HandleFunc("/{id}", getURL)
	router.HandleFunc("/", index)
	http.ListenAndServe(":"+port, router)
}

func loadConfig(file string) Config {
    var config Config
    configFile, err := os.Open(file)
    if err != nil {
        fmt.Println(err.Error())
    }
    jsonParser := json.NewDecoder(configFile)
    jsonParser.Decode(&config)
    configFile.Close()
    return config
}

func index(res http.ResponseWriter, req *http.Request) {
	//req.URL.Path = strings.Replace(req.URL.Path, ":/", "://", -1)
	//fmt.Println(req.URL.Path)
	//param := strings.Split(req.URL.Path, "/")

	fmt.Fprint(res, "Welcome to the URL Shortener Service!\n")
}

func createURL(res http.ResponseWriter, req *http.Request) {

	vars := mux.Vars(req)
	originalUrl := vars["url"]

	fmt.Println(originalUrl)

	reg, _ := regexp.Compile(`https?:\/\/(www\.)[a-zA-Z0-9_\-]+\.[(com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)]\/?[/a-zA-Z0-9_\-]+$`)

	if reg.MatchString(originalUrl) {
		idNum := random(0, 9999)
		idStr := strconv.Itoa(idNum)
		check(err)
		shortUrl := "https://morning-retreat-24523.herokuapp.com/" + idStr
		_, err := db.Exec("INSERT INTO urls(id, original_url, short_url) VALUES(?, ?, ?)", idNum, originalUrl, shortUrl)
		check(err)
		response := UrlResponse{OriginalURL: originalUrl, ShortURL: shortUrl}
		js, err := json.Marshal(response)
		check(err)
		res.Header().Set("Content-Type", "application/json")
		res.Write(js)
	} else {
		response := ErrorResponse{Error: "Wrong url format, make sure you have a valid protocol and real site."}
		js, err := json.Marshal(response)
		check(err)
		res.Header().Set("Content-Type", "application/json")
		res.Write(js)
	}

}

func getURL(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	var idStr string = vars["id"]
	var idNum, err = strconv.Atoi(idStr)
	var originalUrl string
	err = db.QueryRow("SELECT original_url FROM urls WHERE id = ?", idNum).Scan(&originalUrl)
	check(err)

	http.Redirect(w, r, originalUrl, 301) //This needs to have a protocol: http or https
}

func random(min, max int) int {
	rand.Seed(time.Now().Unix())
	return rand.Intn(max-min) + min
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}
<|endoftext|>