<commit_before>package maps

import (
	"fmt"
	"image"
	"image/draw"
	"math"

	"github.com/ryankurte/go-mapbox/lib/base"
	"image/color"
)

// Tile is a wrapper around an image that includes positioning data
type Tile struct {
	image.Image
	Level uint64 // Tile zoom level
	Size  uint64 // Tile size
	X, Y  uint64 // Tile X and Y postions (Web Mercurator projection)
}

const (
	SizeStandard uint64 = 256
	SizeHighDPI  uint64 = 512
)

// NewTile creates a tile with a base RGBA object
func NewTile(x, y, level, size uint64, src image.Image) Tile {
	// Convert image to RGBA
	b := src.Bounds()
	m := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
	draw.Draw(m, m.Bounds(), src, b.Min, draw.Src)

	return Tile{
		Image: m,
		X:     x,
		Y:     y,
		Level: level,
		Size:  size,
	}
}

// LocationToPixel translates a global location to a pixel on the tile
func (t *Tile) LocationToPixel(loc base.Location) (float64, float64, error) {
	x, y := MercatorLocationToPixel(loc.Latitude, loc.Longitude, t.Level, t.Size)
	offsetX, offsetY := x-float64(t.X*t.Size), y-float64(t.Y*t.Size)

	if xMax := float64(t.Image.Bounds().Max.X); (offsetX < 0) || (offsetX > xMax) {
		return 0, 0, fmt.Errorf("Tile LocationToPixel error: global X offset not within tile space (x: %d max: %d)", offsetX, int(xMax))
	}
	if yMax := float64(t.Image.Bounds().Max.Y); (offsetY < 0) || (offsetY > yMax) {
		return 0, 0, fmt.Errorf("Tile LocationToPixel error: global Y offset not within tile space (y: %d max: %d)", offsetY, int(yMax))
	}

	return offsetX, offsetY, nil
}

// PixelToLocation translates a pixel location in the tile into a global location
func (t *Tile) PixelToLocation(x, y float64) (*base.Location, error) {
	if xMax := float64(t.Image.Bounds().Max.X); (x < 0) || (x > xMax) {
		return nil, fmt.Errorf("Tile LocationToPixel error: global X offset not within tile space (x: %.2f max: %d)", x, int(xMax))
	}
	if yMax := float64(t.Image.Bounds().Max.Y); (y < 0) || (y > yMax) {
		return nil, fmt.Errorf("Tile LocationToPixel error: global Y offset not within tile space (y: %.2f max: %d)", y, int(yMax))
	}

	offsetX, offsetY := x+float64(t.X*t.Size), y+float64(t.Y*t.Size)
	lat, lng := MercatorPixelToLocation(offsetX, offsetY, t.Level, t.Size)

	return &base.Location{Latitude: lat, Longitude: lng}, nil
}

// Justify sets image offsets for drawing
type Justify string

// Constant justification types
const (
	JustifyTop    Justify = "top"
	JustifyLeft   Justify = "left"
	JustifyCenter Justify = "center"
	JustifyBottom Justify = "bottom"
	JustifyRight  Justify = "right"
)

// DrawConfig configures image drawing
type DrawConfig struct {
	Vertical   Justify
	Horizontal Justify
}

// Center preconfigured centering helper
var Center = DrawConfig{JustifyCenter, JustifyCenter}

// DrawLocalXY draws the provided image at the local X/Y coordinates
func (t *Tile) DrawLocalXY(src image.Image, x, y int, config DrawConfig) error {
	dp := image.Point{}

	switch config.Horizontal {
	case JustifyLeft:
		dp.X = x
	case JustifyCenter:
		dp.X = x - src.Bounds().Dx()/2
	case JustifyRight:
		dp.X = x - src.Bounds().Dx()
	default:
		return fmt.Errorf("Unsupported horizontal justification (%s)", config.Horizontal)
	}

	switch config.Vertical {
	case JustifyTop:
		dp.Y = y
	case JustifyCenter:
		dp.Y = y - src.Bounds().Dy()/2
	case JustifyBottom:
		dp.Y = y - src.Bounds().Dy()
	default:
		return fmt.Errorf("Unsupported vertical justification (%s)", config.Horizontal)
	}

	r := image.Rectangle{dp, dp.Add(src.Bounds().Size())}
	draw.Draw(t.Image.(draw.Image), r, src, src.Bounds().Min, draw.Over)

	return nil
}

func (t *Tile) translateGlobalToLocalXY(x, y int) (int, int, error) {
	offsetX := x - int(t.X*t.Size)
	offsetY := y - int(t.Y*t.Size)

	if xMax := int(t.Image.Bounds().Max.X); (offsetX < 0) || (offsetX > xMax) {
		return 0, 0, fmt.Errorf("Tile DrawGlobalXY error: global X offset not within tile space (x: %d max: %d)", offsetX, xMax)
	}
	if yMax := int(t.Image.Bounds().Max.Y); (offsetY < 0) || (offsetY > yMax) {
		return 0, 0, fmt.Errorf("Tile DrawGlobalXY error: global Y offset not within tile space (y: %d max: %d)", offsetY, yMax)
	}

	return offsetX, offsetY, nil
}

// DrawGlobalXY draws the provided image at the global X/Y coordinates
func (t *Tile) DrawGlobalXY(src image.Image, x, y int, config DrawConfig) error {
	offsetX, offsetY, err := t.translateGlobalToLocalXY(x, y)
	if err != nil {
		return err
	}
	t.DrawLocalXY(src, offsetX, offsetY, config)
	return nil
}

// DrawLocation draws the provided image at the provided lat lng
func (t *Tile) DrawLocation(src image.Image, loc base.Location, config DrawConfig) {
	// Calculate location in pixel space
	x, y := MercatorLocationToPixel(loc.Latitude, loc.Longitude, t.Level, t.Size)
	t.DrawGlobalXY(src, int(x), int(y), config)
}

// Interpolate function to be passed to generic line interpolator
type Interpolate func(pixel color.Color) color.Color

// InterpolateLocalXY interpolates a line between two local points and calls the interpolate function on each point
func (t *Tile) InterpolateLocalXY(x1, y1, x2, y2 int, interpolate Interpolate) {
	// This is a bit insane because the ordering between (x1, y1) and (x2, y2) must be preserved
	// So that points

	dx := int(float64(x2) - float64(x1))
	dy := int(float64(y2) - float64(y1))

	len := int(math.Sqrt(math.Pow(float64(dx), 2) + math.Pow(float64(dy), 2)))

	img := t.Image.(draw.Image)

	for i := 0; i < len; i++ {
		x := x1 + i*dx/len
		y := y1 + i*dy/len
		pixel := interpolate(img.At(x, y))
		img.Set(x, y, pixel)
	}
}

// InterpolateGlobalXY interpolates a line between two global points and calls the interpolate function on each point
func (t *Tile) InterpolateGlobalXY(x1, y1, x2, y2 int, interpolate Interpolate) error {
	offsetX1, offsetY1, err := t.translateGlobalToLocalXY(x1, y1)
	if err != nil {
		return err
	}
	offsetX2, offsetY2, err := t.translateGlobalToLocalXY(x2, y2)
	if err != nil {
		return err
	}
	t.InterpolateLocalXY(offsetX1, offsetY1, offsetX2, offsetY2, interpolate)
	return nil
}

// InterpolateLocations interpolates a line between two locations and calls the interpolate function on each point
func (t *Tile) InterpolateLocations(loc1, loc2 base.Location, interpolate Interpolate) error {
	x1, y1 := MercatorLocationToPixel(loc1.Latitude, loc1.Longitude, t.Level, t.Size)
	x2, y2 := MercatorLocationToPixel(loc2.Latitude, loc2.Longitude, t.Level, t.Size)
	return t.InterpolateGlobalXY(int(x1), int(y1), int(x2), int(y2), interpolate)
}

// DrawLine uses InterpolateLocations to draw a line between two points
func (t *Tile) DrawLine(loc1, loc2 base.Location, c color.Color) {
	t.InterpolateLocations(loc1, loc2, func(color.Color) color.Color {
		return c
	})
}

func (t *Tile) GetAltitude(loc base.Location) (float64, error) {
	x, y := MercatorLocationToPixel(loc.Latitude, loc.Longitude, t.Level, t.Size)
	offsetX, offsetY, err := t.translateGlobalToLocalXY(int(x), int(y))
	if err != nil {
		return 0.0, err
	}
	p := t.Image.At(offsetX, offsetY).(color.RGBA)
	return PixelToHeight(p.R, p.G, p.B), nil
}

func (t *Tile) InterpolateAltitudes(loc1, loc2 base.Location) []float64 {
	altitudes := make([]float64, 0)
	t.InterpolateLocations(loc1, loc2, func(c color.Color) color.Color {
		p := c.(color.RGBA)
		alt := PixelToHeight(p.R, p.G, p.B)
		altitudes = append(altitudes, alt)
		return c
	})
	return altitudes
}

func (t *Tile) GetHighestAltitude() float64 {
	p := t.Image.At(0, 0).(color.RGBA)
	max := PixelToHeight(p.R, p.G, p.B)
	for y := 0; y < t.Image.Bounds().Dy(); y++ {
		for x := 0; x < t.Image.Bounds().Dx(); x++ {
			p := t.Image.At(x, y).(color.RGBA)
			alt := PixelToHeight(p.R, p.G, p.B)
			if alt > max {
				max = alt
			}
		}
	}
	return max
}

func (t *Tile) FlattenAltitudes(maxHeight float64) Tile {
	img := image.NewRGBA(t.Image.Bounds())

	for y := 0; y < t.Image.Bounds().Dy(); y++ {
		for x := 0; x < t.Image.Bounds().Dx(); x++ {
			p := t.Image.At(x, y).(color.RGBA)
			alt := uint8(PixelToHeight(p.R, p.G, p.B) / maxHeight * 255)
			img.Set(x, y, color.RGBA{R: alt, G: alt, B: alt, A: 255})
		}
	}

	return NewTile(t.X, t.Y, t.Level, t.Size, img)
}
<commit_msg>Patch terrain parsing to NRGBA<commit_after>package maps

import (
	"fmt"
	"image"
	"image/draw"
	"math"

	"github.com/ryankurte/go-mapbox/lib/base"
	"image/color"
)

// Tile is a wrapper around an image that includes positioning data
type Tile struct {
	image.Image
	Level uint64 // Tile zoom level
	Size  uint64 // Tile size
	X, Y  uint64 // Tile X and Y postions (Web Mercurator projection)
}

const (
	SizeStandard uint64 = 256
	SizeHighDPI  uint64 = 512
)

// NewTile creates a tile with a base RGBA object
func NewTile(x, y, level, size uint64, src image.Image) Tile {
	// Convert image to RGBA
	b := src.Bounds()
	m := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
	draw.Draw(m, m.Bounds(), src, b.Min, draw.Src)

	return Tile{
		Image: m,
		X:     x,
		Y:     y,
		Level: level,
		Size:  size,
	}
}

// LocationToPixel translates a global location to a pixel on the tile
func (t *Tile) LocationToPixel(loc base.Location) (float64, float64, error) {
	x, y := MercatorLocationToPixel(loc.Latitude, loc.Longitude, t.Level, t.Size)
	offsetX, offsetY := x-float64(t.X*t.Size), y-float64(t.Y*t.Size)

	if xMax := float64(t.Image.Bounds().Max.X); (offsetX < 0) || (offsetX > xMax) {
		return 0, 0, fmt.Errorf("Tile LocationToPixel error: global X offset not within tile space (x: %d max: %d)", offsetX, int(xMax))
	}
	if yMax := float64(t.Image.Bounds().Max.Y); (offsetY < 0) || (offsetY > yMax) {
		return 0, 0, fmt.Errorf("Tile LocationToPixel error: global Y offset not within tile space (y: %d max: %d)", offsetY, int(yMax))
	}

	return offsetX, offsetY, nil
}

// PixelToLocation translates a pixel location in the tile into a global location
func (t *Tile) PixelToLocation(x, y float64) (*base.Location, error) {
	if xMax := float64(t.Image.Bounds().Max.X); (x < 0) || (x > xMax) {
		return nil, fmt.Errorf("Tile LocationToPixel error: global X offset not within tile space (x: %.2f max: %d)", x, int(xMax))
	}
	if yMax := float64(t.Image.Bounds().Max.Y); (y < 0) || (y > yMax) {
		return nil, fmt.Errorf("Tile LocationToPixel error: global Y offset not within tile space (y: %.2f max: %d)", y, int(yMax))
	}

	offsetX, offsetY := x+float64(t.X*t.Size), y+float64(t.Y*t.Size)
	lat, lng := MercatorPixelToLocation(offsetX, offsetY, t.Level, t.Size)

	return &base.Location{Latitude: lat, Longitude: lng}, nil
}

// Justify sets image offsets for drawing
type Justify string

// Constant justification types
const (
	JustifyTop    Justify = "top"
	JustifyLeft   Justify = "left"
	JustifyCenter Justify = "center"
	JustifyBottom Justify = "bottom"
	JustifyRight  Justify = "right"
)

// DrawConfig configures image drawing
type DrawConfig struct {
	Vertical   Justify
	Horizontal Justify
}

// Center preconfigured centering helper
var Center = DrawConfig{JustifyCenter, JustifyCenter}

