<commit_before>// Package admin desrcibes the admin view containing references to
// various managers and editors
package admin

import (
	"bytes"
	"encoding/json"
	"html/template"
	"net/http"

	"github.com/bosssauce/ponzu/content"
	"github.com/bosssauce/ponzu/system/admin/user"
	"github.com/bosssauce/ponzu/system/db"
)

var startAdminHTML = `<!doctype html>

        <title>{{ .Logo }}</title>

        <link rel="stylesheet" href="/admin/static/dashboard/css/material-icons.css" />
        <link rel="stylesheet" href="/admin/static/dashboard/css/materialize.min.css" />
        <link rel="stylesheet" href="/admin/static/editor/css/materialNote.css" />
        <link rel="stylesheet" href="/admin/static/dashboard/css/admin.css" />

        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">

                {{ .Logo }}

Logout

`

var mainAdminHTML = `

Content

                    {{ range $t, $f := .Types }}

playlist_add{{ $t }}

                    {{ end }}

System

settingsConfiguration

supervisor_accountUsers

            {{ if .Subview}}

                {{ .Subview }}

            {{ end }}`

var endAdminHTML = `

Powered by © Ponzu  |  open-sourced by Boss Sauce Creative

`

type admin struct {
	Logo    string
	Types   map[string]func() interface{}
	Subview template.HTML
}

