<commit_before>/*
	Faye Server

*/
package fayeserver

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/serverhorror/uuid"
	"sync"
)

type FayeServer struct {
	Connections   []Connection
	Subscriptions map[string][]Client
	SubMutex      sync.RWMutex
	Clients       map[string]Client
	ClientMutex   sync.RWMutex
}

/*
Instantiate a new faye server
*/
func NewFayeServer() *FayeServer {
	return &FayeServer{Connections: []Connection{},
		Subscriptions: make(map[string][]Client),
		Clients:       make(map[string]Client)}
}

// general message handling
/*

*/
func (f *FayeServer) publishToChannel(channel, data string) {
	subs, ok := f.Subscriptions[channel]
	if ok {
		f.multiplexWrite(subs, data)
	}
}

/*

*/
func (f *FayeServer) multiplexWrite(subs []Client, data string) {
	var group sync.WaitGroup
	for i := range subs {
		group.Add(1)
		go func(client chan<- string, data string) {
			client <- data
			group.Done()
		}(subs[i].WriteChannel, data)
	}
	go func() {
		group.Wait()
	}()
}

func (f *FayeServer) findClientForChannel(c chan string) *Client {
	f.ClientMutex.Lock()
	defer f.ClientMutex.Unlock()

	for _, client := range f.Clients {
		if client.WriteChannel == c {
			fmt.Println("Matched Client: ", client.ClientId)
			return &client
		}
	}
	return nil
}

func (f *FayeServer) DisconnectChannel(c chan string) {
	client := f.findClientForChannel(c)
	if client != nil {
		fmt.Println("Disconnect Client: ", client.ClientId)
		f.removeClientFromServer(client.ClientId)
	}
}

// ========

type FayeMessage struct {
	Channel      string      `json:"channel"`
	ClientId     string      `json:"clientId,omitempty"`
	Subscription string      `json:"subscription,omitempty"`
	Data         interface{} `json:"data,omitempty"`
	Id           string      `json:"id,omitempty"`
}

// Message handling

func (f *FayeServer) HandleMessage(message []byte, c chan string) ([]byte, error) {
	// parse message JSON
	fm := FayeMessage{}
	err := json.Unmarshal(message, &fm)

	if err != nil {
		fmt.Println("Error parsing message json")
	}

	switch fm.Channel {
	case "/meta/handshake":
		fmt.Println("handshake")
		return f.handshake()
	case "/meta/connect":
		fmt.Println("connect")
		return f.connect(fm.ClientId)
	case "/meta/disconnect":
		fmt.Println("disconnect")
		return f.disconnect(fm.ClientId)
	case "/meta/subscribe":
		fmt.Println("subscribe")
		return f.subscribe(fm.ClientId, fm.Subscription, c)
	case "/meta/unsubscribe":
		fmt.Println("subscribe")
		return f.unsubscribe(fm.ClientId, fm.Subscription)
	default:
		fmt.Println("publish")
		fmt.Println("data is: ", fm.Data)
		return f.publish(fm.Channel, fm.Id, fm.Data)
	}

	return []byte{}, errors.New("Invalid Faye Message")
}

/*
FayeResponse
*/

type FayeResponse struct {
	Channel                  string            `json:"channel,omitempty"`
	Successful               bool              `json:"successful,omitempty"`
	Version                  string            `json:"version,omitempty"`
	SupportedConnectionTypes []string          `json:"supportedConnectionTypes,omitempty"`
	ClientId                 string            `json:"clientId,omitempty"`
	Advice                   map[string]string `json:"advice,omitempty"`
	Subscription             string            `json:"subscription,omitempty"`
	Error                    string            `json:"error,omitempty"`
	Id                       string            `json:"id,omitempty"`
	Data                     interface{}       `json:"data,omitempty"`
}

/*

Handshake:

Example response:
{
    "channel": "/meta/handshake",
    "successful": true,
    "version": "1.0",
    "supportedConnectionTypes": [
        "long-polling",
        "cross-origin-long-polling",
        "callback-polling",
        "websocket",
        "eventsource",
        "in-process"
    ],
    "clientId": "1fg1b9s10zm29e0ahpk490mzkqk3",
    "advice": {
        "reconnect": "retry",
        "interval": 0,
        "timeout": 45000
    }
}

Bayeux Handshake response

*/