// DrawLocalXY draws the provided image at the local X/Y coordinates
func (t *Tile) DrawLocalXY(src image.Image, x, y int, config DrawConfig) error {
	dp := image.Point{}

	switch config.Horizontal {
	case JustifyLeft:
		dp.X = x
	case JustifyCenter:
		dp.X = x - src.Bounds().Dx()/2
	case JustifyRight:
		dp.X = x - src.Bounds().Dx()
	default:
		return fmt.Errorf("Unsupported horizontal justification (%s)", config.Horizontal)
	}

	switch config.Vertical {
	case JustifyTop:
		dp.Y = y
	case JustifyCenter:
		dp.Y = y - src.Bounds().Dy()/2
	case JustifyBottom:
		dp.Y = y - src.Bounds().Dy()
	default:
		return fmt.Errorf("Unsupported vertical justification (%s)", config.Horizontal)
	}

	r := image.Rectangle{dp, dp.Add(src.Bounds().Size())}
	draw.Draw(t.Image.(draw.Image), r, src, src.Bounds().Min, draw.Over)

	return nil
}

func (t *Tile) translateGlobalToLocalXY(x, y int) (int, int, error) {
	offsetX := x - int(t.X*t.Size)
	offsetY := y - int(t.Y*t.Size)

	if xMax := int(t.Image.Bounds().Max.X); (offsetX < 0) || (offsetX > xMax) {
		return 0, 0, fmt.Errorf("Tile DrawGlobalXY error: global X offset not within tile space (x: %d max: %d)", offsetX, xMax)
	}
	if yMax := int(t.Image.Bounds().Max.Y); (offsetY < 0) || (offsetY > yMax) {
		return 0, 0, fmt.Errorf("Tile DrawGlobalXY error: global Y offset not within tile space (y: %d max: %d)", offsetY, yMax)
	}

	return offsetX, offsetY, nil
}

// DrawGlobalXY draws the provided image at the global X/Y coordinates
func (t *Tile) DrawGlobalXY(src image.Image, x, y int, config DrawConfig) error {
	offsetX, offsetY, err := t.translateGlobalToLocalXY(x, y)
	if err != nil {
		return err
	}
	t.DrawLocalXY(src, offsetX, offsetY, config)
	return nil
}

// DrawLocation draws the provided image at the provided lat lng
func (t *Tile) DrawLocation(src image.Image, loc base.Location, config DrawConfig) {
	// Calculate location in pixel space
	x, y := MercatorLocationToPixel(loc.Latitude, loc.Longitude, t.Level, t.Size)
	t.DrawGlobalXY(src, int(x), int(y), config)
}

// Interpolate function to be passed to generic line interpolator
type Interpolate func(pixel color.Color) color.Color

// InterpolateLocalXY interpolates a line between two local points and calls the interpolate function on each point
func (t *Tile) InterpolateLocalXY(x1, y1, x2, y2 int, interpolate Interpolate) {
	// This is a bit insane because the ordering between (x1, y1) and (x2, y2) must be preserved
	// So that points

	dx := int(float64(x2) - float64(x1))
	dy := int(float64(y2) - float64(y1))

	len := int(math.Sqrt(math.Pow(float64(dx), 2) + math.Pow(float64(dy), 2)))

	img := t.Image.(draw.Image)

	for i := 0; i < len; i++ {
		x := x1 + i*dx/len
		y := y1 + i*dy/len
		pixel := interpolate(img.At(x, y))
		img.Set(x, y, pixel)
	}
}

// InterpolateGlobalXY interpolates a line between two global points and calls the interpolate function on each point
func (t *Tile) InterpolateGlobalXY(x1, y1, x2, y2 int, interpolate Interpolate) error {
	offsetX1, offsetY1, err := t.translateGlobalToLocalXY(x1, y1)
	if err != nil {
		return err
	}
	offsetX2, offsetY2, err := t.translateGlobalToLocalXY(x2, y2)
	if err != nil {
		return err
	}
	t.InterpolateLocalXY(offsetX1, offsetY1, offsetX2, offsetY2, interpolate)
	return nil
}

// InterpolateLocations interpolates a line between two locations and calls the interpolate function on each point
func (t *Tile) InterpolateLocations(loc1, loc2 base.Location, interpolate Interpolate) error {
	x1, y1 := MercatorLocationToPixel(loc1.Latitude, loc1.Longitude, t.Level, t.Size)
	x2, y2 := MercatorLocationToPixel(loc2.Latitude, loc2.Longitude, t.Level, t.Size)
	return t.InterpolateGlobalXY(int(x1), int(y1), int(x2), int(y2), interpolate)
}

// DrawLine uses InterpolateLocations to draw a line between two points
func (t *Tile) DrawLine(loc1, loc2 base.Location, c color.Color) {
	t.InterpolateLocations(loc1, loc2, func(color.Color) color.Color {
		return c
	})
}

func (t *Tile) GetAltitude(loc base.Location) (float64, error) {
	x, y := MercatorLocationToPixel(loc.Latitude, loc.Longitude, t.Level, t.Size)
	offsetX, offsetY, err := t.translateGlobalToLocalXY(int(x), int(y))
	if err != nil {
		return 0.0, err
	}
	p := t.Image.At(offsetX, offsetY).(color.NRGBA)
	return PixelToHeight(p.R, p.G, p.B), nil
}

func (t *Tile) InterpolateAltitudes(loc1, loc2 base.Location) []float64 {
	altitudes := make([]float64, 0)
	t.InterpolateLocations(loc1, loc2, func(c color.Color) color.Color {
		p := c.(color.NRGBA)
		alt := PixelToHeight(p.R, p.G, p.B)
		altitudes = append(altitudes, alt)
		return c
	})
	return altitudes
}

func (t *Tile) GetHighestAltitude() float64 {
	p := t.Image.At(0, 0).(color.NRGBA)
	max := PixelToHeight(p.R, p.G, p.B)
	for y := 0; y < t.Image.Bounds().Dy(); y++ {
		for x := 0; x < t.Image.Bounds().Dx(); x++ {
			p := t.Image.At(x, y).(color.NRGBA)
			alt := PixelToHeight(p.R, p.G, p.B)
			if alt > max {
				max = alt
			}
		}
	}
	return max
}

func (t *Tile) FlattenAltitudes(maxHeight float64) Tile {
	img := image.NewNRGBA(t.Image.Bounds())

	for y := 0; y < t.Image.Bounds().Dy(); y++ {
		for x := 0; x < t.Image.Bounds().Dx(); x++ {
			p := t.Image.At(x, y).(color.NRGBA)
			alt := uint8(PixelToHeight(p.R, p.G, p.B) / maxHeight * 255)
			img.Set(x, y, color.RGBA{R: alt, G: alt, B: alt, A: 255})
		}
	}

	return NewTile(t.X, t.Y, t.Level, t.Size, img)
}
<|endoftext|>


<commit_before>package main

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

	"github.com/colinmarc/hdfs"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/stripe/sequins/backend"
)

func setupHdfs(t *testing.T) *backend.HdfsBackend {
	nn := os.Getenv("HADOOP_NAMENODE")
	if nn == "" {
		t.Skip("Skipping hdfs tests because HADOOP_NAMENODE isn't set")
	}

	client, err := hdfs.New(nn)
	if err != nil {
		t.Fatal(err)
	}

	infos, _ := ioutil.ReadDir("test/baby-names/1")
	rootDest := path.Join("/", "_test_sequins", "baby-names")
	for _, info := range infos {
		putHDFS(client, path.Join(rootDest, "0", info.Name()), filepath.Join("test/baby-names/1", info.Name()))
		putHDFS(client, path.Join(rootDest, "1", info.Name()), filepath.Join("test/baby-names/1", info.Name()))
	}

	client.CreateEmptyFile(path.Join(rootDest, "0", "_SUCCESS"))
	return backend.NewHdfsBackend(client, nn, "/_test_sequins")
}

func tearDownHdfs(t *testing.T) {
	nn := os.Getenv("HADOOP_NAMENODE")

	client, err := hdfs.New(nn)
	if err != nil {
		t.Fatal(err)
	}

	client.Remove("/_test_sequins")
}

func putHDFS(client *hdfs.Client, dest, src string) {
	dir, _ := path.Split(dest)
	client.MkdirAll(dir, 0777|os.ModeDir)
	client.CopyToRemote(src, dest)
}

func getHdfsSequins(t *testing.T) *sequins {
	backend := setupHdfs(t)
	s := getSequins(t, backend, "")

	return s
}

func TestHdfsBackend(t *testing.T) {
	h := setupHdfs(t)

	dbs, err := h.ListDBs()
	require.NoError(t, err, "it should be able to list dbs")
	assert.Equal(t, []string{"names"}, dbs, "the list of dbs should be correct")

	versions, err := h.ListVersions("names", false)
	require.NoError(t, err, "it should be able to list versions")
	assert.Equal(t, []string{"0", "1"}, versions, "it should be able to list versions")

	versions, err = h.ListVersions("names", true)
	require.NoError(t, err, "it should be able to list versions with a _SUCCESS file")
	assert.Equal(t, []string{"0"}, versions, "the list of versions with a _SUCCESS file should be correct")

	files, err := h.ListFiles("names", "0")
	require.NoError(t, err, "it should be able to list files")
	assert.Equal(t, []string{"part-00000", "part-00001"}, files, "the list of files should be correct")

	tearDownHdfs(t)
}

func TestHdfsSequins(t *testing.T) {
	ts := getHdfsSequins(t)
	testBasicSequins(t, ts, fmt.Sprintf("hdfs://%s/_test_sequins/baby-names/1", os.Getenv("HADOOP_NAMENODE")))
	tearDownHdfs(t)
}
<commit_msg>A few more test fixes<commit_after>package main

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

	"github.com/colinmarc/hdfs"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/stripe/sequins/backend"
)

func setupHdfs(t *testing.T) *backend.HdfsBackend {
	nn := os.Getenv("HADOOP_NAMENODE")
	if nn == "" {
		t.Skip("Skipping hdfs tests because HADOOP_NAMENODE isn't set")
	}

	client, err := hdfs.New(nn)
	if err != nil {
		t.Fatal(err)
	}

	infos, _ := ioutil.ReadDir("test/baby-names/1")
	rootDest := path.Join("/", "_test_sequins", "baby-names")
	for _, info := range infos {
		putHDFS(client, path.Join(rootDest, "0", info.Name()), filepath.Join("test/baby-names/1", info.Name()))
		putHDFS(client, path.Join(rootDest, "1", info.Name()), filepath.Join("test/baby-names/1", info.Name()))
	}

	client.CreateEmptyFile(path.Join(rootDest, "0", "_SUCCESS"))
	return backend.NewHdfsBackend(client, nn, "/_test_sequins")
}

func tearDownHdfs(t *testing.T) {
	nn := os.Getenv("HADOOP_NAMENODE")

	client, err := hdfs.New(nn)
	if err != nil {
		t.Fatal(err)
	}

	client.Remove("/_test_sequins")
}

func putHDFS(client *hdfs.Client, dest, src string) {
	dir, _ := path.Split(dest)
	client.MkdirAll(dir, 0777|os.ModeDir)
	client.CopyToRemote(src, dest)
}

func getHdfsSequins(t *testing.T) *sequins {
	backend := setupHdfs(t)
	s := getSequins(t, backend, "")

	return s
}

func TestHdfsBackend(t *testing.T) {
	h := setupHdfs(t)

	dbs, err := h.ListDBs()
	require.NoError(t, err, "it should be able to list dbs")
	assert.Equal(t, []string{"baby-names"}, dbs, "the list of dbs should be correct")

	versions, err := h.ListVersions("baby-names", false)
	require.NoError(t, err, "it should be able to list versions")
	assert.Equal(t, []string{"0", "1"}, versions, "it should be able to list versions")

	versions, err = h.ListVersions("baby-names", true)
	require.NoError(t, err, "it should be able to list versions with a _SUCCESS file")
	assert.Equal(t, []string{"0"}, versions, "the list of versions with a _SUCCESS file should be correct")

	files, err := h.ListFiles("baby-names", "0")
	require.NoError(t, err, "it should be able to list files")
	assert.Equal(t, 20, len(files), "the list of files should be correct")

	tearDownHdfs(t)
}

func TestHdfsSequins(t *testing.T) {
	ts := getHdfsSequins(t)
	testBasicSequins(t, ts, fmt.Sprintf("hdfs://%s/_test_sequins/baby-names/1", os.Getenv("HADOOP_NAMENODE")))
	tearDownHdfs(t)
}
<|endoftext|>


<commit_before>package main

import (
	//	"encoding/binary"
	"fmt"
	"syscall"
	"unsafe"
)

const (
	MAX_AUDIT_MESSAGE_LENGTH = 8970
)

/*
#define MAX_AUDIT_MESSAGE_LENGTH    8970 // PATH_MAX*2+CONTEXT_SIZE*2+11+256+1
struct audit_message {
	struct nlmsghdr nlh;
	char   data[MAX_AUDIT_MESSAGE_LENGTH];
};
*/
/*
type AuditMessage struct {
	Mesg   []byte
	Family uint8
}
struct audit_reply {
	int                      type;
	int                      len;
	struct nlmsghdr         *nlh;
	struct audit_message     msg;

	// Using a union to compress this structure since only one of
	 * the following should be valid for any packet. //
	union {
	struct audit_status     *status;
	struct audit_rule_data  *ruledata;
	struct audit_login      *login;
	const char              *message;
	struct nlmsgerr         *error;
	struct audit_sig_info   *signal_info;
	struct daemon_conf      *conf;
#if HAVE_DECL_AUDIT_FEATURE_VERSION
	struct audit_features	*features;
#endif
	};
};

*/
type netlinkAuditRequest struct {
	Header syscall.NlMsghdr
	Data   byte
}

/*
func (rr *netlinkAuditRequest) toWireFormat() []byte {
	b := make([]byte, rr.Header.Len)
	*(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
	*(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
	*(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
	*(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
	*(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
	b[16] = byte(rr.Data.Family)
	return b
}
*/