// Admin ...
func Admin(view []byte) ([]byte, error) {
	cfg, err := db.Config("name")
	if err != nil {
		return nil, err
	}

	if cfg == nil {
		cfg = []byte("")
	}

	a := admin{
		Logo:    string(cfg),
		Types:   content.Types,
		Subview: template.HTML(view),
	}

	buf := &bytes.Buffer{}
	html := startAdminHTML + mainAdminHTML + endAdminHTML
	tmpl := template.Must(template.New("admin").Parse(html))
	err = tmpl.Execute(buf, a)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

var initAdminHTML = `

Welcome!

You need to initialize your system by filling out the form below. All of
    this information can be updated later on, but you will not be able to start
    without first completing this step.

    <form method="post" action="/admin/init" class="row">

Configuration

            <input placeholder="Enter the name of your site (interal use only)" class="validate required" type="text" id="name" name="name"/>
            Site Name

            <input placeholder="Used for acquiring SSL certificate (e.g. www.example.com or  example.com)" class="validate" type="text" id="domain" name="domain"/>
            Domain

Admin Details

            <input placeholder="Your email address e.g. you@example.com" class="validate required" type="email" id="email" name="email"/>
            Email

            <input placeholder="Enter a strong password" class="validate required" type="password" id="password" name="password"/>
            Password

        <button class="btn waves-effect waves-light right">Start</button>
    </form>

`

// Init ...
func Init() ([]byte, error) {
	html := startAdminHTML + initAdminHTML + endAdminHTML

	cfg, err := db.Config("name")
	if err != nil {
		return nil, err
	}

	if cfg == nil {
		cfg = []byte("")
	}

	a := admin{
		Logo: string(cfg),
	}

	buf := &bytes.Buffer{}
	tmpl := template.Must(template.New("init").Parse(html))
	err = tmpl.Execute(buf, a)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

var loginAdminHTML = `

Welcome!

Please log in to the system using your email address and password.

    <form method="post" action="/admin/login" class="row">

            <input placeholder="Enter your email address e.g. you@example.com" class="validate required" type="email" id="email" name="email"/>
            Email

            <input placeholder="Enter your password" class="validate required" type="password" id="password" name="password"/>
            Password

        <button class="btn waves-effect waves-light right">Log in</button>
    </form>

`

// Login ...
func Login() ([]byte, error) {
	html := startAdminHTML + loginAdminHTML + endAdminHTML

	cfg, err := db.Config("name")
	if err != nil {
		return nil, err
	}

	if cfg == nil {
		cfg = []byte("")
	}

	a := admin{
		Logo: string(cfg),
	}

	buf := &bytes.Buffer{}
	tmpl := template.Must(template.New("login").Parse(html))
	err = tmpl.Execute(buf, a)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

// UsersList ...
func UsersList(req *http.Request) ([]byte, error) {
	html := `

        <form class="row" enctype="multipart/form-data" action="/admin/configure/users/edit" method="post">

Edit your account:

                Email Address
                <input type="email" name="email" value="{{ .User.Email }}"/>

To approve changes, enter your password:

                Current Password
                <input type="password" name="password"/>

                New Password: (leave blank if no password change needed)
                <input type="email" name="new_password" type="password"/>

            <button class="btn waves-effect waves-light green right" type="submit">Save</button>
        </form>

        <form class="row" enctype="multipart/form-data" action="/admin/configure/users" method="post">

Add a new user:

                Email Address
                <input type="email" name="email" value=""/>

                Password
                <input type="password" name="password"/>

            <button class="btn waves-effect waves-light green right" type="submit">Add User</button>
        </form>

            {{ range .Users }}

                {{ .Email }}
                <form enctype="multipart/form-data" class="delete-user __ponzu right" action="/admin/configure/users/delete" method="post">
                    Delete
                    <input type="hidden" name="email" value="{{ .Email }}"/>
                    <input type="hidden" name="id" value="{{ .ID }}"/>
                </form>

            {{ end }}

    `
	script := `

    `
	var usr user.User
	var usrs []user.User
	// get current user out to pass as data to execute template
	j, err := db.CurrentUser(req)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(j, &usr)
	if err != nil {
		return nil, err
	}

	// get all users to list
	jj, err := db.UserAll()
	if err != nil {
		return nil, err
	}
	for i := range jj {
		var u user.User
		err = json.Unmarshal(jj[i], &u)
		if err != nil {
			return nil, err
		}
		usrs = append(usrs, u)
	}

	// make buffer to execute html into then pass buffer's bytes to Admin
	buf := &bytes.Buffer{}
	tmpl := template.Must(template.New("users").Parse(html + script))
	data := map[string]interface{}{
		"User":  usr,
		"Users": usrs,
	}

	err = tmpl.Execute(buf, data)
	if err != nil {
		return nil, err
	}

	view, err := Admin(buf.Bytes())
	if err != nil {
		return nil, err
	}

	return view, nil
}

var err400HTML = `

400 Error: Bad Request

Sorry, the request was unable to be completed.

`

// Error400 creates a subview for a 400 error page
func Error400() ([]byte, error) {
	view, err := Admin([]byte(err400HTML))
	if err != nil {
		return nil, err
	}

	return view, nil
}

var err404HTML = `

404 Error: Not Found

Sorry, the page you requested could not be found.

`

// Error404 creates a subview for a 404 error page
func Error404() ([]byte, error) {
	view, err := Admin([]byte(err404HTML))
	if err != nil {
		return nil, err
	}

	return view, nil
}

var err405HTML = `

405 Error: Method Not Allowed

Sorry, the page you requested could not be found.

`

// Error405 creates a subview for a 405 error page
func Error405() ([]byte, error) {
	view, err := Admin([]byte(err405HTML))
	if err != nil {
		return nil, err
	}

	return view, nil
}

var err500HTML = `

500 Error: Internal Service Error

Sorry, something unexpectedly went wrong.

`

// Error500 creates a subview for a 500 error page
func Error500() ([]byte, error) {
	view, err := Admin([]byte(err500HTML))
	if err != nil {
		return nil, err
	}

	return view, nil
}
<commit_msg>adding initial support to edit and add admin users<commit_after>// Package admin desrcibes the admin view containing references to
// various managers and editors
package admin

import (
	"bytes"
	"encoding/json"
	"html/template"
	"net/http"

	"github.com/bosssauce/ponzu/content"
	"github.com/bosssauce/ponzu/system/admin/user"
	"github.com/bosssauce/ponzu/system/db"
)

var startAdminHTML = `<!doctype html>

        <title>{{ .Logo }}</title>

        <link rel="stylesheet" href="/admin/static/dashboard/css/material-icons.css" />
        <link rel="stylesheet" href="/admin/static/dashboard/css/materialize.min.css" />
        <link rel="stylesheet" href="/admin/static/editor/css/materialNote.css" />
        <link rel="stylesheet" href="/admin/static/dashboard/css/admin.css" />

        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">

                {{ .Logo }}

Logout

`

var mainAdminHTML = `

Content

                    {{ range $t, $f := .Types }}

playlist_add{{ $t }}

                    {{ end }}

System

settingsConfiguration

supervisor_accountUsers

            {{ if .Subview}}

                {{ .Subview }}

            {{ end }}`

var endAdminHTML = `

Powered by © Ponzu  |  open-sourced by Boss Sauce Creative

`

type admin struct {
	Logo    string
	Types   map[string]func() interface{}
	Subview template.HTML
}

// Admin ...
func Admin(view []byte) ([]byte, error) {
	cfg, err := db.Config("name")
	if err != nil {
		return nil, err
	}

	if cfg == nil {
		cfg = []byte("")
	}

	a := admin{
		Logo:    string(cfg),
		Types:   content.Types,
		Subview: template.HTML(view),
	}

	buf := &bytes.Buffer{}
	html := startAdminHTML + mainAdminHTML + endAdminHTML
	tmpl := template.Must(template.New("admin").Parse(html))
	err = tmpl.Execute(buf, a)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

var initAdminHTML = `

Welcome!

You need to initialize your system by filling out the form below. All of
    this information can be updated later on, but you will not be able to start
    without first completing this step.

    <form method="post" action="/admin/init" class="row">

Configuration

            <input placeholder="Enter the name of your site (interal use only)" class="validate required" type="text" id="name" name="name"/>
            Site Name

            <input placeholder="Used for acquiring SSL certificate (e.g. www.example.com or  example.com)" class="validate" type="text" id="domain" name="domain"/>
            Domain

Admin Details

            <input placeholder="Your email address e.g. you@example.com" class="validate required" type="email" id="email" name="email"/>
            Email

            <input placeholder="Enter a strong password" class="validate required" type="password" id="password" name="password"/>
            Password

        <button class="btn waves-effect waves-light right">Start</button>
    </form>

`

// Init ...
func Init() ([]byte, error) {
	html := startAdminHTML + initAdminHTML + endAdminHTML

	cfg, err := db.Config("name")
	if err != nil {
		return nil, err
	}

	if cfg == nil {
		cfg = []byte("")
	}

	a := admin{
		Logo: string(cfg),
	}

	buf := &bytes.Buffer{}
	tmpl := template.Must(template.New("init").Parse(html))
	err = tmpl.Execute(buf, a)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

var loginAdminHTML = `

Welcome!

Please log in to the system using your email address and password.

    <form method="post" action="/admin/login" class="row">

            <input placeholder="Enter your email address e.g. you@example.com" class="validate required" type="email" id="email" name="email"/>
            Email

            <input placeholder="Enter your password" class="validate required" type="password" id="password" name="password"/>
            Password

        <button class="btn waves-effect waves-light right">Log in</button>
    </form>

`

// Login ...
func Login() ([]byte, error) {
	html := startAdminHTML + loginAdminHTML + endAdminHTML

	cfg, err := db.Config("name")
	if err != nil {
		return nil, err
	}

	if cfg == nil {
		cfg = []byte("")
	}

	a := admin{
		Logo: string(cfg),
	}

	buf := &bytes.Buffer{}
	tmpl := template.Must(template.New("login").Parse(html))
	err = tmpl.Execute(buf, a)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

// UsersList ...
func UsersList(req *http.Request) ([]byte, error) {
	html := `

        <form class="row" enctype="multipart/form-data" action="/admin/configure/users/edit" method="post">

Edit your account:

                Email Address
                <input type="email" name="email" value="{{ .User.Email }}"/>

To approve changes, enter your password:

                Current Password
                <input type="password" name="password"/>

                New Password: (leave blank if no password change needed)
                <input type="email" name="new_password" type="password"/>

            <button class="btn waves-effect waves-light green right" type="submit">Save</button>
        </form>

        <form class="row" enctype="multipart/form-data" action="/admin/configure/users" method="post">

Add a new user:

                Email Address
                <input type="email" name="email" value=""/>

                Password
                <input type="password" name="password"/>

            <button class="btn waves-effect waves-light green right" type="submit">Add User</button>
        </form>

            {{ range .Users }}

                {{ .Email }}
                <form enctype="multipart/form-data" class="delete-user __ponzu right" action="/admin/configure/users/delete" method="post">
                    Delete
                    <input type="hidden" name="email" value="{{ .Email }}"/>
                    <input type="hidden" name="id" value="{{ .ID }}"/>
                </form>

            {{ end }}

    `
	script := `

    `
	// get current user out to pass as data to execute template
	j, err := db.CurrentUser(req)
	if err != nil {
		return nil, err
	}

	var usr user.User
	err = json.Unmarshal(j, &usr)
	if err != nil {
		return nil, err
	}

	// get all users to list
	jj, err := db.UserAll()
	if err != nil {
		return nil, err
	}
	usrs := make([]user.User, len(jj), len(jj))
	for i := range jj {
		var u user.User
		err = json.Unmarshal(jj[i], &u)
		if err != nil {
			return nil, err
		}
		usrs = append(usrs, u)
	}

	// make buffer to execute html into then pass buffer's bytes to Admin
	buf := &bytes.Buffer{}
	tmpl := template.Must(template.New("users").Parse(html + script))
	data := map[string]interface{}{
		"User":  usr,
		"Users": usrs,
	}

	err = tmpl.Execute(buf, data)
	if err != nil {
		return nil, err
	}

	view, err := Admin(buf.Bytes())
	if err != nil {
		return nil, err
	}

	return view, nil
}

var err400HTML = `

400 Error: Bad Request

Sorry, the request was unable to be completed.

`

// Error400 creates a subview for a 400 error page
func Error400() ([]byte, error) {
	view, err := Admin([]byte(err400HTML))
	if err != nil {
		return nil, err
	}

	return view, nil
}

var err404HTML = `

404 Error: Not Found

Sorry, the page you requested could not be found.

`

// Error404 creates a subview for a 404 error page
func Error404() ([]byte, error) {
	view, err := Admin([]byte(err404HTML))
	if err != nil {
		return nil, err
	}

	return view, nil
}

var err405HTML = `

405 Error: Method Not Allowed

Sorry, the page you requested could not be found.

`

// Error405 creates a subview for a 405 error page
func Error405() ([]byte, error) {
	view, err := Admin([]byte(err405HTML))
	if err != nil {
		return nil, err
	}

	return view, nil
}

var err500HTML = `

500 Error: Internal Service Error

Sorry, something unexpectedly went wrong.

`

// Error500 creates a subview for a 500 error page
func Error500() ([]byte, error) {
	view, err := Admin([]byte(err500HTML))
	if err != nil {
		return nil, err
	}

	return view, nil
}
<|endoftext|>


<commit_before>package sf

import (
	"errors"
	"github.com/go-gl/gl"
	"image"
	"image/png"
	"os"
)

type Texture struct {
	t             gl.Texture
	size          Vector2
	isSmooth      bool   // Status of the smooth filter
	isRepeated    bool   // Is the texture in repeat mode?
	pixelsFlipped bool   // To work around the inconsistency in Y orientation
	cacheId       uint64 // Unique number that identifies the texture to the render target's cache
}

func NewTextureFromFile(fname string) *Texture {
	f, err := os.Open(fname)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	img, err := png.Decode(f)
	if err != nil {
		panic(err)
	}

	t, err := CreateTexture(img)
	if err != nil {
		panic(err)
	}

	return t
}

func (t *Texture) Size() Vector2 {
	return t.size
}

type CoordType uint8

const (
	CoordNormalized CoordType = iota
	CoordPixels
)

// Bind binds the texture
func (t *Texture) Bind(coordType CoordType) {
	// ensureGlContext()

	if t != nil && t.t != 0 {
		// Bind the texture
		t.t.Bind(gl.TEXTURE_2D)

		// Check if we need to define a special texture matrix
		if coordType == CoordPixels || t.pixelsFlipped {
			matrix := [16]float32{1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1}

			// If non-normalized coordinates (= pixels) are requested, we need to
			// setup scale factors that convert the range [0 .. size] to [0 .. 1]
			if coordType == CoordPixels {
				matrix[0] = 1.0 / t.size.X
				matrix[5] = 1.0 / t.size.Y
			}

			// If pixels are flipped we must invert the Y axis
			if t.pixelsFlipped {
				matrix[5] = -matrix[5]
				matrix[13] = 1.0
			}

			// Load the matrix
			gl.MatrixMode(gl.TEXTURE)
			gl.LoadMatrixf(&matrix)

			// Go back to model-view mode (sf::RenderTarget relies on it)
			gl.MatrixMode(gl.MODELVIEW)
		}
	} else {
		// Bind no texture
		gl.Texture(0).Unbind(gl.TEXTURE_2D)

		// Reset the texture matrix
		gl.MatrixMode(gl.TEXTURE)
		gl.LoadIdentity()

		// Go back to model-view mode (sf::RenderTarget relies on it)
		gl.MatrixMode(gl.MODELVIEW)
	}
}

// Utilities ###################################################################

func CreateTexture(img image.Image) (*Texture, error) {
	imgW, imgH := img.Bounds().Dx(), img.Bounds().Dy()
	imgDim := Vector2{float32(imgW), float32(imgH)}

	rgbaImg, ok := img.(*image.NRGBA)
	if !ok {
		return nil, errors.New("texture must be an NRGBA image")
	}

	textureId := gl.GenTexture()
	textureId.Bind(gl.TEXTURE_2D)
	gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)

	gl.TexImage2D(gl.TEXTURE_2D, 0, 4, imgW, imgH, 0, gl.RGBA, gl.UNSIGNED_BYTE, rgbaImg.Pix)

	return &Texture{textureId, imgDim, false, false, false, nextTextureCacheId()}, nil
}

// Unique cache id generator
// Thread-safe unique identifier generator,
// is used for states cache (see RenderTarget)
var nextTexCacheId uint64 = 0

func nextTextureCacheId() uint64 {
	nextTexCacheId++
	return nextTexCacheId
}
<commit_msg>Textures now use GL_NEAREST<commit_after>package sf

import (
	"errors"
	"github.com/go-gl/gl"
	"image"
	"image/png"
	"os"
)

type Texture struct {
	t             gl.Texture
	size          Vector2
	isSmooth      bool   // Status of the smooth filter
	isRepeated    bool   // Is the texture in repeat mode?
	pixelsFlipped bool   // To work around the inconsistency in Y orientation
	cacheId       uint64 // Unique number that identifies the texture to the render target's cache
}

func NewTextureFromFile(fname string) *Texture {
	f, err := os.Open(fname)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	img, err := png.Decode(f)
	if err != nil {
		panic(err)
	}

	t, err := CreateTexture(img)
	if err != nil {
		panic(err)
	}

	return t
}

func (t *Texture) Size() Vector2 {
	return t.size
}

type CoordType uint8

const (
	CoordNormalized CoordType = iota
	CoordPixels
)

// Bind binds the texture
func (t *Texture) Bind(coordType CoordType) {
	// ensureGlContext()

	if t != nil && t.t != 0 {
		// Bind the texture
		t.t.Bind(gl.TEXTURE_2D)

		// Check if we need to define a special texture matrix
		if coordType == CoordPixels || t.pixelsFlipped {
			matrix := [16]float32{1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1}

			// If non-normalized coordinates (= pixels) are requested, we need to
			// setup scale factors that convert the range [0 .. size] to [0 .. 1]
			if coordType == CoordPixels {
				matrix[0] = 1.0 / t.size.X
				matrix[5] = 1.0 / t.size.Y
			}

			// If pixels are flipped we must invert the Y axis
			if t.pixelsFlipped {
				matrix[5] = -matrix[5]
				matrix[13] = 1.0
			}

			// Load the matrix
			gl.MatrixMode(gl.TEXTURE)
			gl.LoadMatrixf(&matrix)

			// Go back to model-view mode (sf::RenderTarget relies on it)
			gl.MatrixMode(gl.MODELVIEW)
		}
	} else {
		// Bind no texture
		gl.Texture(0).Unbind(gl.TEXTURE_2D)

		// Reset the texture matrix
		gl.MatrixMode(gl.TEXTURE)
		gl.LoadIdentity()

		// Go back to model-view mode (sf::RenderTarget relies on it)
		gl.MatrixMode(gl.MODELVIEW)
	}
}

// Utilities ###################################################################

func CreateTexture(img image.Image) (*Texture, error) {
	imgW, imgH := img.Bounds().Dx(), img.Bounds().Dy()
	imgDim := Vector2{float32(imgW), float32(imgH)}

	rgbaImg, ok := img.(*image.NRGBA)
	if !ok {
		return nil, errors.New("texture must be an NRGBA image")
	}

	textureId := gl.GenTexture()
	textureId.Bind(gl.TEXTURE_2D)
	gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
	gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)

	gl.TexImage2D(gl.TEXTURE_2D, 0, 4, imgW, imgH, 0, gl.RGBA, gl.UNSIGNED_BYTE, rgbaImg.Pix)

	return &Texture{textureId, imgDim, false, false, false, nextTextureCacheId()}, nil
}

// Unique cache id generator
// Thread-safe unique identifier generator,
// is used for states cache (see RenderTarget)
var nextTexCacheId uint64 = 0

func nextTextureCacheId() uint64 {
	nextTexCacheId++
	return nextTexCacheId
}
<|endoftext|>


<commit_before>package main

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

func buildinit() {
	e := os.Environ()
	for i := range e {
		if e[i][0:6] == "GOPATH" {
			e[i] = e[i] + ":" + path.Join(config.Uroot, "src/bb/bbsh")
		}
	}
	cmd := exec.Command("go", "build", "-o", "init", ".")
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Dir = path.Join(config.Uroot, "src/bb/bbsh")
	cmd.Env = e

	err := cmd.Run()
	if err != nil {
		log.Fatalf("%v\n", err)
		os.Exit(1)
	}
}
<commit_msg>Make sure CGO_ENABLED is 0<commit_after>package main

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

func buildinit() {
	e := os.Environ()
	for i := range e {
		if e[i][0:6] == "GOPATH" {
			e[i] = e[i] + ":" + path.Join(config.Uroot, "src/bb/bbsh")
		}
	}
	e = append(e, "CGO_ENABLED=0")
	cmd := exec.Command("go", "build", "-o", "init", ".")
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Dir = path.Join(config.Uroot, "src/bb/bbsh")
	cmd.Env = e

	err := cmd.Run()
	if err != nil {
		log.Fatalf("%v\n", err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main
import (
  "encoding/csv"
  "os"
  "strconv"
  "time"
  "fmt"
  "io/ioutil"
  "encoding/json"
)
var ticketId = 1
var gTickets = Tickets{

}
func init(){
  if err := initTickets(); err != nil {
    panic(err)
  }

}
func initTickets() error {
  file, err := os.Open(DATABASE_CACHE_FILE)
  var cached = false
  if err == nil {
    defer file.Close()
    serilized, err := ioutil.ReadAll(file)
    if err = json.Unmarshal(serilized, gTickets); err == nil{
      cached = true
    }
  }
  if !cached{
    if err = loadViolations(); err != nil {
      return fmt.Errorf("Error Loading violations.csv: %v", err)
    }
    if err = loadCitations(); err != nil {
      return fmt.Errorf("Error Loading citations.csv: %v", err)
    }
  }
  return nil
}
func loadViolations() error {
  var err error
  csvfile, err := os.Open("violations.csv")

  if err != nil {
    return fmt.Errorf("Failed to Open violations.csv: %v", err.Error())
  }
  defer csvfile.Close()
  reader := csv.NewReader(csvfile)
  reader.FieldsPerRecord = 10
  rawCSVdata, err := reader.ReadAll()
  if err != nil {
    return err
  }
  gTickets = make(Tickets, len(rawCSVdata))
  for i, record := range(rawCSVdata){
    if i == 0 {
      continue
    }
    var tempTicket = Ticket{}
    tempTicket.Id = ticketId
    ticketId += 1
    if tempTicket.CitationNumber,err  = strconv.Atoi(record[1]); err != nil{
      return fmt.Errorf("Failed to read citation number: %v", err)
    }
    tempTicket.ViolationNumber = record[2]
    switch record[3] {
    case EXPIRED_LICENSE_PLATES_TAGS:
      tempTicket.Violation = EXPIRED_LICENSE_PLATES_TAGS
    case FAILURE_TO_OBEY_ELECTRIC_SIGNAL:
      tempTicket.Violation = FAILURE_TO_OBEY_ELECTRIC_SIGNAL
    case FAILURE_TO_YIELD:
      tempTicket.Violation = FAILURE_TO_YIELD
    case IMPROPER_PASSING:
      tempTicket.Violation = IMPROPER_PASSING
    case NO_BRAKE_LIGHTS:
      tempTicket.Violation = NO_BRAKE_LIGHTS
    case NO_DRIVERS_LICENSE:
      tempTicket.Violation = NO_DRIVERS_LICENSE
    case NO_INSPECTION_STICKER:
      tempTicket.Violation = NO_INSPECTION_STICKER
    case NO_INSURANCE_NO_COMPLIANCE:
      tempTicket.Violation = NO_INSURANCE_NO_COMPLIANCE
    case NO_LICENSE_PLATES:
      tempTicket.Violation = NO_LICENSE_PLATES
    case PARKING_IN_FIRE_ZONE:
      tempTicket.Violation = PARKING_IN_FIRE_ZONE
    case PROHIBITED_UTURN:
      tempTicket.Violation = PROHIBITED_UTURN
    }
    if tempTicket.WarrentStatus, err = strconv.ParseBool(record[4]); err != nil{
      return fmt.Errorf("Failed to read citation number: %v", err)
    }
    tempTicket.WarrentNumber = record[5]
    switch record[6] {
    case CONT_FOR_PAYMENT:
      tempTicket.Status = CONT_FOR_PAYMENT
    case FTA_WARRANT_ISSUED:
      tempTicket.Status = FTA_WARRANT_ISSUED
    case DISMISS_WITHOUT_COSTS:
      tempTicket.Status = DISMISS_WITHOUT_COSTS
    case CLOSED:
      tempTicket.Status = CLOSED
    }
    if tempTicket.StatusDate, err = time.Parse("1/2/2006", record[7]); err != nil{
      return fmt.Errorf("Failed to read status data: %v", err)
    }
    tempTicket.FineAmount = record[8]
    tempTicket.CourtCost = record[9]
    gTickets[i] = tempTicket
  }
  return nil
}
func loadCitations() error {
  var err error
  csvfile, err := os.Open("citations.csv")
  if err != nil {
    return fmt.Errorf("Failed to Open citations.csv: %v", err.Error())
  }
  defer csvfile.Close()
  reader := csv.NewReader(csvfile)
  reader.FieldsPerRecord = 13
  rawCSVdata, err := reader.ReadAll()
  if err != nil {
    return err
  }
  for j, record := range rawCSVdata{
    if j == 0 {
      continue
    }
    var citation_number int
    if citation_number,err  = strconv.Atoi(record[1]); err != nil{
      return fmt.Errorf("Failed to read citation number: %v", err)
    }
    for i, previous_record := range gTickets {
      if previous_record.CitationNumber == citation_number{
        gTickets[i].CitationDate, err = time.Parse("1/2/2006 15:04", record[2])
        gTickets[i].FirstName = record[3]
        gTickets[i].LastName = record[4]
        gTickets[i].DateOfBirth, err = time.Parse("1/2/2006 15:04", record[5])
        gTickets[i].DefendantAddress = record[6]
        gTickets[i].DefendantCity = record[7]
        gTickets[i].DefendantState = record[8]
        gTickets[i].DriverLicenseNumber = record[9]
        gTickets[i].CourtDate, err = time.Parse("1/2/2006 15:04", record[10])
        gTickets[i].CourtLocation = record[11]
        gTickets[i].CourtAddress = record[12]
      }
    }
  }
  return nil
}
<commit_msg>added a reminder<commit_after>package main
import (
  "encoding/csv"
  "os"
  "strconv"
  "time"
  "fmt"
  "io/ioutil"
  "encoding/json"
)
var ticketId = 1
var gTickets = Tickets{

}
func init(){
  if err := initTickets(); err != nil {
    panic(err)
  }

}
func initTickets() error {
  file, err := os.Open(DATABASE_CACHE_FILE)
  var cached = false
  if err == nil {
    defer file.Close()
    serilized, err := ioutil.ReadAll(file)
    if err = json.Unmarshal(serilized, gTickets); err == nil{
      cached = true
    }
  }
  if !cached{
    if err = loadViolations(); err != nil {
      return fmt.Errorf("Error Loading violations.csv: %v", err)
    }
    if err = loadCitations(); err != nil {
      return fmt.Errorf("Error Loading citations.csv: %v", err)
    }
  }
  return nil
}
func loadViolations() error {
  var err error
  csvfile, err := os.Open("violations.csv")

  if err != nil {
    return fmt.Errorf("Failed to Open violations.csv: %v", err.Error())
  }
  defer csvfile.Close()
  reader := csv.NewReader(csvfile)
  reader.FieldsPerRecord = 10
  rawCSVdata, err := reader.ReadAll()
  if err != nil {
    return err
  }
  gTickets = make(Tickets, len(rawCSVdata))
  for i, record := range(rawCSVdata){
    if i == 0 {
      continue
    }
    var tempTicket = Ticket{}
    tempTicket.Id = ticketId
    ticketId += 1
    if tempTicket.CitationNumber,err  = strconv.Atoi(record[1]); err != nil{
      return fmt.Errorf("Failed to read citation number: %v", err)
    }
    tempTicket.ViolationNumber = record[2]
    switch record[3] {
    case EXPIRED_LICENSE_PLATES_TAGS:
      tempTicket.Violation = EXPIRED_LICENSE_PLATES_TAGS
    case FAILURE_TO_OBEY_ELECTRIC_SIGNAL:
      tempTicket.Violation = FAILURE_TO_OBEY_ELECTRIC_SIGNAL
    case FAILURE_TO_YIELD:
      tempTicket.Violation = FAILURE_TO_YIELD
    case IMPROPER_PASSING:
      tempTicket.Violation = IMPROPER_PASSING
    case NO_BRAKE_LIGHTS:
      tempTicket.Violation = NO_BRAKE_LIGHTS
    case NO_DRIVERS_LICENSE:
      tempTicket.Violation = NO_DRIVERS_LICENSE
    case NO_INSPECTION_STICKER:
      tempTicket.Violation = NO_INSPECTION_STICKER
    case NO_INSURANCE_NO_COMPLIANCE:
      tempTicket.Violation = NO_INSURANCE_NO_COMPLIANCE
    case NO_LICENSE_PLATES:
      tempTicket.Violation = NO_LICENSE_PLATES
    case PARKING_IN_FIRE_ZONE:
      tempTicket.Violation = PARKING_IN_FIRE_ZONE
    case PROHIBITED_UTURN:
      tempTicket.Violation = PROHIBITED_UTURN
    }
    if tempTicket.WarrentStatus, err = strconv.ParseBool(record[4]); err != nil{
      return fmt.Errorf("Failed to read citation number: %v", err)
    }
    tempTicket.WarrentNumber = record[5]
    switch record[6] {
    case CONT_FOR_PAYMENT:
      tempTicket.Status = CONT_FOR_PAYMENT
    case FTA_WARRANT_ISSUED:
      tempTicket.Status = FTA_WARRANT_ISSUED
    case DISMISS_WITHOUT_COSTS:
      tempTicket.Status = DISMISS_WITHOUT_COSTS
    case CLOSED:
      tempTicket.Status = CLOSED
    }
    if tempTicket.StatusDate, err = time.Parse("1/2/2006", record[7]); err != nil{
      return fmt.Errorf("Failed to read status data: %v", err)
    }
    tempTicket.FineAmount = record[8]
    tempTicket.CourtCost = record[9]
    gTickets[i] = tempTicket
  }
  return nil
}
func loadCitations() error {
  //TODO: Use a more efficient data structure later
  var err error
  csvfile, err := os.Open("citations.csv")
  if err != nil {
    return fmt.Errorf("Failed to Open citations.csv: %v", err.Error())
  }
  defer csvfile.Close()
  reader := csv.NewReader(csvfile)
  reader.FieldsPerRecord = 13
  rawCSVdata, err := reader.ReadAll()
  if err != nil {
    return err
  }
  for j, record := range rawCSVdata{
    if j == 0 {
      continue
    }
    var citation_number int
    if citation_number,err  = strconv.Atoi(record[1]); err != nil{
      return fmt.Errorf("Failed to read citation number: %v", err)
    }
    for i, previous_record := range gTickets {
      if previous_record.CitationNumber == citation_number{
        gTickets[i].CitationDate, err = time.Parse("1/2/2006 15:04", record[2])
        gTickets[i].FirstName = record[3]
        gTickets[i].LastName = record[4]
        gTickets[i].DateOfBirth, err = time.Parse("1/2/2006 15:04", record[5])
        gTickets[i].DefendantAddress = record[6]
        gTickets[i].DefendantCity = record[7]
        gTickets[i].DefendantState = record[8]
        gTickets[i].DriverLicenseNumber = record[9]
        gTickets[i].CourtDate, err = time.Parse("1/2/2006 15:04", record[10])
        gTickets[i].CourtLocation = record[11]
        gTickets[i].CourtAddress = record[12]
      }
    }
  }
  return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"github.com/go-martini/martini"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
	"net/http"
	"strconv"
	"time"
)

func InitTicketService(m *martini.ClassicMartini) {
	m.Group("/o/ticket", func(r martini.Router) {
		r.Get("/info/:id", func(db *mgo.Database, params martini.Params) string {
			return params["id"]
		})
		r.Group("/list", func(r martini.Router) {
			r.Get("/total_count", RequireLogin(), func(db *mgo.Database) string {
				c := db.C(TicketsC)
				count, _ := c.Find(bson.M{}).Count()
				return strconv.Itoa(count)
			})
			r.Get("/mine/:status", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
				return HandleUserTickets(db, u, p["status"])
			})
			r.Get("/:area/:id/:status", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
				switch p["area"] {
				case "department":
					return HandleDepartmentTickets(db, u, p["id"], p["status"])
					break
				case "user":
					return "unimplemented"
					break
				}
				return ""
			})
		})

		r.Post("/update/:id", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
			return ""
		})
		r.Post("/close/:id", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
			var id string = p["id"]
			var tkt Ticket

			c := db.C(TicketsC)
			err := c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&tkt)
			if err != nil {
				panic(err)
			}

			var allow bool = false

			// Check to see if the user is allowed to close this based on ownership
			if u.Id.Hex() == tkt.Submitter.Hex() {
				allow = true
			}

			// Check to see if the user is allowed to close this based on assignment
			if u.Id.Hex() == tkt.AssignedTo.Hex() {
				allow = true
			}

			// Check to see if the user is allowed to close this based on department
			for i := 0; i < len(u.Department); i++ {
				if u.Department[i].Hex() == tkt.Department.Hex() {
					if u.Roles.DepAdmin || u.Roles.DepCloseTicket {
						allow = true
						break
					}
				}
			}

			// Check to see if the user is allowed to close this based on
			if u.Roles.DomainAdmin {
				allow = true
			}

			var res SimpleResult
			if allow {
				err := c.Update(bson.M{"_id": tkt.Id}, bson.M{"closed": time.Now(), "status": "closed"})
				if err != nil {
					panic(err)
				}
				res.Result = true
			} else {
				res.Result = false
			}

			b, _ := json.Marshal(res)
			return string(b)
		})
		r.Post("/insert", RequireLogin(), func(u User, db *mgo.Database, req *http.Request) string {
			d := json.NewDecoder(req.Body)

			var tkt Ticket

			err := d.Decode(&tkt)
			if err != nil {
				panic(err)
			}

			tkt.Id = bson.NewObjectId()
			tkt.Submitter = u.Id
			tkt.Status = "open"

			tkt.Created = time.Now()
			//tkt.Closed = nil

			c := db.C(TicketsC)
			err = c.Insert(tkt)
			if err != nil {
				panic(err)
			}

			// Move it to json
			out, err := json.Marshal(&tkt)

			if err != nil {
				panic(err)
			}
			return string(out)
		})
	})
}

func HandleDepartmentTickets(db *mgo.Database, u User, t string, s string) string {
	allow := false
	for i := 0; i < len(u.Department); i++ {
		if u.Department[i].Hex() == t {
			allow = true
			break
		}
	}

	if u.Roles.DomainAdmin {
		allow = true
	}

	if allow {
		c := db.C(TicketsC)
		var tickets []Ticket
		if s != "closed" {
			c.Find(bson.M{"department": bson.ObjectIdHex(t), "status": bson.M{"$ne": "closed"}}).All(&tickets)
		} else {
			if s == "all" {
				c.Find(bson.M{"department": bson.ObjectIdHex(t)}).All(&tickets)
			} else {
				c.Find(bson.M{"department": bson.ObjectIdHex(t), "status": "closed"}).All(&tickets)
			}
		}
		b, _ := json.Marshal(&tickets)
		return string(b)
	}
	return "error"
}

func HandleAssignedTickets(db *mgo.Database, t string) string {
	return t
}

func HandleUserTickets(db *mgo.Database, u User, t string) string {
	c := db.C(TicketsC)

	var tkts []Ticket

	if t != "closed" {
		c.Find(bson.M{"submitter": u.Id, "status": bson.M{"$ne": "closed"}}).All(&tkts)

	} else if t == "all" {
		c.Find(bson.M{"submitter": u.Id}).All(&tkts)
	} else if t == "closed" {
		c.Find(bson.M{"submitter": u.Id, "status": "closed"}).All(&tkts)
	}

	j, _ := json.Marshal(&tkts)

	return string(j)
}
<commit_msg>added group for returning counts<commit_after>package main

import (
	"encoding/json"
	"github.com/go-martini/martini"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
	"net/http"
	"strconv"
	"time"
)

func InitTicketService(m *martini.ClassicMartini) {
	m.Group("/o/ticket", func(r martini.Router) {
		r.Get("/info/:id", func(db *mgo.Database, params martini.Params) string {
			return params["id"]
		})
		r.Group("/list", func(r martini.Router) {
			r.Get("/total_count", RequireLogin(), func(db *mgo.Database) string {
				c := db.C(TicketsC)
				count, _ := c.Find(bson.M{}).Count()
				return strconv.Itoa(count)
			})
			r.Get("/mine/:status", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
				return HandleUserTickets(db, u, p["status"])
			})
			r.Get("/:area/:id/:status", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
				switch p["area"] {
				case "department":
					return HandleDepartmentTickets(db, u, p["id"], p["status"])
					break
				case "user":
					return "unimplemented"
					break
				}
				return ""
			})
		})
		r.Group("/count", func(r martini.Router) {
			r.Get("/department/:id/:status", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
				found := false
				for i := 0; i < len(u.Department); i++ {
					if p["id"] == u.Department[i].Hex() {
						found = true
						break
					}
				}
				if !found && !u.Roles.DomainAdmin {
					return "denied"
				}

				c := db.C(TicketsC)
				if p["status"] == "open" {
					count, err := c.Find(bson.M{"department": bson.ObjectIdHex(p["id"]), "status": bson.M{"$ne": "closed"}}).Count()
					if err != nil {
						panic(err)
					}

					return strconv.Itoa(count)
				}
				count, err := c.Find(bson.M{"department": bson.ObjectIdHex(p["id"]), "status": p["status"]}).Count()
				if err != nil {
					panic(err)
				}

				return strconv.Itoa(count)
			})
		})

		r.Post("/update/:id", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
			return ""
		})
		r.Post("/close/:id", RequireLogin(), func(u User, db *mgo.Database, p martini.Params) string {
			var id string = p["id"]
			var tkt Ticket

			c := db.C(TicketsC)
			err := c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&tkt)
			if err != nil {
				panic(err)
			}

			var allow bool = false

			// Check to see if the user is allowed to close this based on ownership
			if u.Id.Hex() == tkt.Submitter.Hex() {
				allow = true
			}

			// Check to see if the user is allowed to close this based on assignment
			if u.Id.Hex() == tkt.AssignedTo.Hex() {
				allow = true
			}

			// Check to see if the user is allowed to close this based on department
			for i := 0; i < len(u.Department); i++ {
				if u.Department[i].Hex() == tkt.Department.Hex() {
					if u.Roles.DepAdmin || u.Roles.DepCloseTicket {
						allow = true
						break
					}
				}
			}

			// Check to see if the user is allowed to close this based on
			if u.Roles.DomainAdmin {
				allow = true
			}

			var res SimpleResult
			if allow {
				err := c.Update(bson.M{"_id": tkt.Id}, bson.M{"closed": time.Now(), "status": "closed"})
				if err != nil {
					panic(err)
				}
				res.Result = true
			} else {
				res.Result = false
			}

			b, _ := json.Marshal(res)
			return string(b)
		})
		r.Post("/insert", RequireLogin(), func(u User, db *mgo.Database, req *http.Request) string {
			d := json.NewDecoder(req.Body)

			var tkt Ticket

			err := d.Decode(&tkt)
			if err != nil {
				panic(err)
			}

			tkt.Id = bson.NewObjectId()
			tkt.Submitter = u.Id
			tkt.Status = "open"

			tkt.Created = time.Now()
			//tkt.Closed = nil

			c := db.C(TicketsC)
			err = c.Insert(tkt)
			if err != nil {
				panic(err)
			}

			// Move it to json
			out, err := json.Marshal(&tkt)

			if err != nil {
				panic(err)
			}
			return string(out)
		})
	})
}