func (f *FayeServer) handshake() ([]byte, error) {
	// build response
	resp := FayeResponse{
		Channel:                  "/meta/handshake",
		Successful:               true,
		Version:                  "1.0",
		SupportedConnectionTypes: []string{"websocket"},
		ClientId:                 generateClientId(),
		Advice:                   map[string]string{"reconnect": "retry"},
	}

	// wrap it in an array & convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*

Connect:

Example response
[
  {
     "channel": "/meta/connect",
     "successful": true,
     "error": "",
     "clientId": "Un1q31d3nt1f13r",
     "timestamp": "12:00:00 1970",
     "advice": { "reconnect": "retry" }
   }
]
*/

func (f *FayeServer) connect(clientId string) ([]byte, error) {
	// TODO: setup client connection state

	resp := FayeResponse{
		Channel:    "/meta/connect",
		Successful: true,
		Error:      "",
		ClientId:   clientId,
		Advice:     map[string]string{"reconnect": "retry"},
	}

	// wrap it in an array & convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*
Disconnect

Example response
[
  {
     "channel": "/meta/disconnect",
     "clientId": "Un1q31d3nt1f13r"
     "successful": true
  }
]
*/

func (f *FayeServer) disconnect(clientId string) ([]byte, error) {
	// tear down client connection state
	f.removeClientFromServer(clientId)

	resp := FayeResponse{
		Channel:    "/meta/disconnect",
		Successful: true,
		ClientId:   clientId,
	}

	// wrap it in an array & convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*
Subscribe

Example response
[
  {
     "channel": "/meta/subscribe",
     "clientId": "Un1q31d3nt1f13r",
     "subscription": "/foo/**",
     "successful": true,
     "error": ""
   }
]
*/

func (f *FayeServer) subscribe(clientId, subscription string, c chan string) ([]byte, error) {

	// subscribe the client to the given channel
	if len(subscription) == 0 {
		return []byte{}, errors.New("Subscription channel not present")
	}

	f.addClientToSubscription(clientId, subscription, c)

	// if successful send success response
	resp := FayeResponse{
		Channel:      "/meta/subscribe",
		ClientId:     clientId,
		Subscription: subscription,
		Successful:   true,
		Error:        "",
	}

	// TODO: handle failure case

	// wrap it in an array and convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*
Unsubscribe

Example response
[
  {
     "channel": "/meta/unsubscribe",
     "clientId": "Un1q31d3nt1f13r",
     "subscription": "/foo/**",
     "successful": true,
     "error": ""
   }
]
*/

func (f *FayeServer) unsubscribe(clientId, subscription string) ([]byte, error) {
	// TODO: unsubscribe the client from the given channel
	if len(subscription) == 0 {
		return []byte{}, errors.New("Subscription channel not present")
	}

	// remove the client as a subscriber on the channel
	if f.removeClientFromSubscription(clientId, subscription) {
		fmt.Println("Successful unsubscribe")
	} else {
		fmt.Println("Failed to unsubscribe")
	}

	// if successful send success response
	resp := FayeResponse{
		Channel:      "/meta/unsubscribe",
		ClientId:     clientId,
		Subscription: subscription,
		Successful:   true,
		Error:        "",
	}

	// TODO: handle failure case

	// wrap it in an array and convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*
Publish

Example response
[
  {
     "channel": "/some/channel",
     "successful": true,
     "id": "some unique message id"
  }
]

*/
func (f *FayeServer) publish(channel, id string, data interface{}) ([]byte, error) {

	//convert data back to json string
	message := FayeResponse{
		Channel: channel,
		Id:      id,
		Data:    data,
	}

	dataStr, err := json.Marshal([]FayeResponse{message})
	if err != nil {
		fmt.Println("Error parsing message!")
		return []byte{}, errors.New("Invalid Message Data")
	}
	f.publishToChannel(channel, string(dataStr))

	resp := FayeResponse{
		Channel:    channel,
		Successful: true,
		Id:         id,
	}

	return json.Marshal([]FayeResponse{resp})
}

// Helper functions:

/*
	Generate a clientId for use in the communication with the client
*/
func generateClientId() string {
	return uuid.UUID4()
}
<commit_msg>fix groupwait logic<commit_after>/*
	Faye Server

*/
package fayeserver

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/serverhorror/uuid"
	"sync"
)

type FayeServer struct {
	Connections   []Connection
	Subscriptions map[string][]Client
	SubMutex      sync.RWMutex
	Clients       map[string]Client
	ClientMutex   sync.RWMutex
}

/*
Instantiate a new faye server
*/
func NewFayeServer() *FayeServer {
	return &FayeServer{Connections: []Connection{},
		Subscriptions: make(map[string][]Client),
		Clients:       make(map[string]Client)}
}

// general message handling
/*

*/
func (f *FayeServer) publishToChannel(channel, data string) {
	subs, ok := f.Subscriptions[channel]
	if ok {
		f.multiplexWrite(subs, data)
	}
}

/*

*/
func (f *FayeServer) multiplexWrite(subs []Client, data string) {
	var group sync.WaitGroup
	for i := range subs {
		group.Add(1)
		go func(client chan<- string, data string) {
			client <- data
			group.Done()
		}(subs[i].WriteChannel, data)
	}
	group.Wait()
}

func (f *FayeServer) findClientForChannel(c chan string) *Client {
	f.ClientMutex.Lock()
	defer f.ClientMutex.Unlock()

	for _, client := range f.Clients {
		if client.WriteChannel == c {
			fmt.Println("Matched Client: ", client.ClientId)
			return &client
		}
	}
	return nil
}

func (f *FayeServer) DisconnectChannel(c chan string) {
	client := f.findClientForChannel(c)
	if client != nil {
		fmt.Println("Disconnect Client: ", client.ClientId)
		f.removeClientFromServer(client.ClientId)
	}
}

// ========

type FayeMessage struct {
	Channel      string      `json:"channel"`
	ClientId     string      `json:"clientId,omitempty"`
	Subscription string      `json:"subscription,omitempty"`
	Data         interface{} `json:"data,omitempty"`
	Id           string      `json:"id,omitempty"`
}

// Message handling

func (f *FayeServer) HandleMessage(message []byte, c chan string) ([]byte, error) {
	// parse message JSON
	fm := FayeMessage{}
	err := json.Unmarshal(message, &fm)

	if err != nil {
		fmt.Println("Error parsing message json")
	}

	switch fm.Channel {
	case "/meta/handshake":
		fmt.Println("handshake")
		return f.handshake()
	case "/meta/connect":
		fmt.Println("connect")
		return f.connect(fm.ClientId)
	case "/meta/disconnect":
		fmt.Println("disconnect")
		return f.disconnect(fm.ClientId)
	case "/meta/subscribe":
		fmt.Println("subscribe")
		return f.subscribe(fm.ClientId, fm.Subscription, c)
	case "/meta/unsubscribe":
		fmt.Println("subscribe")
		return f.unsubscribe(fm.ClientId, fm.Subscription)
	default:
		fmt.Println("publish")
		fmt.Println("data is: ", fm.Data)
		return f.publish(fm.Channel, fm.Id, fm.Data)
	}

	return []byte{}, errors.New("Invalid Faye Message")
}

/*
FayeResponse
*/

type FayeResponse struct {
	Channel                  string            `json:"channel,omitempty"`
	Successful               bool              `json:"successful,omitempty"`
	Version                  string            `json:"version,omitempty"`
	SupportedConnectionTypes []string          `json:"supportedConnectionTypes,omitempty"`
	ClientId                 string            `json:"clientId,omitempty"`
	Advice                   map[string]string `json:"advice,omitempty"`
	Subscription             string            `json:"subscription,omitempty"`
	Error                    string            `json:"error,omitempty"`
	Id                       string            `json:"id,omitempty"`
	Data                     interface{}       `json:"data,omitempty"`
}

/*

Handshake:

Example response:
{
    "channel": "/meta/handshake",
    "successful": true,
    "version": "1.0",
    "supportedConnectionTypes": [
        "long-polling",
        "cross-origin-long-polling",
        "callback-polling",
        "websocket",
        "eventsource",
        "in-process"
    ],
    "clientId": "1fg1b9s10zm29e0ahpk490mzkqk3",
    "advice": {
        "reconnect": "retry",
        "interval": 0,
        "timeout": 45000
    }
}

Bayeux Handshake response

*/

func (f *FayeServer) handshake() ([]byte, error) {
	// build response
	resp := FayeResponse{
		Channel:                  "/meta/handshake",
		Successful:               true,
		Version:                  "1.0",
		SupportedConnectionTypes: []string{"websocket"},
		ClientId:                 generateClientId(),
		Advice:                   map[string]string{"reconnect": "retry"},
	}

	// wrap it in an array & convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*

Connect:

Example response
[
  {
     "channel": "/meta/connect",
     "successful": true,
     "error": "",
     "clientId": "Un1q31d3nt1f13r",
     "timestamp": "12:00:00 1970",
     "advice": { "reconnect": "retry" }
   }
]
*/

func (f *FayeServer) connect(clientId string) ([]byte, error) {
	// TODO: setup client connection state

	resp := FayeResponse{
		Channel:    "/meta/connect",
		Successful: true,
		Error:      "",
		ClientId:   clientId,
		Advice:     map[string]string{"reconnect": "retry"},
	}

	// wrap it in an array & convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*
Disconnect

Example response
[
  {
     "channel": "/meta/disconnect",
     "clientId": "Un1q31d3nt1f13r"
     "successful": true
  }
]
*/

func (f *FayeServer) disconnect(clientId string) ([]byte, error) {
	// tear down client connection state
	f.removeClientFromServer(clientId)

	resp := FayeResponse{
		Channel:    "/meta/disconnect",
		Successful: true,
		ClientId:   clientId,
	}

	// wrap it in an array & convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*
Subscribe

Example response
[
  {
     "channel": "/meta/subscribe",
     "clientId": "Un1q31d3nt1f13r",
     "subscription": "/foo/**",
     "successful": true,
     "error": ""
   }
]
*/

func (f *FayeServer) subscribe(clientId, subscription string, c chan string) ([]byte, error) {

	// subscribe the client to the given channel
	if len(subscription) == 0 {
		return []byte{}, errors.New("Subscription channel not present")
	}

	f.addClientToSubscription(clientId, subscription, c)

	// if successful send success response
	resp := FayeResponse{
		Channel:      "/meta/subscribe",
		ClientId:     clientId,
		Subscription: subscription,
		Successful:   true,
		Error:        "",
	}

	// TODO: handle failure case

	// wrap it in an array and convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*
Unsubscribe

Example response
[
  {
     "channel": "/meta/unsubscribe",
     "clientId": "Un1q31d3nt1f13r",
     "subscription": "/foo/**",
     "successful": true,
     "error": ""
   }
]
*/

func (f *FayeServer) unsubscribe(clientId, subscription string) ([]byte, error) {
	// TODO: unsubscribe the client from the given channel
	if len(subscription) == 0 {
		return []byte{}, errors.New("Subscription channel not present")
	}

	// remove the client as a subscriber on the channel
	if f.removeClientFromSubscription(clientId, subscription) {
		fmt.Println("Successful unsubscribe")
	} else {
		fmt.Println("Failed to unsubscribe")
	}

	// if successful send success response
	resp := FayeResponse{
		Channel:      "/meta/unsubscribe",
		ClientId:     clientId,
		Subscription: subscription,
		Successful:   true,
		Error:        "",
	}

	// TODO: handle failure case

	// wrap it in an array and convert to json
	return json.Marshal([]FayeResponse{resp})
}

/*
Publish

Example response
[
  {
     "channel": "/some/channel",
     "successful": true,
     "id": "some unique message id"
  }
]

*/
func (f *FayeServer) publish(channel, id string, data interface{}) ([]byte, error) {

	//convert data back to json string
	message := FayeResponse{
		Channel: channel,
		Id:      id,
		Data:    data,
	}

	dataStr, err := json.Marshal([]FayeResponse{message})
	if err != nil {
		fmt.Println("Error parsing message!")
		return []byte{}, errors.New("Invalid Message Data")
	}
	f.publishToChannel(channel, string(dataStr))

	resp := FayeResponse{
		Channel:    channel,
		Successful: true,
		Id:         id,
	}

	return json.Marshal([]FayeResponse{resp})
}

// Helper functions:

/*
	Generate a clientId for use in the communication with the client
*/
func generateClientId() string {
	return uuid.UUID4()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
	"image"
	"image/color"
	"image/png"
	"log"
	"os"
	"os/signal"
	"strconv"
	"time"
)

const SOLDER = 0x01
const TERMINAL = 0x02
const TIMESLIZES = 0x04

// Version number of this tool
const Version = "0.0.2"

// Data is a struct for each network packet
type Data struct {
	toa     int64  // Timestamp of arrival in microseconds
	payload []byte // Copied network packet
}

// configs represents all the configuration data
type configs struct {
	bpP   uint // Bits per Pixel
	ppI   uint // Number of packets per Image
	ts    uint // "Duration" for one Image
	limit uint // Number of network packets to process
	stil  uint // Type of illustration
}

func getBitsFromPacket(packet []byte, byteP, bitP *int, bpP uint) uint8 {
	var c uint8
	for i := 0; i < (int(bpP) / 3); i++ {
		if *byteP >= len(packet) {
			break
		}
		c |= (packet[*byteP] & (1 << uint8(7-*bitP)))
		*bitP += 1
		if *bitP%8 == 0 {
			*bitP = 0
			*byteP += 1
		}
	}
	return c
}

func createPixel(packet []byte, byteP, bitP *int, bpP uint) (c color.Color) {
	var r, g, b uint8

	if bpP == 1 {
		if (packet[*byteP] & (1 << uint8(7-*bitP))) == 0 {
			c = color.NRGBA{R: 0,
				G: 0,
				B: 0,
				A: 255}
		} else {
			c = color.NRGBA{R: 255,
				G: 255,
				B: 255,
				A: 255}
		}
		*bitP += 1
		if *bitP%8 == 0 {
			*bitP = 0
			*byteP += 1
		}
	} else {
		r = getBitsFromPacket(packet, byteP, bitP, bpP)
		g = getBitsFromPacket(packet, byteP, bitP, bpP)
		b = getBitsFromPacket(packet, byteP, bitP, bpP)

		c = color.NRGBA{R: r,
			G: g,
			B: b,
			A: 255}
	}
	return
}

func createTerminalVisualization(data []Data, bitsPerPixel uint) {
	var bitPos int
	var bytePos int
	var packetLen int

	for i := range data {
		packetLen = len(data[i].payload)
		bitPos = 0
		bytePos = 0
		for {
			c := createPixel(data[i].payload, &bytePos, &bitPos, bitsPerPixel)
			r, g, b, _ := c.RGBA()
			fmt.Printf("\x1B[0m\x1B[38;2;%d;%d;%dm\u2588", uint8(r), uint8(g), uint8(b))
			if bytePos >= packetLen {
				break
			}
		}
		fmt.Printf("\x1B[m\n")

	}

}
func createTimeVisualization(data []Data, xMax int, prefix string, ts uint, bitsPerPixel uint) {
	var xPos int
	var bitPos int
	var bytePos int
	var packetLen int
	var firstPkg time.Time

	img := image.NewNRGBA(image.Rect(0, 0, (xMax*8)/int(bitsPerPixel)+1, int(ts)))

	for pkg := range data {
		if firstPkg.IsZero() {
			firstPkg = time.Unix(0, data[pkg].toa*int64(time.Microsecond))
		}
		packetLen = len(data[pkg].payload)
		xPos = 0
		bitPos = 0
		bytePos = 0
		for {
			c := createPixel(data[pkg].payload, &bytePos, &bitPos, bitsPerPixel)
			img.Set(xPos, int(data[pkg].toa%int64(ts)), c)
			xPos++
			if bytePos >= packetLen {
				break
			}
		}
	}

	filename := prefix
	filename += "-"
	filename += firstPkg.Format(time.RFC3339Nano)
	filename += ".png"
	f, err := os.Create(filename)
	if err != nil {
		log.Fatal(err)
	}

	if err := png.Encode(f, img); err != nil {
		f.Close()
		log.Fatal(err)
	}

	if err := f.Close(); err != nil {
		log.Fatal(err)
	}

	return
}

func createFixedVisualization(data []Data, xMax int, prefix string, num int, bitsPerPixel uint) {
	var xPos int
	var bitPos int
	var bytePos int
	var packetLen int

	img := image.NewNRGBA(image.Rect(0, 0, (xMax*8)/int(bitsPerPixel)+1, len(data)))

	for yPos := range data {
		packetLen = len(data[yPos].payload)
		xPos = 0
		bitPos = 0
		bytePos = 0
		for {
			c := createPixel(data[yPos].payload, &bytePos, &bitPos, bitsPerPixel)
			img.Set(xPos, yPos, c)
			xPos++
			if bytePos >= packetLen {
				break
			}
		}

	}

	filename := prefix
	filename += strconv.Itoa(num)
	filename += ".png"
	f, err := os.Create(filename)
	if err != nil {
		log.Fatal(err)
	}

	if err := png.Encode(f, img); err != nil {
		f.Close()
		log.Fatal(err)
	}

	if err := f.Close(); err != nil {
		log.Fatal(err)
	}

	return
}

func handlePackets(ps *gopacket.PacketSource, num uint, ch chan Data, sig <-chan os.Signal) {
	var count uint
	for packet := range ps.Packets() {
		var k Data

		select {
		case isr := <-sig:
			fmt.Println(isr)
			close(ch)
			return
		default:
		}
		count++
		if num != 0 && count > num {
			break
		}

		elements := packet.Data()
		if len(elements) == 0 {
			continue
		}
		k = Data{toa: (packet.Metadata().CaptureInfo.Timestamp.UnixNano() / int64(time.Microsecond)), payload: packet.Data()}
		ch <- k
	}
	close(ch)
	return
}

func availableInterfaces() {
	devices, err := pcap.FindAllDevs()
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	for _, device := range devices {
		if len(device.Addresses) == 0 {
			continue
		}
		fmt.Println("Interface: ", device.Name)
		for _, address := range device.Addresses {
			fmt.Println("   IP address:  ", address.IP)
			fmt.Println("   Subnet mask: ", address.Netmask)
		}
		fmt.Println("")
	}
}

func initSource(dev, file *string) (handle *pcap.Handle, err error) {
	if len(*dev) > 0 {
		handle, err = pcap.OpenLive(*dev, 4096, true, pcap.BlockForever)
		if err != nil {
			log.Fatal(err)
			os.Exit(1)
		}
	} else if len(*file) > 0 {
		handle, err = pcap.OpenOffline(*file)
		if err != nil {
			log.Fatal(err)
			os.Exit(1)
		}
	} else {
		return nil, fmt.Errorf("Source is missing\n")
	}
	return
}

func checkConfig(cfg configs) error {
	if cfg.bpP%3 != 0 && cfg.bpP != 1 {
		return fmt.Errorf("%d must be divisible by three or should be one", cfg.bpP)
	} else if cfg.bpP > 25 {
		return fmt.Errorf("%d must be smaller than 25", cfg.bpP)
	}

	if cfg.ts > 0 {
		cfg.stil |= TIMESLIZES
	}

	if cfg.stil == (TIMESLIZES & TERMINAL) {
		return fmt.Errorf("-timeslize and -terminal can't be combined")
	} else if cfg.stil == 0 {
		// If way of stil is provided, we will stick to the default one
		cfg.stil |= SOLDER
	}
	return nil
}

func main() {
	var err error
	var handle *pcap.Handle
	var data []Data
	var xMax int
	var index int = 1
	var slicer int64
	var cfg configs
	ch := make(chan Data)
	sig := make(chan os.Signal)
	signal.Notify(sig, os.Interrupt)

	dev := flag.String("interface", "", "Choose an interface for online processing")
	file := flag.String("file", "", "Choose a file for offline processing")
	filter := flag.String("filter", "", "Set a specific filter")
	lst := flag.Bool("list_interfaces", false, "List available interfaces")
	vers := flag.Bool("version", false, "Show version")
	help := flag.Bool("help", false, "Show this help")
	terminalOut := flag.Bool("terminal", false, "Visualize on terminal")
	num := flag.Uint("count", 25, "Number of packets to process.\n\tIf argument is 0 the limit is removed")
	output := flag.String("prefix", "image", "Prefix of the resulting image")
	size := flag.Uint("size", 25, "Number of packets per image")
	bits := flag.Uint("bits", 24, "Number of bits per pixel.\n\tIt must be divisible by three and smaller than 25\n\tTo get black/white results, choose 1 as input.")
	ts := flag.Uint("timeslize", 0, "Number of microseconds per resulting image.\n\tSo each pixel of the height of the resulting image represents one microsecond")
	flag.Parse()

	if flag.NFlag() < 1 {
		fmt.Println(os.Args[0], "[-bits ...] [-count ...] [-file ... | -interface ...] [-filter ...] [-list_interfaces] [-help] [-prefix ...] [-size ... | -timeslize ... | -terminal] [-version]")
		flag.PrintDefaults()
		return
	}

	if *lst {
		availableInterfaces()
		return
	}

	if *vers {
		fmt.Println("Version:", Version)
		return
	}

	if *help {
		fmt.Println(os.Args[0], "[-bits ...] [-count ...] [-file ... | -interface ...] [-filter ...] [-list_interfaces] [-help] [-prefix ...] [-size ... | -timeslize ... | -terminal] [-version]")
		flag.PrintDefaults()
		return
	}

	cfg.bpP = *bits
	cfg.ppI = *size
	cfg.ts = *ts
	cfg.limit = *num
	cfg.stil = 0

	if *terminalOut == true {
		cfg.stil |= TERMINAL
	}
	if *ts != 0 {
		cfg.stil |= TIMESLIZES
	}

	if err = checkConfig(cfg); err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	handle, err = initSource(dev, file)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	defer handle.Close()

	if len(*filter) != 0 {
		err = handle.SetBPFFilter(*filter)
		if err != nil {
			log.Fatal(err, "\tInvalid filter: ", *filter)
			os.Exit(1)
		}
	}

	packetSource := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)
	packetSource.DecodeOptions = gopacket.Lazy

	go handlePackets(packetSource, cfg.limit, ch, sig)

	switch cfg.stil {
	case SOLDER:
		for i, ok := <-ch; ok; i, ok = <-ch {
			data = append(data, i)
			if xMax < len(i.payload) {
				xMax = len(i.payload)
			}
			if len(data) >= int(*size) {
				xMax++
				createFixedVisualization(data, xMax, *output, index, cfg.bpP)
				xMax = 0
				index++
				data = data[:0]
			}
		}
	case TERMINAL:
		for i, ok := <-ch; ok; i, ok = <-ch {
			data = append(data, i)
			createTerminalVisualization(data, cfg.bpP)
			data = data[:0]
		}
	case TIMESLIZES:
		for i, ok := <-ch; ok; i, ok = <-ch {
			if slicer == 0 {
				slicer = i.toa + int64(*ts)
			}
			if slicer < i.toa {
				xMax++
				createTimeVisualization(data, xMax, *output, *ts, cfg.bpP)
				xMax = 0
				data = data[:0]
				slicer = i.toa + int64(*ts)
			}
			data = append(data, i)
			if xMax < len(i.payload) {
				xMax = len(i.payload)
			}
		}
	}

	if len(data) > 0 {
		xMax++
		switch cfg.stil {
		case SOLDER:
			createFixedVisualization(data, xMax, *output, index, cfg.bpP)
		case TERMINAL:
			createTerminalVisualization(data, cfg.bpP)
		case TIMESLIZES:
			createTimeVisualization(data, xMax, *output, *ts, cfg.bpP)
		}
	}

}
<commit_msg>Further refactoring<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
	"image"
	"image/color"
	"image/png"
	"log"
	"os"
	"os/signal"
	"strconv"
	"time"
)

const (
	SOLDER     = 0x01
	TERMINAL   = 0x02
	TIMESLIZES = 0x04
)

// Version number of this tool
const Version = "0.0.2"

// Data is a struct for each network packet
type Data struct {
	toa     int64  // Timestamp of arrival in microseconds
	payload []byte // Copied network packet
}

// configs represents all the configuration data
type configs struct {
	bpP   uint // Bits per Pixel
	ppI   uint // Number of packets per Image
	ts    uint // "Duration" for one Image
	limit uint // Number of network packets to process
	stil  uint // Type of illustration
}

func getBitsFromPacket(packet []byte, byteP, bitP *int, bpP uint) uint8 {
	var c uint8
	for i := 0; i < (int(bpP) / 3); i++ {
		if *byteP >= len(packet) {
			break
		}
		c |= (packet[*byteP] & (1 << uint8(7-*bitP)))
		*bitP += 1
		if *bitP%8 == 0 {
			*bitP = 0
			*byteP += 1
		}
	}
	return c
}

func createPixel(packet []byte, byteP, bitP *int, bpP uint) (c color.Color) {
	var r, g, b uint8

	if bpP == 1 {
		if (packet[*byteP] & (1 << uint8(7-*bitP))) == 0 {
			c = color.NRGBA{R: 0,
				G: 0,
				B: 0,
				A: 255}
		} else {
			c = color.NRGBA{R: 255,
				G: 255,
				B: 255,
				A: 255}
		}
		*bitP += 1
		if *bitP%8 == 0 {
			*bitP = 0
			*byteP += 1
		}
	} else {
		r = getBitsFromPacket(packet, byteP, bitP, bpP)
		g = getBitsFromPacket(packet, byteP, bitP, bpP)
		b = getBitsFromPacket(packet, byteP, bitP, bpP)

		c = color.NRGBA{R: r,
			G: g,
			B: b,
			A: 255}
	}
	return
}

func createTerminalVisualization(data []Data, bitsPerPixel uint) {
	var bitPos int
	var bytePos int
	var packetLen int

	for i := range data {
		packetLen = len(data[i].payload)
		bitPos = 0
		bytePos = 0
		for {
			c := createPixel(data[i].payload, &bytePos, &bitPos, bitsPerPixel)
			r, g, b, _ := c.RGBA()
			fmt.Printf("\x1B[0m\x1B[38;2;%d;%d;%dm\u2588", uint8(r), uint8(g), uint8(b))
			if bytePos >= packetLen {
				break
			}
		}
		fmt.Printf("\x1B[m\n")

	}

}
func createTimeVisualization(data []Data, xMax int, prefix string, ts uint, bitsPerPixel uint) {
	var xPos int
	var bitPos int
	var bytePos int
	var packetLen int
	var firstPkg time.Time

	img := image.NewNRGBA(image.Rect(0, 0, (xMax*8)/int(bitsPerPixel)+1, int(ts)))

	for pkg := range data {
		if firstPkg.IsZero() {
			firstPkg = time.Unix(0, data[pkg].toa*int64(time.Microsecond))
		}
		packetLen = len(data[pkg].payload)
		xPos = 0
		bitPos = 0
		bytePos = 0
		for {
			c := createPixel(data[pkg].payload, &bytePos, &bitPos, bitsPerPixel)
			img.Set(xPos, int(data[pkg].toa%int64(ts)), c)
			xPos++
			if bytePos >= packetLen {
				break
			}
		}
	}

	filename := prefix
	filename += "-"
	filename += firstPkg.Format(time.RFC3339Nano)
	filename += ".png"
	f, err := os.Create(filename)
	if err != nil {
		log.Fatal(err)
	}

	if err := png.Encode(f, img); err != nil {
		f.Close()
		log.Fatal(err)
	}

	if err := f.Close(); err != nil {
		log.Fatal(err)
	}

	return
}

func createFixedVisualization(data []Data, xMax int, prefix string, num int, bitsPerPixel uint) {
	var xPos int
	var bitPos int
	var bytePos int
	var packetLen int

	img := image.NewNRGBA(image.Rect(0, 0, (xMax*8)/int(bitsPerPixel)+1, len(data)))

	for yPos := range data {
		packetLen = len(data[yPos].payload)
		xPos = 0
		bitPos = 0
		bytePos = 0
		for {
			c := createPixel(data[yPos].payload, &bytePos, &bitPos, bitsPerPixel)
			img.Set(xPos, yPos, c)
			xPos++
			if bytePos >= packetLen {
				break
			}
		}

	}

	filename := prefix
	filename += strconv.Itoa(num)
	filename += ".png"
	f, err := os.Create(filename)
	if err != nil {
		log.Fatal(err)
	}

	if err := png.Encode(f, img); err != nil {
		f.Close()
		log.Fatal(err)
	}

	if err := f.Close(); err != nil {
		log.Fatal(err)
	}

	return
}

func handlePackets(ps *gopacket.PacketSource, num uint, ch chan<- Data, done <-chan bool) {
	var count uint
	for packet := range ps.Packets() {
		var k Data
		select {
		case <-done:
			close(ch)
			return
		default:
		}
		count++
		if num != 0 && count > num {
			break
		}

		elements := packet.Data()
		if len(elements) == 0 {
			continue
		}
		k = Data{toa: (packet.Metadata().CaptureInfo.Timestamp.UnixNano() / int64(time.Microsecond)), payload: packet.Data()}
		ch <- k
	}
	close(ch)
	return
}

func availableInterfaces() {
	devices, err := pcap.FindAllDevs()
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	for _, device := range devices {
		if len(device.Addresses) == 0 {
			continue
		}
		fmt.Println("Interface: ", device.Name)
		for _, address := range device.Addresses {
			fmt.Println("   IP address:  ", address.IP)
			fmt.Println("   Subnet mask: ", address.Netmask)
		}
		fmt.Println("")
	}
}

func initSource(dev, file *string) (handle *pcap.Handle, err error) {
	if len(*dev) > 0 {
		handle, err = pcap.OpenLive(*dev, 4096, true, pcap.BlockForever)
		if err != nil {
			log.Fatal(err)
			os.Exit(1)
		}
	} else if len(*file) > 0 {
		handle, err = pcap.OpenOffline(*file)
		if err != nil {
			log.Fatal(err)
			os.Exit(1)
		}
	} else {
		return nil, fmt.Errorf("Source is missing\n")
	}
	return
}

func checkConfig(cfg configs) error {
	if cfg.bpP%3 != 0 && cfg.bpP != 1 {
		return fmt.Errorf("%d must be divisible by three or should be one", cfg.bpP)
	} else if cfg.bpP > 25 {
		return fmt.Errorf("%d must be smaller than 25", cfg.bpP)
	}

	if cfg.ts > 0 {
		cfg.stil |= TIMESLIZES
	}

	if cfg.stil == (TIMESLIZES & TERMINAL) {
		return fmt.Errorf("-timeslize and -terminal can't be combined")
	} else if cfg.stil == 0 {
		// If way of stil is provided, we will stick to the default one
		cfg.stil |= SOLDER
	}
	return nil
}

func main() {
	var err error
	var handle *pcap.Handle
	var data []Data
	var xMax int
	var index int = 1
	osSig := make(chan os.Signal, 1)
	done := make(chan bool, 1)
	signal.Notify(osSig, os.Interrupt)
	var slicer int64
	var cfg configs
	ch := make(chan Data)

	go func() {
		<-osSig     // Blocking till interrupt signal is received
		osSig = nil // ignore further signals
		done <- true
	}()

	dev := flag.String("interface", "", "Choose an interface for online processing")
	file := flag.String("file", "", "Choose a file for offline processing")
	filter := flag.String("filter", "", "Set a specific filter")
	lst := flag.Bool("list_interfaces", false, "List available interfaces")
	vers := flag.Bool("version", false, "Show version")
	help := flag.Bool("help", false, "Show this help")
	terminalOut := flag.Bool("terminal", false, "Visualize on terminal")
	num := flag.Uint("count", 25, "Number of packets to process.\n\tIf argument is 0 the limit is removed")
	output := flag.String("prefix", "image", "Prefix of the resulting image")
	size := flag.Uint("size", 25, "Number of packets per image")
	bits := flag.Uint("bits", 24, "Number of bits per pixel.\n\tIt must be divisible by three and smaller than 25\n\tTo get black/white results, choose 1 as input.")
	ts := flag.Uint("timeslize", 0, "Number of microseconds per resulting image.\n\tSo each pixel of the height of the resulting image represents one microsecond")
	flag.Parse()

	if flag.NFlag() < 1 {
		fmt.Println(os.Args[0], "[-bits ...] [-count ...] [-file ... | -interface ...] [-filter ...] [-list_interfaces] [-help] [-prefix ...] [-size ... | -timeslize ... | -terminal] [-version]")
		flag.PrintDefaults()
		return
	}

	if *lst {
		availableInterfaces()
		return
	}

	if *vers {
		fmt.Println("Version:", Version)
		return
	}

	if *help {
		fmt.Println(os.Args[0], "[-bits ...] [-count ...] [-file ... | -interface ...] [-filter ...] [-list_interfaces] [-help] [-prefix ...] [-size ... | -timeslize ... | -terminal] [-version]")
		flag.PrintDefaults()
		return
	}

	cfg.bpP = *bits
	cfg.ppI = *size
	cfg.ts = *ts
	cfg.limit = *num
	cfg.stil = 0

	if *terminalOut == true {
		cfg.stil |= TERMINAL
	}
	if *ts != 0 {
		cfg.stil |= TIMESLIZES
	}

	if err = checkConfig(cfg); err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	handle, err = initSource(dev, file)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	defer handle.Close()

	if len(*filter) != 0 {
		err = handle.SetBPFFilter(*filter)
		if err != nil {
			log.Fatal(err, "\tInvalid filter: ", *filter)
			os.Exit(1)
		}
	}

	packetSource := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)
	packetSource.DecodeOptions = gopacket.Lazy

	go handlePackets(packetSource, cfg.limit, ch, done)

	switch cfg.stil {
	case SOLDER:
		for i, ok := <-ch; ok; i, ok = <-ch {
			data = append(data, i)
			if xMax < len(i.payload) {
				xMax = len(i.payload)
			}
			if len(data) >= int(*size) {
				xMax++
				createFixedVisualization(data, xMax, *output, index, cfg.bpP)
				xMax = 0
				index++
				data = data[:0]
			}
		}
	case TERMINAL:
		for i, ok := <-ch; ok; i, ok = <-ch {
			data = append(data, i)
			createTerminalVisualization(data, cfg.bpP)
			data = data[:0]
		}
	case TIMESLIZES:
		for i, ok := <-ch; ok; i, ok = <-ch {
			if slicer == 0 {
				slicer = i.toa + int64(*ts)
			}
			if slicer < i.toa {
				xMax++
				createTimeVisualization(data, xMax, *output, *ts, cfg.bpP)
				xMax = 0
				data = data[:0]
				slicer = i.toa + int64(*ts)
			}
			data = append(data, i)
			if xMax < len(i.payload) {
				xMax = len(i.payload)
			}
		}
	}

	if len(data) > 0 {
		xMax++
		switch cfg.stil {
		case SOLDER:
			createFixedVisualization(data, xMax, *output, index, cfg.bpP)
		case TERMINAL:
			createTerminalVisualization(data, cfg.bpP)
		case TIMESLIZES:
			createTimeVisualization(data, xMax, *output, *ts, cfg.bpP)
		}
	}

}
<|endoftext|>


<commit_before>// @TODO
// This is quite dirty. we have so many way to improve it:
//  * Use websocket for live reload instead of JSONP as currently
//  * Generate temp dir, multiple instance
//  * Pure-Go solution to watch file system
//
package main

import (
  "log"
  "github.com/howeyc/fsnotify"
  "flag"
  "fmt"
  "net/http"
  "os"
  "os/signal"
  "github.com/drone/routes"
  "path/filepath"
  "io"
  "io/ioutil"
  // "os/exec"
  "math/rand"
  "time"
  "strings"
  "crypto/md5"
)

const (
  CHANGE_LOG = "goreload.log.v01"
  DEFAULT_PORT = 51203
)

func Whoami(w http.ResponseWriter, r *http.Request) {
  params := r.URL.Query()
  lastName := params.Get(":last")
  firstName := params.Get(":first")
  fmt.Fprintf(w, "Hey, %s %s. Let include <script> tag to do live reload :-)", firstName, lastName)
}

func BroadcastChange(ev *fsnotify.FileEvent) {
  log.Println("event:", ev)
  contents,_ := ioutil.ReadFile(ev.Name)

  h := md5.New()
  io.WriteString(h, string(contents))
  // io.Writ
  hash := h.Sum(nil)
  fmt.Printf("%x", h.Sum(nil))
  log.Print(hash)
  ioutil.WriteFile("/tmp/" + CHANGE_LOG, []byte(fmt.Sprintf("%x", h.Sum(nil))), 0777)
  //rand.Seed(time.Now().Unix())
  // content := fmt.Sprintf("%v", rand.Int())
}

func main() {
  os.Mkdir("tmp", 0777)
  // Open a channel for signal processing
  c := make(chan os.Signal, 1)
  signal.Notify(c, os.Interrupt, os.Kill)
  go func() {
  for sig := range c {
    fmt.Println("Signal received:", sig)
    //Clean up
    fmt.Println("Cleaning up...")
    os.Remove("/tmp/" + CHANGE_LOG)
    fmt.Println("Exiting...")
    os.Exit(0)
    }
  }()

  // Get the command-line arguments
  // fswatch ~/Sites/goreload "goreload -n $RANDOM"
  argNotice := flag.String("n", "none", "The port to run goreload on. Defaults to 8080.")
  argPort := flag.Int("p", DEFAULT_PORT, "The port to run goreload on. Defaults to 8080.")
  if *argPort < 1024 {
    log.Fatal("You should use port > 1024 to not require sudo perm.")
  }
  argPath := flag.String("d", "./", "The path you want goreload watch for the change. Any change inside this directory will trigger reload. Multiple directory separate by comma.")
  flag.Parse()

  fmt.Println(*argNotice)
  if "none" != *argNotice {
    // log.Fatal("We got new chance")
    //contents,_ := ioutil.ReadFile("plikTekstowy.txt")
    rand.Seed(time.Now().Unix())
    content := fmt.Sprintf("%v", rand.Int())
    log.Print(content)
    ioutil.WriteFile("/tmp/" + CHANGE_LOG, []byte(content), 0777)
    os.Exit(0)
  }

  watcher, err := fsnotify.NewWatcher()
  if err != nil {
    log.Fatal(err)
  }

  done := make(chan bool)
  // Process events
  go func() {
    for {
      select {
        case ev := <-watcher.Event:
          BroadcastChange(ev)
        case err := <-watcher.Error:
          log.Println("error:", err)
        }
    }
  }()

  f := func(d string, info os.FileInfo, err error) error {
    if err != nil {
      return err
    }
    if !info.IsDir() || strings.Contains(d, ".git") || strings.Contains(d, ".svn") {
      return nil
    }

    fmt.Println(fmt.Sprintf("Watch: %s", d))
    err = watcher.Watch(d)
    if err != nil {
      log.Println(err)
    }
    return nil
  }

  filepath.Walk(*argPath, f)

  // <-done

    //Ok, so
    //fswatch ~/Sites/goreload "goreload -n $RANDOM"
    // Watch the change
    // go func() {
    //   c1 := make(chan bool)
    //   path, _ := os.Getwd()
    //   watchCmd := exec.Command(path + "/fswatch", "~/Sites/goreload ", "\"" + path + "/goreload -n changed\"")
    //   //watchCmd := exec.Command("ls", "~/Sites/goreload ", "\"" + path + "/goreload -n changed\"")
    //   err := watchCmd.Run()
    //   //out, err := watchCmd.Output()
    //   // log.Println(out)
    //   if err != nil {
    //       log.Fatal(err)
    //       return
    //   }
    //   <- c1
    // }()

  // Give the user some kind of feedback
  fmt.Println(fmt.Sprintf("Starting static file server at %s on port %v", *argPath, *argPort))

  mux := routes.New()
  pwd, _ := os.Getwd()
  mux.Static("/asset", pwd)
  mux.Get("/hello/:last/:first", Whoami)

  Reload := func (w http.ResponseWriter, r *http.Request) {
          params := r.URL.Query()
          lastChange := params.Get(":last_change")
          js := `(function () {
          var reloadInterval = 2000
          setTimeout(function () {
            var script = document.createElement('script')
            script.src = 'http://127.0.0.1:%v/reload/%s'
            document.getElementsByTagName('head')[0].appendChild(script)
          }, reloadInterval)
        })()`
          if lastChange == "" {
            log.Println("First request. Never do reload on this")
          }
          log.Print(fmt.Sprintf("last change on request: %s", lastChange))

          var _changedAt []byte
          changedAt := ""
          _changedAt, err := ioutil.ReadFile("/tmp/" + CHANGE_LOG)
          if err == nil {
            changedAt = string(_changedAt)
          }
          log.Print(fmt.Sprintf("last change on file: %s", changedAt))

          // log.Print(changedAt)

          if ( string(changedAt) == lastChange || lastChange == "") {
            log.Println("First request or nothing has ever changed. Never do reload on this")
            fmt.Fprintf(w, js, *argPort, changedAt)
          } else {
            //Okay, we got to reload the page
            js = `(function () {window.location.reload(true)})()`
            fmt.Fprintf(w, js)
          }
  }

  mux.Get("/reload" , Reload)
  mux.Get("/reload/" , Reload)
  mux.Get("/reload/:last_change", Reload)

  http.Handle("/", mux)
  fmt.Println(fmt.Sprintf("Include this code in your app:\n <script src=\"http://127.0.0.1:%v/reload\"></script>", *argPort))
  http.ListenAndServe(fmt.Sprintf(":%v", *argPort), nil)
  <- done
  watcher.Close()
}<commit_msg>WIP: build command<commit_after>// @TODO
// This is quite dirty. we have so many way to improve it:
//  * Use websocket for live reload instead of JSONP as currently
//  * Generate temp dir, multiple instance
//  * Pure-Go solution to watch file system
//
package main

import (
  "log"
  "github.com/howeyc/fsnotify"
  "flag"
  "fmt"
  "net/http"
  "os"
  "os/signal"
  "github.com/drone/routes"
  "path/filepath"
  "io"
  "io/ioutil"
  // "os/exec"
  "math/rand"
  "time"
  "strings"
  "crypto/md5"
)

const (
  CHANGE_LOG = "goreload.log.v01"
  DEFAULT_PORT = 51203
)

func Whoami(w http.ResponseWriter, r *http.Request) {
  params := r.URL.Query()
  lastName := params.Get(":last")
  firstName := params.Get(":first")
  fmt.Fprintf(w, "Hey, %s %s. Let include <script> tag to do live reload :-)", firstName, lastName)
}

func BroadcastChange(ev *fsnotify.FileEvent) {
  log.Println("event:", ev)
  contents,_ := ioutil.ReadFile(ev.Name)

  h := md5.New()
  io.WriteString(h, string(contents))
  // io.Writ
  hash := h.Sum(nil)
  fmt.Printf("%x", h.Sum(nil))
  log.Print(hash)
  ioutil.WriteFile("/tmp/" + CHANGE_LOG, []byte(fmt.Sprintf("%x", h.Sum(nil))), 0777)

  //So, we check if the file is coffee, less or sass, the build it
  compile(ev.Name)
  //rand.Seed(time.Now().Unix())
  // content := fmt.Sprintf("%v", rand.Int())
}

func compile(file string) {
    // <-done

    //Ok, so
    //fswatch ~/Sites/goreload "goreload -n $RANDOM"
    // Watch the change
    // go func() {
    //   c1 := make(chan bool)
    //   path, _ := os.Getwd()
    //   watchCmd := exec.Command(path + "/fswatch", "~/Sites/goreload ", "\"" + path + "/goreload -n changed\"")
    //   //watchCmd := exec.Command("ls", "~/Sites/goreload ", "\"" + path + "/goreload -n changed\"")
    //   err := watchCmd.Run()
    //   //out, err := watchCmd.Output()
    //   // log.Println(out)
    //   if err != nil {
    //       log.Fatal(err)
    //       return
    //   }
    //   <- c1
    // }()

}

func main() {
  os.Mkdir("tmp", 0777)
  // Open a channel for signal processing
  c := make(chan os.Signal, 1)
  signal.Notify(c, os.Interrupt, os.Kill)
  go func() {
  for sig := range c {
    fmt.Println("Signal received:", sig)
    //Clean up
    fmt.Println("Cleaning up...")
    os.Remove("/tmp/" + CHANGE_LOG)
    fmt.Println("Exiting...")
    os.Exit(0)
    }
  }()

  // Get the command-line arguments
  // fswatch ~/Sites/goreload "goreload -n $RANDOM"
  argNotice := flag.String("n", "none", "The port to run goreload on. Defaults to 8080.")
  argPort := flag.Int("p", DEFAULT_PORT, "The port to run goreload on. Defaults to 8080.")
  if *argPort < 1024 {
    log.Fatal("You should use port > 1024 to not require sudo perm.")
  }
  argPath := flag.String("d", "./", "The path you want goreload watch for the change. Any change inside this directory will trigger reload. Multiple directory separate by comma.")
  flag.Parse()

  fmt.Println(*argNotice)
  if "none" != *argNotice {
    // log.Fatal("We got new chance")
    //contents,_ := ioutil.ReadFile("plikTekstowy.txt")
    rand.Seed(time.Now().Unix())
    content := fmt.Sprintf("%v", rand.Int())
    log.Print(content)
    ioutil.WriteFile("/tmp/" + CHANGE_LOG, []byte(content), 0777)
    os.Exit(0)
  }

  watcher, err := fsnotify.NewWatcher()
  if err != nil {
    log.Fatal(err)
  }

  done := make(chan bool)
  // Process events
  go func() {
    for {
      select {
        case ev := <-watcher.Event:
          BroadcastChange(ev)
        case err := <-watcher.Error:
          log.Println("error:", err)
        }
    }
  }()

  f := func(d string, info os.FileInfo, err error) error {
    if err != nil {
      return err
    }
    if !info.IsDir() || strings.Contains(d, ".git") || strings.Contains(d, ".svn") {
      return nil
    }

    fmt.Println(fmt.Sprintf("Watch: %s", d))
    err = watcher.Watch(d)
    if err != nil {
      log.Println(err)
    }
    return nil
  }

  filepath.Walk(*argPath, f)

  // Give the user some kind of feedback
  fmt.Println(fmt.Sprintf("Starting static file server at %s on port %v", *argPath, *argPort))

  mux := routes.New()
  pwd, _ := os.Getwd()
  mux.Static("/asset", pwd)
  mux.Get("/hello/:last/:first", Whoami)

  Reload := func (w http.ResponseWriter, r *http.Request) {
          params := r.URL.Query()
          lastChange := params.Get(":last_change")
          js := `(function () {
          var reloadInterval = 2000
          setTimeout(function () {
            var script = document.createElement('script')
            script.src = 'http://127.0.0.1:%v/reload/%s'
            document.getElementsByTagName('head')[0].appendChild(script)
          }, reloadInterval)
        })()`
          if lastChange == "" {
            log.Println("First request. Never do reload on this")
          }
          log.Print(fmt.Sprintf("last change on request: %s", lastChange))

          var _changedAt []byte
          changedAt := ""
          _changedAt, err := ioutil.ReadFile("/tmp/" + CHANGE_LOG)
          if err == nil {
            changedAt = string(_changedAt)
          }
          log.Print(fmt.Sprintf("last change on file: %s", changedAt))

          // log.Print(changedAt)

          if ( string(changedAt) == lastChange || lastChange == "") {
            log.Println("First request or nothing has ever changed. Never do reload on this")
            fmt.Fprintf(w, js, *argPort, changedAt)
          } else {
            //Okay, we got to reload the page
            js = `(function () {window.location.reload(true)})()`
            fmt.Fprintf(w, js)
          }
  }

  mux.Get("/reload" , Reload)
  mux.Get("/reload/" , Reload)
  mux.Get("/reload/:last_change", Reload)

  http.Handle("/", mux)
  fmt.Println(fmt.Sprintf("Include this code in your app:\n <script src=\"http://127.0.0.1:%v/reload\"></script>", *argPort))
  http.ListenAndServe(fmt.Sprintf(":%v", *argPort), nil)
  <- done
  watcher.Close()
}<|endoftext|>


<commit_before>package goscrape

import (
	"encoding/hex"
	"time"
)

type Bulk struct {
	Sess   []Session
	Expire time.Time
}

func NewBulk(trackers []string) Bulk {
	size := len(trackers)
	var sessions []Session = make([]Session, size)
	var channels = make([]chan Session, size)

	for i := 0; i < size; i++ {
		channels[i] = make(chan Session)
		go asyncSession(trackers[i], channels[i])
	}

	for i := 0; i < size; i++ {
		sessions[i] = <-channels[i]
	}

	return Bulk{Sess: sessions, Expire: time.Now().Add(1 * time.Minute)}
}

func (bulk *Bulk) ScrapeBulk(btihs []string) []Result {
	// Refresh sessions if it's been over a minute
	if time.Now().After(bulk.Expire) {
		bulk.refreshSessions()
	}

	// Validate the btihs and get size
	var cleanBtihs []string = make([]string, 0)
	for _, btih := range btihs {
		// Take the BTIH and convert it into bytes
		infohash, err := hex.DecodeString(btih)
		// Check errors
		if err == nil {
			if len(infohash) == 20 {
				cleanBtihs = append(cleanBtihs, btih)
			}
		}
	}

	// Make a result variable
	var results []Result = make([]Result, len(cleanBtihs))
	for i := 0; i < len(results); i++ {
		results[i] = Result{cleanBtihs[i], 0, 0, 0}
	}

	// Loop through the sessions
	for _, sess := range bulk.Sess {
		// Perform a multi scrape with all btihs on the single session
		scrape, err := sess.Scrape(cleanBtihs)
		if err == nil {
			// Merge result array into results
			for i, result := range scrape {
				if result.Seeders > results[i].Seeders {
					results[i].Seeders = result.Seeders
				}
				if result.Leechers > results[i].Leechers {
					results[i].Leechers = result.Leechers
				}
				if result.Completed > results[i].Completed {
					results[i].Completed = result.Completed
				}
			}
		}
	}

	return results
}

func asyncSession(url string, output chan Session) {
	output <- NewConn(url)
}

func (bulk *Bulk) refreshSessions() {
	// Get the size of the sessions
	size := len(bulk.Sess)
	// Make channels
	var channels = make([]chan Session, size)

	// Make channels and make new sessions asynchronously
	for i := 0; i < size; i++ {
		channels[i] = make(chan Session)
		go asyncSession(bulk.Sess[i].URL, channels[i])
	}

	// Replace old sessions with new ones
	for i := 0; i < size; i++ {
		bulk.Sess[i] = <-channels[i]
	}

	// Update the expire time.
	bulk.Expire = time.Now().Add(1 * time.Minute)
}
<commit_msg>Add one-off method for scraping something.<commit_after>package goscrape

import (
	"encoding/hex"
	"time"
)

type Bulk struct {
	Sess   []Session
	Expire time.Time
}

func Single(urls []string, btihs []string) []Result {
	bulk := NewBulk(urls)
	return bulk.ScrapeBulk(btihs)
}

func NewBulk(trackers []string) Bulk {
	size := len(trackers)
	var sessions []Session = make([]Session, size)
	var channels = make([]chan Session, size)

	for i := 0; i < size; i++ {
		channels[i] = make(chan Session)
		go asyncSession(trackers[i], channels[i])
	}

	for i := 0; i < size; i++ {
		sessions[i] = <-channels[i]
	}

	return Bulk{Sess: sessions, Expire: time.Now().Add(1 * time.Minute)}
}

func (bulk *Bulk) ScrapeBulk(btihs []string) []Result {
	// Refresh sessions if it's been over a minute
	if time.Now().After(bulk.Expire) {
		bulk.refreshSessions()
	}

	// Validate the btihs and get size
	var cleanBtihs []string = make([]string, 0)
	for _, btih := range btihs {
		// Take the BTIH and convert it into bytes
		infohash, err := hex.DecodeString(btih)
		// Check errors
		if err == nil {
			if len(infohash) == 20 {
				cleanBtihs = append(cleanBtihs, btih)
			}
		}
	}

	// Make a result variable
	var results []Result = make([]Result, len(cleanBtihs))
	for i := 0; i < len(results); i++ {
		results[i] = Result{cleanBtihs[i], 0, 0, 0}
	}

	// Loop through the sessions
	for _, sess := range bulk.Sess {
		// Perform a multi scrape with all btihs on the single session
		scrape, err := sess.Scrape(cleanBtihs)
		if err == nil {
			// Merge result array into results
			for i, result := range scrape {
				if result.Seeders > results[i].Seeders {
					results[i].Seeders = result.Seeders
				}
				if result.Leechers > results[i].Leechers {
					results[i].Leechers = result.Leechers
				}
				if result.Completed > results[i].Completed {
					results[i].Completed = result.Completed
				}
			}
		}
	}

	return results
}

func asyncSession(url string, output chan Session) {
	output <- NewConn(url)
}

func (bulk *Bulk) refreshSessions() {
	// Get the size of the sessions
	size := len(bulk.Sess)
	// Make channels
	var channels = make([]chan Session, size)

	// Make channels and make new sessions asynchronously
	for i := 0; i < size; i++ {
		channels[i] = make(chan Session)
		go asyncSession(bulk.Sess[i].URL, channels[i])
	}

	// Replace old sessions with new ones
	for i := 0; i < size; i++ {
		bulk.Sess[i] = <-channels[i]
	}

	// Update the expire time.
	bulk.Expire = time.Now().Add(1 * time.Minute)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"os"
	"strings"

	"github.com/google/uuid"
)

type peerKind int

const (
	client peerKind = iota
	server
)

type peerInfo struct {
	Kind    peerKind
	Name    string
	ID      string
	Channel chan string
}

const peerIDParamName string = "peer_id"
const toParamName string = "to"

const peerMessageBufferSize int = 100

var peers = make(map[string]peerInfo)

func printReqHandler(res http.ResponseWriter, req *http.Request) {
	reqDump, err := httputil.DumpRequest(req, true)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(string(reqDump))
}

func registerHandler(path string, handlerFunc func(http.ResponseWriter, *http.Request)) {
	if path != "" {
		fmt.Printf("Registering handler for %s", path)
		fmt.Println()
		http.HandleFunc(path, handlerFunc)
	}
}

func setConnectionHeader(header http.Header, close bool) {
	if close {
		header.Set("Connection", "close")
	} else {
		header.Set("Connection", "keep-alive")
	}
}

func setVersionHeader(header http.Header) {
	header.Set("Server", "PeerConnectionTestServer/0.1g")
}

func setNoCacheHeader(header http.Header) {
	header.Set("Cache-Control", "no-cache")
}

func addCorsHeaders(header http.Header) {
	header.Set("Access-Control-Allow-Origin", "*")
	header.Set("Access-Control-Allow-Credentials", "true")
	header.Set("Access-Control-Allow-Methods", strings.Join([]string{"GET", "POST", "OPTIONS"}, ","))
	header.Set("Access-Control-Allow-Headers", strings.Join([]string{"Content-Type", "Content-Length", "Cache-Control", "Connection"}, ","))
	header.Set("Access-Control-Expose-Headers", strings.Join([]string{"Content-Length", "X-Peer-Id"}, ","))
}

func signinHandler(res http.ResponseWriter, req *http.Request) {
	setConnectionHeader(res.Header(), true)
	setNoCacheHeader(res.Header())
	setVersionHeader(res.Header())
	addCorsHeaders(res.Header())

	if req.Method != "GET" {
		http.Error(res, "Bad request", http.StatusBadRequest)
		return
	}
	var name string
	// Parse out peer name
	for k, v := range req.URL.Query() {
		if v[0] == "" {
			name = k
			break
		}
	}

	if name == "" {
		http.Error(res, "No name", http.StatusBadRequest)
		return
	}

	var peerInfo peerInfo
	peerInfo.Name = name
	peerInfo.Channel = make(chan string, peerMessageBufferSize)

	// Determine peer type
	if strings.Index(name, "renderingserver_") == 0 {
		peerInfo.Kind = server
	}

	// Generate id
	uuid, err := uuid.NewRandom()
	if err != nil {
		http.Error(res, err.Error(), http.StatusInternalServerError)
	}

	peerInfo.ID = uuid.String()

	peers[peerInfo.ID] = peerInfo

	peerInfoString := fmt.Sprintf("%s,%s,1", peerInfo.Name, peerInfo.ID)
	peerInfoString += fmt.Sprintln()
	responseString := peerInfoString

	// Return above + current peers (filtered for oppositing type)
	for pID, pInfo := range peers {
		if pID != peerInfo.ID && pInfo.Kind != peerInfo.Kind {
			responseString += fmt.Sprintf("%s,%s,1", pInfo.Name, pInfo.ID)
			responseString += fmt.Sprintln()

			// Also notify these peers that the new one exists
			if len(pInfo.Channel) < cap(pInfo.Channel) {
				pInfo.Channel <- peerInfoString
			} else {
				// TODO: Figure out what to do when peeer message buffer fills up
			}
		}
	}
	res.WriteHeader(http.StatusOK)
	fmt.Fprintf(res, responseString)
	// http.Error(res, "Not implemented "+name+" "+uuid.String(), http.statusadd)
}

func signoutHandler(res http.ResponseWriter, req *http.Request) {
	if req.Method != "GET" {
		http.Error(res, "Bad request", http.StatusBadRequest)
		return
	}
	setConnectionHeader(res.Header(), true)
	setNoCacheHeader(res.Header())
	setVersionHeader(res.Header())
	addCorsHeaders(res.Header())
	var peerID string
	// Parse out peers id
	for k, v := range req.URL.Query() {
		if k == peerIDParamName {
			peerID = v[0]
		}
	}
	_, exists := peers[peerID]
	if !exists {
		http.Error(res, "Unknown peer", http.StatusBadRequest)
		return
	}
	delete(peers, peerID)
	res.WriteHeader(http.StatusOK)
}

func messageHandler(res http.ResponseWriter, req *http.Request) {
	if req.Method != "POST" {
		http.Error(res, "Bad request", http.StatusBadRequest)
		return
	}

	// Parse out from id
	// Parse out to id
	peerID, peerExists := req.URL.Query()[peerIDParamName]
	toID, toExists := req.URL.Query()[toParamName]

	if !peerExists || !toExists {
		http.Error(res, "Missing Peer or To ID", http.StatusBadRequest)
		return
	}

	_, peerInfoExists := peers[peerID[0]]
	to, toInfoExists := peers[toID[0]]

	if !peerInfoExists || !toInfoExists {
		http.Error(res, "Invalid Peer or To ID", http.StatusBadRequest)
		return
	}

	requestData, err := ioutil.ReadAll(req.Body)
	if err != nil {
		http.Error(res, err.Error(), http.StatusInternalServerError)
	}
	requestString := string(requestData)
	defer req.Body.Close()
	// Look up channel for to id
	if len(to.Channel) == cap(to.Channel) {
		http.Error(res, "Invalid Peer or To ID", http.StatusServiceUnavailable)
		return
	}
	to.Channel <- requestString

	// Send message to channel for to id
	res.WriteHeader(http.StatusOK)
}

func waitHandler(res http.ResponseWriter, req *http.Request) {
	setConnectionHeader(res.Header(), true)
	setNoCacheHeader(res.Header())
	setVersionHeader(res.Header())
	addCorsHeaders(res.Header())

	if req.Method != "GET" {
		http.Error(res, "Bad request", http.StatusBadRequest)
		return
	}

	// Parse out peer id
	peerID, peerExists := req.URL.Query()[peerIDParamName]

	if !peerExists {
		http.Error(res, "Missing Peer ID", http.StatusBadRequest)
		return
	}

	peerInfo, peerInfoExists := peers[peerID[0]]

	if !peerInfoExists {
		http.Error(res, "Peer is backed up", http.StatusBadRequest)
		return
	}

	// Look up message channel for peers id
	// Wait for message to reply
	responseString := <-peerInfo.Channel

	res.WriteHeader(http.StatusOK)
	fmt.Fprint(res, responseString)
}

func main() {

	fmt.Println("gosigsrv starting")
	fmt.Println()

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

	fmt.Printf("Will listen on port %s\n\n", port)

	// Register handlers
	registerHandler("/sign_in", signinHandler)
	registerHandler("/sign_out", signoutHandler)
	registerHandler("/message", messageHandler)
	registerHandler("/wait", waitHandler)
	registerHandler("/", printReqHandler)

	// Start listening
	http.ListenAndServe(fmt.Sprintf(":%s", port), nil)
	fmt.Println()
	fmt.Println("gosigsrv exiting")
}
<commit_msg>Use incrmeenting int for id<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"os"
	"strings"

	"sync"
)

type peerKind int

const (
	client peerKind = iota
	server
)

type peerInfo struct {
	Kind    peerKind
	Name    string
	ID      string
	Channel chan string
}

const peerIDParamName string = "peer_id"
const toParamName string = "to"

const peerMessageBufferSize int = 100

var peers = make(map[string]peerInfo)

var peerIDCount uint
var peerMutex sync.Mutex

func printReqHandler(res http.ResponseWriter, req *http.Request) {
	reqDump, err := httputil.DumpRequest(req, true)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(string(reqDump))
}

func registerHandler(path string, handlerFunc func(http.ResponseWriter, *http.Request)) {
	if path != "" {
		fmt.Printf("Registering handler for %s", path)
		fmt.Println()
		http.HandleFunc(path, handlerFunc)
	}
}

func setConnectionHeader(header http.Header, close bool) {
	if close {
		header.Set("Connection", "close")
	} else {
		header.Set("Connection", "keep-alive")
	}
}

func setVersionHeader(header http.Header) {
	header.Set("Server", "PeerConnectionTestServer/0.1g")
}

func setNoCacheHeader(header http.Header) {
	header.Set("Cache-Control", "no-cache")
}

func addCorsHeaders(header http.Header) {
	header.Set("Access-Control-Allow-Origin", "*")
	header.Set("Access-Control-Allow-Credentials", "true")
	header.Set("Access-Control-Allow-Methods", strings.Join([]string{"GET", "POST", "OPTIONS"}, ","))
	header.Set("Access-Control-Allow-Headers", strings.Join([]string{"Content-Type", "Content-Length", "Cache-Control", "Connection"}, ","))
	header.Set("Access-Control-Expose-Headers", strings.Join([]string{"Content-Length", "X-Peer-Id"}, ","))
}

func signinHandler(res http.ResponseWriter, req *http.Request) {
	setConnectionHeader(res.Header(), true)
	setNoCacheHeader(res.Header())
	setVersionHeader(res.Header())
	addCorsHeaders(res.Header())

	if req.Method != "GET" {
		http.Error(res, "Bad request", http.StatusBadRequest)
		return
	}
	var name string
	// Parse out peer name
	for k, v := range req.URL.Query() {
		if v[0] == "" {
			name = k
			break
		}
	}

	if name == "" {
		http.Error(res, "No name", http.StatusBadRequest)
		return
	}

	var peerInfo peerInfo
	peerInfo.Name = name
	peerInfo.Channel = make(chan string, peerMessageBufferSize)

	// Determine peer type
	if strings.Index(name, "renderingserver_") == 0 {
		peerInfo.Kind = server
	}

	// Generate id
	peerMutex.Lock()
	peerIDCount++
	peerInfo.ID = fmt.Sprintf("%d", peerIDCount)
	peerMutex.Unlock()

	peers[peerInfo.ID] = peerInfo

	peerInfoString := fmt.Sprintf("%s,%s,1", peerInfo.Name, peerInfo.ID)
	peerInfoString += fmt.Sprintln()
	responseString := peerInfoString

	// Return above + current peers (filtered for oppositing type)
	for pID, pInfo := range peers {
		if pID != peerInfo.ID && pInfo.Kind != peerInfo.Kind {
			responseString += fmt.Sprintf("%s,%s,1", pInfo.Name, pInfo.ID)
			responseString += fmt.Sprintln()

			// Also notify these peers that the new one exists
			if len(pInfo.Channel) < cap(pInfo.Channel) {
				pInfo.Channel <- peerInfoString
			} else {
				// TODO: Figure out what to do when peeer message buffer fills up
			}
		}
	}
	res.WriteHeader(http.StatusOK)
	fmt.Fprintf(res, responseString)
	// http.Error(res, "Not implemented "+name+" "+uuid.String(), http.statusadd)
}

func signoutHandler(res http.ResponseWriter, req *http.Request) {
	if req.Method != "GET" {
		http.Error(res, "Bad request", http.StatusBadRequest)
		return
	}
	setConnectionHeader(res.Header(), true)
	setNoCacheHeader(res.Header())
	setVersionHeader(res.Header())
	addCorsHeaders(res.Header())
	var peerID string
	// Parse out peers id
	for k, v := range req.URL.Query() {
		if k == peerIDParamName {
			peerID = v[0]
		}
	}
	_, exists := peers[peerID]
	if !exists {
		http.Error(res, "Unknown peer", http.StatusBadRequest)
		return
	}
	delete(peers, peerID)
	res.WriteHeader(http.StatusOK)
}

func messageHandler(res http.ResponseWriter, req *http.Request) {
	if req.Method != "POST" {
		http.Error(res, "Bad request", http.StatusBadRequest)
		return
	}

	// Parse out from id
	// Parse out to id
	peerID, peerExists := req.URL.Query()[peerIDParamName]
	toID, toExists := req.URL.Query()[toParamName]

	if !peerExists || !toExists {
		http.Error(res, "Missing Peer or To ID", http.StatusBadRequest)
		return
	}

	_, peerInfoExists := peers[peerID[0]]
	to, toInfoExists := peers[toID[0]]

	if !peerInfoExists || !toInfoExists {
		http.Error(res, "Invalid Peer or To ID", http.StatusBadRequest)
		return
	}

	requestData, err := ioutil.ReadAll(req.Body)
	if err != nil {
		http.Error(res, err.Error(), http.StatusInternalServerError)
	}
	requestString := string(requestData)
	defer req.Body.Close()
	// Look up channel for to id
	if len(to.Channel) == cap(to.Channel) {
		http.Error(res, "Peer is backed up", http.StatusServiceUnavailable)
		return
	}
	to.Channel <- requestString

	// Send message to channel for to id
	res.WriteHeader(http.StatusOK)
}

func waitHandler(res http.ResponseWriter, req *http.Request) {
	setConnectionHeader(res.Header(), true)
	setNoCacheHeader(res.Header())
	setVersionHeader(res.Header())
	addCorsHeaders(res.Header())

	if req.Method != "GET" {
		http.Error(res, "Bad request", http.StatusBadRequest)
		return
	}

	// Parse out peer id
	peerID, peerExists := req.URL.Query()[peerIDParamName]

	if !peerExists {
		http.Error(res, "Missing Peer ID", http.StatusBadRequest)
		return
	}

	peerInfo, peerInfoExists := peers[peerID[0]]

	if !peerInfoExists {
		http.Error(res, "Unknown peer", http.StatusBadRequest)
		return
	}

	// Look up message channel for peers id
	// Wait for message to reply
	responseString := <-peerInfo.Channel

	res.WriteHeader(http.StatusOK)
	fmt.Fprint(res, responseString)
}

func main() {

	fmt.Println("gosigsrv starting")
	fmt.Println()

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

	fmt.Printf("Will listen on port %s\n\n", port)

	// Register handlers
	registerHandler("/sign_in", signinHandler)
	registerHandler("/sign_out", signoutHandler)
	registerHandler("/message", messageHandler)
	registerHandler("/wait", waitHandler)
	registerHandler("/", printReqHandler)

	// Start listening
	http.ListenAndServe(fmt.Sprintf(":%s", port), nil)
	fmt.Println()
	fmt.Println("gosigsrv exiting")
}
<|endoftext|>


<commit_before><commit_msg>Fix bug with Notifications history<commit_after><|endoftext|>


<commit_before>package main

import (
	"github.com/nsf/termbox-go"
	"os"
)

type DisplayScreen int

const (
	MainScreen = iota
	GameScreen
	StatsScreen
	AboutScreen
)

var curScreen = MainScreen

const colDef = termbox.ColorDefault

func drawCentered(default_fg termbox.Attribute, default_bg termbox.Attribute, template []string) {
	termbox.Clear(colDef, colDef)
	width, height := termbox.Size()
	start_x := (width) / 2
	start_y := (height - len(template)) / 2
	for index_y, line := range template {
		lineLength := len(line)
		for index_x, runeValue := range line {
			displayRune := ' '
			if runeValue != ' ' {
				if runeValue != '#' {
					displayRune = runeValue
				}
			}
			termbox.SetCell(start_x+index_x-lineLength/2, start_y+index_y, displayRune, default_fg, default_bg)
		}
	}
	termbox.Flush()
}

func drawMainScreen(default_fg termbox.Attribute, default_bg termbox.Attribute) {
	template := []string{
		"GoTyping.",
		"",
		"1: Practice",
		"2: Stats",
		"3: About",
	}
	drawCentered(default_fg, default_bg, template)
}

func drawGameScreen(default_fg termbox.Attribute, default_bg termbox.Attribute, curGame Game) {
	template := []string{"INGAME"}
	drawCentered(default_fg, default_bg, template)
}

func drawStatsScreen(default_fg termbox.Attribute, default_bg termbox.Attribute) {
	template := []string{"Stats"}
	drawCentered(default_fg, default_bg, template)
}

func drawAboutScreen(default_fg termbox.Attribute, default_bg termbox.Attribute) {
	template := []string{"About GoTyping"}
	drawCentered(default_fg, default_bg, template)
}

func main() {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()
	termbox.SetInputMode(termbox.InputEsc)

	// load wordList
	args := os.Args[1:]
	wordsFile := "words.txt"
	statsFile := "stats.json"
	if len(args) > 0 {
		wordsFile = args[0]
		if len(args) > 1 {
			statsFile = args[1]
		}
	}

	fgColor := termbox.ColorWhite
	bgColor := termbox.ColorDefault

mainloop:
	for {
		switch curScreen {
		case MainScreen:
			drawMainScreen(fgColor, bgColor)
		case GameScreen:
			curGame := NewGame(wordsFile, statsFile)
			curGame.loadStats(statsFile)

		gameloop:
			for {
				drawGameScreen(fgColor, bgColor, curGame)

				ev := termbox.PollEvent()
				if ev.Key == termbox.KeyEsc {
					curScreen = MainScreen
					drawMainScreen(fgColor, bgColor)
					break gameloop
				}
			}
		case StatsScreen:
			drawStatsScreen(fgColor, bgColor)
		case AboutScreen:
			drawAboutScreen(fgColor, bgColor)
		}

		ev := termbox.PollEvent()
		switch ev.Key {
		case termbox.KeyEsc:
			if curScreen == MainScreen {
				break mainloop
			}
			curScreen = MainScreen
			continue
		}
		switch curScreen {
		case MainScreen:
			switch ev.Ch {
			case '1':
				curScreen = GameScreen
			case '2':
				curScreen = StatsScreen
			case '3':
				curScreen = AboutScreen
			}
		}
	}
}
<commit_msg>Displays words now<commit_after>package main

import (
	"github.com/nsf/termbox-go"
	"os"
	"strconv"
)

type DisplayScreen int

const (
	MainScreen = iota
	GameScreen
	StatsScreen
	AboutScreen
)

var curScreen = MainScreen

const colDef = termbox.ColorDefault
const colErr = termbox.ColorRed

func drawCentered(default_fg termbox.Attribute, default_bg termbox.Attribute, template []string) {
	termbox.Clear(colDef, colDef)
	width, height := termbox.Size()
	start_x := (width) / 2
	start_y := (height - len(template)) / 2
	for index_y, line := range template {
		lineLength := len(line)
		for index_x, runeValue := range line {
			displayRune := ' '
			if runeValue != ' ' {
				displayRune = runeValue
			}
			termbox.SetCell(start_x+index_x-lineLength/2, start_y+index_y, displayRune, default_fg, default_bg)
		}
	}
	termbox.Flush()
}

func drawMainScreen(default_fg termbox.Attribute, default_bg termbox.Attribute) {
	template := []string{
		"GoTyping",
		"",
		"[1] Practice",
		"[2] Stats   ",
		"[3] About   ",
		"",
		"[Esc] to quit",
		"[h] for help",
	}
	drawCentered(default_fg, default_bg, template)
}

func statsString(curGame *Game) string {
	curStats := curGame.curStats

	words := strconv.Itoa(curStats.words)
	errors := strconv.Itoa(curStats.errors)
	wpm := strconv.Itoa(int(curStats.wpm()))

	statsString := "Words: " + words + " | Errors: " + errors + " | WPM: " + wpm + " | [Esc] to quit"

	return statsString
}

func drawGameScreen(default_fg termbox.Attribute, default_bg termbox.Attribute, curGame *Game) {
	termbox.Clear(colDef, colDef)

	width, height := termbox.Size()
	i := 0
	for y := 0; y < height-2; y = y + 2 {
		for x := 0; x < width; x++ {
			fg, bg := default_fg, default_bg
			if i == curGame.curChar {
				termbox.SetCursor(x, y)
			}

			displayRune := curGame.getRune(i)
			i++
			termbox.SetCell(x, y, displayRune, fg, bg)
		}
	}

	for x := 0; x < width; x++ {
		termbox.SetCell(x, height-2, '_', default_fg, default_bg)
	}
	statsString := statsString(curGame)
	for x := 0; x < len(statsString); x++ {
		termbox.SetCell(x, height-1, rune(statsString[x]), termbox.ColorGreen, default_bg)
	}
	termbox.Flush()
}

func drawStatsScreen(default_fg termbox.Attribute, default_bg termbox.Attribute) {
	template := []string{"Stats"}
	drawCentered(default_fg, default_bg, template)
}

func drawAboutScreen(default_fg termbox.Attribute, default_bg termbox.Attribute) {
	template := []string{"About GoTyping"}
	drawCentered(default_fg, default_bg, template)
}

func main() {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()
	termbox.SetInputMode(termbox.InputEsc)

	// load wordList
	args := os.Args[1:]
	wordsFile := "words.txt"
	statsFile := "stats.json"
	if len(args) > 0 {
		wordsFile = args[0]
		if len(args) > 1 {
			statsFile = args[1]
		}
	}

	fgColor := termbox.ColorWhite
	bgColor := termbox.ColorDefault

mainloop:
	for {
		switch curScreen {
		case MainScreen:
			drawMainScreen(fgColor, bgColor)
		case GameScreen:
			curGame := NewGame(wordsFile, statsFile)

		gameloop:
			for {
				drawGameScreen(fgColor, bgColor, curGame)

				ev := termbox.PollEvent()
				if ev.Key == termbox.KeyEsc {
					curScreen = MainScreen
					drawMainScreen(fgColor, bgColor)
					break gameloop
				}
			}
		case StatsScreen:
			drawStatsScreen(fgColor, bgColor)
		case AboutScreen:
			drawAboutScreen(fgColor, bgColor)
		}

		ev := termbox.PollEvent()
		switch ev.Key {
		case termbox.KeyEsc:
			if curScreen == MainScreen {
				break mainloop
			}
			curScreen = MainScreen
			continue
		}
		switch curScreen {
		case MainScreen:
			switch ev.Ch {
			case '1':
				curScreen = GameScreen
			case '2':
				curScreen = StatsScreen
			case '3':
				curScreen = AboutScreen
			}
		}
	}
}
<|endoftext|>


<commit_before>package smux

import (
	"math/rand"
	"testing"
)

func TestAllocGet(t *testing.T) {
	alloc := NewAllocator()
	if alloc.Get(0) != nil {
		t.Fatal(0)
	}
	if len(alloc.Get(1)) != 1 {
		t.Fatal(1)
	}
	if len(alloc.Get(2)) != 2 {
		t.Fatal(2)
	}
	if len(alloc.Get(3)) != 3 || cap(alloc.Get(3)) != 4 {
		t.Fatal(3)
	}
	if len(alloc.Get(4)) != 4 {
		t.Fatal(4)
	}
	if len(alloc.Get(1023)) != 1023 || cap(alloc.Get(1023)) != 1024 {
		t.Fatal(1023)
	}
	if len(alloc.Get(1024)) != 1024 {
		t.Fatal(1024)
	}
	if len(alloc.Get(65536)) != 65536 {
		t.Fatal(65536)
	}
	if alloc.Get(65537) != nil {
		t.Fatal(65537)
	}
}

func TestAllocPut(t *testing.T) {
	alloc := NewAllocator()
	if err := alloc.Put(nil); err == nil {
		t.Fatal("put nil misbehavior")
	}
	if err := alloc.Put(make([]byte, 3, 3)); err == nil {
		t.Fatal("put elem:3 []bytes misbehavior")
	}
	if err := alloc.Put(make([]byte, 4, 4)); err != nil {
		t.Fatal("put elem:4 []bytes misbehavior")
	}
	if err := alloc.Put(make([]byte, 1023, 1024)); err != nil {
		t.Fatal("put elem:1024 []bytes misbehavior")
	}
	if err := alloc.Put(make([]byte, 65536, 65536)); err != nil {
		t.Fatal("put elem:65536 []bytes misbehavior")
	}
	if err := alloc.Put(make([]byte, 65537, 65537)); err == nil {
		t.Fatal("put elem:65537 []bytes misbehavior")
	}
}

func TestAllocPutThenGet(t *testing.T) {
	alloc := NewAllocator()
	data := alloc.Get(4)
	for k := range data {
		data[k] = 99
	}
	alloc.Put(data)

	newData := alloc.Get(4)
	for k := range newData {
		if newData[k] != 99 {
			t.Fatal("cannot fetch written []bytes from pool")
		}
	}
}

func BenchmarkMSB(b *testing.B) {
	for i := 0; i < b.N; i++ {
		msb(rand.Int())
	}
}
<commit_msg>adjust test function relates to https://github.com/xtaci/smux/issues/55<commit_after>package smux

import (
	"math/rand"
	"testing"
)

func TestAllocGet(t *testing.T) {
	alloc := NewAllocator()
	if alloc.Get(0) != nil {
		t.Fatal(0)
	}
	if len(alloc.Get(1)) != 1 {
		t.Fatal(1)
	}
	if len(alloc.Get(2)) != 2 {
		t.Fatal(2)
	}
	if len(alloc.Get(3)) != 3 || cap(alloc.Get(3)) != 4 {
		t.Fatal(3)
	}
	if len(alloc.Get(4)) != 4 {
		t.Fatal(4)
	}
	if len(alloc.Get(1023)) != 1023 || cap(alloc.Get(1023)) != 1024 {
		t.Fatal(1023)
	}
	if len(alloc.Get(1024)) != 1024 {
		t.Fatal(1024)
	}
	if len(alloc.Get(65536)) != 65536 {
		t.Fatal(65536)
	}
	if alloc.Get(65537) != nil {
		t.Fatal(65537)
	}
}

func TestAllocPut(t *testing.T) {
	alloc := NewAllocator()
	if err := alloc.Put(nil); err == nil {
		t.Fatal("put nil misbehavior")
	}
	if err := alloc.Put(make([]byte, 3, 3)); err == nil {
		t.Fatal("put elem:3 []bytes misbehavior")
	}
	if err := alloc.Put(make([]byte, 4, 4)); err != nil {
		t.Fatal("put elem:4 []bytes misbehavior")
	}
	if err := alloc.Put(make([]byte, 1023, 1024)); err != nil {
		t.Fatal("put elem:1024 []bytes misbehavior")
	}
	if err := alloc.Put(make([]byte, 65536, 65536)); err != nil {
		t.Fatal("put elem:65536 []bytes misbehavior")
	}
	if err := alloc.Put(make([]byte, 65537, 65537)); err == nil {
		t.Fatal("put elem:65537 []bytes misbehavior")
	}
}

func TestAllocPutThenGet(t *testing.T) {
	alloc := NewAllocator()
	data := alloc.Get(4)
	alloc.Put(data)
	newData := alloc.Get(4)
	if cap(data) != cap(newData) {
		t.Fatal("different cap while alloc.Get()")
	}
}

func BenchmarkMSB(b *testing.B) {
	for i := 0; i < b.N; i++ {
		msb(rand.Int())
	}
}
<|endoftext|>


<commit_before>package main

// Imports
import (
	"log"
	"flag"
)

// Config through flags
var seedNodes string
func init() {
	flag.StringVar(&seedNodes, "seeds", "", "Seed nodes, comma separated host:port tuples (e.g. 12.34.56.78,23.34.45.56:8080")
	flag.Parse()
}

// Main function of dispenso
func main() {
	log.Println("Starting dispenso")
}<commit_msg>Author note<commit_after>package main
// @author Robin Verlangen

// Imports
import (
	"log"
	"flag"
)

// Config through flags
var seedNodes string
func init() {
	flag.StringVar(&seedNodes, "seeds", "", "Seed nodes, comma separated host:port tuples (e.g. 12.34.56.78,23.34.45.56:8080")
	flag.Parse()
}

// Main function of dispenso
func main() {
	log.Println("Starting dispenso")
}<|endoftext|>


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

package controller_test

import (
	"fmt"
	"os"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	ctl "github.com/IBM/ubiquity-k8s/controller"
	k8sresources "github.com/IBM/ubiquity-k8s/resources"
	"github.com/IBM/ubiquity/fakes"
	"github.com/IBM/ubiquity/resources"
)

var _ = Describe("Controller", func() {

	var (
		fakeClient     *fakes.FakeStorageClient
		controller     *ctl.Controller
		fakeExec       *fakes.FakeExecutor
		ubiquityConfig resources.UbiquityPluginConfig
	)
	BeforeEach(func() {
		fakeExec = new(fakes.FakeExecutor)
		ubiquityConfig = resources.UbiquityPluginConfig{}
		fakeClient = new(fakes.FakeStorageClient)
		controller = ctl.NewControllerWithClient(testLogger, fakeClient, fakeExec)
		os.MkdirAll("/tmp/test/mnt2", 0777)
	})

	Context(".Init", func() {

		It("does not error when init is successful", func() {
			initResponse := controller.Init(ubiquityConfig)
			Expect(initResponse.Status).To(Equal("Success"))
			Expect(initResponse.Message).To(Equal("Plugin init successfully"))
			Expect(initResponse.Device).To(Equal(""))
		})

		//Context(".Attach", func() {
		//
		//	It("fails when attachRequest does not have volumeName", func() {
		//		fakeClient.GetVolumeReturns(resources.Volume{}, fmt.Errorf("GetVolume error"))
		//		attachRequest := map[string]string{"Filesystem": "gpfs1", "Size": "200m", "Fileset": "fs1", "Path": "myPath"}
		//		attachResponse := controller.Attach(attachRequest)
		//		Expect(attachResponse.Status).To(Equal("Failure"))
		//		Expect(fakeClient.GetVolumeCallCount()).To(Equal(0))
		//	})
		//
		//	It("fails when client fails to fetch volume", func() {
		//		fakeClient.GetVolumeReturns(resources.Volume{}, fmt.Errorf("GetVolume error"))
		//		attachRequest := map[string]string{"volumeName": "vol1", "Filesystem": "gpfs1", "Size": "200m", "Fileset": "fs1", "Path": "myPath"}
		//		attachResponse := controller.Attach(attachRequest)
		//		Expect(attachResponse.Status).To(Equal("Failure"))
		//		Expect(attachResponse.Message).To(Equal("Failed checking volume, call create before attach"))
		//		Expect(attachResponse.Device).To(Equal("vol1"))
		//	})
		//
		//	It("Succeeds when volume exists", func() {
		//		fakeClient.GetVolumeReturns(resources.Volume{}, nil)
		//		attachRequest := map[string]string{"volumeName": "vol1", "Filesystem": "gpfs1", "Size": "200m", "Fileset": "fs1", "Path": "myPath"}
		//		attachResponse := controller.Attach(attachRequest)
		//		Expect(attachResponse.Status).To(Equal("Success"))
		//		Expect(attachResponse.Message).To(Equal("Volume already attached"))
		//		Expect(attachResponse.Device).To(Equal("vol1"))
		//		Expect(fakeClient.CreateVolumeCallCount()).To(Equal(0))
		//	})
		//})
		//
		//Context(".Detach", func() {
		//	It("does not error when existing volume name is given", func() {
		//		fakeClient.RemoveVolumeReturns(nil)
		//		detachRequest := resources.FlexVolumeDetachRequest{Name: "vol1"}
		//		detachResponse := controller.Detach(detachRequest)
		//		Expect(detachResponse.Status).To(Equal("Success"))
		//		Expect(detachResponse.Message).To(Equal("Volume detached successfully"))
		//		Expect(detachResponse.Device).To(Equal("vol1"))
		//		Expect(fakeClient.RemoveVolumeCallCount()).To(Equal(1))
		//	})
		//
		//	It("error when client fails to detach volume", func() {
		//		err := fmt.Errorf("error detaching volume")
		//		fakeClient.RemoveVolumeReturns(err)
		//		detachRequest := resources.FlexVolumeDetachRequest{Name: "vol1"}
		//		detachResponse := controller.Detach(detachRequest)
		//		Expect(detachResponse.Status).To(Equal("Failure"))
		//		Expect(detachResponse.Message).To(Equal(fmt.Sprintf("Failed to detach volume %#v", err)))
		//		Expect(detachResponse.Device).To(Equal("vol1"))
		//		Expect(fakeClient.RemoveVolumeCallCount()).To(Equal(1))
		//	})
	})
	Context(".Mount", func() {
		AfterEach(func() {

			err := os.RemoveAll("/tmp/test/mnt1")
			Expect(err).ToNot(HaveOccurred())

		})
		It("does not error when volume exists and is not currently mounted", func() {
			fakeClient.AttachReturns("/tmp/test/mnt1", nil)

			mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp/test/mnt2", MountDevice: "vol1", Opts: map[string]string{}}
			mountResponse := controller.Mount(mountRequest)
			Expect(mountResponse.Message).To(Equal("Volume mounted successfully to /tmp/test/mnt1"))
			Expect(mountResponse.Status).To(Equal("Success"))

			Expect(mountResponse.Device).To(Equal(""))
			Expect(fakeClient.AttachCallCount()).To(Equal(1))
		})

		It("errors when volume exists and client fails to mount it", func() {
			err := fmt.Errorf("failed to mount volume")
			fakeClient.AttachReturns("", err)
			mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "some-mountpath", MountDevice: "vol1", Opts: map[string]string{}}
			mountResponse := controller.Mount(mountRequest)
			Expect(mountResponse.Status).To(Equal("Failure"))
			Expect(mountResponse.Message).To(MatchRegexp(err.Error()))
			Expect(mountResponse.Device).To(Equal(""))
			Expect(fakeClient.AttachCallCount()).To(Equal(1))
		})
	})
	Context(".Unmount", func() {
		var volumes []resources.Volume
		It("succeeds when volume exists and is currently mounted", func() {
			fakeExec.EvalSymlinksReturns("/path/gpfs/fs/mountpoint", nil)
			fakeClient.DetachReturns(nil)
			volume := resources.Volume{Name: "vol1", Mountpoint: "some-mountpoint"}
			volumes = []resources.Volume{volume}
			fakeClient.ListVolumesReturns(volumes, nil)
			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Success"))
			Expect(unmountResponse.Message).To(Equal("Volume unmounted successfully"))
			Expect(unmountResponse.Device).To(Equal(""))
			Expect(fakeClient.DetachCallCount()).To(Equal(1))
			Expect(fakeClient.ListVolumesCallCount()).To(Equal(1))
		})
		It("errors when client fails to get volume related to the mountpoint", func() {
			err := fmt.Errorf("failed to get fileset")
			fakeClient.ListVolumesReturns(volumes, err)
			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)

			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(err.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			Expect(fakeClient.ListVolumesCallCount()).To(Equal(1))
			Expect(fakeClient.DetachCallCount()).To(Equal(0))
		})
		It("errors when volume does not exist", func() {
			volumes = []resources.Volume{}
			fakeClient.ListVolumesReturns(volumes, nil)
			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)

			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp("Volume not found"))
			Expect(unmountResponse.Device).To(Equal(""))
			Expect(fakeClient.ListVolumesCallCount()).To(Equal(1))
			Expect(fakeClient.DetachCallCount()).To(Equal(0))
		})
		It("errors when volume exists and client fails to unmount it", func() {
			err := fmt.Errorf("error detaching the volume")
			volume := resources.Volume{Name: "vol1", Mountpoint: "some-mountpoint"}
			volumes = []resources.Volume{volume}
			fakeClient.ListVolumesReturns(volumes, nil)
			fakeClient.DetachReturns(err)
			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)

			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(err.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			Expect(fakeClient.ListVolumesCallCount()).To(Equal(1))
			Expect(fakeClient.DetachCallCount()).To(Equal(1))

		})
		It("should fail to umount if mountpoint is not slink", func() {
			errMsg := fmt.Errorf("not a link")
			fakeExec.EvalSymlinksReturns("", errMsg)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)

			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
		})
		It("should fail to umount if detach failed", func() {
			errMsg := fmt.Errorf("error")
			realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN")
			fakeExec.EvalSymlinksReturns(realMountPoint, nil)
			fakeClient.DetachReturns(errMsg)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			detachRequest := fakeClient.DetachArgsForCall(0)
			Expect(detachRequest.Name).To(Equal("pvname"))
		})
		It("should fail to umount if detach failed", func() {
			errMsg := fmt.Errorf("error")
			realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN")
			fakeExec.EvalSymlinksReturns(realMountPoint, nil)
			fakeClient.DetachReturns(errMsg)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			detachRequest := fakeClient.DetachArgsForCall(0)
			Expect(detachRequest.Name).To(Equal("pvname"))
		})

		It("should fail to umount if fail to remove the slink", func() {
			errMsg := fmt.Errorf("error")
			realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN")
			fakeExec.EvalSymlinksReturns(realMountPoint, nil)
			fakeClient.DetachReturns(nil)
			fakeExec.RemoveReturns(errMsg)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			detachRequest := fakeClient.DetachArgsForCall(0)
			Expect(detachRequest.Name).To(Equal("pvname"))
			Expect(fakeExec.RemoveCallCount()).To(Equal(1))
		})
		It("should succeed to umount if the scbe umount flow finished ok", func() {
			realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN")
			fakeExec.EvalSymlinksReturns(realMountPoint, nil)
			fakeClient.DetachReturns(nil)
			fakeExec.RemoveReturns(nil)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Success"))
			Expect(unmountResponse.Message).To(Equal("Volume unmounted successfully"))
			Expect(unmountResponse.Device).To(Equal(""))
			detachRequest := fakeClient.DetachArgsForCall(0)
			Expect(detachRequest.Name).To(Equal("pvname"))
			Expect(fakeExec.RemoveCallCount()).To(Equal(1))
		})

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

package controller_test

import (
//	"fmt"
	"os"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	ctl "github.com/IBM/ubiquity-k8s/controller"
//	k8sresources "github.com/IBM/ubiquity-k8s/resources"
	"github.com/IBM/ubiquity/fakes"
	"github.com/IBM/ubiquity/resources"
)

var _ = Describe("Controller", func() {

	var (
		fakeClient     *fakes.FakeStorageClient
		controller     *ctl.Controller
		fakeExec       *fakes.FakeExecutor
		ubiquityConfig resources.UbiquityPluginConfig
	)
	BeforeEach(func() {
		fakeExec = new(fakes.FakeExecutor)
		ubiquityConfig = resources.UbiquityPluginConfig{}
		fakeClient = new(fakes.FakeStorageClient)
		controller = ctl.NewControllerWithClient(testLogger, fakeClient, fakeExec)
		os.MkdirAll("/tmp/test/mnt2", 0777)
	})

	Context(".Init", func() {

		It("does not error when init is successful", func() {
			initResponse := controller.Init(ubiquityConfig)
			Expect(initResponse.Status).To(Equal("Success"))
			Expect(initResponse.Message).To(Equal("Plugin init successfully"))
			Expect(initResponse.Device).To(Equal(""))
		})

		//Context(".Attach", func() {
		//
		//	It("fails when attachRequest does not have volumeName", func() {
		//		fakeClient.GetVolumeReturns(resources.Volume{}, fmt.Errorf("GetVolume error"))
		//		attachRequest := map[string]string{"Filesystem": "gpfs1", "Size": "200m", "Fileset": "fs1", "Path": "myPath"}
		//		attachResponse := controller.Attach(attachRequest)
		//		Expect(attachResponse.Status).To(Equal("Failure"))
		//		Expect(fakeClient.GetVolumeCallCount()).To(Equal(0))
		//	})
		//
		//	It("fails when client fails to fetch volume", func() {
		//		fakeClient.GetVolumeReturns(resources.Volume{}, fmt.Errorf("GetVolume error"))
		//		attachRequest := map[string]string{"volumeName": "vol1", "Filesystem": "gpfs1", "Size": "200m", "Fileset": "fs1", "Path": "myPath"}
		//		attachResponse := controller.Attach(attachRequest)
		//		Expect(attachResponse.Status).To(Equal("Failure"))
		//		Expect(attachResponse.Message).To(Equal("Failed checking volume, call create before attach"))
		//		Expect(attachResponse.Device).To(Equal("vol1"))
		//	})
		//
		//	It("Succeeds when volume exists", func() {
		//		fakeClient.GetVolumeReturns(resources.Volume{}, nil)
		//		attachRequest := map[string]string{"volumeName": "vol1", "Filesystem": "gpfs1", "Size": "200m", "Fileset": "fs1", "Path": "myPath"}
		//		attachResponse := controller.Attach(attachRequest)
		//		Expect(attachResponse.Status).To(Equal("Success"))
		//		Expect(attachResponse.Message).To(Equal("Volume already attached"))
		//		Expect(attachResponse.Device).To(Equal("vol1"))
		//		Expect(fakeClient.CreateVolumeCallCount()).To(Equal(0))
		//	})
		//})
		//
		//Context(".Detach", func() {
		//	It("does not error when existing volume name is given", func() {
		//		fakeClient.RemoveVolumeReturns(nil)
		//		detachRequest := resources.FlexVolumeDetachRequest{Name: "vol1"}
		//		detachResponse := controller.Detach(detachRequest)
		//		Expect(detachResponse.Status).To(Equal("Success"))
		//		Expect(detachResponse.Message).To(Equal("Volume detached successfully"))
		//		Expect(detachResponse.Device).To(Equal("vol1"))
		//		Expect(fakeClient.RemoveVolumeCallCount()).To(Equal(1))
		//	})
		//
		//	It("error when client fails to detach volume", func() {
		//		err := fmt.Errorf("error detaching volume")
		//		fakeClient.RemoveVolumeReturns(err)
		//		detachRequest := resources.FlexVolumeDetachRequest{Name: "vol1"}
		//		detachResponse := controller.Detach(detachRequest)
		//		Expect(detachResponse.Status).To(Equal("Failure"))
		//		Expect(detachResponse.Message).To(Equal(fmt.Sprintf("Failed to detach volume %#v", err)))
		//		Expect(detachResponse.Device).To(Equal("vol1"))
		//		Expect(fakeClient.RemoveVolumeCallCount()).To(Equal(1))
		//	})
	})
	/*
	Context(".Mount", func() {
		AfterEach(func() {

			err := os.RemoveAll("/tmp/test/mnt1")
			Expect(err).ToNot(HaveOccurred())

		})
		It("does not error when volume exists and is not currently mounted", func() {
			fakeClient.AttachReturns("/tmp/test/mnt1", nil)

			mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp/test/mnt2", MountDevice: "vol1", Opts: map[string]string{}}
			mountResponse := controller.Mount(mountRequest)
			Expect(mountResponse.Message).To(Equal("Volume mounted successfully to /tmp/test/mnt1"))
			Expect(mountResponse.Status).To(Equal("Success"))

			Expect(mountResponse.Device).To(Equal(""))
			Expect(fakeClient.AttachCallCount()).To(Equal(1))
		})

		It("errors when volume exists and client fails to mount it", func() {
			err := fmt.Errorf("failed to mount volume")
			fakeClient.AttachReturns("", err)
			mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "some-mountpath", MountDevice: "vol1", Opts: map[string]string{}}
			mountResponse := controller.Mount(mountRequest)
			Expect(mountResponse.Status).To(Equal("Failure"))
			Expect(mountResponse.Message).To(MatchRegexp(err.Error()))
			Expect(mountResponse.Device).To(Equal(""))
			Expect(fakeClient.AttachCallCount()).To(Equal(1))
		})
	})
	Context(".Unmount", func() {
		var volumes []resources.Volume
		It("succeeds when volume exists and is currently mounted", func() {
			fakeExec.EvalSymlinksReturns("/path/gpfs/fs/mountpoint", nil)
			fakeClient.DetachReturns(nil)
			volume := resources.Volume{Name: "vol1", Mountpoint: "some-mountpoint"}
			volumes = []resources.Volume{volume}
			fakeClient.ListVolumesReturns(volumes, nil)
			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Success"))
			Expect(unmountResponse.Message).To(Equal("Volume unmounted successfully"))
			Expect(unmountResponse.Device).To(Equal(""))
			Expect(fakeClient.DetachCallCount()).To(Equal(1))
			Expect(fakeClient.ListVolumesCallCount()).To(Equal(1))
		})
		It("errors when client fails to get volume related to the mountpoint", func() {
			err := fmt.Errorf("failed to get fileset")
			fakeClient.ListVolumesReturns(volumes, err)
			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)

			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(err.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			Expect(fakeClient.ListVolumesCallCount()).To(Equal(1))
			Expect(fakeClient.DetachCallCount()).To(Equal(0))
		})
		It("errors when volume does not exist", func() {
			volumes = []resources.Volume{}
			fakeClient.ListVolumesReturns(volumes, nil)
			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)

			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp("Volume not found"))
			Expect(unmountResponse.Device).To(Equal(""))
			Expect(fakeClient.ListVolumesCallCount()).To(Equal(1))
			Expect(fakeClient.DetachCallCount()).To(Equal(0))
		})
		It("errors when volume exists and client fails to unmount it", func() {
			err := fmt.Errorf("error detaching the volume")
			volume := resources.Volume{Name: "vol1", Mountpoint: "some-mountpoint"}
			volumes = []resources.Volume{volume}
			fakeClient.ListVolumesReturns(volumes, nil)
			fakeClient.DetachReturns(err)
			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)

			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(err.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			Expect(fakeClient.ListVolumesCallCount()).To(Equal(1))
			Expect(fakeClient.DetachCallCount()).To(Equal(1))

		})
		It("should fail to umount if mountpoint is not slink", func() {
			errMsg := fmt.Errorf("not a link")
			fakeExec.EvalSymlinksReturns("", errMsg)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"}
			unmountResponse := controller.Unmount(unmountRequest)

			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
		})
		It("should fail to umount if detach failed", func() {
			errMsg := fmt.Errorf("error")
			realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN")
			fakeExec.EvalSymlinksReturns(realMountPoint, nil)
			fakeClient.DetachReturns(errMsg)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			detachRequest := fakeClient.DetachArgsForCall(0)
			Expect(detachRequest.Name).To(Equal("pvname"))
		})
		It("should fail to umount if detach failed", func() {
			errMsg := fmt.Errorf("error")
			realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN")
			fakeExec.EvalSymlinksReturns(realMountPoint, nil)
			fakeClient.DetachReturns(errMsg)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			detachRequest := fakeClient.DetachArgsForCall(0)
			Expect(detachRequest.Name).To(Equal("pvname"))
		})

		It("should fail to umount if fail to remove the slink", func() {
			errMsg := fmt.Errorf("error")
			realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN")
			fakeExec.EvalSymlinksReturns(realMountPoint, nil)
			fakeClient.DetachReturns(nil)
			fakeExec.RemoveReturns(errMsg)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Failure"))
			Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error()))
			Expect(unmountResponse.Device).To(Equal(""))
			detachRequest := fakeClient.DetachArgsForCall(0)
			Expect(detachRequest.Name).To(Equal("pvname"))
			Expect(fakeExec.RemoveCallCount()).To(Equal(1))
		})
		It("should succeed to umount if the scbe umount flow finished ok", func() {
			realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN")
			fakeExec.EvalSymlinksReturns(realMountPoint, nil)
			fakeClient.DetachReturns(nil)
			fakeExec.RemoveReturns(nil)

			unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"}
			unmountResponse := controller.Unmount(unmountRequest)
			Expect(unmountResponse.Status).To(Equal("Success"))
			Expect(unmountResponse.Message).To(Equal("Volume unmounted successfully"))
			Expect(unmountResponse.Device).To(Equal(""))
			detachRequest := fakeClient.DetachArgsForCall(0)
			Expect(detachRequest.Name).To(Equal("pvname"))
			Expect(fakeExec.RemoveCallCount()).To(Equal(1))
		})
	})
	*/
})
<|endoftext|>