func newNetlinkAuditRequest(proto, seq, family int) []byte {
	rr := &netlinkAuditRequest{}

	rr.Header.Len = uint32(syscall.NLMSG_HDRLEN) //
	rr.Header.Type = uint16(proto)
	rr.Header.Flags = syscall.NLM_F_REQUEST
	rr.Header.Seq = uint32(seq)
	b := make([]byte, rr.Header.Len)
	*(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
	*(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
	//	fmt.Printf("%+v,%+v\n", *(*uint16)(unsafe.Pointer(&b[4:6][0])), rr.Header.Type)
	*(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
	//	fmt.Printf("%+v,%+v\n", *(*uint16)(unsafe.Pointer(&b[6:8][0])), rr.Header.Flags)

	*(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
	*(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
	//b[16] = byte(family)
	return b
}

// Round the length of a netlink message up to align it properly.
func nlmAlignOf(msglen int) int {
	return (msglen + syscall.NLMSG_ALIGNTO - 1) & ^(syscall.NLMSG_ALIGNTO - 1)
}

/*
func nativeEndian() binary.ByteOrder {
	var x uint32 = 0x01020304
	if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
		return binary.BigEndian
	}
	return binary.LittleEndian
}
*/
func ParseAuditNetlinkMessage(b []byte) ([]syscall.NetlinkMessage, error) {
	var msgs []syscall.NetlinkMessage
	for len(b) >= syscall.NLMSG_HDRLEN {
		h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
		if err != nil {
			fmt.Println("Error in parse")
			return nil, err
		}
		m := syscall.NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len)-syscall.NLMSG_HDRLEN]}
		msgs = append(msgs, m)
		b = b[dlen:]
	}
	return msgs, nil
}

func netlinkMessageHeaderAndData(b []byte) (*syscall.NlMsghdr, []byte, int, error) {

	h := (*syscall.NlMsghdr)(unsafe.Pointer(&b[0]))
	if int(h.Len) < syscall.NLMSG_HDRLEN || int(h.Len) > len(b) {
		fmt.Println("Error Here")
		fmt.Println(syscall.NLMSG_HDRLEN, h.Len, h.Len, len(b))
		return nil, nil, 0, syscall.EINVAL
	}
	return h, b[syscall.NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
}

func newNetlink(proto, family int) ([]byte, error) {
	//native := nativeEndian()
	s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_AUDIT)
	if err != nil {
		return nil, err
	}
	defer syscall.Close(s)
	lsa := &syscall.SockaddrNetlink{Family: syscall.AF_NETLINK, Pid: 0, Groups: 0}
	if err := syscall.Bind(s, lsa); err != nil {
		return nil, err
	}

	wb := newNetlinkAuditRequest(proto, 1, family)
	//Sending the request to kernel

	//fmt.Printf("Sent(Raw) %+v\n", wb)
	if err := syscall.Sendto(s, wb, 0, lsa); err != nil {
		return nil, err
	}
	var tab []byte
	// done:
	//for {
	//Running for one time only
	rb := make([]byte, syscall.Getpagesize())

	nr, _, err := syscall.Recvfrom(s, rb, syscall.MSG_PEEK|syscall.MSG_DONTWAIT)
	//		fmt.Printf("%v\n", nr)

	if err != nil {
		fmt.Println("Error on Receiving")
		return nil, err
	}
	if nr < syscall.NLMSG_HDRLEN {
		return nil, syscall.EINVAL
	}
	rb = rb[:nr]
	//		fmt.Printf("Received (Raw)%v\n", rb)
	//		fmt.Printf("Received (Raw)%x\n", rb)

	tab = append(tab, rb...)
	msgs, err := ParseAuditNetlinkMessage(rb)
	if err != nil {
		fmt.Println("Error in Parsing")
		return nil, err
	}
	for _, m := range msgs {
		lsa, err := syscall.Getsockname(s)
		if err != nil {
			fmt.Println("Error in getting Sockaddr name")
			return nil, err
		}
		switch v := lsa.(type) {
		case *syscall.SockaddrNetlink:
			if m.Header.Seq != 1 || m.Header.Pid != v.Pid {
				fmt.Println("Messgage sequence or Pid didn't match")
				return nil, syscall.EINVAL
			}
		default:
			fmt.Println("foo4")
			return nil, syscall.EINVAL
		}
		if m.Header.Type == syscall.NLMSG_DONE {
			//return tab, nil
			fmt.Println("Message parsed..")
			break
		}
		if m.Header.Type == syscall.NLMSG_ERROR {

			//	fmt.Printf("%x\n", m.Data)
			//	fmt.Printf("%v\n", m.Header.Flags)
			//				fmt.Println("%x\n", m.Header.Type)
			fmt.Println("NLMSG_ERROR")
			//				fmt.Println(error)
			break
			//return nil, EINVAL
		}
	}
	//}
	return tab, nil

}

func main() {
	v, er := newNetlink(1000, syscall.AF_NETLINK)
	//Types are defined in /usr/include/linux/audit.h
	//See https://www.redhat.com/archives/linux-audit/2011-January/msg00030.html
	if er != nil {
		fmt.Println("Got error on last")

		//fmt.Println(er)
	} else {
		//str := string(v[:])
		fmt.Println(v)
	}
	//	NetLinkListener()
}
<commit_msg>Restructured Code + AUDIT_STATUS<commit_after>package main

import (
	//	"encoding/binary"
	"fmt"
	"syscall"
	"unsafe"
)

const (
	MAX_AUDIT_MESSAGE_LENGTH = 8970
	AUDIT_GET                = 1000
)

/*
#define MAX_AUDIT_MESSAGE_LENGTH    8970 // PATH_MAX*2+CONTEXT_SIZE*2+11+256+1
struct audit_message {
	struct nlmsghdr nlh;
	char   data[MAX_AUDIT_MESSAGE_LENGTH];
};
*/
/*
struct audit_reply {
	int                      type;
	int                      len;
	struct nlmsghdr         *nlh;
	struct audit_message     msg;

	// Using a union to compress this structure since only one of
	 * the following should be valid for any packet. //
	union {
	struct audit_status     *status;
	struct audit_rule_data  *ruledata;
	struct audit_login      *login;
	const char              *message;
	struct nlmsgerr         *error;
	struct audit_sig_info   *signal_info;
	struct daemon_conf      *conf;
#if HAVE_DECL_AUDIT_FEATURE_VERSION
	struct audit_features	*features;
#endif
	};
};

*/
/*
func nativeEndian() binary.ByteOrder {
	var x uint32 = 0x01020304
	if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
		return binary.BigEndian
	}
	return binary.LittleEndian
}
*/

type NetlinkAuditRequest struct {
	Header syscall.NlMsghdr
	Data   byte
}

type AuditReply struct {
	RepHeader syscall.NlMsghdr
	Message   NetlinkAuditRequest
}

func (rr *NetlinkAuditRequest) ToWireFormat() []byte {
	b := make([]byte, rr.Header.Len)
	*(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
	*(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
	//	fmt.Printf("%+v,%+v\n", *(*uint16)(unsafe.Pointer(&b[4:6][0])), rr.Header.Type)
	*(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
	//	fmt.Printf("%+v,%+v\n", *(*uint16)(unsafe.Pointer(&b[6:8][0])), rr.Header.Flags)

	*(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
	*(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
	//b[16] = byte(family)
	return b
}

func newNetlinkAuditRequest(proto, seq, family int) *NetlinkAuditRequest {
	rr := &NetlinkAuditRequest{}

	rr.Header.Len = uint32(syscall.NLMSG_HDRLEN) //
	rr.Header.Type = uint16(proto)
	rr.Header.Flags = syscall.NLM_F_REQUEST
	rr.Header.Seq = uint32(seq)
	return rr
	//	return rr.ToWireFormat()
}

// Round the length of a netlink message up to align it properly.
func nlmAlignOf(msglen int) int {
	return (msglen + syscall.NLMSG_ALIGNTO - 1) & ^(syscall.NLMSG_ALIGNTO - 1)
}

func ParseAuditNetlinkMessage(b []byte) ([]syscall.NetlinkMessage, error) {
	var msgs []syscall.NetlinkMessage
	for len(b) >= syscall.NLMSG_HDRLEN {
		h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
		if err != nil {
			fmt.Println("Error in parse")
			return nil, err
		}
		m := syscall.NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len)-syscall.NLMSG_HDRLEN]}
		msgs = append(msgs, m)
		b = b[dlen:]
	}
	return msgs, nil
}

func netlinkMessageHeaderAndData(b []byte) (*syscall.NlMsghdr, []byte, int, error) {

	h := (*syscall.NlMsghdr)(unsafe.Pointer(&b[0]))
	if int(h.Len) < syscall.NLMSG_HDRLEN || int(h.Len) > len(b) {
		fmt.Println("Error Here")
		fmt.Println(syscall.NLMSG_HDRLEN, h.Len, h.Len, len(b))
		return nil, nil, 0, syscall.EINVAL
	}
	return h, b[syscall.NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
}

/*
Inspired from Docker library

type NetlinkRequest struct {
	syscall.NlMsghdr
	Data []NetlinkRequestData
}

func (rr *NetlinkRequest) ToWireFormat() []byte {
	native := nativeEndian()

	length := rr.Len
	dataBytes := make([][]byte, len(rr.Data))
	for i, data := range rr.Data {
		dataBytes[i] = data.ToWireFormat()
		length += uint32(len(dataBytes[i]))
	}
	b := make([]byte, length)
	native.PutUint32(b[0:4], length)
	native.PutUint16(b[4:6], rr.Type)
	native.PutUint16(b[6:8], rr.Flags)
	native.PutUint32(b[8:12], rr.Seq)
	native.PutUint32(b[12:16], rr.Pid)

	next := 16
	for _, data := range dataBytes {
		copy(b[next:], data)
		next += len(data)
	}
	return b
}

func (rr *NetlinkRequest) AddData(data NetlinkRequestData) {
	if data != nil {
		rr.Data = append(rr.Data, data)
	}
}

func newNetlinkRequest(proto, flags int) *NetlinkRequest {
	return &NetlinkRequest{
		NlMsghdr: syscall.NlMsghdr{
			Len:   uint32(syscall.NLMSG_HDRLEN),
			Type:  uint16(proto),
			Flags: syscall.NLM_F_REQUEST | uint16(flags),
			Seq:   atomic.AddUint32(&nextSeqNr, 1),
		},
	}
}
*/
type NetlinkSocket struct {
	fd  int
	lsa syscall.SockaddrNetlink
}

func getNetlinkSocket() (*NetlinkSocket, error) {
	fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_AUDIT)
	if err != nil {
		return nil, err
	}
	s := &NetlinkSocket{
		fd: fd,
	}
	s.lsa.Family = syscall.AF_NETLINK
	s.lsa.Groups = 0
	s.lsa.Pid = 0

	if err := syscall.Bind(fd, &s.lsa); err != nil {
		syscall.Close(fd)
		return nil, err
	}
	return s, nil
}

func (s *NetlinkSocket) Close() {
	syscall.Close(s.fd)
}

func (s *NetlinkSocket) Send(request *NetlinkAuditRequest) error {
	//fmt.Printf("Sent(Raw) %+v\n", wb)
	//Sending the request to kernel

	if err := syscall.Sendto(s.fd, request.ToWireFormat(), 0, &s.lsa); err != nil {
		return err
	}
	return nil
}

func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
	rb := make([]byte, syscall.Getpagesize())
	nr, _, err := syscall.Recvfrom(s.fd, rb, syscall.MSG_PEEK|syscall.MSG_DONTWAIT)
	//nr, _, err := syscall.Recvfrom(s, rb, syscall.MSG_PEEK|syscall.MSG_DONTWAIT)

	if err != nil {
		return nil, err
	}
	if nr < syscall.NLMSG_HDRLEN {
		return nil, syscall.EINVAL //ErrShortResponse
	}
	rb = rb[:nr]
	fmt.Printf("Received (Raw)%v\n", rb)
	return ParseAuditNetlinkMessage(rb) //Or syscall.ParseNetlinkMessage(rb)
}

func AuditNetlink(proto, family int) ([]byte, error) {
	//native := nativeEndian()
	s, err := getNetlinkSocket()

	if err != nil {
		return nil, err
	}

	defer s.Close()

	wb := newNetlinkAuditRequest(proto, 1, family)

	if err := s.Send(wb); err != nil {
		return nil, err
	}

	/*
		if err := syscall.Sendto(s, wb, 0, lsa); err != nil {
			return nil, err
		}
	*/
	var tab []byte

	// done:
	//for {
	//Running for one time only
	/*rb := make([]byte, syscall.Getpagesize())

	nr, _, err := syscall.Recvfrom(s, rb, syscall.MSG_PEEK|syscall.MSG_DONTWAIT)

	if err != nil {
		fmt.Println("Error on Receiving")
		return nil, err
	}
	if nr < syscall.NLMSG_HDRLEN {
		return nil, syscall.EINVAL
	}
	rb = rb[:nr]
	*/
	//	tab = append(tab, rb...)
	msgs, err := s.Receive() //ParseAuditNetlinkMessage(rb)
	if err != nil {
		fmt.Println("Error in Parsing")
		return nil, err
	}

	for _, m := range msgs {
		lsa, err := syscall.Getsockname(s.fd)
		if err != nil {
			fmt.Println("Error in getting Sockaddr name")
			return nil, err
		}
		switch v := lsa.(type) {
		case *syscall.SockaddrNetlink:

			if m.Header.Seq != 1 || m.Header.Pid != v.Pid {
				fmt.Println("Messgage sequence or Pid didn't match")
				return nil, syscall.EINVAL
			}
		default:
			fmt.Println("foo4")
			return nil, syscall.EINVAL
			/*
				if m.Header.Seq != wb.seq {
					return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, seq)
				}
				if m.Header.Pid != pid {
					return fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
				}

			*/

		}

		if m.Header.Type == syscall.NLMSG_DONE {
			break //done
		}
		if m.Header.Type == syscall.NLMSG_ERROR {
			//error := int32(native.Uint32(m.Data[0:4]))
			fmt.Println("NLMSG_ERROR")
			return nil, syscall.EINVAL
		}
		if m.Header.Type == AUDIT_GET { //SHORT FOR AUDIT_GET
			fmt.Println("ENABLED")
			break
		}

	}
	//}
	return tab, nil

}

func main() {
	_, er := AuditNetlink(AUDIT_GET, syscall.AF_NETLINK)
	//Types are defined in /usr/include/linux/audit.h
	//See https://www.redhat.com/archives/linux-audit/2011-January/msg00030.html
	if er != nil {
		fmt.Println("Got error on last")

		//fmt.Println(er)
	} else {
		//str := string(v[:])
		fmt.Println("Sucess!")
	}
	//	NetLinkListener()
}
<|endoftext|>


<commit_before>package typhon

import (
	"encoding/json"
	"errors"

	"github.com/mondough/terrors"
	"github.com/mondough/terrors/proto"
)

// networkFilter prepares the request and response for network transport
func networkFilter(req Request, svc Service) Response {
	rsp := svc(req)
	rsp.ctx = req.Context

	if rsp.Response == nil {
		// Errors often won't have a HTTP response
		rsp.Response = newHttpResponse(req)
	}

	if rsp.Error != nil {
		// Serialise the error into the response
		terr := terrors.Wrap(rsp.Error, nil).(*terrors.Error)
		rsp.Encode(terrors.Marshal(terr))
		rsp.StatusCode = terr2StatusCode(terr.Code)
		rsp.Header.Set("Terror", "1")
	} else if rsp.StatusCode >= 400 && rsp.StatusCode <= 599 {
		// Deserialise the response error
		b, err := rsp.BodyBytes(false)
		if err == nil {
			if rsp.Header.Get("Terror") == "1" {
				tp := &terrorsproto.Error{}
				if err := json.Unmarshal(b, tp); err == nil {
					rsp.Error = terrors.Unmarshal(tp)
				}
			}
			if rsp.Error == nil {
				rsp.Error = errors.New(string(b))
			}
		}
	}

	return rsp
}
<commit_msg>Don't "upgrade" any old 4xx to a terror<commit_after>package typhon

import (
	"encoding/json"
	"errors"

	log "github.com/mondough/slog"
	"github.com/mondough/terrors"
	"github.com/mondough/terrors/proto"
)

// networkFilter prepares the request and response for network transport
func networkFilter(req Request, svc Service) Response {
	rsp := svc(req)
	rsp.ctx = req.Context

	if rsp.Response == nil {
		// Errors often won't have a HTTP response
		rsp.Response = newHttpResponse(req)
	}

	if rsp.Error != nil {
		// Serialise the error into the response
		terr := terrors.Wrap(rsp.Error, nil).(*terrors.Error)
		rsp.Encode(terrors.Marshal(terr))
		rsp.StatusCode = terr2StatusCode(terr.Code)
		rsp.Header.Set("Terror", "1")
	} else if rsp.StatusCode >= 400 && rsp.StatusCode <= 599 && rsp.Header.Get("Terror") == "1" {
		b, _ := rsp.BodyBytes(false)
		tp := &terrorsproto.Error{}
		if err := json.Unmarshal(b, tp); err != nil {
			log.Warn(req, "Failed to unmarshal terror: %v", err)
			rsp.Error = errors.New(string(b))
		} else {
			rsp.Error = terrors.Unmarshal(tp)
		}
	} else if rsp.StatusCode >= 500 && rsp.StatusCode <= 599 {
		b, _ := rsp.BodyBytes(false)
		rsp.Error = errors.New(string(b))
	}

	return rsp
}
<|endoftext|>


<commit_before>package host

import (
	"os"
	"os/user"
	"strings"
	"syscall"

	h "github.com/shirou/gopsutil/host"
)

type Facter interface {
	Add(string, interface{})
}

// int8ToString converts [65]int8 in syscall.Utsname to string
func int8ToString(bs [65]int8) string {
	b := make([]byte, len(bs))
	for i, v := range bs {
		if v < 0 {
			b[i] = byte(256 + int(v))
		} else {
			b[i] = byte(v)
		}
	}
	return string(b)
}

func GetHostFacts(f Facter) error {
	hostInfo, err := h.Info()
	if err != nil {
		return err
	}
	// TODO - capitalize the first letter of kernel and OS
	f.Add("fqdn", hostInfo.Hostname)
	splitted := strings.SplitN(hostInfo.Hostname, ".", 2)
	var hostname *string
	if len(splitted) > 1 {
		hostname = &splitted[0]
		f.Add("domain", splitted[1])
	} else {
		hostname = &hostInfo.Hostname
	}
	f.Add("hostname", *hostname)

	var is_virtual bool
	if hostInfo.VirtualizationRole == "host" {
		is_virtual = false
	} else {
		is_virtual = true
	}
	f.Add("is_virtual", is_virtual)

	f.Add("kernel", hostInfo.OS)
	f.Add("operatingsystemrelease", hostInfo.PlatformVersion)
	f.Add("operatingsystem", hostInfo.Platform)
	f.Add("osfamily", hostInfo.PlatformFamily)
	f.Add("uptime_seconds", hostInfo.Uptime)
	f.Add("uptime_minutes", hostInfo.Uptime/60)
	f.Add("uptime_hours", hostInfo.Uptime/60/60)
	f.Add("uptime_days", hostInfo.Uptime/60/60/24)
	f.Add("virtual", hostInfo.VirtualizationSystem)

	envPath := os.Getenv("PATH")
	if envPath != "" {
		f.Add("path", envPath)
	}

	user, err := user.Current()
	if err == nil {
		f.Add("id", user.Username)
	} else {
		panic(err)
	}

	var uname syscall.Utsname
	err = syscall.Uname(&uname)
	if err == nil {
		kernelRelease := int8ToString(uname.Release)
		f.Add("kernelrelease", kernelRelease)
		f.Add("kernelversion", strings.Split(kernelRelease, "-")[0])
		f.Add("hardwaremodel", int8ToString(uname.Machine))
	}

	return nil
}
<commit_msg>Guess Architecture if possible<commit_after>package host

import (
	"os"
	"os/user"
	"strings"
	"syscall"

	h "github.com/shirou/gopsutil/host"
)

type Facter interface {
	Add(string, interface{})
}

func guessArch(HWModel string) string {
	var arch string
	switch HWModel {
	case "x86_64":
		arch = "amd64"
		break
	default:
		arch = "unknown"
		break
	}
	return arch
}

// int8ToString converts [65]int8 in syscall.Utsname to string
func int8ToString(bs [65]int8) string {
	b := make([]byte, len(bs))
	for i, v := range bs {
		if v < 0 {
			b[i] = byte(256 + int(v))
		} else {
			b[i] = byte(v)
		}
	}
	return string(b)
}

func GetHostFacts(f Facter) error {
	hostInfo, err := h.Info()
	if err != nil {
		return err
	}
	// TODO - capitalize the first letter of kernel and OS
	f.Add("fqdn", hostInfo.Hostname)
	splitted := strings.SplitN(hostInfo.Hostname, ".", 2)
	var hostname *string
	if len(splitted) > 1 {
		hostname = &splitted[0]
		f.Add("domain", splitted[1])
	} else {
		hostname = &hostInfo.Hostname
	}
	f.Add("hostname", *hostname)

	var is_virtual bool
	if hostInfo.VirtualizationRole == "host" {
		is_virtual = false
	} else {
		is_virtual = true
	}
	f.Add("is_virtual", is_virtual)

	f.Add("kernel", hostInfo.OS)
	f.Add("operatingsystemrelease", hostInfo.PlatformVersion)
	f.Add("operatingsystem", hostInfo.Platform)
	f.Add("osfamily", hostInfo.PlatformFamily)
	f.Add("uptime_seconds", hostInfo.Uptime)
	f.Add("uptime_minutes", hostInfo.Uptime/60)
	f.Add("uptime_hours", hostInfo.Uptime/60/60)
	f.Add("uptime_days", hostInfo.Uptime/60/60/24)
	f.Add("virtual", hostInfo.VirtualizationSystem)

	envPath := os.Getenv("PATH")
	if envPath != "" {
		f.Add("path", envPath)
	}

	user, err := user.Current()
	if err == nil {
		f.Add("id", user.Username)
	} else {
		panic(err)
	}

	var uname syscall.Utsname
	err = syscall.Uname(&uname)
	if err == nil {
		kernelRelease := int8ToString(uname.Release)
		f.Add("kernelrelease", kernelRelease)
		f.Add("kernelversion", strings.Split(kernelRelease, "-")[0])

		hardwareModel := int8ToString(uname.Machine)
		f.Add("hardwaremodel", hardwareModel)
		f.Add("architecture", guessArch(hardwareModel))
	}

	return nil
}
<|endoftext|>


<commit_before>package apixu

import (
	"os"
	"testing"
	"time"
)

const InvalidCityName = "INVALID-CITY-NAME"

var cities = []string{
	"Cairo",
	"London",
	"Paris",
	"Berlin",
	"New York",
}

func getAPIKey() string {
	return os.Getenv("APIXU_KEY")
}

func TestInvalidAPIKey(t *testing.T) {
	client := NewClient("Invalid_Key")
	_, err := client.Current("Paris")

	if err == nil {
		t.Error("Worked with invalid key")
	}
}

func TestCurrentWeatherValidCities(t *testing.T) {
	client := NewClient(getAPIKey())

	for _, city := range cities {
		_, err := client.Current(city)

		if err != nil {
			t.Errorf("There was an error getting current weather of %s: %v", city, err)
		}
	}
}

func TestCurrentWeatherInValidCity(t *testing.T) {
	client := NewClient(getAPIKey())
	_, err := client.Current(InvalidCityName)

	if err == nil {
		t.Error("No errors getting current weather of invalid city name")
	}
}

func TestForecastWeatherValidCities(t *testing.T) {
	days := []int{1, 5, 10}
	client := NewClient(getAPIKey())

	for _, day := range days {
		for _, city := range cities {
			_, err := client.Forecast(city, day)

			if err != nil {
				t.Errorf("There was an error getting forecast weather of %s days %d: %v", city, day, err)
			}
		}
	}
}

func TestForecastWeatherInValidCity(t *testing.T) {
	days := []int{1, 5, 10}
	client := NewClient(getAPIKey())

	for _, day := range days {
		_, err := client.Forecast(InvalidCityName, day)

		if err == nil {
			t.Error("No errors getting forecast weather of invalid city name")
		}
	}
}

func TestHistoryWeatherValidCities(t *testing.T) {
	yesterday := time.Now().AddDate(0, 0, -1)
	client := NewClient(getAPIKey())

	for _, city := range cities {
		_, err := client.History(city, yesterday.Format("2006 01 2"))

		if err != nil {
			t.Errorf("There was an error getting current weather of %s: %v", city, err)
		}
	}
}

func TestHistoryWeatherInValidCity(t *testing.T) {
	yesterday := time.Now().AddDate(0, 0, -1)
	client := NewClient(getAPIKey())

	_, err := client.History(InvalidCityName, yesterday.Format("2006 01 2"))

	if err == nil {
		t.Error("No errors getting history weather of invalid city name")
	}

}

func TestSearchValidCities(t *testing.T) {
	client := NewClient(getAPIKey())

	for _, city := range cities {
		_, err := client.Search(city)

		if err != nil {
			t.Errorf("There was an error getting current weather of %s: %v", city, err)
		}
	}
}

func TestSearchInValidCity(t *testing.T) {
	client := NewClient(getAPIKey())

	matchedCities, err := client.Search(InvalidCityName)

	if err != nil {
		t.Error(err)
	}

	if len(*matchedCities) != 0 {
		t.Error("Non-Empty array of matched cities for invalid city name")
	}
}
<commit_msg>Fix date format<commit_after>package apixu

import (
	"os"
	"testing"
	"time"
)

const InvalidCityName = "INVALID-CITY-NAME"

var cities = []string{
	"Cairo",
	"London",
	"Paris",
	"Berlin",
	"New York",
}

func getAPIKey() string {
	return os.Getenv("APIXU_KEY")
}

func TestInvalidAPIKey(t *testing.T) {
	client := NewClient("Invalid_Key")
	_, err := client.Current("Paris")

	if err == nil {
		t.Error("Worked with invalid key")
	}
}

func TestCurrentWeatherValidCities(t *testing.T) {
	client := NewClient(getAPIKey())

	for _, city := range cities {
		_, err := client.Current(city)

		if err != nil {
			t.Errorf("There was an error getting current weather of %s: %v", city, err)
		}
	}
}

func TestCurrentWeatherInValidCity(t *testing.T) {
	client := NewClient(getAPIKey())
	_, err := client.Current(InvalidCityName)

	if err == nil {
		t.Error("No errors getting current weather of invalid city name")
	}
}

func TestForecastWeatherValidCities(t *testing.T) {
	days := []int{1, 5, 10}
	client := NewClient(getAPIKey())

	for _, day := range days {
		for _, city := range cities {
			_, err := client.Forecast(city, day)

			if err != nil {
				t.Errorf("There was an error getting forecast weather of %s days %d: %v", city, day, err)
			}
		}
	}
}

func TestForecastWeatherInValidCity(t *testing.T) {
	days := []int{1, 5, 10}
	client := NewClient(getAPIKey())

	for _, day := range days {
		_, err := client.Forecast(InvalidCityName, day)

		if err == nil {
			t.Error("No errors getting forecast weather of invalid city name")
		}
	}
}

func TestHistoryWeatherValidCities(t *testing.T) {
	yesterday := time.Now().AddDate(0, 0, -1)
	client := NewClient(getAPIKey())

	for _, city := range cities {
		_, err := client.History(city, yesterday.Format("2006-01-2"))

		if err != nil {
			t.Errorf("There was an error getting current weather of %s: %v", city, err)
		}
	}
}

func TestHistoryWeatherInValidCity(t *testing.T) {
	yesterday := time.Now().AddDate(0, 0, -1)
	client := NewClient(getAPIKey())

	_, err := client.History(InvalidCityName, yesterday.Format("2006-01-2"))

	if err == nil {
		t.Error("No errors getting history weather of invalid city name")
	}

}

func TestSearchValidCities(t *testing.T) {
	client := NewClient(getAPIKey())

	for _, city := range cities {
		_, err := client.Search(city)

		if err != nil {
			t.Errorf("There was an error getting current weather of %s: %v", city, err)
		}
	}
}

func TestSearchInValidCity(t *testing.T) {
	client := NewClient(getAPIKey())

	matchedCities, err := client.Search(InvalidCityName)

	if err != nil {
		t.Error(err)
	}

	if len(*matchedCities) != 0 {
		t.Error("Non-Empty array of matched cities for invalid city name")
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"image"

	"github.com/anthonynsimon/bild/channel"
	"github.com/spf13/cobra"
)

func extractChannel() *cobra.Command {
	var channels string

	var cmd = &cobra.Command{
		Use:     "extract",
		Short:   "extracts RGBA channels from an input image",
		Args:    cobra.ExactArgs(2),
		Example: "extract --channels rb input.jpg output.png",
		Run: func(cmd *cobra.Command, args []string) {
			fin := args[0]
			fout := args[1]

			// Apply takes care of resolving the destination encoder
			apply(fin, fout, func(img image.Image) (image.Image, error) {
				onlyChannels := []channel.Channel{}
				for _, c := range channels {
					switch c {
					case 'r':
						onlyChannels = append(onlyChannels, channel.Red)
					case 'g':
						onlyChannels = append(onlyChannels, channel.Green)
					case 'b':
						onlyChannels = append(onlyChannels, channel.Blue)
					case 'a':
						onlyChannels = append(onlyChannels, channel.Alpha)
					default:
						return nil, fmt.Errorf("unknown channel alias '%c'", c)
					}
				}

				result := channel.ExtractMultiple(img, onlyChannels...)
				return result, nil
			})
		}}

	cmd.Flags().StringVarP(&channels, "channels", "c", "rgba", "the channels to include in the histogram")

	return cmd
}

func createChannel() *cobra.Command {
	var cmd = &cobra.Command{
		Use:   "channel",
		Short: "channel operations on images",
	}

	cmd.AddCommand(extractChannel())

	return cmd
}
<commit_msg>Update example<commit_after>package cmd

import (
	"fmt"
	"image"

	"github.com/anthonynsimon/bild/channel"
	"github.com/spf13/cobra"
)

func extractChannel() *cobra.Command {
	var channels string

	var cmd = &cobra.Command{
		Use:     "extract",
		Short:   "extracts RGBA channels from an input image",
		Args:    cobra.ExactArgs(2),
		Example: "extract --channels rba input.jpg output.png",
		Run: func(cmd *cobra.Command, args []string) {
			fin := args[0]
			fout := args[1]

			// Apply takes care of resolving the destination encoder
			apply(fin, fout, func(img image.Image) (image.Image, error) {
				onlyChannels := []channel.Channel{}
				for _, c := range channels {
					switch c {
					case 'r':
						onlyChannels = append(onlyChannels, channel.Red)
					case 'g':
						onlyChannels = append(onlyChannels, channel.Green)
					case 'b':
						onlyChannels = append(onlyChannels, channel.Blue)
					case 'a':
						onlyChannels = append(onlyChannels, channel.Alpha)
					default:
						return nil, fmt.Errorf("unknown channel alias '%c'", c)
					}
				}

				result := channel.ExtractMultiple(img, onlyChannels...)
				return result, nil
			})
		}}

	cmd.Flags().StringVarP(&channels, "channels", "c", "rgba", "the channels to include in the histogram")

	return cmd
}

func createChannel() *cobra.Command {
	var cmd = &cobra.Command{
		Use:   "channel",
		Short: "channel operations on images",
	}

	cmd.AddCommand(extractChannel())

	return cmd
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/funkygao/gafka"
	"github.com/funkygao/gafka/ctx"
	"github.com/funkygao/gafka/zk"
	"github.com/funkygao/gocli"
	"github.com/funkygao/log4go"
)

func main() {
	ctx.LoadFromHome()
	setupLogging()

	app := os.Args[0]
	args := os.Args[1:]
	for _, arg := range args {
		if arg == "-v" || arg == "--version" {
			newArgs := make([]string, len(args)+1)
			newArgs[0] = "version"
			copy(newArgs[1:], args)
			args = newArgs
			break
		}

		if arg == "--generate-bash-completion" {
			if len(args) > 1 {
				// contextual auto complete
				lastArg := args[len(args)-2]
				switch lastArg {
				case "-z": // zone
					for _, zone := range ctx.SortedZones() {
						fmt.Println(zone)
					}
					return

				case "-c": // cluster
					zone := ctx.ZkDefaultZone()
					for i := 0; i < len(args)-1; i++ {
						if args[i] == "-z" {
							zone = args[i+1]
						}
					}
					zkzone := zk.NewZkZone(zk.DefaultConfig(zone, ctx.ZoneZkAddrs(zone)))
					zkzone.ForSortedClusters(func(zkcluster *zk.ZkCluster) {
						fmt.Println(zkcluster.Name())
					})
					return
				}
			}

			for name := range commands {
				fmt.Println(name)
			}
			for _, cmd := range ctx.Aliases() {
				fmt.Println(cmd)
			}
			return
		}
	}

	c := cli.NewCLI(app, gafka.Version+"-"+gafka.BuildId+"-"+gafka.BuiltAt)
	c.Args = os.Args[1:]
	if len(os.Args) > 1 {
		// command given, convert alias
		if alias, present := ctx.Alias(os.Args[1]); present {
			var cargs []string
			cargs = append(cargs, strings.Split(alias, " ")...)
			if len(os.Args) > 2 {
				cargs = append(cargs, os.Args[2:]...)
			}
			c.Args = cargs
		}
	}
	c.Commands = commands
	c.HelpFunc = func(m map[string]cli.CommandFactory) string {
		var buf bytes.Buffer
		buf.WriteString(fmt.Sprintf("Unified multi-datacenter multi-cluster kafka swiss-knife management console\n\n"))
		buf.WriteString(cli.BasicHelpFunc(app)(m))
		return buf.String()
	}

	exitCode, err := c.Run()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%+v\n", err)
		os.Exit(1)
	} else if c.IsVersion() {
		os.Exit(0)
	}

	os.Exit(exitCode)
}

func setupLogging() {
	log.SetOutput(ioutil.Discard)

	level := log4go.DEBUG
	switch ctx.LogLevel() {
	case "info":
		level = log4go.INFO

	case "warn":
		level = log4go.WARNING

	case "error":
		level = log4go.ERROR

	case "debug":
		level = log4go.DEBUG

	case "trace":
		level = log4go.TRACE

	case "alarm":
		level = log4go.ALARM
	}

	for _, filter := range log4go.Global {
		filter.Level = level
	}

	log4go.AddFilter("stdout", level, log4go.NewConsoleLogWriter())
}
<commit_msg>auto complete topic name<commit_after>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/funkygao/gafka"
	"github.com/funkygao/gafka/ctx"
	"github.com/funkygao/gafka/zk"
	"github.com/funkygao/gocli"
	"github.com/funkygao/log4go"
)

func main() {
	ctx.LoadFromHome()
	setupLogging()

	app := os.Args[0]
	args := os.Args[1:]
	for _, arg := range args {
		if arg == "-v" || arg == "--version" {
			newArgs := make([]string, len(args)+1)
			newArgs[0] = "version"
			copy(newArgs[1:], args)
			args = newArgs
			break
		}

		if arg == "--generate-bash-completion" {
			if len(args) > 1 {
				// contextual auto complete
				lastArg := args[len(args)-2]
				switch lastArg {
				case "-z": // zone
					for _, zone := range ctx.SortedZones() {
						fmt.Println(zone)
					}
					return

				case "-c": // cluster
					zone := ctx.ZkDefaultZone()
					for i := 0; i < len(args)-1; i++ {
						if args[i] == "-z" {
							zone = args[i+1]
						}
					}
					zkzone := zk.NewZkZone(zk.DefaultConfig(zone, ctx.ZoneZkAddrs(zone)))
					zkzone.ForSortedClusters(func(zkcluster *zk.ZkCluster) {
						fmt.Println(zkcluster.Name())
					})
					return

				case "-t": // topic
					zone := ctx.ZkDefaultZone()
					var cluster string
					for i := 0; i < len(args)-1; i++ {
						if args[i] == "-z" {
							zone = args[i+1]
						}

						if args[i] == "-c" {
							cluster = args[i+1]
						}
					}
					if cluster != "" {
						zkzone := zk.NewZkZone(zk.DefaultConfig(zone, ctx.ZoneZkAddrs(zone)))
						zkcluster := zkzone.NewCluster(cluster)
						topics, _ := zkcluster.Topics()
						for _, t := range topics {
							fmt.Println(t)
						}
					}
				}

			}

			for name := range commands {
				fmt.Println(name)
			}
			for _, cmd := range ctx.Aliases() {
				fmt.Println(cmd)
			}
			return
		}
	}

	c := cli.NewCLI(app, gafka.Version+"-"+gafka.BuildId+"-"+gafka.BuiltAt)
	c.Args = os.Args[1:]
	if len(os.Args) > 1 {
		// command given, convert alias
		if alias, present := ctx.Alias(os.Args[1]); present {
			var cargs []string
			cargs = append(cargs, strings.Split(alias, " ")...)
			if len(os.Args) > 2 {
				cargs = append(cargs, os.Args[2:]...)
			}
			c.Args = cargs
		}
	}
	c.Commands = commands
	c.HelpFunc = func(m map[string]cli.CommandFactory) string {
		var buf bytes.Buffer
		buf.WriteString(fmt.Sprintf("Unified multi-datacenter multi-cluster kafka swiss-knife management console\n\n"))
		buf.WriteString(cli.BasicHelpFunc(app)(m))
		return buf.String()
	}

	exitCode, err := c.Run()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%+v\n", err)
		os.Exit(1)
	} else if c.IsVersion() {
		os.Exit(0)
	}

	os.Exit(exitCode)
}

func setupLogging() {
	log.SetOutput(ioutil.Discard)

	level := log4go.DEBUG
	switch ctx.LogLevel() {
	case "info":
		level = log4go.INFO

	case "warn":
		level = log4go.WARNING

	case "error":
		level = log4go.ERROR

	case "debug":
		level = log4go.DEBUG

	case "trace":
		level = log4go.TRACE

	case "alarm":
		level = log4go.ALARM
	}

	for _, filter := range log4go.Global {
		filter.Level = level
	}

	log4go.AddFilter("stdout", level, log4go.NewConsoleLogWriter())
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"

	speaker "github.com/devopsdays/devopsdays-cli/speaker"
	"github.com/spf13/cobra"
)

// addSpeakerCmd represents the "speaker add" command
var addSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Add a speaker to an existing talk",
	Long: `Add a speaker to an existing talk.
You can provide the speaker's name as an argument to this command, but it must be the "cleaned" name.
		`,
	Example: `  devopsdays-cli add speaker george-bluth
  devopsdays-cli add speaker --city new-york
  devopsdays-cli add speaker george-bluth -c "New York" --year "2017"`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		addSpeaker()
	},
}