func HandleDepartmentTickets(db *mgo.Database, u User, t string, s string) string {
	allow := false
	for i := 0; i < len(u.Department); i++ {
		if u.Department[i].Hex() == t {
			allow = true
			break
		}
	}

	if u.Roles.DomainAdmin {
		allow = true
	}

	if allow {
		c := db.C(TicketsC)
		var tickets []Ticket
		if s != "closed" {
			c.Find(bson.M{"department": bson.ObjectIdHex(t), "status": bson.M{"$ne": "closed"}}).All(&tickets)
		} else {
			if s == "all" {
				c.Find(bson.M{"department": bson.ObjectIdHex(t)}).All(&tickets)
			} else {
				c.Find(bson.M{"department": bson.ObjectIdHex(t), "status": "closed"}).All(&tickets)
			}
		}
		b, _ := json.Marshal(&tickets)
		return string(b)
	}
	return "error"
}

func HandleAssignedTickets(db *mgo.Database, t string) string {
	return t
}

func HandleUserTickets(db *mgo.Database, u User, t string) string {
	c := db.C(TicketsC)

	var tkts []Ticket

	if t != "closed" {
		c.Find(bson.M{"submitter": u.Id, "status": bson.M{"$ne": "closed"}}).All(&tkts)

	} else if t == "all" {
		c.Find(bson.M{"submitter": u.Id}).All(&tkts)
	} else if t == "closed" {
		c.Find(bson.M{"submitter": u.Id, "status": "closed"}).All(&tkts)
	}

	j, _ := json.Marshal(&tkts)

	return string(j)
}
<|endoftext|>


<commit_before>package main

import (
	"conui"
	"core"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/nsf/termbox-go"
)

func NewSyncCommand() cli.Command {
	return cli.Command{
		Name:  "sync",
		Usage: "Synchronize files to devices",
		Action: func(c *cli.Context) {
			err := checkEnvVariables(c)
			if err != nil {
				panic(fatal{fmt.Sprintf("Could not set environment variables: %s", err)})
			}
			if !c.GlobalBool("no-file-log") {
				lp := cleanPath(c.GlobalString("log"))
				var err error
				GDS_LOG_FD, err = os.Create(lp)
				if err != nil {
					panic(fatal{fmt.Sprintf("Could not create log file: %s", err)})
				}
				log.Out = GDS_LOG_FD
			}
			lvl, err := logrus.ParseLevel(c.GlobalString("log-level"))
			if err != nil {
				panic(fatalShowHelp{fmt.Sprintf("Error parsing log level: %s", err)})
			}
			log.Level = lvl
			syncStart(c)
		},
	}
}

// loadInitialState prepares the applicaton for usage
func loadInitialState(c *cli.Context) *core.Context {
	cPath, err := getConfigFile(c.GlobalString("config"))
	if err != nil {
		panic(fatal{err})
	}
	log.WithFields(logrus.Fields{
		"path": cPath,
	}).Info("Using configuration file")

	c2, err := core.ContextFromPath(cPath)
	if err != nil {
		panic(fatal{fmt.Sprintf("Error loading config: %s", err.Error())})
	}

	c2.Files, err = core.NewFileList(c2)
	if err != nil {
		panic(fatal{fmt.Sprintf("Error retrieving FileList %s", err.Error())})
	}

	c2.Catalog, err = core.NewCatalog(c2)
	if err != nil {
		// Not wrapped in fatal here because NewCatalog returns custom error types
		panic(err)
	}

	return c2
}

func dumpContextToFile(c *cli.Context, c2 *core.Context) {
	cf, err := getContextFile(c.GlobalString("context"))
	if err != nil {
		panic(fatal{fmt.Sprintf("Could not create context JSON output file: %s", err.Error())})
	}
	j, err := json.Marshal(c2)
	if err == nil {
		err = ioutil.WriteFile(cf, j, 0644)
	}
	if err != nil {
		panic(fatal{fmt.Sprintf("Could not marshal JSON to file: %s", err.Error())})
	}
}

// BuildConsole creates the UI widgets First is the main progress guage for the overall progress Widgets are then created for
// each of the devices, but are hidden initially.
func BuildConsole(c *core.Context) {
	visible := c.OutputStreamNum
	for x, y := range c.Devices {
		conui.Body.DevicePanels = append(conui.Body.DevicePanels, conui.NewDevicePanel(y.Name, y.SizeTotal))
		if visible > 0 && len(c.Catalog[y.Name]) > 0 {
			log.Debugln("Making device", x, "visible")
			conui.Body.DevicePanels[x].SetVisible(true)
			if x == 0 {
				conui.Body.DevicePanels[x].SetSelected(true)
			}
			visible--
		}
	}
	conui.Body.ProgressPanel = conui.NewProgressGauge(c.Catalog.TotalSize())
	conui.Body.ProgressPanel.SetVisible(true)
	conui.Layout()
}

func eventListener(c *core.Context) {
	defer cleanupAtExit()
	for {
		select {
		case e := <-conui.Events:
			if e.Type == conui.EventKey && e.Ch == 'j' {
				conui.Body.SelectNext()
			}
			if e.Type == conui.EventKey && e.Ch == 'k' {
				conui.Body.SelectPrevious()
			}
			if e.Type == conui.EventKey && e.Ch == 'd' {
				p := conui.Body.Selected()
				p.SetVisible(false)
			}
			if e.Type == conui.EventKey && e.Ch == 's' {
				p := conui.Body.Selected()
				p.SetVisible(true)
			}
			if e.Type == conui.EventKey && e.Key == conui.KeyEnter {
				p := conui.Body.Selected().Prompt()
				if p != nil {
					p.Action()
				}
			}
			if e.Type == conui.EventKey && e.Ch == 'q' {
				conui.Close()
				c.Exit = true
				break
			}
			if e.Type == conui.EventResize {
				conui.Layout()
				go func() { conui.Redraw <- true }()
			}
		case <-conui.Redraw:
			conui.Render()
		}
	}
}