// createSpeakerCmd represents the "speaker create" command
var createSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Creates a new speaker for an event",
	Long: `Creates a new speaker for an event.
	`,
	Example: `  devopsdays-cli create speaker
  devopsdays-cli create speaker --city new-york
  devopsdays-cli create speaker -c "New York" --year "2017"`,

	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		createSpeakerPrompt(City, Year)
	},
}

// editSpeakerCmd represents the "speaker edi" command
var editSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Edit an event's speaker",
	Long: `Edit an event's speaker.
You can provide the speaker's name as an argument to this command, but it must be the "cleaned" name.
`,
	Example: `  devopsdays-cli edit speaker george-bluth
  devopsdays-cli edit speaker --city new-york
  devopsdays-cli edit speaker george-bluth -c "New York" --year "2017"`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) > 0 {
			editSpeaker(args[0], "", "")
		} else {
			editSpeaker("", "", "")
		}
	},
}

// removeSpeakerCmd represents the "speaker remove" command
var removeSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Remove a speaker from an event",
	Long: `Remove a speaker from an event.
You can provide the speaker's name as an argument to this command, but it must be the "cleaned" name.
	`,
	Example: `  devopsdays-cli remove speaker george-bluth
  devopsdays-cli remove speaker --city new-york
  devopsdays-cli remove speaker george-bluth -c "New York" --year "2017"`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		removeSpeaker()
	},
}