// deviceMountHandler checks to see if the device is mounted and writable. Meant to be run as a goroutine.
func deviceMountHandler(c *core.Context, deviceIndex int) {
	// Listen on the channel for a mount request
	ns := time.Now()
	log.Debugf("Waiting for receive on SyncDeviceMount[%d]", deviceIndex)
	<-c.SyncDeviceMount[deviceIndex]
	log.Debugf("Receive from SyncDeviceMount[%d] after wait of %s", deviceIndex, time.Since(ns))

	d := &c.Devices[deviceIndex]
	wg := conui.Body.DevicePanelByIndex(deviceIndex)
	wg.SetVisible(true)

	// Used to correctly time the display of the message in the prompt for the device panel.
	pmc := make(chan string, 10)

	checkDevice := func(p *conui.PromptAction, keyEvent bool, mesgChan chan string) (err error) {
		// The actual checking
		err = ensureDeviceIsReady(*d)
		if err != nil {
			log.Errorf("checkDevice error: %s", err)
			switch err.(type) {
			case deviceTestPermissionDeniedError:
				p.Message = "Device is mounted but not writable... " +
					"Please fix write permissions then press Enter to continue."
			case deviceNotFoundByUUIDError:
				if keyEvent {
					pmc <- fmt.Sprintf("Device not found! (UUID=%s)", d.UUID)
				} else {
					pmc <- fmt.Sprintf("Please mount device to %q and press Enter to continue...", d.MountPoint)
				}
			}
			return
		}
		if deviceIndex == 0 {
			wg.SetSelected(true)
		}
		return
	}

	// The prompt that will be displayed in the device panel. Allow the user to press enter on the device panel to force
	// a device check
	prompt := &conui.PromptAction{}
	prompt.Action = func() {
		// With the device selected in the panel, the user has pressed the enter key.
		log.Printf("Action for panel %q!", wg.Border.Label)
		checkDevice(prompt, true, pmc)
	}
	wg.SetPrompt(prompt)

	// Pre-check
	err := checkDevice(prompt, false, pmc)
	if err != nil {
		// Check device automatically periodically until the device is mounted
	loop:
		for {
			// This will make sure the message is visible for a constant amount of time
			select {
			case pmsg := <-pmc:
				prompt.Message = pmsg
				conui.Redraw <- true
			case <-time.After(time.Second * 5):
				err := checkDevice(prompt, false, pmc)
				if err == nil {
					break loop
				}
			}
		}
	}

	// The prompt is not needed anymore
	wg.SetPrompt(nil)
	c.SyncDeviceMount[deviceIndex] <- true
}

func update(c *core.Context) {
	// Main progress panel updater
	go func() {
		for {
			p := <-c.SyncProgress.Report
			prg := conui.Body.ProgressPanel
			prg.SizeWritn = p.SizeWritn
			prg.BytesPerSecond = p.BytesPerSecond
			if c.Exit {
				break
			}
		}
	}()
	// Device panel updaters
	for x := 0; x < len(c.Devices); x++ {
		go deviceMountHandler(c, x)
		c.SyncDeviceMount[x] = make(chan bool)
		go func(index int) {
			dw := conui.Body.DevicePanelByIndex(index)
			for {
				if fp, ok := <-c.SyncProgress.Device[index].Report; ok {
					dw.SizeWritn += fp.DeviceSizeWritn
					dw.BytesPerSecond = fp.DeviceBytesPerSecond
					log.WithFields(logrus.Fields{
						"fp.FileName":           fp.FileName,
						"fp.FilePath":           fp.FilePath,
						"fp.FileSize":           fp.FileSize,
						"fp.FileSizeWritn":      fp.FileSizeWritn,
						"fp.FileTotalSizeWritn": fp.FileTotalSizeWritn,
						"deviceIndex":           index,
					}).Debugln("Sync file progress")
				} else if !ok || c.Exit {
					dw.BytesPerSecondVisible = false
					break
				}
			}
			log.Debugln("DONE REPORTING index:", index)
		}(x)
	}
	go func() {
		for {
			if !termbox.IsInit || c.Exit {
				break
			}
			conui.Redraw <- true
			// Rate limit redrawing
			time.Sleep(time.Second / 3)
		}
	}()
}

func syncStart(c *cli.Context) {
	defer cleanupAtExit()
	log.WithFields(logrus.Fields{
		"version": 0.2,
		"date":    time.Now().Format(time.RFC3339),
	}).Infoln("Ghetto Device Storage")
	c2 := loadInitialState(c)

	conui.Init()
	BuildConsole(c2)
	go eventListener(c2)
	update(c2)

	errChan := make(chan error, 100)

	// Sync the things
	go func() {
		core.Sync(c2, c.GlobalBool("no-dev-context"), errChan)
		log.Info("ALL DONE -- Sync complete!")
		// c2.Exit = true
	}()

	// Give the user time to review the sync in the UI
outer:
	for {
		select {
		case err := <-errChan:
			log.Errorf("Sync error: %s", err)
		case <-time.After(time.Second):
			if c2.Exit {
				break outer
			}
		}
	}

	// Fin
	dumpContextToFile(c, c2)
}
<commit_msg>cmd/sync.go: Only handle needed device mounts<commit_after>package main

import (
	"conui"
	"core"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/nsf/termbox-go"
)

func NewSyncCommand() cli.Command {
	return cli.Command{
		Name:  "sync",
		Usage: "Synchronize files to devices",
		Action: func(c *cli.Context) {
			err := checkEnvVariables(c)
			if err != nil {
				panic(fatal{fmt.Sprintf("Could not set environment variables: %s", err)})
			}
			if !c.GlobalBool("no-file-log") {
				lp := cleanPath(c.GlobalString("log"))
				var err error
				GDS_LOG_FD, err = os.Create(lp)
				if err != nil {
					panic(fatal{fmt.Sprintf("Could not create log file: %s", err)})
				}
				log.Out = GDS_LOG_FD
			}
			lvl, err := logrus.ParseLevel(c.GlobalString("log-level"))
			if err != nil {
				panic(fatalShowHelp{fmt.Sprintf("Error parsing log level: %s", err)})
			}
			log.Level = lvl
			syncStart(c)
		},
	}
}

// loadInitialState prepares the applicaton for usage
func loadInitialState(c *cli.Context) *core.Context {
	cPath, err := getConfigFile(c.GlobalString("config"))
	if err != nil {
		panic(fatal{err})
	}
	log.WithFields(logrus.Fields{
		"path": cPath,
	}).Info("Using configuration file")

	c2, err := core.ContextFromPath(cPath)
	if err != nil {
		panic(fatal{fmt.Sprintf("Error loading config: %s", err.Error())})
	}

	c2.Files, err = core.NewFileList(c2)
	if err != nil {
		panic(fatal{fmt.Sprintf("Error retrieving FileList %s", err.Error())})
	}

	c2.Catalog, err = core.NewCatalog(c2)
	if err != nil {
		// Not wrapped in fatal here because NewCatalog returns custom error types
		panic(err)
	}

	return c2
}

func dumpContextToFile(c *cli.Context, c2 *core.Context) {
	cf, err := getContextFile(c.GlobalString("context"))
	if err != nil {
		panic(fatal{fmt.Sprintf("Could not create context JSON output file: %s", err.Error())})
	}
	j, err := json.Marshal(c2)
	if err == nil {
		err = ioutil.WriteFile(cf, j, 0644)
	}
	if err != nil {
		panic(fatal{fmt.Sprintf("Could not marshal JSON to file: %s", err.Error())})
	}
}

// BuildConsole creates the UI widgets First is the main progress guage for the overall progress Widgets are then created for
// each of the devices, but are hidden initially.
func BuildConsole(c *core.Context) {
	visible := c.OutputStreamNum
	for x, y := range c.Devices {
		conui.Body.DevicePanels = append(conui.Body.DevicePanels, conui.NewDevicePanel(y.Name, y.SizeTotal))
		if visible > 0 && len(c.Catalog[y.Name]) > 0 {
			log.Debugln("Making device", x, "visible")
			conui.Body.DevicePanels[x].SetVisible(true)
			if x == 0 {
				conui.Body.DevicePanels[x].SetSelected(true)
			}
			visible--
		}
	}
	conui.Body.ProgressPanel = conui.NewProgressGauge(c.Catalog.TotalSize())
	conui.Body.ProgressPanel.SetVisible(true)
	conui.Layout()
}

func eventListener(c *core.Context) {
	defer cleanupAtExit()
	for {
		select {
		case e := <-conui.Events:
			if e.Type == conui.EventKey && e.Ch == 'j' {
				conui.Body.SelectNext()
			}
			if e.Type == conui.EventKey && e.Ch == 'k' {
				conui.Body.SelectPrevious()
			}
			if e.Type == conui.EventKey && e.Ch == 'd' {
				p := conui.Body.Selected()
				p.SetVisible(false)
			}
			if e.Type == conui.EventKey && e.Ch == 's' {
				p := conui.Body.Selected()
				p.SetVisible(true)
			}
			if e.Type == conui.EventKey && e.Key == conui.KeyEnter {
				p := conui.Body.Selected().Prompt()
				if p != nil {
					p.Action()
				}
			}
			if e.Type == conui.EventKey && e.Ch == 'q' {
				conui.Close()
				c.Exit = true
				break
			}
			if e.Type == conui.EventResize {
				conui.Layout()
				go func() { conui.Redraw <- true }()
			}
		case <-conui.Redraw:
			conui.Render()
		}
	}
}

// deviceMountHandler checks to see if the device is mounted and writable. Meant to be run as a goroutine.
func deviceMountHandler(c *core.Context, deviceIndex int) {
	// Listen on the channel for a mount request
	ns := time.Now()
	log.Debugf("Waiting for receive on SyncDeviceMount[%d]", deviceIndex)
	<-c.SyncDeviceMount[deviceIndex]
	log.Debugf("Receive from SyncDeviceMount[%d] after wait of %s", deviceIndex, time.Since(ns))

	d := &c.Devices[deviceIndex]
	wg := conui.Body.DevicePanelByIndex(deviceIndex)
	wg.SetVisible(true)

	// Used to correctly time the display of the message in the prompt for the device panel.
	pmc := make(chan string, 10)

	checkDevice := func(p *conui.PromptAction, keyEvent bool, mesgChan chan string) (err error) {
		// The actual checking
		err = ensureDeviceIsReady(*d)
		if err != nil {
			log.Errorf("checkDevice error: %s", err)
			switch err.(type) {
			case deviceTestPermissionDeniedError:
				p.Message = "Device is mounted but not writable... " +
					"Please fix write permissions then press Enter to continue."
			case deviceNotFoundByUUIDError:
				if keyEvent {
					pmc <- fmt.Sprintf("Device not found! (UUID=%s)", d.UUID)
				} else {
					pmc <- fmt.Sprintf("Please mount device to %q and press Enter to continue...", d.MountPoint)
				}
			}
			return
		}
		if deviceIndex == 0 {
			wg.SetSelected(true)
		}
		return
	}

	// The prompt that will be displayed in the device panel. Allow the user to press enter on the device panel to force
	// a device check
	prompt := &conui.PromptAction{}
	prompt.Action = func() {
		// With the device selected in the panel, the user has pressed the enter key.
		log.Printf("Action for panel %q!", wg.Border.Label)
		checkDevice(prompt, true, pmc)
	}
	wg.SetPrompt(prompt)

	// Pre-check
	err := checkDevice(prompt, false, pmc)
	if err != nil {
		// Check device automatically periodically until the device is mounted
	loop:
		for {
			// This will make sure the message is visible for a constant amount of time
			select {
			case pmsg := <-pmc:
				prompt.Message = pmsg
				conui.Redraw <- true
			case <-time.After(time.Second * 5):
				err := checkDevice(prompt, false, pmc)
				if err == nil {
					break loop
				}
			}
		}
	}

	// The prompt is not needed anymore
	wg.SetPrompt(nil)
	c.SyncDeviceMount[deviceIndex] <- true
}