// showSpeakerCmd represents the "speaker show" command
var showSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Show a speaker from an event",
	Long: `Show a speaker from an event.
		`,
	Example: `  devopsdays-cli remove speaker george-bluth
  devopsdays-cli show speaker --city new-york --year 2017 --all
  devopsdays-cli remove speaker george-bluth -c "New York" --year "2017"`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		showSpeakerPrompt(City, Year)
	},
}

func init() {
	addCmd.AddCommand(addSpeakerCmd)
	createCmd.AddCommand(createSpeakerCmd)
	editCmd.AddCommand(editSpeakerCmd)
	removeCmd.AddCommand(removeSpeakerCmd)
	showCmd.AddCommand(showSpeakerCmd)

	addSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	addSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	createSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	createSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	editSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	editSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	removeSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	removeSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	showSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	showSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	showSpeakerCmd.Flags().BoolVarP(&All, "all", "a", false, "show all")

}

// Main functions go down here

func addSpeaker() {
	fmt.Println("You would have added a speaker to a talk if this happened")
}

func editSpeaker(speakerName, city, year string) {
	fmt.Println("You would have edited a speaker if this happened")
}

func removeSpeaker() {
	fmt.Println("You would have removed a speaker if this happened")
}

func showSpeaker() {
	fmt.Println("Showing a speaker")
	mySpeaker, _ := speaker.GetSpeakerInfo("fluttershy.md", "ponyville", "2017")
	fmt.Println(mySpeaker)
}
<commit_msg>Fix incorrect examples for help on show speaker command<commit_after>package cmd