func update(c *core.Context) {
	// Main progress panel updater
	go func() {
		for {
			p := <-c.SyncProgress.Report
			prg := conui.Body.ProgressPanel
			prg.SizeWritn = p.SizeWritn
			prg.BytesPerSecond = p.BytesPerSecond
			if c.Exit {
				break
			}
		}
	}()
	// Device panel updaters
	for x := 0; x < len(c.Catalog); x++ {
		go deviceMountHandler(c, x)
		c.SyncDeviceMount[x] = make(chan bool)
		go func(index int) {
			dw := conui.Body.DevicePanelByIndex(index)
			for {
				if fp, ok := <-c.SyncProgress.Device[index].Report; ok {
					dw.SizeWritn += fp.DeviceSizeWritn
					dw.BytesPerSecond = fp.DeviceBytesPerSecond
					log.WithFields(logrus.Fields{
						"fp.FileName":           fp.FileName,
						"fp.FilePath":           fp.FilePath,
						"fp.FileSize":           fp.FileSize,
						"fp.FileSizeWritn":      fp.FileSizeWritn,
						"fp.FileTotalSizeWritn": fp.FileTotalSizeWritn,
						"deviceIndex":           index,
					}).Debugln("Sync file progress")
				} else if !ok || c.Exit {
					dw.BytesPerSecondVisible = false
					break
				}
			}
			log.Debugln("DONE REPORTING index:", index)
		}(x)
	}
	go func() {
		for {
			if !termbox.IsInit || c.Exit {
				break
			}
			conui.Redraw <- true
			// Rate limit redrawing
			time.Sleep(time.Second / 3)
		}
	}()
}

func syncStart(c *cli.Context) {
	defer cleanupAtExit()
	log.WithFields(logrus.Fields{
		"version": 0.2,
		"date":    time.Now().Format(time.RFC3339),
	}).Infoln("Ghetto Device Storage")
	c2 := loadInitialState(c)

	conui.Init()
	BuildConsole(c2)
	go eventListener(c2)
	update(c2)

	errChan := make(chan error, 100)

	// Sync the things
	go func() {
		core.Sync(c2, c.GlobalBool("no-dev-context"), errChan)
		log.Info("ALL DONE -- Sync complete!")
		// c2.Exit = true
	}()

	// Give the user time to review the sync in the UI
outer:
	for {
		select {
		case err := <-errChan:
			log.Errorf("Sync error: %s", err)
		case <-time.After(time.Second):
			if c2.Exit {
				break outer
			}
		}
	}

	// Fin
	dumpContextToFile(c, c2)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"runtime"

	log "github.com/Sirupsen/logrus"
)

func runUsage() {
	fmt.Printf("USAGE: %s run [backend] [options] [prefix]\n\n", os.Args[0])

	fmt.Printf("'backend' specifies the run backend.\n")
	fmt.Printf("If not specified the platform specific default will be used\n")
	fmt.Printf("Supported backends are (default platform in brackets):\n")
	fmt.Printf("  hyperkit [macOS]\n")
	fmt.Printf("  vmware\n")
	fmt.Printf("\n")
	fmt.Printf("'options' are the backend specific options.\n")
	fmt.Printf("See 'moby run [backend] --help' for details.\n\n")
	fmt.Printf("'prefix' specifies the path to the VM image.\n")
	fmt.Printf("It defaults to './moby'.\n")
}

func run(args []string) {
	if len(args) < 1 {
		runUsage()
		os.Exit(1)
	}

	switch args[0] {
	case "help", "-h", "-help", "--help":
		runUsage()
		os.Exit(0)
	case "hyperkit":
		runHyperKit(args[1:])
	case "vmware":
		runVMware(args[1:])
	case "gcp":
		runGcp(args[1:])
	default:
		switch runtime.GOOS {
		case "darwin":
			runHyperKit(args)
		default:
			log.Errorf("There currently is no default 'run' backend for your platform.")
		}
	}
}
<commit_msg>moby: Add gcp platform to usage in moby run<commit_after>package main

import (
	"fmt"
	"os"
	"runtime"

	log "github.com/Sirupsen/logrus"
)

func runUsage() {
	fmt.Printf("USAGE: %s run [backend] [options] [prefix]\n\n", os.Args[0])

	fmt.Printf("'backend' specifies the run backend.\n")
	fmt.Printf("If not specified the platform specific default will be used\n")
	fmt.Printf("Supported backends are (default platform in brackets):\n")
	fmt.Printf("  gcp\n")
	fmt.Printf("  hyperkit [macOS]\n")
	fmt.Printf("  vmware\n")
	fmt.Printf("\n")
	fmt.Printf("'options' are the backend specific options.\n")
	fmt.Printf("See 'moby run [backend] --help' for details.\n\n")
	fmt.Printf("'prefix' specifies the path to the VM image.\n")
	fmt.Printf("It defaults to './moby'.\n")
}

func run(args []string) {
	if len(args) < 1 {
		runUsage()
		os.Exit(1)
	}

	switch args[0] {
	case "help", "-h", "-help", "--help":
		runUsage()
		os.Exit(0)
	case "hyperkit":
		runHyperKit(args[1:])
	case "vmware":
		runVMware(args[1:])
	case "gcp":
		runGcp(args[1:])
	default:
		switch runtime.GOOS {
		case "darwin":
			runHyperKit(args)
		default:
			log.Errorf("There currently is no default 'run' backend for your platform.")
		}
	}
}
<|endoftext|>


<commit_before>package control

const (
    BIN_   float64 = 1 << iota
    BIN_KI float64 = 1 << (10 * iota)
    BIN_MI
    BIN_GI
    BIN_TI
    BIN_PI
    BIN_EI
)

const (
    DEC_  float64 = 1 << iota
    DEC_K float64 = DEC_  * 1000
    DEC_M         = DEC_K * 1000
    DEC_G         = DEC_M * 1000
    DEC_T         = DEC_G * 1000
    DEC_P         = DEC_T * 1000
    DEC_E         = DEC_P * 1000
)

func ToUnits(val float64, base uint) (float64, string) {
    prefix := DEC_
    mult := DEC_K
    if base == 2 {
        mult = BIN_KI
    }

    for val >= (prefix * mult) {
        prefix = prefix * mult
    }

    return val / prefix, GetUnitPrefix(prefix)
}

func GetUnitPrefix(prefix float64) string {
    var ret string

    switch prefix {
        default:
        case BIN_:
            ret = ""
        case BIN_KI:
            ret = "Ki"
        case BIN_MI:
            ret = "Mi"
        case BIN_GI:
            ret = "Gi"
        case BIN_TI:
            ret = "Ti"
        case BIN_PI:
            ret = "Pi"
        case BIN_EI:
            ret = "Ei"
        case DEC_K:
            ret = "k"
        case DEC_M:
            ret = "M"
        case DEC_G:
            ret = "G"
        case DEC_T:
            ret = "T"
        case DEC_P:
            ret = "P"
        case DEC_E:
            ret = "E"
    }

    return ret
}
<commit_msg>Moved units to github.com/shanebarnes/goto/units<commit_after><|endoftext|>


<commit_before>// Package emacs provides a set of utilities that
// simplify Emacs interop.
// It wraps most common functions invoked with lisp.Call
// in a typesafe interface.
package emacs

// By approximation, this file will be usable after
// roadmap-1 will be finished.

import (
	"emacs/lisp"
)

func Insert(arg string) {
	lisp.Call("insert", lisp.String(arg))
}
<commit_msg>documenting Insert function<commit_after>// Package emacs provides a set of utilities that
// simplify Emacs interop.
// It wraps most common functions invoked with lisp.Call
// in a typesafe interface.
package emacs

// By approximation, this file will be usable after
// roadmap-1 will be finished.

import (
	"emacs/lisp"
)

// Insert calls Emacs "insert" function with single string argument.
func Insert(text string) {
	lisp.Call("insert", lisp.String(text))
}
<|endoftext|>


<commit_before>package graph

import (
	"fmt"
	"os"
	"strings"
	"strconv"
)

func (node NodeId) String() string {
	return strconv.Itoa(int(uint(node)))
}

func (conn Connection) String() string {
	return fmt.Sprintf("%v->%v", conn.Tail, conn.Head)
}

type IWriter interface {
	Write(s string)
}

type StringWriter struct {
	Str string
}

func (wr *StringWriter) Write(s string) {
	wr.Str += s
}

type IOsStringWriter interface {
	WriteString(s string) (ret int, err os.Error)
}

type IoWriterAdapter struct {
	writer IOsStringWriter
}

func NewIoWriter(writer IOsStringWriter) *IoWriterAdapter {
	return &IoWriterAdapter{writer}
}

func (wr *IoWriterAdapter) Write(s string) {
	slen := len(s)
	wrote := 0
	for wrote<slen {
		curWrote, err := wr.writer.WriteString(s[wrote:])
		if err!=nil {
			panic(err)
		}
		wrote += curWrote
	}
}

func styleMapToString(style map[string]string) string {
	chunks := make([]string, len(style))
	i := 0
	for k, v := range style {
		chunks[i] = fmt.Sprintf("%v=%v", k, v)
		i++
	}
	return "[" + strings.Join(chunks, ",") + "]"
}

type DotNodeStyleFunc func(node NodeId) map[string]string
type DotConnectionStyleFunc func(conn Connection) map[string]string

func SimpleNodeStyle(node NodeId) map[string]string {
	style := make(map[string]string)
	style["label"] = node.String()
	return style
}

func SimpleArcStyle(conn Connection) map[string]string {
	return make(map[string]string)
}

func PlotNodesToDot(nodesIter NodesIterable, wr IWriter, styleFunc DotNodeStyleFunc) {
	for node := range nodesIter.NodesIter() {
		wr.Write("n" + node.String() + styleMapToString(styleFunc(node)) + ";\n")
	}
}

func PlotArcsToDot(connIter TypedConnectionsIterable, wr IWriter, styleFunc DotConnectionStyleFunc) {
	for conn := range connIter.TypedConnectionsIter() {
		wr.Write(fmt.Sprintf("n%v->n%v%v;\n",
			conn.Tail.String(),
			conn.Head.String(),
			styleMapToString(styleFunc(conn.Connection))))
	}
}

func PlotDirectedGraphToDot(gr DirectedGraphReader, wr IWriter, nodeStyleFunc DotNodeStyleFunc, arcStyleFunc DotConnectionStyleFunc) {
	wr.Write("digraph messages {\n")
	PlotNodesToDot(gr, wr, nodeStyleFunc)
	PlotArcsToDot(ArcsToTypedConnIterable(gr), wr, arcStyleFunc)
	wr.Write("}\n")
}

func PlotMixedGraphToDot(gr MixedGraph, wr IWriter, nodeStyleFunc DotNodeStyleFunc, connStyleFunc DotConnectionStyleFunc) {
	wr.Write("digraph messages {\n")
	PlotNodesToDot(gr, wr, nodeStyleFunc)
	PlotArcsToDot(gr, wr, connStyleFunc)
	wr.Write("}\n")
}
<commit_msg>add TypedConnection String method<commit_after>package graph

import (
	"fmt"
	"os"
	"strings"
	"strconv"
)

func (node NodeId) String() string {
	return strconv.Itoa(int(uint(node)))
}

func (conn Connection) String() string {
	return fmt.Sprintf("%v->%v", conn.Tail, conn.Head)
}

func (conn TypedConnection) String() string {
	switch conn.Type {
		case CT_UNDIRECTED:
			return fmt.Sprintf("%v--%v", conn.Tail, conn.Head)
		case CT_DIRECTED:
			return fmt.Sprintf("%v->%v", conn.Tail, conn.Head)
		case CT_DIRECTED_REVERSED:
			return fmt.Sprintf("%v<-%v", conn.Tail, conn.Head)
		case CT_NONE:
			return fmt.Sprintf("%v><%v", conn.Tail, conn.Head)
	}
	return fmt.Sprintf("%v!!%v", conn.Tail, conn.Head)
}

type IWriter interface {
	Write(s string)
}

type StringWriter struct {
	Str string
}

func (wr *StringWriter) Write(s string) {
	wr.Str += s
}

type IOsStringWriter interface {
	WriteString(s string) (ret int, err os.Error)
}

type IoWriterAdapter struct {
	writer IOsStringWriter
}

func NewIoWriter(writer IOsStringWriter) *IoWriterAdapter {
	return &IoWriterAdapter{writer}
}

func (wr *IoWriterAdapter) Write(s string) {
	slen := len(s)
	wrote := 0
	for wrote<slen {
		curWrote, err := wr.writer.WriteString(s[wrote:])
		if err!=nil {
			panic(err)
		}
		wrote += curWrote
	}
}

func styleMapToString(style map[string]string) string {
	chunks := make([]string, len(style))
	i := 0
	for k, v := range style {
		chunks[i] = fmt.Sprintf("%v=%v", k, v)
		i++
	}
	return "[" + strings.Join(chunks, ",") + "]"
}

type DotNodeStyleFunc func(node NodeId) map[string]string
type DotConnectionStyleFunc func(conn Connection) map[string]string

func SimpleNodeStyle(node NodeId) map[string]string {
	style := make(map[string]string)
	style["label"] = node.String()
	return style
}

func SimpleArcStyle(conn Connection) map[string]string {
	return make(map[string]string)
}

func PlotNodesToDot(nodesIter NodesIterable, wr IWriter, styleFunc DotNodeStyleFunc) {
	for node := range nodesIter.NodesIter() {
		wr.Write("n" + node.String() + styleMapToString(styleFunc(node)) + ";\n")
	}
}

func PlotArcsToDot(connIter TypedConnectionsIterable, wr IWriter, styleFunc DotConnectionStyleFunc) {
	for conn := range connIter.TypedConnectionsIter() {
		wr.Write(fmt.Sprintf("n%v->n%v%v;\n",
			conn.Tail.String(),
			conn.Head.String(),
			styleMapToString(styleFunc(conn.Connection))))
	}
}

func PlotDirectedGraphToDot(gr DirectedGraphReader, wr IWriter, nodeStyleFunc DotNodeStyleFunc, arcStyleFunc DotConnectionStyleFunc) {
	wr.Write("digraph messages {\n")
	PlotNodesToDot(gr, wr, nodeStyleFunc)
	PlotArcsToDot(ArcsToTypedConnIterable(gr), wr, arcStyleFunc)
	wr.Write("}\n")
}

func PlotMixedGraphToDot(gr MixedGraph, wr IWriter, nodeStyleFunc DotNodeStyleFunc, connStyleFunc DotConnectionStyleFunc) {
	wr.Write("digraph messages {\n")
	PlotNodesToDot(gr, wr, nodeStyleFunc)
	PlotArcsToDot(gr, wr, connStyleFunc)
	wr.Write("}\n")
}
<|endoftext|>


<commit_before>package daemon

import (
	"bytes"
	"fmt"
	"runtime"
	"strings"
	"time"

	"golang.org/x/net/context"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/container"
	"github.com/docker/docker/daemon/exec"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/strslice"
)

const (
	// Longest healthcheck probe output message to store. Longer messages will be truncated.
	maxOutputLen = 4096

	// Default interval between probe runs (from the end of the first to the start of the second).
	// Also the time before the first probe.
	defaultProbeInterval = 30 * time.Second

	// The maximum length of time a single probe run should take. If the probe takes longer
	// than this, the check is considered to have failed.
	defaultProbeTimeout = 30 * time.Second

	// Default number of consecutive failures of the health check
	// for the container to be considered unhealthy.
	defaultProbeRetries = 3

	// Maximum number of entries to record
	maxLogEntries = 5
)

const (
	// Exit status codes that can be returned by the probe command.

	exitStatusHealthy   = 0 // Container is healthy
	exitStatusUnhealthy = 1 // Container is unhealthy
)

// probe implementations know how to run a particular type of probe.
type probe interface {
	// Perform one run of the check. Returns the exit code and an optional
	// short diagnostic string.
	run(context.Context, *Daemon, *container.Container) (*types.HealthcheckResult, error)
}

// cmdProbe implements the "CMD" probe type.
type cmdProbe struct {
	// Run the command with the system's default shell instead of execing it directly.
	shell bool
}

// exec the healthcheck command in the container.
// Returns the exit code and probe output (if any)
func (p *cmdProbe) run(ctx context.Context, d *Daemon, container *container.Container) (*types.HealthcheckResult, error) {
	cmdSlice := strslice.StrSlice(container.Config.Healthcheck.Test)[1:]
	if p.shell {
		if runtime.GOOS != "windows" {
			cmdSlice = append([]string{"/bin/sh", "-c"}, cmdSlice...)
		} else {
			cmdSlice = append([]string{"cmd", "/S", "/C"}, cmdSlice...)
		}
	}
	entrypoint, args := d.getEntrypointAndArgs(strslice.StrSlice{}, cmdSlice)
	execConfig := exec.NewConfig()
	execConfig.OpenStdin = false
	execConfig.OpenStdout = true
	execConfig.OpenStderr = true
	execConfig.ContainerID = container.ID
	execConfig.DetachKeys = []byte{}
	execConfig.Entrypoint = entrypoint
	execConfig.Args = args
	execConfig.Tty = false
	execConfig.Privileged = false
	execConfig.User = container.Config.User

	d.registerExecCommand(container, execConfig)
	d.LogContainerEvent(container, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " "))

	output := &limitedBuffer{}
	err := d.ContainerExecStart(ctx, execConfig.ID, nil, output, output)
	if err != nil {
		return nil, err
	}
	info, err := d.getExecConfig(execConfig.ID)
	if err != nil {
		return nil, err
	}
	if info.ExitCode == nil {
		return nil, fmt.Errorf("Healthcheck has no exit code!")
	}
	// Note: Go's json package will handle invalid UTF-8 for us
	out := output.String()
	return &types.HealthcheckResult{
		End:      time.Now(),
		ExitCode: *info.ExitCode,
		Output:   out,
	}, nil
}

// Update the container's Status.Health struct based on the latest probe's result.
func handleProbeResult(d *Daemon, c *container.Container, result *types.HealthcheckResult) {
	c.Lock()
	defer c.Unlock()

	retries := c.Config.Healthcheck.Retries
	if retries <= 0 {
		retries = defaultProbeRetries
	}

	h := c.State.Health
	oldStatus := h.Status

	if len(h.Log) >= maxLogEntries {
		h.Log = append(h.Log[len(h.Log)+1-maxLogEntries:], result)
	} else {
		h.Log = append(h.Log, result)
	}

	if result.ExitCode == exitStatusHealthy {
		h.FailingStreak = 0
		h.Status = types.Healthy
	} else {
		// Failure (including invalid exit code)
		h.FailingStreak++
		if h.FailingStreak >= retries {
			h.Status = types.Unhealthy
		}
		// Else we're starting or healthy. Stay in that state.
	}

	if oldStatus != h.Status {
		d.LogContainerEvent(c, "health_status: "+h.Status)
	}
}

// Run the container's monitoring thread until notified via "stop".
// There is never more than one monitor thread running per container at a time.
func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe) {
	probeTimeout := timeoutWithDefault(c.Config.Healthcheck.Timeout, defaultProbeTimeout)
	probeInterval := timeoutWithDefault(c.Config.Healthcheck.Interval, defaultProbeInterval)
	for {
		select {
		case <-stop:
			logrus.Debug("Stop healthcheck monitoring (received while idle)")
			return
		case <-time.After(probeInterval):
			logrus.Debug("Running health check...")
			startTime := time.Now()
			ctx, cancelProbe := context.WithTimeout(context.Background(), probeTimeout)
			results := make(chan *types.HealthcheckResult)
			go func() {
				result, err := probe.run(ctx, d, c)
				if err != nil {
					logrus.Warnf("Health check error: %v", err)
					results <- &types.HealthcheckResult{
						ExitCode: -1,
						Output:   err.Error(),
						Start:    startTime,
						End:      time.Now(),
					}
				} else {
					result.Start = startTime
					logrus.Debugf("Health check done (exitCode=%d)", result.ExitCode)
					results <- result
				}
				close(results)
			}()
			select {
			case <-stop:
				logrus.Debug("Stop healthcheck monitoring (received while probing)")
				// Stop timeout and kill probe, but don't wait for probe to exit.
				cancelProbe()
				return
			case result := <-results:
				handleProbeResult(d, c, result)
				// Stop timeout
				cancelProbe()
			case <-ctx.Done():
				logrus.Debug("Health check taking too long")
				handleProbeResult(d, c, &types.HealthcheckResult{
					ExitCode: -1,
					Output:   fmt.Sprintf("Health check exceeded timeout (%v)", probeTimeout),
					Start:    startTime,
					End:      time.Now(),
				})
				cancelProbe()
				// Wait for probe to exit (it might take a while to respond to the TERM
				// signal and we don't want dying probes to pile up).
				<-results
			}
		}
	}
}

// Get a suitable probe implementation for the container's healthcheck configuration.
// Nil will be returned if no healthcheck was configured or NONE was set.
func getProbe(c *container.Container) probe {
	config := c.Config.Healthcheck
	if config == nil || len(config.Test) == 0 {
		return nil
	}
	switch config.Test[0] {
	case "CMD":
		return &cmdProbe{shell: false}
	case "CMD-SHELL":
		return &cmdProbe{shell: true}
	default:
		logrus.Warnf("Unknown healthcheck type '%s' (expected 'CMD')", config.Test[0])
		return nil
	}
}

// Ensure the health-check monitor is running or not, depending on the current
// state of the container.
// Called from monitor.go, with c locked.
func (d *Daemon) updateHealthMonitor(c *container.Container) {
	h := c.State.Health
	if h == nil {
		return // No healthcheck configured
	}

	probe := getProbe(c)
	wantRunning := c.Running && !c.Paused && probe != nil
	if wantRunning {
		if stop := h.OpenMonitorChannel(); stop != nil {
			go monitor(d, c, stop, probe)
		}
	} else {
		h.CloseMonitorChannel()
	}
}

// Reset the health state for a newly-started, restarted or restored container.
// initHealthMonitor is called from monitor.go and we should never be running
// two instances at once.
// Called with c locked.
func (d *Daemon) initHealthMonitor(c *container.Container) {
	// If no healthcheck is setup then don't init the monitor
	if getProbe(c) == nil {
		return
	}

	// This is needed in case we're auto-restarting
	d.stopHealthchecks(c)

	if c.State.Health == nil {
		h := &container.Health{}
		h.Status = types.Starting
		c.State.Health = h
	}

	d.updateHealthMonitor(c)
}

// Called when the container is being stopped (whether because the health check is
// failing or for any other reason).
func (d *Daemon) stopHealthchecks(c *container.Container) {
	h := c.State.Health
	if h != nil {
		h.CloseMonitorChannel()
	}
}

// Buffer up to maxOutputLen bytes. Further data is discarded.
type limitedBuffer struct {
	buf       bytes.Buffer
	truncated bool // indicates that data has been lost
}

// Append to limitedBuffer while there is room.
func (b *limitedBuffer) Write(data []byte) (int, error) {
	bufLen := b.buf.Len()
	dataLen := len(data)
	keep := min(maxOutputLen-bufLen, dataLen)
	if keep > 0 {
		b.buf.Write(data[:keep])
	}
	if keep < dataLen {
		b.truncated = true
	}
	return dataLen, nil
}

// The contents of the buffer, with "..." appended if it overflowed.
func (b *limitedBuffer) String() string {
	out := b.buf.String()
	if b.truncated {
		out = out + "..."
	}
	return out
}