import (
	"fmt"

	speaker "github.com/devopsdays/devopsdays-cli/speaker"
	"github.com/spf13/cobra"
)

// addSpeakerCmd represents the "speaker add" command
var addSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Add a speaker to an existing talk",
	Long: `Add a speaker to an existing talk.
You can provide the speaker's name as an argument to this command, but it must be the "cleaned" name.
		`,
	Example: `  devopsdays-cli add speaker george-bluth
  devopsdays-cli add speaker --city new-york
  devopsdays-cli add speaker george-bluth -c "New York" --year "2017"`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		addSpeaker()
	},
}

// createSpeakerCmd represents the "speaker create" command
var createSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Creates a new speaker for an event",
	Long: `Creates a new speaker for an event.
	`,
	Example: `  devopsdays-cli create speaker
  devopsdays-cli create speaker --city new-york
  devopsdays-cli create speaker -c "New York" --year "2017"`,

	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		createSpeakerPrompt(City, Year)
	},
}

// editSpeakerCmd represents the "speaker edi" command
var editSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Edit an event's speaker",
	Long: `Edit an event's speaker.
You can provide the speaker's name as an argument to this command, but it must be the "cleaned" name.
`,
	Example: `  devopsdays-cli edit speaker george-bluth
  devopsdays-cli edit speaker --city new-york
  devopsdays-cli edit speaker george-bluth -c "New York" --year "2017"`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) > 0 {
			editSpeaker(args[0], "", "")
		} else {
			editSpeaker("", "", "")
		}
	},
}

// removeSpeakerCmd represents the "speaker remove" command
var removeSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Remove a speaker from an event",
	Long: `Remove a speaker from an event.
You can provide the speaker's name as an argument to this command, but it must be the "cleaned" name.
	`,
	Example: `  devopsdays-cli remove speaker george-bluth
  devopsdays-cli remove speaker --city new-york
  devopsdays-cli remove speaker george-bluth -c "New York" --year "2017"`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		removeSpeaker()
	},
}

// showSpeakerCmd represents the "speaker show" command
var showSpeakerCmd = &cobra.Command{
	Use:   "speaker",
	Short: "Show a speaker from an event",
	Long: `Show a speaker from an event.
		`,
	Example: `  devopsdays-cli show speaker george-bluth
  devopsdays-cli show speaker --city new-york --year 2017 --all
  devopsdays-cli show speaker george-bluth -c "New York" --year "2017"`,
	Args: cobra.MaximumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		showSpeakerPrompt(City, Year)
	},
}

func init() {
	addCmd.AddCommand(addSpeakerCmd)
	createCmd.AddCommand(createSpeakerCmd)
	editCmd.AddCommand(editSpeakerCmd)
	removeCmd.AddCommand(removeSpeakerCmd)
	showCmd.AddCommand(showSpeakerCmd)

	addSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	addSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	createSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	createSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	editSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	editSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	removeSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	removeSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	showSpeakerCmd.Flags().StringVarP(&City, "city", "c", "", "city to use")
	showSpeakerCmd.Flags().StringVarP(&Year, "year", "y", "", "year to use")
	showSpeakerCmd.Flags().BoolVarP(&All, "all", "a", false, "show all")

}

// Main functions go down here

func addSpeaker() {
	fmt.Println("You would have added a speaker to a talk if this happened")
}

func editSpeaker(speakerName, city, year string) {
	fmt.Println("You would have edited a speaker if this happened")
}

func removeSpeaker() {
	fmt.Println("You would have removed a speaker if this happened")
}

func showSpeaker() {
	fmt.Println("Showing a speaker")
	mySpeaker, _ := speaker.GetSpeakerInfo("fluttershy.md", "ponyville", "2017")
	fmt.Println(mySpeaker)
}
<|endoftext|>


<commit_before>package check

import (
	"bufio"
	"bytes"
	"fmt"
	"os/exec"
	"strings"
)

// PackageManager runs queries against the underlying operating system's
// package manager
type PackageManager interface {
	IsAvailable(PackageQuery) (bool, error)
	IsInstalled(PackageQuery) (bool, error)
	Enforced() bool
}

func IsPackageReadyToContinue(m PackageManager, q PackageQuery) (bool, error) {
	if m.Enforced() {
		installed, _ := m.IsInstalled(q)

		if installed {
			return true, nil
		}

		available, _ := m.IsAvailable(q)

		if available {
			return false, fmt.Errorf("%v is not installed but is available in a package repository", q)
		}

		return false, fmt.Errorf("%v is not installed and isn't available in known package repositories", q)
	}
	return true, nil
}

// NewPackageManager returns a package manager for the given distribution
func NewPackageManager(distro Distro, enforcePackages bool) (PackageManager, error) {
	run := func(name string, arg ...string) ([]byte, error) {
		r, err := exec.Command(name, arg...).CombinedOutput()
		return r, err
	}
	switch distro {
	case RHEL, CentOS:
		return &rpmManager{
			run:             run,
			enforcePackages: enforcePackages,
		}, nil
	case Ubuntu:
		return &debManager{
			run:             run,
			enforcePackages: enforcePackages,
		}, nil
	case Darwin:
		return noopManager{}, nil
	default:
		return nil, fmt.Errorf("%s is not supported", distro)
	}
}

type noopManager struct{}

func (noopManager) IsAvailable(PackageQuery) (bool, error) {
	return false, fmt.Errorf("unable to determine if package is available using noop pkg manager")
}

// package manager for EL-based distributions
type rpmManager struct {
	run             func(string, ...string) ([]byte, error)
	enforcePackages bool
}

func (m rpmManager) Enforced() bool {
	return m.enforcePackages
}

func (m rpmManager) IsAvailable(p PackageQuery) (bool, error) {
	out, err := m.run("yum", "list", "available", "-q", p.Name)
	if err != nil && strings.Contains(string(out), "No matching Packages to list") {
		return false, nil
	}
	if err != nil {
		return false, fmt.Errorf("unable to determine if %s %s is available: %v", p.Name, p.Version, err)
	}
	return m.isPackageListed(p, out), nil
}

func (m rpmManager) IsInstalled(p PackageQuery) (bool, error) {
	out, err := m.run("yum", "list", "installed", "-q", p.Name)
	if err != nil && strings.Contains(string(out), "No matching Packages to list") {
		return false, nil
	}
	if err != nil {
		return false, fmt.Errorf("unable to determine if %s %s is installed: %v", p.Name, p.Version, err)
	}
	return m.isPackageListed(p, out), nil
}

func (m rpmManager) isPackageListed(p PackageQuery, list []byte) bool {
	s := bufio.NewScanner(bytes.NewReader(list))

	for s.Scan() {
		line := s.Text()
		f := strings.Fields(line)
		if len(f) != 3 {
			// Ignore lines that don't match the expected format
			continue
		}
		maybeName := strings.Split(f[0], ".")[0]
		maybeVersion := strings.Split(f[1], "-")[0]
		if p.Name == maybeName && p.Version == maybeVersion {
			return true
		}
	}
	return false
}

// package manager for debian-based distributions
type debManager struct {
	run             func(string, ...string) ([]byte, error)
	enforcePackages bool
}

func (m debManager) Enforced() bool {
	return m.enforcePackages
}

func (m debManager) IsInstalled(p PackageQuery) (bool, error) {
	// First check if the package is installed
	installed, err := m.isPackageListed(p)
	if err != nil {
		return false, err
	}
	return installed, nil
}