// If configuredValue is zero, use defaultValue instead.
func timeoutWithDefault(configuredValue time.Duration, defaultValue time.Duration) time.Duration {
	if configuredValue == 0 {
		return defaultValue
	}
	return configuredValue
}

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}
<commit_msg>Prevent stdout / stderr race condition in limitedBuffer.<commit_after>package daemon

import (
	"bytes"
	"fmt"
	"runtime"
	"strings"
	"sync"
	"time"

	"golang.org/x/net/context"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/container"
	"github.com/docker/docker/daemon/exec"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/strslice"
)

const (
	// Longest healthcheck probe output message to store. Longer messages will be truncated.
	maxOutputLen = 4096

	// Default interval between probe runs (from the end of the first to the start of the second).
	// Also the time before the first probe.
	defaultProbeInterval = 30 * time.Second

	// The maximum length of time a single probe run should take. If the probe takes longer
	// than this, the check is considered to have failed.
	defaultProbeTimeout = 30 * time.Second

	// Default number of consecutive failures of the health check
	// for the container to be considered unhealthy.
	defaultProbeRetries = 3

	// Maximum number of entries to record
	maxLogEntries = 5
)

const (
	// Exit status codes that can be returned by the probe command.

	exitStatusHealthy   = 0 // Container is healthy
	exitStatusUnhealthy = 1 // Container is unhealthy
)

// probe implementations know how to run a particular type of probe.
type probe interface {
	// Perform one run of the check. Returns the exit code and an optional
	// short diagnostic string.
	run(context.Context, *Daemon, *container.Container) (*types.HealthcheckResult, error)
}

// cmdProbe implements the "CMD" probe type.
type cmdProbe struct {
	// Run the command with the system's default shell instead of execing it directly.
	shell bool
}

// exec the healthcheck command in the container.
// Returns the exit code and probe output (if any)
func (p *cmdProbe) run(ctx context.Context, d *Daemon, container *container.Container) (*types.HealthcheckResult, error) {
	cmdSlice := strslice.StrSlice(container.Config.Healthcheck.Test)[1:]
	if p.shell {
		if runtime.GOOS != "windows" {
			cmdSlice = append([]string{"/bin/sh", "-c"}, cmdSlice...)
		} else {
			cmdSlice = append([]string{"cmd", "/S", "/C"}, cmdSlice...)
		}
	}
	entrypoint, args := d.getEntrypointAndArgs(strslice.StrSlice{}, cmdSlice)
	execConfig := exec.NewConfig()
	execConfig.OpenStdin = false
	execConfig.OpenStdout = true
	execConfig.OpenStderr = true
	execConfig.ContainerID = container.ID
	execConfig.DetachKeys = []byte{}
	execConfig.Entrypoint = entrypoint
	execConfig.Args = args
	execConfig.Tty = false
	execConfig.Privileged = false
	execConfig.User = container.Config.User

	d.registerExecCommand(container, execConfig)
	d.LogContainerEvent(container, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " "))

	output := &limitedBuffer{}
	err := d.ContainerExecStart(ctx, execConfig.ID, nil, output, output)
	if err != nil {
		return nil, err
	}
	info, err := d.getExecConfig(execConfig.ID)
	if err != nil {
		return nil, err
	}
	if info.ExitCode == nil {
		return nil, fmt.Errorf("Healthcheck has no exit code!")
	}
	// Note: Go's json package will handle invalid UTF-8 for us
	out := output.String()
	return &types.HealthcheckResult{
		End:      time.Now(),
		ExitCode: *info.ExitCode,
		Output:   out,
	}, nil
}

// Update the container's Status.Health struct based on the latest probe's result.
func handleProbeResult(d *Daemon, c *container.Container, result *types.HealthcheckResult) {
	c.Lock()
	defer c.Unlock()

	retries := c.Config.Healthcheck.Retries
	if retries <= 0 {
		retries = defaultProbeRetries
	}

	h := c.State.Health
	oldStatus := h.Status

	if len(h.Log) >= maxLogEntries {
		h.Log = append(h.Log[len(h.Log)+1-maxLogEntries:], result)
	} else {
		h.Log = append(h.Log, result)
	}

	if result.ExitCode == exitStatusHealthy {
		h.FailingStreak = 0
		h.Status = types.Healthy
	} else {
		// Failure (including invalid exit code)
		h.FailingStreak++
		if h.FailingStreak >= retries {
			h.Status = types.Unhealthy
		}
		// Else we're starting or healthy. Stay in that state.
	}

	if oldStatus != h.Status {
		d.LogContainerEvent(c, "health_status: "+h.Status)
	}
}

// Run the container's monitoring thread until notified via "stop".
// There is never more than one monitor thread running per container at a time.
func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe) {
	probeTimeout := timeoutWithDefault(c.Config.Healthcheck.Timeout, defaultProbeTimeout)
	probeInterval := timeoutWithDefault(c.Config.Healthcheck.Interval, defaultProbeInterval)
	for {
		select {
		case <-stop:
			logrus.Debug("Stop healthcheck monitoring (received while idle)")
			return
		case <-time.After(probeInterval):
			logrus.Debug("Running health check...")
			startTime := time.Now()
			ctx, cancelProbe := context.WithTimeout(context.Background(), probeTimeout)
			results := make(chan *types.HealthcheckResult)
			go func() {
				result, err := probe.run(ctx, d, c)
				if err != nil {
					logrus.Warnf("Health check error: %v", err)
					results <- &types.HealthcheckResult{
						ExitCode: -1,
						Output:   err.Error(),
						Start:    startTime,
						End:      time.Now(),
					}
				} else {
					result.Start = startTime
					logrus.Debugf("Health check done (exitCode=%d)", result.ExitCode)
					results <- result
				}
				close(results)
			}()
			select {
			case <-stop:
				logrus.Debug("Stop healthcheck monitoring (received while probing)")
				// Stop timeout and kill probe, but don't wait for probe to exit.
				cancelProbe()
				return
			case result := <-results:
				handleProbeResult(d, c, result)
				// Stop timeout
				cancelProbe()
			case <-ctx.Done():
				logrus.Debug("Health check taking too long")
				handleProbeResult(d, c, &types.HealthcheckResult{
					ExitCode: -1,
					Output:   fmt.Sprintf("Health check exceeded timeout (%v)", probeTimeout),
					Start:    startTime,
					End:      time.Now(),
				})
				cancelProbe()
				// Wait for probe to exit (it might take a while to respond to the TERM
				// signal and we don't want dying probes to pile up).
				<-results
			}
		}
	}
}

// Get a suitable probe implementation for the container's healthcheck configuration.
// Nil will be returned if no healthcheck was configured or NONE was set.
func getProbe(c *container.Container) probe {
	config := c.Config.Healthcheck
	if config == nil || len(config.Test) == 0 {
		return nil
	}
	switch config.Test[0] {
	case "CMD":
		return &cmdProbe{shell: false}
	case "CMD-SHELL":
		return &cmdProbe{shell: true}
	default:
		logrus.Warnf("Unknown healthcheck type '%s' (expected 'CMD')", config.Test[0])
		return nil
	}
}

// Ensure the health-check monitor is running or not, depending on the current
// state of the container.
// Called from monitor.go, with c locked.
func (d *Daemon) updateHealthMonitor(c *container.Container) {
	h := c.State.Health
	if h == nil {
		return // No healthcheck configured
	}

	probe := getProbe(c)
	wantRunning := c.Running && !c.Paused && probe != nil
	if wantRunning {
		if stop := h.OpenMonitorChannel(); stop != nil {
			go monitor(d, c, stop, probe)
		}
	} else {
		h.CloseMonitorChannel()
	}
}

// Reset the health state for a newly-started, restarted or restored container.
// initHealthMonitor is called from monitor.go and we should never be running
// two instances at once.
// Called with c locked.
func (d *Daemon) initHealthMonitor(c *container.Container) {
	// If no healthcheck is setup then don't init the monitor
	if getProbe(c) == nil {
		return
	}

	// This is needed in case we're auto-restarting
	d.stopHealthchecks(c)

	if c.State.Health == nil {
		h := &container.Health{}
		h.Status = types.Starting
		c.State.Health = h
	}

	d.updateHealthMonitor(c)
}

// Called when the container is being stopped (whether because the health check is
// failing or for any other reason).
func (d *Daemon) stopHealthchecks(c *container.Container) {
	h := c.State.Health
	if h != nil {
		h.CloseMonitorChannel()
	}
}

// Buffer up to maxOutputLen bytes. Further data is discarded.
type limitedBuffer struct {
	buf       bytes.Buffer
	mu        sync.Mutex
	truncated bool // indicates that data has been lost
}

// Append to limitedBuffer while there is room.
func (b *limitedBuffer) Write(data []byte) (int, error) {
	b.mu.Lock()
	defer b.mu.Unlock()

	bufLen := b.buf.Len()
	dataLen := len(data)
	keep := min(maxOutputLen-bufLen, dataLen)
	if keep > 0 {
		b.buf.Write(data[:keep])
	}
	if keep < dataLen {
		b.truncated = true
	}
	return dataLen, nil
}

// The contents of the buffer, with "..." appended if it overflowed.
func (b *limitedBuffer) String() string {
	b.mu.Lock()
	defer b.mu.Unlock()

	out := b.buf.String()
	if b.truncated {
		out = out + "..."
	}
	return out
}

// If configuredValue is zero, use defaultValue instead.
func timeoutWithDefault(configuredValue time.Duration, defaultValue time.Duration) time.Duration {
	if configuredValue == 0 {
		return defaultValue
	}
	return configuredValue
}

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}
<|endoftext|>


<commit_before>package daemon

import (
    "github.com/BluePecker/JwtAuth/daemon/server"
    "github.com/BluePecker/JwtAuth/api/router"
    "github.com/BluePecker/JwtAuth/api/router/token"
    "fmt"
    "github.com/kataras/iris"
    "github.com/kataras/iris/core/netutil"
)

func (d *Daemon) Shadow(ch chan struct{}) error {
    d.shadow = &server.Shadow{}
    Listener, err := netutil.UNIX(d.Options.SockFile, 0666)
    if err != nil {
        return nil
    }
    return d.shadow.New(ch, iris.Listener(Listener))
}

func (d *Daemon) Rosiness(ch chan struct{}) error {
    d.rosiness = &server.Rosiness{
        Routes:[]router.Router{token.NewRouter(d)},
    }
    Addr := fmt.Sprintf("%s:%d", d.Options.Host, d.Options.Port)
    if d.Options.TLS.Cert != "" && d.Options.TLS.Key != "" {
        return d.rosiness.New(iris.Addr(Addr))
    }
    runner := iris.TLS(Addr, d.Options.TLS.Cert, d.Options.TLS.Key)
    return d.rosiness.New(ch, runner)
}<commit_msg>fix bug<commit_after>package daemon

import (
    "github.com/BluePecker/JwtAuth/daemon/server"
    "github.com/BluePecker/JwtAuth/api/router"
    "github.com/BluePecker/JwtAuth/api/router/token"
    "fmt"
    "github.com/kataras/iris"
    "github.com/kataras/iris/core/netutil"
)

func (d *Daemon) Shadow(ch chan struct{}) error {
    d.shadow = &server.Shadow{}
    Listener, err := netutil.UNIX(d.Options.SockFile, 0666)
    if err != nil {
        return nil
    }
    return d.shadow.New(ch, iris.Listener(Listener))
}

func (d *Daemon) Rosiness(ch chan struct{}) error {
    d.rosiness = &server.Rosiness{
        Routes:[]router.Router{token.NewRouter(d)},
    }
    Addr := fmt.Sprintf("%s:%d", d.Options.Host, d.Options.Port)
    if d.Options.TLS.Cert != "" && d.Options.TLS.Key != "" {
        return d.rosiness.New(ch, iris.Addr(Addr))
    }
    runner := iris.TLS(Addr, d.Options.TLS.Cert, d.Options.TLS.Key)
    return d.rosiness.New(ch, runner)
}<|endoftext|>