func (m debManager) IsAvailable(p PackageQuery) (bool, error) {
	// If it's not installed, ensure that it is available via the
	// package manager. We attempt to install using --dry-run. If exit status is zero, we
	// know the package is available for download
	out, err := m.run("apt-get", "install", "-q", "--dry-run", fmt.Sprintf("%s=%s", p.Name, p.Version))
	if err != nil && strings.Contains(string(out), "Unable to locate package") {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	return true, nil
}

func (m debManager) isPackageListed(p PackageQuery) (bool, error) {
	out, err := m.run("dpkg", "-l", p.Name)
	if err != nil && strings.Contains(string(out), "no packages found matching") {
		return false, nil
	}
	if err != nil {
		return false, fmt.Errorf("unable to determine if %s %s is installed: %v", p.Name, p.Version, err)
	}
	s := bufio.NewScanner(bytes.NewReader(out))
	for s.Scan() {
		line := s.Text()
		f := strings.Fields(line)
		if len(f) < 5 {
			// Ignore lines with unexpected format
			continue
		}
		maybeName := strings.Split(f[1], ".")[0]
		maybeVersion := strings.Split(f[2], "-")[0]
		if p.Name == maybeName && p.Version == maybeVersion {
			return true, nil
		}
	}
	return false, nil
}
<commit_msg>Fix noop package manager<commit_after>package check

import (
	"bufio"
	"bytes"
	"fmt"
	"os/exec"
	"strings"
)

// PackageManager runs queries against the underlying operating system's
// package manager
type PackageManager interface {
	IsAvailable(PackageQuery) (bool, error)
	IsInstalled(PackageQuery) (bool, error)
	Enforced() bool
}

func IsPackageReadyToContinue(m PackageManager, q PackageQuery) (bool, error) {
	if m.Enforced() {
		installed, _ := m.IsInstalled(q)

		if installed {
			return true, nil
		}

		available, _ := m.IsAvailable(q)

		if available {
			return false, fmt.Errorf("%v is not installed but is available in a package repository", q)
		}

		return false, fmt.Errorf("%v is not installed and isn't available in known package repositories", q)
	}
	return true, nil
}

// NewPackageManager returns a package manager for the given distribution
func NewPackageManager(distro Distro, enforcePackages bool) (PackageManager, error) {
	run := func(name string, arg ...string) ([]byte, error) {
		r, err := exec.Command(name, arg...).CombinedOutput()
		return r, err
	}
	switch distro {
	case RHEL, CentOS:
		return &rpmManager{
			run:             run,
			enforcePackages: enforcePackages,
		}, nil
	case Ubuntu:
		return &debManager{
			run:             run,
			enforcePackages: enforcePackages,
		}, nil
	case Darwin:
		return noopManager{}, nil
	default:
		return nil, fmt.Errorf("%s is not supported", distro)
	}
}

type noopManager struct{}

func (noopManager) IsAvailable(PackageQuery) (bool, error) {
	return false, fmt.Errorf("unable to determine if package is available using noop pkg manager")
}
func (noopManager) IsInstalled(PackageQuery) (bool, error) {
	return false, fmt.Errorf("unable to determine if package is installed using noop pkg manager")
}
func (noopManager) Enforced() bool {
	return false
}

// package manager for EL-based distributions
type rpmManager struct {
	run             func(string, ...string) ([]byte, error)
	enforcePackages bool
}

func (m rpmManager) Enforced() bool {
	return m.enforcePackages
}

func (m rpmManager) IsAvailable(p PackageQuery) (bool, error) {
	out, err := m.run("yum", "list", "available", "-q", p.Name)
	if err != nil && strings.Contains(string(out), "No matching Packages to list") {
		return false, nil
	}
	if err != nil {
		return false, fmt.Errorf("unable to determine if %s %s is available: %v", p.Name, p.Version, err)
	}
	return m.isPackageListed(p, out), nil
}

func (m rpmManager) IsInstalled(p PackageQuery) (bool, error) {
	out, err := m.run("yum", "list", "installed", "-q", p.Name)
	if err != nil && strings.Contains(string(out), "No matching Packages to list") {
		return false, nil
	}
	if err != nil {
		return false, fmt.Errorf("unable to determine if %s %s is installed: %v", p.Name, p.Version, err)
	}
	return m.isPackageListed(p, out), nil
}

func (m rpmManager) isPackageListed(p PackageQuery, list []byte) bool {
	s := bufio.NewScanner(bytes.NewReader(list))

	for s.Scan() {
		line := s.Text()
		f := strings.Fields(line)
		if len(f) != 3 {
			// Ignore lines that don't match the expected format
			continue
		}
		maybeName := strings.Split(f[0], ".")[0]
		maybeVersion := strings.Split(f[1], "-")[0]
		if p.Name == maybeName && p.Version == maybeVersion {
			return true
		}
	}
	return false
}

// package manager for debian-based distributions
type debManager struct {
	run             func(string, ...string) ([]byte, error)
	enforcePackages bool
}

func (m debManager) Enforced() bool {
	return m.enforcePackages
}

func (m debManager) IsInstalled(p PackageQuery) (bool, error) {
	// First check if the package is installed
	installed, err := m.isPackageListed(p)
	if err != nil {
		return false, err
	}
	return installed, nil
}

func (m debManager) IsAvailable(p PackageQuery) (bool, error) {
	// If it's not installed, ensure that it is available via the
	// package manager. We attempt to install using --dry-run. If exit status is zero, we
	// know the package is available for download
	out, err := m.run("apt-get", "install", "-q", "--dry-run", fmt.Sprintf("%s=%s", p.Name, p.Version))
	if err != nil && strings.Contains(string(out), "Unable to locate package") {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	return true, nil
}

func (m debManager) isPackageListed(p PackageQuery) (bool, error) {
	out, err := m.run("dpkg", "-l", p.Name)
	if err != nil && strings.Contains(string(out), "no packages found matching") {
		return false, nil
	}
	if err != nil {
		return false, fmt.Errorf("unable to determine if %s %s is installed: %v", p.Name, p.Version, err)
	}
	s := bufio.NewScanner(bytes.NewReader(out))
	for s.Scan() {
		line := s.Text()
		f := strings.Fields(line)
		if len(f) < 5 {
			// Ignore lines with unexpected format
			continue
		}
		maybeName := strings.Split(f[1], ".")[0]
		maybeVersion := strings.Split(f[2], "-")[0]
		if p.Name == maybeName && p.Version == maybeVersion {
			return true, nil
		}
	}
	return false, nil
}
<|endoftext|>


<commit_before>package alignment

//package main

import . "./interface"
import "fmt"
import "math"

type Rgotoh struct {
	x string
	y string
	h [][][]int
	Constants
}

func NewRGotoh(y string, x string, settings Constants) *Rgotoh {
	xlen := len(x) + 1
	h := make([][][]int, 3)
	for i := 0; i < 3; i++ {
		h[i] = make([][]int, xlen)
		for y := 0; y < xlen; y++ {
			h[i][y] = make([]int, 2)
		}
	}
	Rgotoh := &Rgotoh{x: x, y: y, h: h}
	Rgotoh.Constants = settings
	return Rgotoh
}

func (l Rgotoh) Strlen() (int, int) {
	return len(l.x), len(l.y)
}

func (l Rgotoh) Substitution(x int, y int) int {
	return l.Constants.Substitution(l.x[x-1], l.y[y-1])
}

func (l Rgotoh) Score() int {
	e, _ := l.ScoreArgs(3, 3)
	return e
}

func (l *Rgotoh) Length() {
	var m = len(l.x)
	var n = len(l.y)
	l.h[1][0][0] = math.MinInt64
	l.h[2][0][0] = math.MinInt64
	for i := 1; i <= 2; i++ {
		l.h[0][i][0] = math.MinInt32
		l.h[1][i][0] = l.Cost(i)
		l.h[2][i][0] = math.MinInt32
	}
	for j := 1; j <= 1; j++ {
		l.h[0][0][j] = math.MinInt32
		l.h[1][0][j] = math.MinInt32
		l.h[2][0][j] = l.Cost(j)
	}

	for j := 1; j <= n; j++ {
		for i := 1; i <= m; i++ {
			var nexth int
			//Update H^1 (l.h[0])
			nexth, _ = Max(l.h[0][i-1][0], l.h[1][i-1][0], l.h[2][i-1][0])
			//fmt.Println(i,j)
			l.h[0][i][1] = nexth + l.Substitution(i, j)
			//Update H^2 (l.h[1])
			e, d := l.Geted()
			nexth, _ = Max(l.h[0][i-1][1]-d, l.h[1][i-1][1]-e, l.h[2][i-1][1]-d)
			l.h[1][i][1] = nexth
			//Update H^3 (l.h[2])
			nexth, _ = Max(l.h[0][i][0]-d, math.MinInt64, l.h[2][i][0]-e)
			l.h[2][i][1] = nexth
		}
		for i := 1; i <= m; i++ {
			l.h[0][i][0] = l.h[0][i][1]
			l.h[1][i][0] = l.h[1][i][1]
			l.h[2][i][0] = l.h[2][i][1]
		}
	}
}

func (l *Rgotoh) RegionAlign(i1 int, i2 int, j1 int, j2 int) (result int, class int) {
	var m = i2 - i1
	var n = j2 - j1
	l.h[1][0][0] = math.MinInt64
	l.h[2][0][0] = math.MinInt64
	for i := 1; i <= m; i++ {
		l.h[0][i][0] = math.MinInt32
		l.h[1][i][0] = l.Cost(i)
		l.h[2][i][0] = math.MinInt32
	}
	for j := 1; j <= 1; j++ {
		l.h[0][0][j] = math.MinInt32
		l.h[1][0][j] = math.MinInt32
		l.h[2][0][j] = l.Cost(j)
	}

	for j := 1; j <= n; j++ {
		for i := 1; i <= m; i++ {
			var nexth int
			//Update H^1 (l.h[0])
			nexth, _ = Max(l.h[0][i-1][0], l.h[1][i-1][0], l.h[2][i-1][0])
			//fmt.Println(i,j)
			l.h[0][i][1] = nexth + l.Substitution(i, j)
			//Update H^2 (l.h[1])
			e, d := l.Geted()
			nexth, _ = Max(l.h[0][i-1][1]-d, l.h[1][i-1][1]-e, l.h[2][i-1][1]-d)
			l.h[1][i][1] = nexth
			//Update H^3 (l.h[2])
			nexth, _ = Max(l.h[0][i][0]-d, math.MinInt64, l.h[2][i][0]-e)
			l.h[2][i][1] = nexth
		}
		for i := 1; i <= m; i++ {
			l.h[0][i][0] = l.h[0][i][1]
			l.h[1][i][0] = l.h[1][i][1]
			l.h[2][i][0] = l.h[2][i][1]
		}
	}
	e, k := Max(l.h[0][m][0], l.h[1][m][0], l.h[2][m][0])
	return e, k
}

func (l Rgotoh) ScoreArgs(x int, y int) (int, int) {
	e, k := Max(l.h[0][x][0], l.h[1][x][0], l.h[2][x][0])
	return e, k
}

func (l Rgotoh) Print(i int, j int) (string, string, string) {
	//_, arg := l.ScoreArgs(i, j)
	//fmt.Println(l.RegionAlign(0,i,0,j))
	return l.LinearSpaceAlign(0, i, 0, j) //Print_iter(i, j, arg)
}

func (l Rgotoh) LinearSpaceAlign(i1 int, i2 int, j1 int, j2 int) (p string, q string, r string) {
	i := i2 - i1
	j := j2 - j1
	fmt.Println(i1, i2, j1, j2)
	if i <= 0 && j <= 0 {
		return "", "", ""
	} else if i <= 0 {
		//p,q,r = l.Print(i,j-1)
		for ; j2 > j1; j2-- {
			p += "-"
			q += " "
			r += fmt.Sprintf("%c", l.y[j2-1])
		}
		return p, q, r
	} else if j <= 0 {
		//p,q,r = l.Print(i-1,j)
		for ; i2 > i1; i2-- {
			p += fmt.Sprintf("%c", l.x[i2-1])
			q += " "
			r += "-"
		}
		return p, q, r
	} else if i == 1 && j == 1 {
		p += fmt.Sprintf("%c", l.x[i1])
		q += "|"
		r += fmt.Sprintf("%c", l.y[i1])
		return p, q, r
	}
	ih := ((i1 + i2) / 2)
	if ih >= len(l.x) || ih < i1 {
		panic(i1 + i2)
	}
	maxscore, maxj := math.MinInt64, -1
	fmt.Println(i1, i2, j1, j2, ih, maxj)
	for jh := j1; jh < j2; jh++ {
		tmp1, err1 := l.RegionAlign(i1, ih, j1, jh)
		tmp2, err2 := l.RegionAlign(ih, i2, jh, j2)
		tmp := tmp1 + tmp2
		_, d := l.Geted()
		if err1 >= 1 && err2 >= 1 {
			tmp -= d
		}
		fmt.Println(i1, i2, j1, j2, ih, jh, tmp)
		if tmp >= maxscore {
			maxscore = tmp
			maxj = jh
		}
	}

	p, q, r = l.LinearSpaceAlign(i1, ih, j1, maxj)
	p += fmt.Sprintf("%c", l.x[ih])
	q += "|"
	r += fmt.Sprintf("%c", l.y[maxj])
	p2, q2, r2 := l.LinearSpaceAlign(ih, i2, maxj, j2)
	p += p2
	q += q2
	r += r2
	return
}

/*
func main() {
	arr := [][]int{{1, -1, -1, -1}, {-1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, -1, -1, 1}}
	charlist := "acgt"
	var settings = NewConstants(2, 1, arr, charlist)
	var lcs = NewRgotoh("ggatgcatgcatgc", "atgcatgcatgccc", *settings)
	lcs.Length()
	fmt.Println(lcs.h)
	fmt.Println(lcs.Score())
	fmt.Println(lcs.h[0][8][8])
	var lx, ly = lcs.Strlen()
	var p, q, r = lcs.Print(lx, ly)
	fmt.Println(p)
	fmt.Println(q)
	fmt.Println(r)
}
*/
<commit_msg>Fix Length<commit_after>package alignment

//package main

import . "./interface"
import "fmt"
import "math"

type Rgotoh struct {
	x string
	y string
	h [][][]int
	Constants
}

func NewRGotoh(y string, x string, settings Constants) *Rgotoh {
	xlen := len(x) + 1
	h := make([][][]int, 3)
	for i := 0; i < 3; i++ {
		h[i] = make([][]int, xlen)
		for y := 0; y < xlen; y++ {
			h[i][y] = make([]int, 2)
		}
	}
	Rgotoh := &Rgotoh{x: x, y: y, h: h}
	Rgotoh.Constants = settings
	return Rgotoh
}

func (l Rgotoh) Strlen() (int, int) {
	return len(l.x), len(l.y)
}

func (l Rgotoh) Substitution(x int, y int) int {
	return l.Constants.Substitution(l.x[x-1], l.y[y-1])
}

func (l Rgotoh) Score() int {
	e, _ := l.ScoreArgs(3, 3)
	return e
}

func (l *Rgotoh) Length() {
	var m = len(l.x)
	var n = len(l.y)
	l.h[0][0][0] = 0
	l.h[1][0][0] = math.MinInt64
	l.h[2][0][0] = math.MinInt64
	for i := 1; i <= m; i++ {
		l.h[0][i][0] = math.MinInt32
		l.h[1][i][0] = l.Cost(i)
		l.h[2][i][0] = math.MinInt32
	}
	for j := 1; j <= 1; j++ {
		l.h[0][0][j] = math.MinInt32
		l.h[1][0][j] = math.MinInt32
		l.h[2][0][j] = l.Cost(j)
	}

	for j := 1; j <= n; j++ {
		for i := 1; i <= m; i++ {
			var nexth int
			//Update H^1 (l.h[0])
			nexth, _ = Max(l.h[0][i-1][0], l.h[1][i-1][0], l.h[2][i-1][0])
			//fmt.Println(i,j)
			l.h[0][i][1] = nexth + l.Substitution(i, j)
			//Update H^2 (l.h[1])
			e, d := l.Geted()
			nexth, _ = Max(l.h[0][i-1][1]-d, l.h[1][i-1][1]-e, l.h[2][i-1][1]-d)
			l.h[1][i][1] = nexth
			//Update H^3 (l.h[2])
			nexth, _ = Max(l.h[0][i][0]-d, math.MinInt64, l.h[2][i][0]-e)
			l.h[2][i][1] = nexth
		}
		for i := 1; i <= m; i++ {
			l.h[0][i][0] = l.h[0][i][1]
			l.h[1][i][0] = l.h[1][i][1]
			l.h[2][i][0] = l.h[2][i][1]
		}
		l.h[0][0][0] = math.MinInt32
		l.h[1][0][0] = math.MinInt32
		l.h[2][0][0] = l.Cost(j)
	}
}

func (l *Rgotoh) RegionAlign(i1 int, i2 int, j1 int, j2 int) (result int, class int) {
	var m = i2 - i1
	var n = j2 - j1
	l.h[0][0][0] = 0
	l.h[1][0][0] = math.MinInt64
	l.h[2][0][0] = math.MinInt64
	for i := 1; i <= m; i++ {
		l.h[0][i][0] = math.MinInt32
		l.h[1][i][0] = l.Cost(i)
		l.h[2][i][0] = math.MinInt32
	}
	for j := 1; j <= 1; j++ {
		l.h[0][0][j] = math.MinInt32
		l.h[1][0][j] = math.MinInt32
		l.h[2][0][j] = l.Cost(j)
	}

	for j := 1; j <= n; j++ {
		for i := 1; i <= m; i++ {
			var nexth int
			//Update H^1 (l.h[0])
			nexth, _ = Max(l.h[0][i-1][0], l.h[1][i-1][0], l.h[2][i-1][0])
			//fmt.Println(i, j)
			l.h[0][i][1] = nexth + l.Substitution(i+i1, j+j1)
			//Update H^2 (l.h[1])
			e, d := l.Geted()
			nexth, _ = Max(l.h[0][i-1][1]-d, l.h[1][i-1][1]-e, l.h[2][i-1][1]-d)
			l.h[1][i][1] = nexth
			//Update H^3 (l.h[2])
			nexth, _ = Max(l.h[0][i][0]-d, math.MinInt64, l.h[2][i][0]-e)
			l.h[2][i][1] = nexth
		}
		for i := 1; i <= m; i++ {
			l.h[0][i][0] = l.h[0][i][1]
			l.h[1][i][0] = l.h[1][i][1]
			l.h[2][i][0] = l.h[2][i][1]
		}
		l.h[0][0][0] = math.MinInt32
		l.h[1][0][0] = math.MinInt32
		l.h[2][0][0] = l.Cost(j)
	}
	fmt.Println(l.h)
	e, k := Max(l.h[0][m][0], l.h[1][m][0], l.h[2][m][0])
	return e, k
}

func (l Rgotoh) ScoreArgs(x int, y int) (int, int) {
	e, k := Max(l.h[0][x][0], l.h[1][x][0], l.h[2][x][0])
	return e, k
}

func (l Rgotoh) Print(i int, j int) (string, string, string) {
	//_, arg := l.ScoreArgs(i, j)
	//fmt.Println(l.Score())
	//fmt.Println(l.RegionAlign(0, 1, 0, 1))
	return l.LinearSpaceAlign(0, i, 0, j) //Print_iter(i, j, arg)
}

func (l Rgotoh) LinearSpaceAlign(i1 int, i2 int, j1 int, j2 int) (p string, q string, r string) {
	i := i2 - i1 - 1
	j := j2 - j1 - 1
	fmt.Println(i1, i2, j1, j2, i, j, "hantei")
	if i <= 0 && j <= 0 {
		return "", "", ""
	} else if i <= 0 {
		//p,q,r = l.Print(i,j-1)
		for ; j2 > j1; j2-- {
			p += "-"
			q += " "
			r += fmt.Sprintf("%c", l.y[j2-1])
		}
		return p, q, r
	} else if j <= 0 {
		//p,q,r = l.Print(i-1,j)
		for ; i2 > i1; i2-- {
			p += fmt.Sprintf("%c", l.x[i2-1])
			q += " "
			r += "-"
		}
		return p, q, r
	}
	//else if i <= 1 && j == 1 {
	//	p += fmt.Sprintf("%c", l.x[i1])
	//	q += "|"
	//	r += fmt.Sprintf("%c", l.y[i1])
	//	return p, q, r
	//}
	ih := ((i1 + i2) / 2)
	if ih >= len(l.x) || ih < i1 {
		panic(i1 + i2)
	}
	maxscore, maxj := math.MinInt64, -1
	for jh := j1; jh < j2; jh++ {
		tmp1, err1 := l.RegionAlign(i1, ih, j1, jh)
		tmp2, err2 := l.RegionAlign(ih, i2, jh, j2)
		fmt.Println(tmp1, tmp2)
		tmp := tmp1 + tmp2
		_, d := l.Geted()
		if err1 >= 1 && err2 >= 1 {
			tmp -= d
		}
		fmt.Println(i1, i2, j1, j2, ih, jh, tmp)
		if tmp > maxscore {
			maxscore = tmp
			maxj = jh
		}
	}
	fmt.Println(i1, ih, i2, j1, maxj, j2)
	p, q, r = l.LinearSpaceAlign(i1, ih, j1, maxj)
	p += fmt.Sprintf("%c", l.x[ih])
	q += "!"
	r += fmt.Sprintf("%c", l.y[maxj])
	p2, q2, r2 := l.LinearSpaceAlign(ih, i2, maxj, j2)
	p += p2
	q += q2
	r += r2
	return
}

/*
func main() {
	arr := [][]int{{1, -1, -1, -1}, {-1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, -1, -1, 1}}
	charlist := "acgt"
	var settings = NewConstants(2, 1, arr, charlist)
	var lcs = NewRgotoh("ggatgcatgcatgc", "atgcatgcatgccc", *settings)
	lcs.Length()
	fmt.Println(lcs.h)
	fmt.Println(lcs.Score())
	fmt.Println(lcs.h[0][8][8])
	var lx, ly = lcs.Strlen()
	var p, q, r = lcs.Print(lx, ly)
	fmt.Println(p)
	fmt.Println(q)
	fmt.Println(r)
}
*/
<|endoftext|>


<commit_before>// Package nms provides network monitoring system through
// different various protocols such as SNMP, SSH
package nms

import (
	"fmt"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/briandowns/spinner"
	"github.com/k-sone/snmpgo"
	"github.com/olekukonko/tablewriter"

	"github.com/mehrdadrad/mylg/cli"
)

// Client represents NMS client
type Client struct {
	SNMP *SNMPClient
	Host string
}

// NewClient makes new NMS client
func NewClient(args string, cfg cli.Config) (Client, error) {
	var (
		client Client
		err    error
	)

	_, flags := cli.Flag(args)
	if _, ok := flags["help"]; ok {
		help()
		return client, nil
	}

	switch {

	default:
		if client.SNMP, err = NewSNMP(args, cfg); err != nil {
			return client, err
		}
		client.Host = client.SNMP.Host

		r, err := client.SNMP.GetOIDs(OID["sysDescr"])
		if err != nil {
			println(err.Error())
		} else {
			descr := r[0].Variable.(*snmpgo.OctetString).String()
			printEff(trim("Connected: "+descr, 80))
		}
	}
	return client, err
}

// ShowInterface shows interface(s) information based on
// Specific portocol (SNMP/SSH/...) for now it support only SNMP
func (c *Client) ShowInterface() {
	c.snmpShowInterface()
}

func (c *Client) snmpShowInterface() {
	var (
		data [][][]string
		once sync.Once
		spin = spinner.New(spinner.CharSets[26], 220*time.Millisecond)
	)

	for range []int{0, 1} {
		sample, err := c.snmpGetInterfaces()
		if err != nil {
			return
		}
		data = append(data, sample)
		once.Do(
			func() {
				fmt.Printf("* %d interfaces (physical/logical) has been found\n", len(sample)-1)
				spin.Prefix = "please wait "
				spin.Start()
				time.Sleep(10 * time.Second)
				spin.Stop()
			},
		)
	}
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader(data[0][0])

	data[0] = data[0][1:] // remove title row
	data[1] = data[1][1:] // remove title row

	for i := range data[0] {
		row := normalize(data[0][i], data[1][i], 10)
		table.Append(row)
	}
	table.Render()
}

func normalize(time0, time1 []string, t int) []string {
	var f = []int{8, 8, 1, 1, 1, 1, 1, 1}

	for _, i := range []int{1, 2, 3, 4} {
		n, _ := strconv.Atoi(time0[i])
		n = n * f[i-1]
		m, _ := strconv.Atoi(time1[i])
		m = m * f[i-1]
		time1[i] = fmt.Sprintf("%d", (m-n)/t)
	}
	return time1
}

func (c *Client) snmpGetInterfaces() ([][]string, error) {
	var (
		data   = make([][]string, 100)
		maxIdx = 0
		oids   []string
		cols   [][]string
	)

	cols = append(cols, []string{"Interface", "ifDescr"})
	cols = append(cols, []string{"Traffic In", "ifHCInOctets"})
	cols = append(cols, []string{"Traffic Out", "ifHCOutOctets"})
	cols = append(cols, []string{"PPS In", "ifHCInUcastPkts"})
	cols = append(cols, []string{"PPS Out", "ifHCOutUcastPkts"})
	cols = append(cols, []string{"Discard In", "ifInDiscards"})
	cols = append(cols, []string{"Discard Out", "ifOutDiscards"})
	cols = append(cols, []string{"Error In", "ifInErrors"})
	cols = append(cols, []string{"Error Out", "ifOutErrors"})

	for _, c := range cols {
		oids = append(oids, OID[c[1]])
		data[0] = append(data[0], c[0])
	}

	r, err := c.SNMP.BulkWalk(oids...)
	if err != nil {
		return data, err
	}

	for _, v := range r {
		a := strings.Split(v.Oid.String(), ".")
		idx, _ := strconv.Atoi(a[len(a)-1])
		if len(data[idx]) < 1 {
			data[idx] = make([]string, len(cols))
		}

		colNum := 0
		for _, c := range cols {
			if OID[c[1]] == strings.Join(a[:len(a)-1], ".") {
				data[idx][colNum] = v.Variable.String()
				break
			}
			colNum++
		}
		if idx > maxIdx {
			maxIdx = idx
		}
	}
	return data[:maxIdx+1], nil
}

func trim(s string, n int) string {
	if len(s) < n {
		return s
	}
	return s[:n] + " ..."
}

func printEff(s string) {
	for _, c := range s {
		fmt.Printf("%s", string(c))
		time.Sleep(3 * time.Millisecond)
	}
	println("")
}

func help() {
	fmt.Println(`
        Usage:
              connect host [options]

        Options:
        Example:
              connect 127.0.0.1 -c public
		`)
}
<commit_msg>add more help context, add filter interfaces<commit_after>// Package nms provides network monitoring system through
// different various protocols such as SNMP, SSH
package nms

import (
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/briandowns/spinner"
	"github.com/k-sone/snmpgo"
	"github.com/olekukonko/tablewriter"

	"github.com/mehrdadrad/mylg/cli"
)

// Client represents NMS client
type Client struct {
	SNMP *SNMPClient
	Host string
}

// NewClient makes new NMS client
func NewClient(args string, cfg cli.Config) (Client, error) {
	var (
		client Client
		err    error
	)

	_, flags := cli.Flag(args)
	if _, ok := flags["help"]; ok {
		help(cfg)
		return client, nil
	}

	switch {

	default:
		if client.SNMP, err = NewSNMP(args, cfg); err != nil {
			return client, err
		}
		client.Host = client.SNMP.Host

		r, err := client.SNMP.GetOIDs(OID["sysDescr"])
		if err != nil {
			println(err.Error())
		} else {
			descr := r[0].Variable.(*snmpgo.OctetString).String()
			printEff(trim("Connected: "+descr, 80))
		}
	}
	return client, err
}

// ShowInterface prints out interface(s) information based on
// specific portocol (SNMP/SSH/...) for now it supports only SNMP
func (c *Client) ShowInterface(filter string) error {
	if c.SNMP != nil {
		c.snmpShowInterface(filter)
	} else {
		return fmt.Errorf("snmp not connected, try connect help")
	}
	return nil
}

// snmpGetIdx finds SNMP index(es) based on the filter
func (c *Client) snmpGetIdx(filter string) []int {
	var res []int

	filter = fmt.Sprintf("^%s$", filter)
	filter = strings.Replace(filter, "*", ".*", -1)
	re := regexp.MustCompile(filter)

	r, _ := c.SNMP.BulkWalk(OID["ifDescr"])
	for _, v := range r {
		a := strings.Split(v.Oid.String(), ".")
		if re.MatchString(v.Variable.String()) {
			idx, _ := strconv.Atoi(a[len(a)-1])
			res = append(res, idx)
		}
	}
	return res
}

func (c *Client) snmpShowInterface(filter string) {
	var (
		data [][][]string
		once sync.Once
		idxs []int
		spin = spinner.New(spinner.CharSets[26], 220*time.Millisecond)
	)

	if len(strings.TrimSpace(filter)) > 1 {
		idxs = c.snmpGetIdx(filter)
	}

	for range []int{0, 1} {
		sample, err := c.snmpGetInterfaces(idxs)
		if err != nil {
			return
		}
		data = append(data, sample)
		once.Do(
			func() {
				fmt.Printf("* %d interfaces (physical/logical) has been found\n", len(sample)-1)
				spin.Prefix = "please wait "
				spin.Start()
				time.Sleep(10 * time.Second)
				spin.Stop()
			},
		)
	}
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader(data[0][0])

	data[0] = data[0][1:] // remove title row
	data[1] = data[1][1:] // remove title row

	for i := range data[0] {
		row := normalize(data[0][i], data[1][i], 10)
		table.Append(row)
	}
	table.Render()
}

func (c *Client) snmpGetInterfaces(filter []int) ([][]string, error) {
	var (
		data = make([][]string, 100)
		oids []string
		cols [][]string
		res  [][]string
		err  error
		r    []*snmpgo.VarBind
	)

	cols = append(cols, []string{"Interface", "ifDescr"})
	cols = append(cols, []string{"Traffic In", "ifHCInOctets"})
	cols = append(cols, []string{"Traffic Out", "ifHCOutOctets"})
	cols = append(cols, []string{"PPS In", "ifHCInUcastPkts"})
	cols = append(cols, []string{"PPS Out", "ifHCOutUcastPkts"})
	cols = append(cols, []string{"Discard In", "ifInDiscards"})
	cols = append(cols, []string{"Discard Out", "ifOutDiscards"})
	cols = append(cols, []string{"Error In", "ifInErrors"})
	cols = append(cols, []string{"Error Out", "ifOutErrors"})

	if len(filter) < 1 {
		for _, c := range cols {
			oids = append(oids, OID[c[1]])
			data[0] = append(data[0], c[0])
		}

		r, err = c.SNMP.BulkWalk(oids...)
		if err != nil {
			return data, err
		}
	} else {
		for _, c := range cols {
			for _, idx := range filter {
				oids = append(oids, fmt.Sprintf("%s.%d", OID[c[1]], idx))
			}
			data[0] = append(data[0], c[0])
		}

		r, err = c.SNMP.GetOIDs(oids...)
		if err != nil {
			return data, err
		}
	}

	for _, v := range r {
		a := strings.Split(v.Oid.String(), ".")
		idx, _ := strconv.Atoi(a[len(a)-1])
		if len(data[idx]) < 1 {
			data[idx] = make([]string, len(cols))
		}

		colNum := 0
		for _, c := range cols {
			if OID[c[1]] == strings.Join(a[:len(a)-1], ".") {
				data[idx][colNum] = v.Variable.String()
				break
			}
			colNum++
		}
	}

	// remove empty slices
	for i := range data {
		if len(data[i]) != 0 {
			res = append(res, data[i])
		}
	}

	return res, nil
}

func normalize(time0, time1 []string, t int) []string {
	var f = []int{8, 8, 1, 1, 1, 1, 1, 1}

	for _, i := range []int{1, 2, 3, 4} {
		n, _ := strconv.Atoi(time0[i])
		n = n * f[i-1]
		m, _ := strconv.Atoi(time1[i])
		m = m * f[i-1]
		time1[i] = fmt.Sprintf("%d", (m-n)/t)
	}
	return time1
}

func trim(s string, n int) string {
	if len(s) < n {
		return s
	}
	return s[:n] + " ..."
}

func printEff(s string) {
	for _, c := range s {
		fmt.Printf("%s", string(c))
		time.Sleep(3 * time.Millisecond)
	}
	println("")
}

func help(cfg cli.Config) {
	fmt.Printf(`
        SNMP Usage:
              connect host [options]

        Options:
              -v version    Specifies the protocol version: 1/2c/3 (default: %s)
              -c community  Community string for SNMPv1/v2c transactions (default: %s)
              -t timeout    Specify a timeout in format "ms", "s", "m" (default: %s)
              -p port       Specify SNMP port number (default: %d)
              -r retries    Specifies the number of retries (default:%d)
        Example:
              connect 127.0.0.1 -c public
		`,
		cfg.Snmp.Version,
		cfg.Snmp.Community,
		cfg.Snmp.Timeout,
		cfg.Snmp.Port,
		cfg.Snmp.Retries)
}
<|endoftext|>