<commit_before>package main

import (
	"flag"
	"log"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"./kumo"
	"github.com/sww/dumblog"
)

func main() {
	configName := flag.String("config", "config.json", "config file")
	debug := flag.Bool("debug", false, "show debug statements")

	flag.Parse()

	configFile, err := os.Open(*configName)
	if err != nil {
		log.Fatal("Error opening config file: %v\n", err)
	}

	config, err := kumo.GetConfig(configFile)
	if err != nil {
		log.Fatalf("Error reading config: %v\n", err)
	}

	files := flag.Args()
	if len(files) == 0 {
		log.Fatalf("[MAIN] No files specified")
	}

	logger := dumblog.DumbLog{Debug: *debug}
	wait := new(sync.WaitGroup)

	for i := 0; i < len(files); i++ {
		download, err := kumo.InitDownload(config.Host, config.Username, config.Password, config.Port, config.Connections, wait)
		if err != nil {
			log.Fatalf("Failed to InitDownload, with error: %v\n", err)
		}

		decode := kumo.InitDecode(wait)
		join := kumo.InitJoiner(wait)

		download.DecodeQueue = decode.Queue
		decode.JoinQueue = join.Queue

		download.Logger = &logger
		decode.Logger = &logger
		join.Logger = &logger

		progress := kumo.InitProgress()
		download.Progress = progress

		go download.Run()
		go decode.Run()
		go join.Run()

		filename := files[i]
		nf, err := os.Open(filename)
		if err != nil {
			continue
		}

		nzb, err := kumo.Parse(nf)

		if err != nil {
			log.Fatalf("[MAIN] Failed to parse file \"%v\", with error %v\n", filename, err)
		}

		logger.Print("[MAIN] Files: ", len(nzb.Files))

		_, dirName := filepath.Split(strings.TrimSuffix(filename, filepath.Ext(filename)))

		download.TempPath = filepath.Join(config.Temp, dirName)
		decode.TempPath = filepath.Join(config.Temp, dirName)
		join.TempPath = filepath.Join(config.Temp, dirName)
		join.DownloadPath = filepath.Join(config.Download, dirName)

		go progress.Run()

		logger.Print("[MAIN] Creating temp path: ", download.TempPath)
		os.Mkdir(download.TempPath, 0775)
		logger.Print("[MAIN] Creating download path: ", join.DownloadPath)
		os.Mkdir(join.DownloadPath, 0775)

		for j := 0; j < len(nzb.Files); j++ {
			logger.Printf("[MAIN] Size: %v", nzb.Size())

			progress.Total = nzb.Size()

			nzbFiles := nzb.Files[j]

			numSegments := len(nzbFiles.Segments)
			wait.Add(numSegments)
			logger.Print("[MAIN] Adding(", numSegments, ")")

			for k := 0; k < numSegments; k++ {
				s := nzbFiles.Segments[k]
				logger.Print("[MAIN] Queuing", s)
				s.Group = nzbFiles.Groups[0]
				download.Queue <- &s
			}
		}

		logger.Print("[MAIN] Waiting")
		wait.Wait()
		progress.Wait.Wait()

		os.RemoveAll(decode.TempPath)
	}

	println("⚑ All Done!")
}
<commit_msg>Added the temp directory check and creation.<commit_after>package main

import (
	"flag"
	"log"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"./kumo"
	"github.com/sww/dumblog"
)

func main() {
	configName := flag.String("config", "config.json", "config file")
	debug := flag.Bool("debug", false, "show debug statements")

	flag.Parse()

	configFile, err := os.Open(*configName)
	if err != nil {
		log.Fatal("Error opening config file: %v\n", err)
	}

	config, err := kumo.GetConfig(configFile)
	if err != nil {
		log.Fatalf("Error reading config: %v\n", err)
	}

	files := flag.Args()
	if len(files) == 0 {
		log.Fatalf("[MAIN] No files specified")
	}

	logger := dumblog.DumbLog{Debug: *debug}
	wait := new(sync.WaitGroup)

	// Make sure root directories are there.
	_, err = os.Stat(config.Temp)
	if err != nil {
		if os.Mkdir(config.Temp, 0775) != nil {
			log.Fatalf("Cannot make temp directory %v", config.Temp)
		}
	}

	for i := 0; i < len(files); i++ {
		download, err := kumo.InitDownload(config.Host, config.Username, config.Password, config.Port, config.Connections, wait)
		if err != nil {
			log.Fatalf("Failed to InitDownload, with error: %v\n", err)
		}

		decode := kumo.InitDecode(wait)
		join := kumo.InitJoiner(wait)

		download.DecodeQueue = decode.Queue
		decode.JoinQueue = join.Queue

		download.Logger = &logger
		decode.Logger = &logger
		join.Logger = &logger

		progress := kumo.InitProgress()
		download.Progress = progress

		go download.Run()
		go decode.Run()
		go join.Run()

		filename := files[i]
		nf, err := os.Open(filename)
		if err != nil {
			continue
		}

		nzb, err := kumo.Parse(nf)

		if err != nil {
			log.Fatalf("[MAIN] Failed to parse file \"%v\", with error %v\n", filename, err)
		}

		logger.Print("[MAIN] Files: ", len(nzb.Files))

		_, dirName := filepath.Split(strings.TrimSuffix(filename, filepath.Ext(filename)))

		download.TempPath = filepath.Join(config.Temp, dirName)
		decode.TempPath = filepath.Join(config.Temp, dirName)
		join.TempPath = filepath.Join(config.Temp, dirName)
		join.DownloadPath = filepath.Join(config.Download, dirName)

		go progress.Run()

		logger.Print("[MAIN] Creating temp path: ", download.TempPath)
		os.Mkdir(download.TempPath, 0775)
		logger.Print("[MAIN] Creating download path: ", join.DownloadPath)
		os.Mkdir(join.DownloadPath, 0775)

		for j := 0; j < len(nzb.Files); j++ {
			logger.Printf("[MAIN] Size: %v", nzb.Size())

			progress.Total = nzb.Size()

			nzbFiles := nzb.Files[j]

			numSegments := len(nzbFiles.Segments)
			wait.Add(numSegments)
			logger.Print("[MAIN] Adding(", numSegments, ")")

			for k := 0; k < numSegments; k++ {
				s := nzbFiles.Segments[k]
				logger.Print("[MAIN] Queuing", s)
				s.Group = nzbFiles.Groups[0]
				download.Queue <- &s
			}
		}

		logger.Print("[MAIN] Waiting")
		wait.Wait()
		progress.Wait.Wait()

		os.RemoveAll(decode.TempPath)
	}

	println("⚑ All Done!")
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/sachaos/todoist/lib"
	"github.com/urfave/cli"
)

func traverseItems(item *todoist.Item, f func(item *todoist.Item, depth int), depth int) {
	f(item, depth)

	if item.ChildItem != nil {
		traverseItems(item.ChildItem, f, depth + 1)
	}

	if item.BrotherItem != nil {
		traverseItems(item.BrotherItem, f, depth)
	}
}

func List(c *cli.Context) error {
	client := GetClient(c)

	colorList := ColorList()
	projectsCount := len(client.Store.Projects)
	projectIds := make([]int, projectsCount, projectsCount)
	for i, project := range client.Store.Projects {
		projectIds[i] = project.GetID()
	}
	projectColorHash := GenerateColorHash(projectIds, colorList)
	ex := Filter(c.String("filter"))

	itemList := [][]string{}
	rootItem := client.Store.RootItem

	traverseItems(rootItem, func(item *todoist.Item, depth int) {
		r, err := Eval(ex, item, client.Store.Projects, client.Store.Labels)
		if err != nil {
			return
		}
		if !r || item.Checked == 1 {
			return
		}
		itemList = append(itemList, []string{
			IdFormat(item),
			PriorityFormat(item.Priority),
			DueDateFormat(item.DateTime(), item.AllDay),
			ProjectFormat(item.ProjectID, client.Store, projectColorHash, c),
			item.LabelsString(client.Store),
			ContentPrefix(client.Store, item, depth, c) + ContentFormat(item),
		})
	}, 0)

	defer writer.Flush()

	if c.GlobalBool("header") {
		writer.Write([]string{"ID", "Priority", "DueDate", "Project", "Labels", "Content"})
	}

	for _, strings := range itemList {
		writer.Write(strings)
	}

	return nil
}
<commit_msg>Add more confortable error message<commit_after>package main

import (
	"fmt"
	"github.com/sachaos/todoist/lib"
	"github.com/urfave/cli"
	"os"
)

func traverseItems(item *todoist.Item, f func(item *todoist.Item, depth int), depth int) {
	f(item, depth)

	if item.ChildItem != nil {
		traverseItems(item.ChildItem, f, depth + 1)
	}

	if item.BrotherItem != nil {
		traverseItems(item.BrotherItem, f, depth)
	}
}

func List(c *cli.Context) error {
	client := GetClient(c)

	colorList := ColorList()
	projectsCount := len(client.Store.Projects)
	projectIds := make([]int, projectsCount, projectsCount)
	for i, project := range client.Store.Projects {
		projectIds[i] = project.GetID()
	}
	projectColorHash := GenerateColorHash(projectIds, colorList)
	ex := Filter(c.String("filter"))

	itemList := [][]string{}
	rootItem := client.Store.RootItem

	if rootItem == nil {
		fmt.Fprintln(os.Stderr, "There is no task. You can fetch latest tasks by `todoist sync`.")
		return nil
	}

	traverseItems(rootItem, func(item *todoist.Item, depth int) {
		r, err := Eval(ex, item, client.Store.Projects, client.Store.Labels)
		if err != nil {
			return
		}
		if !r || item.Checked == 1 {
			return
		}
		itemList = append(itemList, []string{
			IdFormat(item),
			PriorityFormat(item.Priority),
			DueDateFormat(item.DateTime(), item.AllDay),
			ProjectFormat(item.ProjectID, client.Store, projectColorHash, c),
			item.LabelsString(client.Store),
			ContentPrefix(client.Store, item, depth, c) + ContentFormat(item),
		})
	}, 0)

	defer writer.Flush()

	if c.GlobalBool("header") {
		writer.Write([]string{"ID", "Priority", "DueDate", "Project", "Labels", "Content"})
	}

	for _, strings := range itemList {
		writer.Write(strings)
	}

	return nil
}
<|endoftext|>


<commit_before>package fixtures

import (
	"database/sql"
	"fmt"
	"io/ioutil"
	"strings"

	"gopkg.in/yaml.v2"
)

// NewProcessingError ...
func NewProcessingError(row int, cause error) error {
	return fmt.Errorf("Error loading row %d: %s", row, cause.Error())
}

// NewFileError ...
func NewFileError(filename string, cause error) error {
	return fmt.Errorf("Error loading file %s: %s", filename, cause.Error())
}

// Load processes a YAML fixture and inserts/updates the database accordingly
func Load(data []byte, db *sql.DB, driver string) error {
	// Unmarshal the YAML data into a []Row slice
	var rows []Row
	if err := yaml.Unmarshal(data, &rows); err != nil {
		return err
	}

	// Begin a transaction
	tx, err := db.Begin()
	if err != nil {
		return err
	}

	// Iterate over rows define in the fixture
	for i, row := range rows {
		// Load internat struct variables
		row.Init()

		// Run a SELECT query to find out if we need to insert or UPDATE
		selectQuery := fmt.Sprintf(
			`SELECT COUNT(*) FROM "%s" WHERE %s`,
			row.Table,
			row.GetWhere(driver, 0),
		)
		var count int
		err = tx.QueryRow(selectQuery, row.GetPKValues()...).Scan(&count)
		if err != nil {
			tx.Rollback() // rollback the transaction
			return NewProcessingError(i+1, err)
		}

		if count == 0 {
			// Primary key not found, let's run an INSERT query
			insertQuery := fmt.Sprintf(
				`INSERT INTO "%s"(%s) VALUES(%s)`,
				row.Table,
				strings.Join(row.GetInsertColumns(), ", "),
				strings.Join(row.GetInsertPlaceholders(driver), ", "),
			)
			_, err := tx.Exec(insertQuery, row.GetInsertValues()...)
			if err != nil {
				tx.Rollback() // rollback the transaction
				return NewProcessingError(i+1, err)
			}
			if driver == postgresDriver && row.GetInsertColumns()[0] == "\"id\"" {

				var dtype string
				err = tx.QueryRow(checkPostgresPKDataType(row.Table)).Scan(&dtype)
				if err != nil {
					tx.Rollback() // rollback the transaction
					return NewProcessingError(i+1, err)
				}

				if dtype == "integer" {
					// Fixed the primary ID sequence for Postgres
					_, err := tx.Exec(fixPostgresPKSequence(row.Table))
					if err != nil {
						tx.Rollback() // rollback the transaction
						return NewProcessingError(i+1, err)
					}
				}
			}
		} else {
			// Primary key found, let's run UPDATE query
			updateQuery := fmt.Sprintf(
				`UPDATE "%s" SET %s WHERE %s`,
				row.Table,
				strings.Join(row.GetUpdatePlaceholders(driver), ", "),
				row.GetWhere(driver, row.GetUpdateColumnsLength()),
			)
			values := append(row.GetUpdateValues(), row.GetPKValues()...)
			_, err := tx.Exec(updateQuery, values...)
			if err != nil {
				tx.Rollback() // rollback the transaction
				return NewProcessingError(i+1, err)
			}
			if driver == postgresDriver && row.GetUpdateColumns()[0] == "\"id\"" {
				var dtype string
				err = tx.QueryRow(checkPostgresPKDataType(row.Table)).Scan(&dtype)
				if err != nil {
					tx.Rollback() // rollback the transaction
					return NewProcessingError(i+1, err)
				}

				if dtype == "integer" {
					// Fixed the primary ID sequence for Postgres
					_, err := tx.Exec(fixPostgresPKSequence(row.Table))
					if err != nil {
						tx.Rollback() // rollback the transaction
						return NewProcessingError(i+1, err)
					}
				}
			}
		}
	}

	// Commit the transaction
	if err := tx.Commit(); err != nil {
		tx.Rollback() // rollback the transaction
		return err
	}

	return nil
}

func checkPostgresPKDataType(table string) string {
	return fmt.Sprintf(
		"SELECT data_type "+
			"FROM information_schema.columns WHERE table_name='%s' "+
			"AND column_name='id';",
		table,
	)
}

// fixPostgresPKSequence resets primary key sequence after manual insertion
func fixPostgresPKSequence(table string) string {
	return fmt.Sprintf(
		"SELECT pg_catalog.setval(pg_get_serial_sequence('%s', 'id'), "+
			"(SELECT MAX(id) FROM %s));",
		table,
		table,
	)
}

// LoadFile ...
func LoadFile(filename string, db *sql.DB, driver string) error {
	// Read fixture data from the file
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return NewFileError(filename, err)
	}

	// Insert the fixture data
	return Load(data, db, driver)
}

// LoadFiles ...
func LoadFiles(filenames []string, db *sql.DB, driver string) error {
	for _, filename := range filenames {
		if err := LoadFile(filename, db, driver); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>:bug: Fix #5; fix sequence more reliably<commit_after>package fixtures

import (
	"database/sql"
	"fmt"
	"io/ioutil"
	"strings"

	"gopkg.in/yaml.v2"
)

// NewProcessingError ...
func NewProcessingError(row int, cause error) error {
	return fmt.Errorf("Error loading row %d: %s", row, cause.Error())
}

// NewFileError ...
func NewFileError(filename string, cause error) error {
	return fmt.Errorf("Error loading file %s: %s", filename, cause.Error())
}

// fixPostgresPKSequence
func fixPostgresPKSequence(tx *sql.Tx, table string, column string) error {
	// Query for the qualified sequence name
	var seqName *string
	err := tx.QueryRow(`
		SELECT pg_get_serial_sequence($1, $2)
	`, table, column).Scan(&seqName)

	if err != nil {
		return err
	}

	if seqName == nil {
		// No sequence to fix
		return nil
	}

	// Set the sequence
	_, err = tx.Exec(fmt.Sprintf(`
		SELECT pg_catalog.setval($1, (SELECT MAX("%s") FROM "%s"))
	`, column, table), *seqName)

	return err
}

// Load processes a YAML fixture and inserts/updates the database accordingly
func Load(data []byte, db *sql.DB, driver string) error {
	// Unmarshal the YAML data into a []Row slice
	var rows []Row
	if err := yaml.Unmarshal(data, &rows); err != nil {
		return err
	}

	// Begin a transaction
	tx, err := db.Begin()
	if err != nil {
		return err
	}

	// Iterate over rows define in the fixture
	for i, row := range rows {
		// Load internat struct variables
		row.Init()

		// Run a SELECT query to find out if we need to insert or UPDATE
		selectQuery := fmt.Sprintf(
			`SELECT COUNT(*) FROM "%s" WHERE %s`,
			row.Table,
			row.GetWhere(driver, 0),
		)
		var count int
		err = tx.QueryRow(selectQuery, row.GetPKValues()...).Scan(&count)
		if err != nil {
			tx.Rollback() // rollback the transaction
			return NewProcessingError(i+1, err)
		}

		if count == 0 {
			// Primary key not found, let's run an INSERT query
			insertQuery := fmt.Sprintf(
				`INSERT INTO "%s"(%s) VALUES(%s)`,
				row.Table,
				strings.Join(row.GetInsertColumns(), ", "),
				strings.Join(row.GetInsertPlaceholders(driver), ", "),
			)
			_, err := tx.Exec(insertQuery, row.GetInsertValues()...)
			if err != nil {
				tx.Rollback() // rollback the transaction
				return NewProcessingError(i+1, err)
			}
			if driver == postgresDriver && row.GetInsertColumns()[0] == "\"id\"" {
				err = fixPostgresPKSequence(tx, row.Table, "id")
				if err != nil {
					tx.Rollback()
					return NewProcessingError(i+1, err)
				}
			}
		} else {
			// Primary key found, let's run UPDATE query
			updateQuery := fmt.Sprintf(
				`UPDATE "%s" SET %s WHERE %s`,
				row.Table,
				strings.Join(row.GetUpdatePlaceholders(driver), ", "),
				row.GetWhere(driver, row.GetUpdateColumnsLength()),
			)
			values := append(row.GetUpdateValues(), row.GetPKValues()...)
			_, err := tx.Exec(updateQuery, values...)
			if err != nil {
				tx.Rollback() // rollback the transaction
				return NewProcessingError(i+1, err)
			}
			if driver == postgresDriver && row.GetUpdateColumns()[0] == "\"id\"" {
				err = fixPostgresPKSequence(tx, row.Table, "id")
				if err != nil {
					tx.Rollback()
					return NewProcessingError(i+1, err)
				}
			}
		}
	}

	// Commit the transaction
	if err := tx.Commit(); err != nil {
		tx.Rollback() // rollback the transaction
		return err
	}

	return nil
}

// LoadFile ...
func LoadFile(filename string, db *sql.DB, driver string) error {
	// Read fixture data from the file
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return NewFileError(filename, err)
	}

	// Insert the fixture data
	return Load(data, db, driver)
}

// LoadFiles ...
func LoadFiles(filenames []string, db *sql.DB, driver string) error {
	for _, filename := range filenames {
		if err := LoadFile(filename, db, driver); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

// #cgo LDFLAGS: -lm
// #include "tclled.h"
import "C"
import "fmt"

// import "time"
import "errors"

// import "time"

//////////////////
// STRAND CODE
//////////////////

type Strand struct {
	device   C.int
	buffer   *_Ctype_tcl_buffer
	ledCount int
}

func (s *Strand) Connect(ledCount int) error {
	s.ledCount = ledCount
	s.device = C.open_device()

	if s.device <= 0 {
		return errors.New("Device init failed")
	}

	C.set_gamma(2.2, 2.2, 2.2)
	spiStatus := C.spi_init(s.device)
	if spiStatus != 0 {
		return errors.New("SPI init failed")
	}

	s.buffer = &C.tcl_buffer{}
	tclStatus := C.tcl_init(s.buffer, C.int(s.ledCount))
	if tclStatus != 0 {
		return errors.New("TCL init failed")
	}

	return nil
}

func (s *Strand) SetColor(ledNumber int, r int, g int, b int) {
	C.write_gamma_color_to_buffer(s.buffer, C.int(ledNumber), C.uint8_t(r), C.uint8_t(g), C.uint8_t(b))
}

func (s *Strand) Save() {
	fmt.Println("Strand (", s, ") saving...")
	C.send_buffer(s.device, s.buffer)
}

//////////////////
// BOARD CODE
//////////////////

type Board struct {
	strand  *Strand
	pixelW  int
	pixelH  int
	squareW int
	squareH int
}

func (brd *Board) Connect(pixelW int, pixelH int, squareW int, squareH int) error {
	brd.pixelW = pixelW
	brd.pixelH = pixelH
	brd.squareW = squareW
	brd.squareH = squareH
	brd.strand = &Strand{}
	return brd.strand.Connect(pixelW * pixelH)
}

func (brd *Board) Save() {
	brd.strand.Save()
}

func getPixelNum(x int, y int) int {
	xSq := x / 5
	ySq := y / 5
	var boardNum, pixelNum int

	// NOTE: this is hardcoded for a 4 x 5 board with 25px/square
	if ySq%2 == 0 {
		boardNum = ySq*4 + xSq
	} else {
		boardNum = ySq*4 + 3 - xSq
	}

	xPixelInSq := x % 5
	yPixelInSq := y % 5

	if yPixelInSq%2 == 0 {
		pixelNum = yPixelInSq*5 + xPixelInSq
	} else {
		pixelNum = yPixelInSq*5 + 4 - xPixelInSq
	}

	return boardNum*25 + pixelNum
}

func (brd *Board) DrawPixel(x int, y int, r int, g int, b int) {
	pixelNum := getPixelNum(x, y)
	fmt.Println("Pixel Drawn at: (", x, y, ") ->", pixelNum)
	brd.strand.SetColor(pixelNum, r, g, b)
}

func (brd *Board) SetPixel(x int, r int, g int, b int) {
	fmt.Println("(", r, g, b, ") Pixel Drawn ->", x)
	fmt.Println("Double Checking: () ->", x)
	brd.strand.SetColor(x, r, g, b)
}

func main() {
	// board := Board{}
	// w := 100
	// h := 125
	// err := board.Connect(w, h, 4, 5)

	// if err != nil {
	// 	fmt.Print("Error: ")
	// 	fmt.Println(err)
	// 	return
	// }
	// for {
	// 	x := 0
	// 	r := 0
	// 	g := 0
	// 	b := 0

	// 	fmt.Scan(&x, &r, &g, &b)
	// 	board.SetPixel(x, r, g, b)
	// 	board.Save()
	// }

	board := Strand{}
	c := 500
	err := board.Connect(c)

	if err != nil {
		fmt.Print("Error: ")
		fmt.Println(err)
		return
	}
	for {
		x := 0
		r := 0
		g := 0
		b := 0

		fmt.Scan(&x, &r, &g, &b)
		board.SetColor(x, r, g, b)
		board.Save()
	}

	// xPix := 0
	// yPix := 0
	// for {
	// 	xPix++
	// 	if xPix > w {
	// 		xPix = 0
	// 		yPix++
	// 	}
	// 	if yPix > h {
	// 		xPix = 0
	// 		yPix = 0
	// 	}

	// 	for x := 0; x < w; x++ {
	// 		for y := 0; y < h; y++ {
	// 			if x == xPix && y == yPix {
	// 				board.DrawPixel(x, y, 100, 100, 100)
	// 			} else {
	// 				board.DrawPixel(x, y, 0, 0, 0)
	// 			}
	// 		}
	// 	}
	// 	board.Save()
	// 	time.Sleep(20 * time.Millisecond)
	// }
}
<commit_msg>Fix stupid bug, add some Free functions<commit_after>package main

// #cgo LDFLAGS: -lm
// #include "tclled.h"
import "C"
import "fmt"
import "time"
import "errors"

//////////////////
// STRAND CODE
//////////////////

type Strand struct {
	device   C.int
	buffer   *_Ctype_tcl_buffer
	ledCount int
}

func (s *Strand) Connect(ledCount int) error {
	s.ledCount = ledCount
	s.device = C.open_device()

	if s.device <= 0 {
		return errors.New("Device init failed")
	}

	C.set_gamma(2.2, 2.2, 2.2)
	spiStatus := C.spi_init(s.device)
	if spiStatus != 0 {
		return errors.New("SPI init failed")
	}

	s.buffer = &C.tcl_buffer{}
	tclStatus := C.tcl_init(s.buffer, C.int(s.ledCount))
	if tclStatus != 0 {
		return errors.New("TCL init failed")
	}

	for i := 0; i < ledCount; i++ {
		s.SetColor(i, 0, 0, 0)
	}
	s.Save()

	return nil
}

func (s *Strand) Free() error {
	C.tcl_free(s.buffer)
	C.close_device(s.device)
	fmt.Println("closed!")

	return nil
}

func (s *Strand) SetColor(ledNumber int, r int, g int, b int) {
	C.write_gamma_color_to_buffer(s.buffer, C.int(ledNumber), C.uint8_t(r), C.uint8_t(g), C.uint8_t(b))
}

func (s *Strand) Save() {
	C.send_buffer(s.device, s.buffer)
}

//////////////////
// BOARD CODE
//////////////////

type Board struct {
	strand  *Strand
	pixelW  int
	pixelH  int
	squareW int
	squareH int
}

func (brd *Board) Connect(pixelW int, pixelH int, squareW int, squareH int) error {
	brd.pixelW = pixelW
	brd.pixelH = pixelH
	brd.squareW = squareW
	brd.squareH = squareH
	brd.strand = &Strand{}
	return brd.strand.Connect(pixelW * pixelH)
}

func (brd *Board) Free() {
	brd.strand.Free()
}

func (brd *Board) Save() {
	brd.strand.Save()
}

func getPixelNum(x int, y int) int {
	xSq := x / 5
	ySq := y / 5
	var boardNum, pixelNum int

	// NOTE: this is hardcoded for a 4 x 5 board with 25px/square
	if ySq%2 == 0 {
		boardNum = ySq*4 + xSq
	} else {
		boardNum = ySq*4 + 3 - xSq
	}

	xPixelInSq := x % 5
	yPixelInSq := y % 5

	if yPixelInSq%2 == 0 {
		pixelNum = yPixelInSq*5 + xPixelInSq
	} else {
		pixelNum = yPixelInSq*5 + 4 - xPixelInSq
	}

	return boardNum*25 + pixelNum
}

func (brd *Board) DrawPixel(x int, y int, r int, g int, b int) {
	pixelNum := getPixelNum(x, y)
	// fmt.Println("Pixel Drawn at: (", x, y, ") ->", pixelNum)
	brd.strand.SetColor(pixelNum, r, g, b)
}

func (brd *Board) SetColor(x int, r int, g int, b int) {
	// fmt.Println("(", r, g, b, ") Pixel Drawn ->", x)
	// fmt.Println("Double Checking: () ->", x)
	brd.strand.SetColor(x, r, g, b)
}

func main() {
	fmt.Println("foo3")
	board := Board{}

	w := 20
	h := 25
	err := board.Connect(w, h, 4, 5)
	defer board.Free()

	// if err != nil {
	// 	fmt.Print("Error: ")
	// 	fmt.Println(err)
	// 	return
	// }
	// for {
	// 	x := 0
	// 	r := 0
	// 	g := 0
	// 	b := 0

	// 	fmt.Scan(&x, &r, &g, &b)
	// 	board.SetColor(x, r, g, b)
	// 	board.Save()
	// }

	// board := Strand{}
	// c := 500
	// err := board.Connect(c)

	if err != nil {
		fmt.Print("Error: ")
		fmt.Println(err)
		return
	}
	// for {
	// 	r := 0
	// 	g := 0
	// 	b := 0
	// 	x := 0
	// 	fmt.Scan(&x, &r, &g, &b)
	// 	board.SetColor(x, r, g, b)
	// 	board.Save()
	// }

	fmt.Println("foo2")
	xPix := 0
	yPix := 0
	for {
		xPix++
		if xPix > w {
			xPix = 0
			yPix++
		}
		if yPix > h {
			xPix = 0
			yPix = 0
		}
		fmt.Println("foo")
		fmt.Println(xPix, yPix)

		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				if x == xPix && y == yPix {
					board.DrawPixel(x, y, 100, 100, 100)
				} else {
					board.DrawPixel(x, y, 0, 0, 0)
				}
			}
		}
		board.Save()
		time.Sleep(20 * time.Millisecond)
	}
}
<|endoftext|>


<commit_before>package arn

import "sort"

// Post represents a forum post.
type Post struct {
	ID       string   `json:"id"`
	Text     string   `json:"text"`
	AuthorID string   `json:"authorId"`
	ThreadID string   `json:"threadId"`
	Tags     []string `json:"tags"`
	Likes    []string `json:"likes"`
	Created  string   `json:"created"`
	Edited   string   `json:"edited"`

	author *User
	thread *Thread
}

// Author returns the post author.
func (post *Post) Author() *User {
	if post.author != nil {
		return post.author
	}

	post.author, _ = GetUser(post.AuthorID)
	return post.author
}

// Thread returns the thread this post was posted in.
func (post *Post) Thread() *Thread {
	if post.thread != nil {
		return post.thread
	}

	post.thread, _ = GetThread(post.ThreadID)
	return post.thread
}

// Link returns the relative URL of the post.
func (post *Post) Link() string {
	return "/posts/" + post.ID
}

// ToPostable converts a post into an object that implements the Postable interface.
func (post *Post) ToPostable() Postable {
	return &PostPostable{post}
}

// GetPost ...
func GetPost(id string) (*Post, error) {
	obj, err := DB.Get("Post", id)
	return obj.(*Post), err
}

// GetPosts ...
func GetPosts() ([]*Post, error) {
	var posts []*Post

	channel := make(chan *Post)
	err := DB.Scan("Post", channel)

	for post := range channel {
		posts = append(posts, post)
	}

	return posts, err
}

// SortPostsLatestFirst sorts the slice of posts.
func SortPostsLatestFirst(posts []*Post) {
	sort.Slice(posts, func(i, j int) bool {
		return posts[i].Created > posts[j].Created
	})
}

// SortPostsLatestLast sorts the slice of posts.
func SortPostsLatestLast(posts []*Post) {
	sort.Slice(posts, func(i, j int) bool {
		return posts[i].Created < posts[j].Created
	})
}

// GetPostsByUser ...
func GetPostsByUser(user *User) ([]*Post, error) {
	var posts []*Post

	scan := make(chan *Post)
	err := DB.Scan("Post", scan)

	if err != nil {
		return nil, err
	}

	for post := range scan {
		if post.AuthorID == user.ID {
			posts = append(posts, post)
		}
	}

	return posts, nil
}

// FilterPosts filters all forum posts by a custom function.
func FilterPosts(filter func(*Post) bool) ([]*Post, error) {
	var filtered []*Post

	channel := make(chan *Post)
	err := DB.Scan("Post", channel)

	if err != nil {
		return filtered, err
	}

	for post := range channel {
		if filter(post) {
			filtered = append(filtered, post)
		}
	}

	return filtered, nil
}
<commit_msg>Renamed scan to stream<commit_after>package arn

import "sort"

// Post represents a forum post.
type Post struct {
	ID       string   `json:"id"`
	Text     string   `json:"text"`
	AuthorID string   `json:"authorId"`
	ThreadID string   `json:"threadId"`
	Tags     []string `json:"tags"`
	Likes    []string `json:"likes"`
	Created  string   `json:"created"`
	Edited   string   `json:"edited"`

	author *User
	thread *Thread
}

// Author returns the post author.
func (post *Post) Author() *User {
	if post.author != nil {
		return post.author
	}

	post.author, _ = GetUser(post.AuthorID)
	return post.author
}

// Thread returns the thread this post was posted in.
func (post *Post) Thread() *Thread {
	if post.thread != nil {
		return post.thread
	}

	post.thread, _ = GetThread(post.ThreadID)
	return post.thread
}

// Link returns the relative URL of the post.
func (post *Post) Link() string {
	return "/posts/" + post.ID
}

// ToPostable converts a post into an object that implements the Postable interface.
func (post *Post) ToPostable() Postable {
	return &PostPostable{post}
}

// GetPost ...
func GetPost(id string) (*Post, error) {
	obj, err := DB.Get("Post", id)
	return obj.(*Post), err
}

// GetPosts ...
func GetPosts() ([]*Post, error) {
	var posts []*Post

	channel := make(chan *Post)
	err := DB.Scan("Post", channel)

	for post := range channel {
		posts = append(posts, post)
	}

	return posts, err
}

// SortPostsLatestFirst sorts the slice of posts.
func SortPostsLatestFirst(posts []*Post) {
	sort.Slice(posts, func(i, j int) bool {
		return posts[i].Created > posts[j].Created
	})
}

// SortPostsLatestLast sorts the slice of posts.
func SortPostsLatestLast(posts []*Post) {
	sort.Slice(posts, func(i, j int) bool {
		return posts[i].Created < posts[j].Created
	})
}

// GetPostsByUser ...
func GetPostsByUser(user *User) ([]*Post, error) {
	var posts []*Post

	stream := make(chan *Post)
	err := DB.Scan("Post", stream)

	if err != nil {
		return nil, err
	}

	for post := range stream {
		if post.AuthorID == user.ID {
			posts = append(posts, post)
		}
	}

	return posts, nil
}

// FilterPosts filters all forum posts by a custom function.
func FilterPosts(filter func(*Post) bool) ([]*Post, error) {
	var filtered []*Post

	channel := make(chan *Post)
	err := DB.Scan("Post", channel)

	if err != nil {
		return filtered, err
	}

	for post := range channel {
		if filter(post) {
			filtered = append(filtered, post)
		}
	}

	return filtered, nil
}
<|endoftext|>


<commit_before>package yamux

import (
	"fmt"
	"net"
)

// hasAddr is used to get the address from the underlying connection
type hasAddr interface {
	LocalAddr() net.Addr
	RemoteAddr() net.Addr
}

// yamuxAddr is used when we cannot get the underlying address
type yamuxAddr struct {
	Addr string
}

func (*yamuxAddr) Network() string {
	return "yamux"
}

func (y *yamuxAddr) String() string {
	return fmt.Sprintf("yamux:%s", y.Addr)
}

// Addr is used to get the address of the listener.
func (s *Session) Addr() net.Addr {
	return s.LocalAddr()
}

// LocalAddr is used to get the local address of the
// underlying connection.
func (s *Session) LocalAddr() net.Addr {
	addr, ok := s.conn.(hasAddr)
	if !ok {
		return &yamuxAddr{"local"}
	}
	return addr.LocalAddr()
}

// RemoteAddr is used to get the address of remote end
// of the underlying connection
func (s *Session) RemoteAddr() net.Addr {
	addr, ok := s.conn.(hasAddr)
	if !ok {
		return &yamuxAddr{"remote"}
	}
	return addr.RemoteAddr()
}

// LocalAddr returns the local address
func (s *Stream) LocalAddr() net.Addr {
	return s.session.LocalAddr()
}

// LocalAddr returns the remote address
func (s *Stream) RemoteAddr() net.Addr {
	return s.session.RemoteAddr()
}
<commit_msg>Fix function comments based on best practices from Effective Go<commit_after>package yamux

import (
	"fmt"
	"net"
)

// hasAddr is used to get the address from the underlying connection
type hasAddr interface {
	LocalAddr() net.Addr
	RemoteAddr() net.Addr
}

// yamuxAddr is used when we cannot get the underlying address
type yamuxAddr struct {
	Addr string
}

func (*yamuxAddr) Network() string {
	return "yamux"
}

func (y *yamuxAddr) String() string {
	return fmt.Sprintf("yamux:%s", y.Addr)
}

// Addr is used to get the address of the listener.
func (s *Session) Addr() net.Addr {
	return s.LocalAddr()
}

// LocalAddr is used to get the local address of the
// underlying connection.
func (s *Session) LocalAddr() net.Addr {
	addr, ok := s.conn.(hasAddr)
	if !ok {
		return &yamuxAddr{"local"}
	}
	return addr.LocalAddr()
}

// RemoteAddr is used to get the address of remote end
// of the underlying connection
func (s *Session) RemoteAddr() net.Addr {
	addr, ok := s.conn.(hasAddr)
	if !ok {
		return &yamuxAddr{"remote"}
	}
	return addr.RemoteAddr()
}

// LocalAddr returns the local address
func (s *Stream) LocalAddr() net.Addr {
	return s.session.LocalAddr()
}

// RemoteAddr returns the remote address
func (s *Stream) RemoteAddr() net.Addr {
	return s.session.RemoteAddr()
}
<|endoftext|>


<commit_before>package http_digest_auth

import (
	"fmt"
	//	"io/ioutil"
	"crypto/md5"
	"crypto/rand"
	"encoding/base64"
	"io"
	"net/http"
	"net/url"
	"strings"
)

type myjar struct {
	jar map[string][]*http.Cookie
}

func (p *myjar) SetCookies(u *url.URL, cookies []*http.Cookie) {
	p.jar[u.Host] = cookies
}

func (p *myjar) Cookies(u *url.URL) []*http.Cookie {
	return p.jar[u.Host]
}

func Auth(username string, password string, uri string) (bool, error) {
	client := &http.Client{}
	jar := &myjar{}
	jar.jar = make(map[string][]*http.Cookie)
	client.Jar = jar
	var req *http.Request
	var resp *http.Response
	var err error
	req, err = http.NewRequest("GET", uri, nil)
	resp, err = client.Do(req)
	if err != nil {
		return false, err
	}
	if resp.StatusCode == 401 {
		var authorization map[string]string = DigestAuthParams(resp)
		realmHeader := authorization["realm"]
		qopHeader := authorization["qop"]
		nonceHeader := authorization["nonce"]
		opaqueHeader := authorization["opaque"]
		realm := realmHeader
		// A1
		h := md5.New()
		A1 := fmt.Sprintf("%s:%s:%s", username, realm, password)
		io.WriteString(h, A1)
		HA1 := fmt.Sprintf("%x", h.Sum(nil))

		// A2
		h = md5.New()
		A2 := fmt.Sprintf("GET:%s", "/auth")
		io.WriteString(h, A2)
		HA2 := fmt.Sprintf("%x", h.Sum(nil))

		// response
		cnonce := RandomKey()
		response := H(strings.Join([]string{HA1, nonceHeader, "00000001", cnonce, qopHeader, HA2}, ":"))

		// now make header
		AuthHeader := fmt.Sprintf(`Digest username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=00000001, qop=%s, response="%s", opaque="%s", algorithm=MD5`,
			username, realmHeader, nonceHeader, "/auth", cnonce, qopHeader, response, opaqueHeader)
		req.Header.Set("Authorization", AuthHeader)
		resp, err = client.Do(req)
	} else {
		return false, fmt.Errorf("response status code should have been 401, it was %v", resp.StatusCode)
	}
	return resp.StatusCode == 200, err
}

/*
 Parse Authorization header from the http.Request. Returns a map of
 auth parameters or nil if the header is not a valid parsable Digest
 auth header.
*/
func DigestAuthParams(r *http.Response) map[string]string {
	s := strings.SplitN(r.Header.Get("Www-Authenticate"), " ", 2)
	if len(s) != 2 || s[0] != "Digest" {
		return nil
	}

	result := map[string]string{}
	for _, kv := range strings.Split(s[1], ",") {
		parts := strings.SplitN(kv, "=", 2)
		if len(parts) != 2 {
			continue
		}
		result[strings.Trim(parts[0], "\" ")] = strings.Trim(parts[1], "\" ")
	}
	return result
}
func RandomKey() string {
	k := make([]byte, 12)
	for bytes := 0; bytes < len(k); {
		n, err := rand.Read(k[bytes:])
		if err != nil {
			panic("rand.Read() failed")
		}
		bytes += n
	}
	return base64.StdEncoding.EncodeToString(k)
}

/*
 H function for MD5 algorithm (returns a lower-case hex MD5 digest)
*/
func H(data string) string {
	digest := md5.New()
	digest.Write([]byte(data))
	return fmt.Sprintf("%x", digest.Sum(nil))
}
<commit_msg>Fixed to use general perpose.<commit_after>package http_digest_auth

import (
	"fmt"
	//	"io/ioutil"
	"crypto/md5"
	"crypto/rand"
	"encoding/base64"
	"io"
	"log"
	"net/http"
	"net/url"
	"strings"
)

const (
	nc = "00000001"
)

type myjar struct {
	jar map[string][]*http.Cookie
}

type digestHeader struct {
	Realm string
	Qop string
	Nonce string
	Opaque string
	Algorithm string
	HA1 string
	HA2 string
	Cnonce string
	Path string
}

func (p *myjar) SetCookies(u *url.URL, cookies []*http.Cookie) {
	p.jar[u.Host] = cookies
}

func (p *myjar) Cookies(u *url.URL) []*http.Cookie {
	return p.jar[u.Host]
}

func (d *digestHeader) digestChecksum(username string, password string) {
	switch d.Algorithm {
	case "MD5":
		// A1
		h := md5.New()
		A1 := fmt.Sprintf("%s:%s:%s", username, d.Realm, password)
		io.WriteString(h, A1)
		d.HA1 = fmt.Sprintf("%x", h.Sum(nil))

		// A2
		h =  md5.New()
		A2 := fmt.Sprintf("GET:%s", d.Path)
		io.WriteString(h, A2)
		d.HA2 = fmt.Sprintf("%x", h.Sum(nil))
	case "MD5-sess":
	default:
		//token
	}
}

func (d *digestHeader) Auth(username string, password string, uri string) (bool, error) {

	client := &http.Client{}
	jar := &myjar{}
	jar.jar = make(map[string][]*http.Cookie)
	client.Jar = jar

	req, err := http.NewRequest("GET", uri, nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	if resp.StatusCode == 401 {
		d := &digestHeader{}
		u, _ := url.Parse(uri)
		d.Path = u.Path
		authn := DigestAuthParams(resp)
		d.Realm = authn["realm"]
		d.Qop = authn["qop"]
		d.Nonce = authn["nonce"]
		d.Opaque = authn["opaque"]
		d.Algorithm = authn["algorithm"]
		d.Cnonce = RandomKey()

		// HA1 and HA2
		d.digestChecksum(username, password)

		// response
		response := H(strings.Join([]string{d.HA1, d.Nonce, nc, d.Cnonce, d.Qop, d.HA2}, ":"))

		// now make header
		AuthHeader := fmt.Sprintf(`Digest username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=00000001, qop=%s, response="%s", algorithm=%s`,
			username, d.Realm, d.Nonce, d.Path, d.Cnonce, d.Qop, response, d.Algorithm)
		if d.Opaque != "" {
			AuthHeader = fmt.Sprintf(`%s, opaque="%s"`, AuthHeader, d.Opaque)
		}

		req.Header.Set("Authorization", AuthHeader)
		resp, err = client.Do(req)
	} else {
		return false, fmt.Errorf("response status code should have been 401, it was %v", resp.StatusCode)
	}
	return resp.StatusCode == 200, err
}

/*
 Parse Authorization header from the http.Request. Returns a map of
 auth parameters or nil if the header is not a valid parsable Digest
 auth header.
*/
func DigestAuthParams(r *http.Response) map[string]string {
	s := strings.SplitN(r.Header.Get("Www-Authenticate"), " ", 2)
	if len(s) != 2 || s[0] != "Digest" {
		return nil
	}

	result := map[string]string{}
	for _, kv := range strings.Split(s[1], ",") {
		parts := strings.SplitN(kv, "=", 2)
		if len(parts) != 2 {
			continue
		}
		result[strings.Trim(parts[0], "\" ")] = strings.Trim(parts[1], "\" ")
	}
	return result
}

func RandomKey() string {
	k := make([]byte, 12)
	for bytes := 0; bytes < len(k); {
		n, err := rand.Read(k[bytes:])
		if err != nil {
			panic("rand.Read() failed")
		}
		bytes += n
	}
	return base64.StdEncoding.EncodeToString(k)
}

/*
 H function for MD5 algorithm (returns a lower-case hex MD5 digest)
*/
func H(data string) string {
	digest := md5.New()
	digest.Write([]byte(data))
	return fmt.Sprintf("%x", digest.Sum(nil))
}
<|endoftext|>


<commit_before>package garminconnect

import (
	"errors"
	"io/ioutil"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"regexp"
)

const (
	GARMIN_CONNECT_URL = "https://connect.garmin.com"
)

type Client struct {
	client      *http.Client
	displayName string
}

func NewClient(httpClient ...*http.Client) (*Client, error) {
	cookies, err := cookiejar.New(nil)

	if err != nil {
		return nil, err
	}

	var client *http.Client

	if len(httpClient) > 0 {
		client = httpClient[0]
	} else {
		client = &http.Client{}
	}

	client.Jar = cookies

	return &Client{
		client: client,
	}, nil
}

func (gc *Client) Auth(username, password string) error {
	loginUrl, err := url.Parse("https://sso.garmin.com/sso/login?service=" + GARMIN_CONNECT_URL + "/post-auth/login&webhost=olaxpw-connect13.garmin.com&source=" + GARMIN_CONNECT_URL + "/en-US/signin&redirectAfterAccountLoginUrl=" + GARMIN_CONNECT_URL + "/post-auth/login&redirectAfterAccountCreationUrl=" + GARMIN_CONNECT_URL + "/post-auth/login&gauthHost=https://sso.garmin.com/sso&locale=en_US&id=gauth-widget&cssUrl=https://static.garmincdn.com/com.garmin.connect/ui/css/gauth-custom-v1.2-min.css&clientId=GarminConnect&rememberMeShown=true&rememberMeChecked=false&createAccountShown=true&openCreateAccount=false&usernameShown=false&displayNameShown=false&consumeServiceTicket=false&initialFocus=true&embedWidget=false&generateExtraServiceTicket=false")

	if err != nil {
		return err
	}

	_, err = gc.client.Get(loginUrl.String())

	if err != nil {
		return err
	}

	data := url.Values{}

	data.Set("username", username)
	data.Set("password", password)
	data.Set("_eventId", "submit")
	data.Set("embed", "true")
	data.Set("lt", "e1s1")
	data.Set("displayNameRequired", "false")

	response, err := gc.client.PostForm(loginUrl.String(), data)

	if err != nil {
		return err
	}

	if response.StatusCode != http.StatusOK {
		return errors.New("auth request not good")
	}

	body, err := ioutil.ReadAll(response.Body)

	if err != nil {
		return err
	}

	re := regexp.MustCompile(`ticket=([^']+)'`)
	ticket := re.FindAllStringSubmatch(string(body), 1)[0][1]

	response, err = gc.client.Get(GARMIN_CONNECT_URL + "/post-auth/login?ticket=" + ticket)

	if err != nil {
		return err
	}

	defer response.Body.Close()

	return nil
}
<commit_msg>Correct regex<commit_after>package garminconnect

import (
	"errors"
	"io/ioutil"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"regexp"
)

const (
	GARMIN_CONNECT_URL = "https://connect.garmin.com"
)

type Client struct {
	client      *http.Client
	displayName string
}

func NewClient(httpClient ...*http.Client) (*Client, error) {
	cookies, err := cookiejar.New(nil)

	if err != nil {
		return nil, err
	}

	var client *http.Client

	if len(httpClient) > 0 {
		client = httpClient[0]
	} else {
		client = &http.Client{}
	}

	client.Jar = cookies

	return &Client{
		client: client,
	}, nil
}

func (gc *Client) Auth(username, password string) error {
	loginUrl, err := url.Parse("https://sso.garmin.com/sso/login?service=" + GARMIN_CONNECT_URL + "/post-auth/login&webhost=olaxpw-connect13.garmin.com&source=" + GARMIN_CONNECT_URL + "/en-US/signin&redirectAfterAccountLoginUrl=" + GARMIN_CONNECT_URL + "/post-auth/login&redirectAfterAccountCreationUrl=" + GARMIN_CONNECT_URL + "/post-auth/login&gauthHost=https://sso.garmin.com/sso&locale=en_US&id=gauth-widget&cssUrl=https://static.garmincdn.com/com.garmin.connect/ui/css/gauth-custom-v1.2-min.css&clientId=GarminConnect&rememberMeShown=true&rememberMeChecked=false&createAccountShown=true&openCreateAccount=false&usernameShown=false&displayNameShown=false&consumeServiceTicket=false&initialFocus=true&embedWidget=false&generateExtraServiceTicket=false")

	if err != nil {
		return err
	}

	_, err = gc.client.Get(loginUrl.String())

	if err != nil {
		return err
	}

	data := url.Values{}

	data.Set("username", username)
	data.Set("password", password)
	data.Set("_eventId", "submit")
	data.Set("embed", "true")
	data.Set("lt", "e1s1")
	data.Set("displayNameRequired", "false")

	response, err := gc.client.PostForm(loginUrl.String(), data)

	if err != nil {
		return err
	}

	if response.StatusCode != http.StatusOK {
		return errors.New("auth request not good")
	}

	body, err := ioutil.ReadAll(response.Body)

	if err != nil {
		return err
	}

	re := regexp.MustCompile(`ticket=([^"]+)`)
	ticket := re.FindAllStringSubmatch(string(body), 1)[0][1]
	response, err = gc.client.Get(GARMIN_CONNECT_URL + "/post-auth/login?ticket=" + ticket)

	if err != nil {
		return err
	}

	defer response.Body.Close()

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2017 Christoph Berger. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package bank

import (
	"encoding/gob"
	"fmt"
	"os"

	"github.com/pkg/errors"
)

// Account is a bank account with a name, a balance, and a
// transaction history.
type Account struct {
	Name string
	Bal  int
	Hist []history
}

type history struct {
	Amt, Bal int
}

// The fields of the above structs could be internal, too. Only for
// gob functionality (see Save and Load), they had to be exported.

var accounts map[string]*Account

// NewAccount creates a new account with a name. Initial balance is 0.
// The new account is added to the bank's map of accounts.
func NewAccount(s string) *Account {
	if accounts == nil {
		accounts = make(map[string]*Account)
	}
	a := &Account{Name: s}
	accounts[s] = a
	return a
}

// GetAccount receives a name and returns the account of that name, if it exists.
// GetAccount panics if the bank has no accounts.
func GetAccount(name string) (*Account, error) {
	accnt, ok := accounts[name]
	if !ok {
		return nil, errors.New("account '" + name + "' does not exist")
	}
	return accnt, nil
}

// ListAccounts returns a formatted string that lists
// each account and its current balance.
func ListAccounts() string {
	list := "Accounts:\n"
	for _, v := range accounts {
		list += fmt.Sprintf("Account: %s, balance: %d\n", v.Name, v.Bal)
	}
	return list
}

// Name returns the name of account a.
func Name(a *Account) string {
	return a.Name
}

// Balance returns the current balance of account a.
func Balance(a *Account) int {
	return a.Bal
}

// Deposit adds amount m to account a's balance.
// The amount must be positive.
func Deposit(a *Account, m int) (int, error) {
	if m < 0 {
		return a.Bal, errors.Errorf("Deposit: amount must be positive, but is %d.", m)
	}
	a.Bal += m
	a.Hist = append(a.Hist, history{m, a.Bal})
	return a.Bal, nil
}

// Withdraw removes amount m from account a's balance.
// The amount must be positive.
func Withdraw(a *Account, m int) (int, error) {
	if m < 0 {
		return a.Bal, errors.Errorf("Withdraw: amount must be positive, but is %d.", m)
	}
	if m > a.Bal {
		return a.Bal, errors.Errorf("Withdraw: amount (%d) must be less than actual balance (%d).", m, a.Bal)
	}
	a.Bal -= m
	a.Hist = append(a.Hist, history{-m, a.Bal})
	return a.Bal, nil
}

// Transfer transfers amount m from account a to account b.
// The amount must be positive.
// The sending account must have at least as much money as the
// amount to be transferred.
func Transfer(a, b *Account, m int) (int, int, error) {
	switch {
	case m < 0:
		return a.Bal, b.Bal, errors.Errorf("Transfer: amount must be positive, but is %d.", m)
	case m > a.Bal:
		return 0, a.Bal, errors.Errorf("Withdraw: amount (%d) must be less than actual balance of sending account (%d).", m, a.Bal)
	}
	a.Bal -= m
	b.Bal += m
	a.Hist = append(a.Hist, history{-m, a.Bal})
	b.Hist = append(b.Hist, history{m, b.Bal})
	return a.Bal, b.Bal, nil
}

// History returns a closure that returns one account transaction at a time.
// On each call, the closure returns the amount of the transaction, the resulting balance,
// and a boolean that is true as long as there are more history elements to read.
// The closure returns the history items from oldest to newest.
func History(a *Account) func() (int, int, bool) {
	i := 0
	more := true
	return func() (int, int, bool) {
		if i >= len(a.Hist)-1 {
			more = false
		}
		h := a.Hist[i]
		i++
		return h.Amt, h.Bal, more
	}
}

// Persist the accounts map on disk.
func Save() error {
	f, err := os.OpenFile("bank.data", os.O_WRONLY, 0666) // Note: octal #
	if err != nil {
		f, err = os.Create("bank.data")
		if err != nil {
			return errors.Wrap(err, "Save: Create failed")
		}
	}
	defer f.Close()
	e := gob.NewEncoder(f)
	err = e.Encode(accounts)
	if err != nil {
		return errors.Wrap(err, "Save: Encode failed")
	}
	return nil
}

// Restore the accounts map from disk.
func Load() error {
	f, err := os.Open("bank.data")
	if err != nil {
		if os.IsNotExist(err) {
			// Expected. The file does not exist initially.
			return nil
		}
		return errors.Wrap(err, "Load: Open failed")
	}
	defer f.Close()
	d := gob.NewDecoder(f)
	err = d.Decode(&accounts)
	if err != nil {
		return errors.Wrap(err, "Load: Decode failed")
	}
	return nil
}
<commit_msg>Fix error handling in deferred Close() call of writeable file<commit_after>// Copyright 2017 Christoph Berger. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package bank

import (
	"encoding/gob"
	"fmt"
	"os"

	"github.com/pkg/errors"
)

// Account is a bank account with a name, a balance, and a
// transaction history.
type Account struct {
	Name string
	Bal  int
	Hist []history
}

type history struct {
	Amt, Bal int
}

// The fields of the above structs could be internal, too. Only for
// gob functionality (see Save and Load), they had to be exported.

var accounts map[string]*Account

// NewAccount creates a new account with a name. Initial balance is 0.
// The new account is added to the bank's map of accounts.
func NewAccount(s string) *Account {
	if accounts == nil {
		accounts = make(map[string]*Account)
	}
	a := &Account{Name: s}
	accounts[s] = a
	return a
}

// GetAccount receives a name and returns the account of that name, if it exists.
// GetAccount panics if the bank has no accounts.
func GetAccount(name string) (*Account, error) {
	accnt, ok := accounts[name]
	if !ok {
		return nil, errors.New("account '" + name + "' does not exist")
	}
	return accnt, nil
}

// ListAccounts returns a formatted string that lists
// each account and its current balance.
func ListAccounts() string {
	list := "Accounts:\n"
	for _, v := range accounts {
		list += fmt.Sprintf("Account: %s, balance: %d\n", v.Name, v.Bal)
	}
	return list
}

// Name returns the name of account a.
func Name(a *Account) string {
	return a.Name
}

// Balance returns the current balance of account a.
func Balance(a *Account) int {
	return a.Bal
}

// Deposit adds amount m to account a's balance.
// The amount must be positive.
func Deposit(a *Account, m int) (int, error) {
	if m < 0 {
		return a.Bal, errors.Errorf("Deposit: amount must be positive, but is %d.", m)
	}
	a.Bal += m
	a.Hist = append(a.Hist, history{m, a.Bal})
	return a.Bal, nil
}

// Withdraw removes amount m from account a's balance.
// The amount must be positive.
func Withdraw(a *Account, m int) (int, error) {
	if m < 0 {
		return a.Bal, errors.Errorf("Withdraw: amount must be positive, but is %d.", m)
	}
	if m > a.Bal {
		return a.Bal, errors.Errorf("Withdraw: amount (%d) must be less than actual balance (%d).", m, a.Bal)
	}
	a.Bal -= m
	a.Hist = append(a.Hist, history{-m, a.Bal})
	return a.Bal, nil
}

// Transfer transfers amount m from account a to account b.
// The amount must be positive.
// The sending account must have at least as much money as the
// amount to be transferred.
func Transfer(a, b *Account, m int) (int, int, error) {
	switch {
	case m < 0:
		return a.Bal, b.Bal, errors.Errorf("Transfer: amount must be positive, but is %d.", m)
	case m > a.Bal:
		return 0, a.Bal, errors.Errorf("Withdraw: amount (%d) must be less than actual balance of sending account (%d).", m, a.Bal)
	}
	a.Bal -= m
	b.Bal += m
	a.Hist = append(a.Hist, history{-m, a.Bal})
	b.Hist = append(b.Hist, history{m, b.Bal})
	return a.Bal, b.Bal, nil
}

// History returns a closure that returns one account transaction at a time.
// On each call, the closure returns the amount of the transaction, the resulting balance,
// and a boolean that is true as long as there are more history elements to read.
// The closure returns the history items from oldest to newest.
func History(a *Account) func() (int, int, bool) {
	i := 0
	more := true
	return func() (int, int, bool) {
		if i >= len(a.Hist)-1 {
			more = false
		}
		h := a.Hist[i]
		i++
		return h.Amt, h.Bal, more
	}
}

// Save persists the accounts map on disk.
func Save() (err error) {
	f, err := os.OpenFile("bank.data", os.O_WRONLY, 0666) // Note: octal #
	if err != nil {
		f, err = os.Create("bank.data")
		if err != nil {
			return errors.Wrap(err, "Save: Create failed")
		}
	}
	defer func() {
		e := f.Close()
		if e != nil {
			if err == nil {
				err = e
				return
			}
			err = errors.Wrap(err, e.Error())
		}
	}()

	e := gob.NewEncoder(f)
	err = e.Encode(accounts)
	if err != nil {
		return errors.Wrap(err, "Save: Encode failed")
	}
	return nil
}

// Load restores the accounts map from disk.
func Load() error {
	f, err := os.Open("bank.data")
	if err != nil {
		if os.IsNotExist(err) {
			// Expected. The file does not exist initially.
			return nil
		}
		return errors.Wrap(err, "Load: Open failed")
	}
	defer f.Close() // closing a readonly file needs no error checking
	d := gob.NewDecoder(f)
	err = d.Decode(&accounts)
	if err != nil {
		return errors.Wrap(err, "Load: Decode failed")
	}
	return nil
}
<|endoftext|>


<commit_before>package sqlx

import (
	"bytes"
	"errors"
	"reflect"
	"strconv"
	"strings"

	"github.com/jmoiron/sqlx/reflectx"
)

// Bindvar types supported by Rebind, BindMap and BindStruct.
const (
	UNKNOWN = iota
	QUESTION
	DOLLAR
	NAMED
)

// BindType returns the bindtype for a given database given a drivername.
func BindType(driverName string) int {
	switch driverName {
	case "postgres", "pgx", "pq-timeouts":
		return DOLLAR
	case "mysql":
		return QUESTION
	case "sqlite3":
		return QUESTION
	case "oci8", "ora", "goracle":
		return NAMED
	}
	return UNKNOWN
}

// FIXME: this should be able to be tolerant of escaped ?'s in queries without
// losing much speed, and should be to avoid confusion.

// Rebind a query from the default bindtype (QUESTION) to the target bindtype.
func Rebind(bindType int, query string) string {
	switch bindType {
	case QUESTION, UNKNOWN:
		return query
	}

	// Add space enough for 10 params before we have to allocate
	rqb := make([]byte, 0, len(query)+10)

	var i, j int

	for i = strings.Index(query, "?"); i != -1; i = strings.Index(query, "?") {
		rqb = append(rqb, query[:i]...)

		switch bindType {
		case DOLLAR:
			rqb = append(rqb, '$')
		case NAMED:
			rqb = append(rqb, ':', 'a', 'r', 'g')
		}

		j++
		rqb = strconv.AppendInt(rqb, int64(j), 10)

		query = query[i+1:]
	}

	return string(append(rqb, query...))
}

// Experimental implementation of Rebind which uses a bytes.Buffer.  The code is
// much simpler and should be more resistant to odd unicode, but it is twice as
// slow.  Kept here for benchmarking purposes and to possibly replace Rebind if
// problems arise with its somewhat naive handling of unicode.
func rebindBuff(bindType int, query string) string {
	if bindType != DOLLAR {
		return query
	}

	b := make([]byte, 0, len(query))
	rqb := bytes.NewBuffer(b)
	j := 1
	for _, r := range query {
		if r == '?' {
			rqb.WriteRune('$')
			rqb.WriteString(strconv.Itoa(j))
			j++
		} else {
			rqb.WriteRune(r)
		}
	}

	return rqb.String()
}

// In expands slice values in args, returning the modified query string
// and a new arg list that can be executed by a database. The `query` should
// use the `?` bindVar.  The return value uses the `?` bindVar.
func In(query string, args ...interface{}) (string, []interface{}, error) {
	// argMeta stores reflect.Value and length for slices and
	// the value itself for non-slice arguments
	type argMeta struct {
		v      reflect.Value
		i      interface{}
		length int
	}

	var flatArgsCount int
	var anySlices bool

	meta := make([]argMeta, len(args))

	for i, arg := range args {
		v := reflect.ValueOf(arg)
		t := reflectx.Deref(v.Type())

		if t.Kind() == reflect.Slice {
			meta[i].length = v.Len()
			meta[i].v = v

			anySlices = true
			flatArgsCount += meta[i].length

			if meta[i].length == 0 {
				return "", nil, errors.New("empty slice passed to 'in' query")
			}
		} else {
			meta[i].i = arg
			flatArgsCount++
		}
	}

	// don't do any parsing if there aren't any slices;  note that this means
	// some errors that we might have caught below will not be returned.
	if !anySlices {
		return query, args, nil
	}

	newArgs := make([]interface{}, 0, flatArgsCount)
	buf := bytes.NewBuffer(make([]byte, 0, len(query)+len(", ?")*flatArgsCount))

	var arg, offset int

	for i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') {
		if arg >= len(meta) {
			// if an argument wasn't passed, lets return an error;  this is
			// not actually how database/sql Exec/Query works, but since we are
			// creating an argument list programmatically, we want to be able
			// to catch these programmer errors earlier.
			return "", nil, errors.New("number of bindVars exceeds arguments")
		}

		argMeta := meta[arg]
		arg++

		// not a slice, continue.
		// our questionmark will either be written before the next expansion
		// of a slice or after the loop when writing the rest of the query
		if argMeta.length == 0 {
			offset = offset + i + 1
			newArgs = append(newArgs, argMeta.i)
			continue
		}

		// write everything up to and including our ? character
		buf.WriteString(query[:offset+i+1])

		for si := 1; si < argMeta.length; si++ {
			buf.WriteString(", ?")
		}

		newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length)

		// slice the query and reset the offset. this avoids some bookkeeping for
		// the write after the loop
		query = query[offset+i+1:]
		offset = 0
	}

	buf.WriteString(query)

	if arg < len(meta) {
		return "", nil, errors.New("number of bindVars less than number arguments")
	}

	return buf.String(), newArgs, nil
}

func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} {
	switch val := v.Interface().(type) {
	case []interface{}:
		args = append(args, val...)
	case []int:
		for i := range val {
			args = append(args, val[i])
		}
	case []string:
		for i := range val {
			args = append(args, val[i])
		}
	default:
		for si := 0; si < vlen; si++ {
			args = append(args, v.Index(si).Interface())
		}
	}

	return args
}
<commit_msg>added support for the cloudsqlpostgres driver<commit_after>package sqlx

import (
	"bytes"
	"errors"
	"reflect"
	"strconv"
	"strings"

	"github.com/jmoiron/sqlx/reflectx"
)

// Bindvar types supported by Rebind, BindMap and BindStruct.
const (
	UNKNOWN = iota
	QUESTION
	DOLLAR
	NAMED
)

// BindType returns the bindtype for a given database given a drivername.
func BindType(driverName string) int {
	switch driverName {
	case "postgres", "pgx", "pq-timeouts", "cloudsqlpostgres":
		return DOLLAR
	case "mysql":
		return QUESTION
	case "sqlite3":
		return QUESTION
	case "oci8", "ora", "goracle":
		return NAMED
	}
	return UNKNOWN
}

// FIXME: this should be able to be tolerant of escaped ?'s in queries without
// losing much speed, and should be to avoid confusion.

// Rebind a query from the default bindtype (QUESTION) to the target bindtype.
func Rebind(bindType int, query string) string {
	switch bindType {
	case QUESTION, UNKNOWN:
		return query
	}

	// Add space enough for 10 params before we have to allocate
	rqb := make([]byte, 0, len(query)+10)

	var i, j int

	for i = strings.Index(query, "?"); i != -1; i = strings.Index(query, "?") {
		rqb = append(rqb, query[:i]...)

		switch bindType {
		case DOLLAR:
			rqb = append(rqb, '$')
		case NAMED:
			rqb = append(rqb, ':', 'a', 'r', 'g')
		}

		j++
		rqb = strconv.AppendInt(rqb, int64(j), 10)

		query = query[i+1:]
	}

	return string(append(rqb, query...))
}

// Experimental implementation of Rebind which uses a bytes.Buffer.  The code is
// much simpler and should be more resistant to odd unicode, but it is twice as
// slow.  Kept here for benchmarking purposes and to possibly replace Rebind if
// problems arise with its somewhat naive handling of unicode.
func rebindBuff(bindType int, query string) string {
	if bindType != DOLLAR {
		return query
	}

	b := make([]byte, 0, len(query))
	rqb := bytes.NewBuffer(b)
	j := 1
	for _, r := range query {
		if r == '?' {
			rqb.WriteRune('$')
			rqb.WriteString(strconv.Itoa(j))
			j++
		} else {
			rqb.WriteRune(r)
		}
	}

	return rqb.String()
}

// In expands slice values in args, returning the modified query string
// and a new arg list that can be executed by a database. The `query` should
// use the `?` bindVar.  The return value uses the `?` bindVar.
func In(query string, args ...interface{}) (string, []interface{}, error) {
	// argMeta stores reflect.Value and length for slices and
	// the value itself for non-slice arguments
	type argMeta struct {
		v      reflect.Value
		i      interface{}
		length int
	}

	var flatArgsCount int
	var anySlices bool

	meta := make([]argMeta, len(args))

	for i, arg := range args {
		v := reflect.ValueOf(arg)
		t := reflectx.Deref(v.Type())

		if t.Kind() == reflect.Slice {
			meta[i].length = v.Len()
			meta[i].v = v

			anySlices = true
			flatArgsCount += meta[i].length

			if meta[i].length == 0 {
				return "", nil, errors.New("empty slice passed to 'in' query")
			}
		} else {
			meta[i].i = arg
			flatArgsCount++
		}
	}

	// don't do any parsing if there aren't any slices;  note that this means
	// some errors that we might have caught below will not be returned.
	if !anySlices {
		return query, args, nil
	}

	newArgs := make([]interface{}, 0, flatArgsCount)
	buf := bytes.NewBuffer(make([]byte, 0, len(query)+len(", ?")*flatArgsCount))

	var arg, offset int

	for i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') {
		if arg >= len(meta) {
			// if an argument wasn't passed, lets return an error;  this is
			// not actually how database/sql Exec/Query works, but since we are
			// creating an argument list programmatically, we want to be able
			// to catch these programmer errors earlier.
			return "", nil, errors.New("number of bindVars exceeds arguments")
		}

		argMeta := meta[arg]
		arg++

		// not a slice, continue.
		// our questionmark will either be written before the next expansion
		// of a slice or after the loop when writing the rest of the query
		if argMeta.length == 0 {
			offset = offset + i + 1
			newArgs = append(newArgs, argMeta.i)
			continue
		}

		// write everything up to and including our ? character
		buf.WriteString(query[:offset+i+1])

		for si := 1; si < argMeta.length; si++ {
			buf.WriteString(", ?")
		}

		newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length)

		// slice the query and reset the offset. this avoids some bookkeeping for
		// the write after the loop
		query = query[offset+i+1:]
		offset = 0
	}

	buf.WriteString(query)

	if arg < len(meta) {
		return "", nil, errors.New("number of bindVars less than number arguments")
	}

	return buf.String(), newArgs, nil
}

func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} {
	switch val := v.Interface().(type) {
	case []interface{}:
		args = append(args, val...)
	case []int:
		for i := range val {
			args = append(args, val[i])
		}
	case []string:
		for i := range val {
			args = append(args, val[i])
		}
	default:
		for si := 0; si < vlen; si++ {
			args = append(args, v.Index(si).Interface())
		}
	}

	return args
}
<|endoftext|>


<commit_before>// golang_blog

package main

import (
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"

	"github.com/gorilla/mux"
	"github.com/mholt/binding"
	"github.com/unrolled/render"
)

type PostList struct {
	Posts        []Post
	Next_Page    int
	Prev_Page    int
	Current_Page int
	More         bool
	Less         bool
}

type PostPage struct {
	Post     Post
	Comments []Comment
}

func (c *Comment) FieldMap() binding.FieldMap {
	return binding.FieldMap{
		&c.Author:  "author",
		&c.Body:    "comment",
		&c.Post_Id: "post_id",
	}
}

var ADMIN_USER = os.Getenv("BA_USER")
var ADMIN_PASS = os.Getenv("BA_PASS")

const NUMBER_POSTS_PER_PAGE = 5

// renderer is our global renderer, used for returning pretty JSON
var renderer = render.New(render.Options{IndentJSON: true})

// parse the templates once and hold them in memory
var templates = template.Must(template.ParseGlob("templates/*"))

func main() {
	if ADMIN_USER == "" || ADMIN_PASS == "" {
		log.Fatalln("need to set admin username and password")
	}
	fs := http.FileServer(http.Dir("static"))
	http.Handle("/static/", http.StripPrefix("/static/", fs))

	r := mux.NewRouter().StrictSlash(false)

	// Home Page
	r.HandleFunc("/", viewHomePage).Methods("GET")

	// blog list view
	r.HandleFunc("/blog/", viewBlogListView).Methods("GET")
	r.HandleFunc("/blog/{page}", viewBlogListView).Methods("GET")

	// post detail view
	r.HandleFunc("/article/{id}", viewBlogPost).Methods("GET")

	// post add view
	r.HandleFunc("/article/", addBlogPost).Methods("POST")

	// contact view
	r.HandleFunc("/contact/", viewContactPage).Methods("GET")

	// create a comment
	r.HandleFunc("/comment/", addCommentToPost).Methods("POST")

	http.Handle("/", r)

	http.ListenAndServe(":8000", nil)
}

// viewHomePage renders the index.html template
func viewHomePage(w http.ResponseWriter, req *http.Request) {
	templates.ExecuteTemplate(w, "index", nil)
}

// viewHomePage renders the list.html template
func viewBlogListView(w http.ResponseWriter, req *http.Request) {
	var page_int int
	var offset int
	var post_list PostList
	var err error

	vars := mux.Vars(req)
	if page, ok := vars["page"]; ok {
		page_int, err = strconv.Atoi(page)
		if err != nil {
			renderer.JSON(w, 400, "Invalid page request")
			return
		}
	} else {
		page_int = 1
	}

	offset = (page_int - 1) * NUMBER_POSTS_PER_PAGE
	nPosts, _ := getNumberOfPosts()

	post_list.Posts, _ = getBlogPosts(offset)

	post_list.More = (offset + NUMBER_POSTS_PER_PAGE) < nPosts
	post_list.Less = page_int > 1

	post_list.Next_Page = page_int + 1
	post_list.Prev_Page = page_int - 1
	post_list.Current_Page = page_int

	templates.ExecuteTemplate(w, "blog_list", post_list)
}

// viewBlogPost renders a single blog post corresponding to the id in the URL
func viewBlogPost(w http.ResponseWriter, req *http.Request) {
	var post_page PostPage

	vars := mux.Vars(req)
	id, err := strconv.Atoi(vars["id"])

	if err != nil {
		renderer.JSON(w, 400, "Invalid article request")
		return
	}

	post, _ := getBlogPost(id)
	comments, _ := getCommentsForPost(id)

	post_page.Post = post
	post_page.Comments = comments

	templates.ExecuteTemplate(w, "blog", &post_page)
}

// viewContactPage renders the contact template
func viewContactPage(w http.ResponseWriter, req *http.Request) {
	templates.ExecuteTemplate(w, "contact", nil)
}

// addCommentToPost takes comment data and adds it to the post
func addCommentToPost(w http.ResponseWriter, req *http.Request) {
	var comment Comment

	binding.Bind(req, &comment)
	err := createComment(comment)
	if err != nil {
		renderer.JSON(w, 500, "Failed to create comment")
		return
	}
	url := fmt.Sprintf("/article/%d", comment.Post_Id)
	http.Redirect(w, req, url, http.StatusFound)
}

// addBlogTask tasks a file and information posted to this endpoint and saves
// it in the DB as a blog post
func addBlogPost(w http.ResponseWriter, req *http.Request) {
	username, password, _ := req.BasicAuth()
	if username != os.Getenv("BA_USER") || password != os.Getenv("BA_PASS") {
		renderer.JSON(w, 403, "Be gone, pest")
		return
	}

	var post Post

	// the FormFile function takes in the POST input id file
	file, _, err := req.FormFile("file")

	title := req.FormValue("title")

	if err != nil {
		renderer.JSON(w, 500, "Failed to receive file")
		return
	}

	defer file.Close()

	out, err := os.Create("/tmp/new_post")
	if err != nil {
		renderer.JSON(w, 500, "Failed to create tmp file")
		return
	}

	defer out.Close()

	//  write the content from POST to the file
	_, err = io.Copy(out, file)
	if err != nil {
		fmt.Fprintln(w, err)
	}

	content, _ := ioutil.ReadFile("/tmp/new_post")
	post.Body = content
	post.Title = title
	createBlogPost(post)
}
<commit_msg>Use env vars for template and static dir<commit_after>// golang_blog

package main

import (
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"

	"github.com/gorilla/mux"
	"github.com/mholt/binding"
	"github.com/unrolled/render"
)

type PostList struct {
	Posts        []Post
	Next_Page    int
	Prev_Page    int
	Current_Page int
	More         bool
	Less         bool
}

type PostPage struct {
	Post     Post
	Comments []Comment
}

func (c *Comment) FieldMap() binding.FieldMap {
	return binding.FieldMap{
		&c.Author:  "author",
		&c.Body:    "comment",
		&c.Post_Id: "post_id",
	}
}

var ADMIN_USER = os.Getenv("BA_USER")
var ADMIN_PASS = os.Getenv("BA_PASS")

var TEMPLATE_DIR = os.Getenv("TEMPLATE_DIR")
var STATIC_DIR = os.Getenv("STATIC_DIR")

const NUMBER_POSTS_PER_PAGE = 5

// renderer is our global renderer, used for returning pretty JSON
var renderer = render.New(render.Options{IndentJSON: true})

// parse the templates once and hold them in memory
var templates = template.Must(template.ParseGlob(fmt.Sprintf("%s/*", TEMPLATE_DIR)))

func main() {
	if ADMIN_USER == "" || ADMIN_PASS == "" {
		log.Fatalln("need to set admin username and password")
	}
	fs := http.FileServer(http.Dir(STATIC_DIR))
	http.Handle("/static/", http.StripPrefix("/static/", fs))

	r := mux.NewRouter().StrictSlash(false)

	// Home Page
	r.HandleFunc("/", viewHomePage).Methods("GET")

	// blog list view
	r.HandleFunc("/blog/", viewBlogListView).Methods("GET")
	r.HandleFunc("/blog/{page}", viewBlogListView).Methods("GET")

	// post detail view
	r.HandleFunc("/article/{id}", viewBlogPost).Methods("GET")

	// post add view
	r.HandleFunc("/article/", addBlogPost).Methods("POST")

	// contact view
	r.HandleFunc("/contact/", viewContactPage).Methods("GET")

	// create a comment
	r.HandleFunc("/comment/", addCommentToPost).Methods("POST")

	http.Handle("/", r)

	http.ListenAndServe(":8000", nil)
}

// viewHomePage renders the index.html template
func viewHomePage(w http.ResponseWriter, req *http.Request) {
	templates.ExecuteTemplate(w, "index", nil)
}

// viewHomePage renders the list.html template
func viewBlogListView(w http.ResponseWriter, req *http.Request) {
	var page_int int
	var offset int
	var post_list PostList
	var err error

	vars := mux.Vars(req)
	if page, ok := vars["page"]; ok {
		page_int, err = strconv.Atoi(page)
		if err != nil {
			renderer.JSON(w, 400, "Invalid page request")
			return
		}
	} else {
		page_int = 1
	}

	offset = (page_int - 1) * NUMBER_POSTS_PER_PAGE
	nPosts, _ := getNumberOfPosts()

	post_list.Posts, _ = getBlogPosts(offset)

	post_list.More = (offset + NUMBER_POSTS_PER_PAGE) < nPosts
	post_list.Less = page_int > 1

	post_list.Next_Page = page_int + 1
	post_list.Prev_Page = page_int - 1
	post_list.Current_Page = page_int

	templates.ExecuteTemplate(w, "blog_list", post_list)
}

// viewBlogPost renders a single blog post corresponding to the id in the URL
func viewBlogPost(w http.ResponseWriter, req *http.Request) {
	var post_page PostPage

	vars := mux.Vars(req)
	id, err := strconv.Atoi(vars["id"])

	if err != nil {
		renderer.JSON(w, 400, "Invalid article request")
		return
	}

	post, _ := getBlogPost(id)
	comments, _ := getCommentsForPost(id)

	post_page.Post = post
	post_page.Comments = comments

	templates.ExecuteTemplate(w, "blog", &post_page)
}

// viewContactPage renders the contact template
func viewContactPage(w http.ResponseWriter, req *http.Request) {
	templates.ExecuteTemplate(w, "contact", nil)
}

// addCommentToPost takes comment data and adds it to the post
func addCommentToPost(w http.ResponseWriter, req *http.Request) {
	var comment Comment

	binding.Bind(req, &comment)
	err := createComment(comment)
	if err != nil {
		renderer.JSON(w, 500, "Failed to create comment")
		return
	}
	url := fmt.Sprintf("/article/%d", comment.Post_Id)
	http.Redirect(w, req, url, http.StatusFound)
}

// addBlogTask tasks a file and information posted to this endpoint and saves
// it in the DB as a blog post
func addBlogPost(w http.ResponseWriter, req *http.Request) {
	username, password, _ := req.BasicAuth()
	if username != os.Getenv("BA_USER") || password != os.Getenv("BA_PASS") {
		renderer.JSON(w, 403, "Be gone, pest")
		return
	}

	var post Post

	// the FormFile function takes in the POST input id file
	file, _, err := req.FormFile("file")

	title := req.FormValue("title")

	if err != nil {
		renderer.JSON(w, 500, "Failed to receive file")
		return
	}

	defer file.Close()

	out, err := os.Create("/tmp/new_post")
	if err != nil {
		renderer.JSON(w, 500, "Failed to create tmp file")
		return
	}

	defer out.Close()

	//  write the content from POST to the file
	_, err = io.Copy(out, file)
	if err != nil {
		fmt.Fprintln(w, err)
	}

	content, _ := ioutil.ReadFile("/tmp/new_post")
	post.Body = content
	post.Title = title
	createBlogPost(post)
}
<|endoftext|>


<commit_before>package gostore

//TODO: Extract methods into functions
import (
	"bytes"
	"github.com/boltdb/bolt"
	"github.com/fatih/structs"
	"log"
	"time"
)

type BoltStore struct {
	Bucket []byte
	Db     *bolt.DB
}

func NewBoltStore(bucket string, db *bolt.DB) BoltStore {
	e := BoltStore{[]byte(bucket), db}
	//	e.CreateBucket(bucket)
	return e
}

func (s BoltStore) CreateBucket(bucket string) {
	s.Db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte(bucket))
		if err != nil {
			log.Fatalf("create bucket: %s", err)
		}
		return nil
	})
}

func Get(key []byte, bucket []byte, db *bolt.DB) (v []byte, err error) {
	defer timeTrack(time.Now(), "Bolt Store::Get "+string(key)+" from "+string(bucket))
	err = db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucket)
		v = b.Get(key)
		if v == nil {
			return ErrNotFound
		}
		return nil
	})
	return
}

func PrefixGet(prefix []byte, bucket []byte, db *bolt.DB) (k, v []byte, err error) {
	defer timeTrack(time.Now(), "Bolt Store::PrefixGet "+string(prefix)+" from "+string(bucket))
	err = db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket(bucket).Cursor()
		k, v = c.Seek(prefix)
		if v == nil {
			return ErrNotFound
		}
		return nil
	})
	return
}

func (s BoltStore) Get(key []byte, resource string) (v [][]byte, err error) {
	s.CreateBucket(resource)
	vv, err := Get(key, []byte(resource), s.Db)
	if vv != nil {
		v = [][]byte{key, vv}
	}
	return
}

func (s BoltStore) PrefixGet(prefix []byte, resource string) (v [][]byte, err error) {
	s.CreateBucket(resource)
	kk, vv, err := PrefixGet(prefix, []byte(resource), s.Db)
	if vv != nil {
		v = [][]byte{kk, vv}
	}
	return
}

func (s BoltStore) Save(key []byte, data []byte, resource string) error {
	s.CreateBucket(resource)
	err := s.Db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(resource))
		err := b.Put(key, data)
		return err
	})
	return err
}

func (s BoltStore) Delete(key []byte, resource string) error {
	s.CreateBucket(resource)
	err := s.Db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(resource))
		err := b.Delete(key)
		return err
	})
	return err
}

func (s BoltStore) DeleteAll(resource string) error {
	s.CreateBucket(resource)
	err := s.Db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(resource))
		c := b.Cursor()
		for k, _ := c.First(); k != nil; k, _ = c.Next() {
			b.Delete(k)
		}
		return nil
	})
	return err
}

func (s BoltStore) GetAll(count int, skip int, resource string) (objs [][][]byte, err error) {
	s.CreateBucket(resource)
	err = s.Db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte(resource)).Cursor()
		//Skip a certain amount
		if skip > 0 {
			//make sure we hit the database once
			var skip_lim int = 1
			var target_count int = skip - 1
			for k, _ := c.Last(); k != nil; k, _ = c.Prev() {
				if skip_lim >= target_count {
					break
				}
				skip_lim++
			}
		} else {
			//no skip needed. Get first item
			k, v := c.Last()
			if k != nil {
				objs = append(objs, [][]byte{k, v})
			} else {
				return err
			}
		}

		//Get next items after skipping or getting first item
		var lim int = 2
		for k, v := c.Prev(); k != nil; k, v = c.Prev() {
			objs = append(objs, [][]byte{k, v})
			if lim == count {
				break
			}
			lim++
		}
		return err
	})
	return
}

func (s BoltStore) GetAllAfter(key []byte, count int, skip int, resource string) (objs [][][]byte, err error) {
	s.CreateBucket(resource)
	err = s.Db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte(resource)).Cursor()
		if skip > 0 {
			var skip_lim int = 1
			var target_count int = skip - 1
			for k, _ := c.Seek(key); k != nil; k, _ = c.Next() {
				log.Println("Skipped ", string(k), "Current lim is ", skip_lim, " target count is ", target_count)
				if skip_lim >= target_count {
					break
				}
				skip_lim++
			}
		} else {
			//no skip needed. Get first item
			k, v := c.Seek(key)
			if k != nil {
				objs = append(objs, [][]byte{k, v})
			} else {
				return err
			}
		}
		var lim int = 2
		for k, v := c.Next(); k != nil; k, v = c.Next() {
			objs = append(objs, [][]byte{k, v})
			if lim == count {
				break
			}
			lim++
		}
		return err
	})
	return
}

func (s BoltStore) GetAllBefore(key []byte, count int, skip int, resource string) (objs [][][]byte, err error) {
	s.CreateBucket(resource)
	err = s.Db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte(resource)).Cursor()
		if skip > 0 {
			var skip_lim int = 1
			var target_count int = skip - 1
			for k, _ := c.Seek(key); k != nil; k, _ = c.Prev() {
				if skip_lim >= target_count {
					break
				}
				skip_lim++
			}
		} else {
			//no skip needed. Get first item
			k, v := c.Seek(key)
			if k != nil {
				objs = append(objs, [][]byte{k, v})
			} else {
				return err
			}
		}
		var lim int = 2
		for k, v := c.Prev(); k != nil; k, v = c.Prev() {
			objs = append(objs, [][]byte{k, v})
			if lim == count {
				break
			}
			lim++
		}
		return err
	})
	return
}

func (s BoltStore) Filter(prefix []byte, count int, skip int, resource string) (objs [][][]byte, err error) {
	s.CreateBucket(resource)
	b_prefix := []byte(prefix)
	err = s.Db.View(func(tx *bolt.Tx) error {
		var lim int = 1
		c := tx.Bucket([]byte(resource)).Cursor()
		if skip > 0 {
			var skip_lim int = 1
			var target_count int = skip - 1
			for k, _ := c.Seek(b_prefix); k != nil; k, _ = c.Next() {
				if skip_lim >= target_count {
					break
				}
				skip_lim++
			}
		} else {
			//no skip needed. Get first item
			k, v := c.Seek(b_prefix)
			if k != nil {
				objs = append(objs, [][]byte{k, v})
			} else {
				return err
			}
		}

		for k, v := c.Next(); bytes.HasPrefix(k, b_prefix); k, v = c.Next() {
			objs = append(objs, [][]byte{k, v})
			if lim == count {
				break
			}
			lim++
		}
		return nil
	})
	return
}

func (s BoltStore) FilterSuffix(suffix []byte, count int, resource string) (objs [][]byte, err error) {
	s.CreateBucket(resource)
	b_prefix := []byte(suffix)
	err = s.Db.View(func(tx *bolt.Tx) error {
		var lim int = 1
		c := tx.Bucket([]byte(resource)).Cursor()
		for k, v := c.Seek(b_prefix); bytes.HasPrefix(k, b_prefix); k, v = c.Next() {
			objs = append(objs, v)
			if lim == count {
				break
			}
			lim++
		}
		return nil
	})
	return
}

func (s BoltStore) StreamFilter(key []byte, count int, resource string) chan []byte {

	s.CreateBucket(resource)
	//Uses channels to stream filtered keys
	ch := make(chan []byte)
	go func() {
		b_prefix := []byte(key)
		s.Db.View(func(tx *bolt.Tx) error {
			var lim int = 1
			c := tx.Bucket([]byte(resource)).Cursor()
			for k, v := c.Seek(b_prefix); bytes.HasPrefix(k, b_prefix); k, v = c.Next() {
				ch <- v
				if lim == count {
					break
				}
				lim++
			}
			return nil
		})
		close(ch)
	}()
	return ch
}

func (s BoltStore) StreamAll(count int, resource string) chan [][]byte {

	s.CreateBucket(resource)
	//Uses channels to stream filtered keys
	ch := make(chan [][]byte)
	go func() {
		s.Db.View(func(tx *bolt.Tx) error {
			var lim int = 1
			c := tx.Bucket([]byte(resource)).Cursor()
			for k, v := c.Last(); k != nil; k, v = c.Prev() {
				ch <- [][]byte{k, v}
				if lim == count {
					break
				}
				lim++
			}
			close(ch)
			return nil
		})
	}()
	return ch
}

func (s BoltStore) Stats(bucket string) (data map[string]interface{}, err error) {
	err = s.Db.View(func(tx *bolt.Tx) error {
		v := tx.Bucket([]byte(bucket)).Stats()
		data = structs.Map(v)
		return nil
	})
	return
}

func (s BoltStore) GetStoreObject() interface{}{
	return s.Db
}

func NewBoltObjectStore(db *bolt.DB, database string) BoltObjectStore {
	e := BoltObjectStore{db}
	//	e.CreateBucket(bucket)
	return e
}

type BoltObjectStore struct{
	Db     *bolt.DB
}<commit_msg>update<commit_after>package gostore

//TODO: Extract methods into functions
import (
	"bytes"
	"github.com/boltdb/bolt"
	"github.com/fatih/structs"
	"log"
	"time"
	"github.com/dustin/gojson"
)

type BoltStore struct {
	Bucket []byte
	Db     *bolt.DB
}

func NewBoltStore(bucket string, db *bolt.DB) BoltStore {
	e := BoltStore{[]byte(bucket), db}
	//	e.CreateBucket(bucket)
	return e
}

func (s BoltStore) CreateBucket(bucket string) {
	s.Db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte(bucket))
		if err != nil {
			log.Fatalf("create bucket: %s", err)
		}
		return nil
	})
}

func Get(key []byte, bucket []byte, db *bolt.DB) (v []byte, err error) {
	defer timeTrack(time.Now(), "Bolt Store::Get "+string(key)+" from "+string(bucket))
	err = db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucket)
		v = b.Get(key)
		if v == nil {
			return ErrNotFound
		}
		return nil
	})
	return
}

func PrefixGet(prefix []byte, bucket []byte, db *bolt.DB) (k, v []byte, err error) {
	defer timeTrack(time.Now(), "Bolt Store::PrefixGet "+string(prefix)+" from "+string(bucket))
	err = db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket(bucket).Cursor()
		k, v = c.Seek(prefix)
		if v == nil {
			return ErrNotFound
		}
		return nil
	})
	return
}

func (s BoltStore) _Get(key []byte, resource string) (v [][]byte, err error) {
	s.CreateBucket(resource)
	vv, err := Get(key, []byte(resource), s.Db)
	if vv != nil {
		v = [][]byte{key, vv}
	}
	return
}

func (s BoltStore) _PrefixGet(prefix []byte, resource string) (v [][]byte, err error) {
	s.CreateBucket(resource)
	kk, vv, err := PrefixGet(prefix, []byte(resource), s.Db)
	if vv != nil {
		v = [][]byte{kk, vv}
	}
	return
}

func (s BoltStore) _Save(key []byte, data []byte, resource string) error {
	s.CreateBucket(resource)
	err := s.Db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(resource))
		err := b.Put(key, data)
		return err
	})
	return err
}

func (s BoltStore) _Delete(key []byte, resource string) error {
	s.CreateBucket(resource)
	err := s.Db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(resource))
		err := b.Delete(key)
		return err
	})
	return err
}

func (s BoltStore) _DeleteAll(resource string) error {
	s.CreateBucket(resource)
	err := s.Db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(resource))
		c := b.Cursor()
		for k, _ := c.First(); k != nil; k, _ = c.Next() {
			b.Delete(k)
		}
		return nil
	})
	return err
}

func (s BoltStore) _GetAll(count int, skip int, resource string) (objs [][][]byte, err error) {
	s.CreateBucket(resource)
	err = s.Db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte(resource)).Cursor()
		//Skip a certain amount
		if skip > 0 {
			//make sure we hit the database once
			var skip_lim int = 1
			var target_count int = skip - 1
			for k, _ := c.Last(); k != nil; k, _ = c.Prev() {
				if skip_lim >= target_count {
					break
				}
				skip_lim++
			}
		} else {
			//no skip needed. Get first item
			k, v := c.Last()
			if k != nil {
				objs = append(objs, [][]byte{k, v})
			} else {
				return err
			}
		}

		//Get next items after skipping or getting first item
		var lim int = 2
		for k, v := c.Prev(); k != nil; k, v = c.Prev() {
			objs = append(objs, [][]byte{k, v})
			if lim == count {
				break
			}
			lim++
		}
		return err
	})
	return
}

func (s BoltStore) _GetAllAfter(key []byte, count int, skip int, resource string) (objs [][][]byte, err error) {
	s.CreateBucket(resource)
	err = s.Db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte(resource)).Cursor()
		if skip > 0 {
			var skip_lim int = 1
			var target_count int = skip - 1
			for k, _ := c.Seek(key); k != nil; k, _ = c.Next() {
				log.Println("Skipped ", string(k), "Current lim is ", skip_lim, " target count is ", target_count)
				if skip_lim >= target_count {
					break
				}
				skip_lim++
			}
		} else {
			//no skip needed. Get first item
			k, v := c.Seek(key)
			if k != nil {
				objs = append(objs, [][]byte{k, v})
			} else {
				return err
			}
		}
		var lim int = 2
		for k, v := c.Next(); k != nil; k, v = c.Next() {
			objs = append(objs, [][]byte{k, v})
			if lim == count {
				break
			}
			lim++
		}
		return err
	})
	return
}

func (s BoltStore) _GetAllBefore(key []byte, count int, skip int, resource string) (objs [][][]byte, err error) {
	s.CreateBucket(resource)
	err = s.Db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte(resource)).Cursor()
		if skip > 0 {
			var skip_lim int = 1
			var target_count int = skip - 1
			for k, _ := c.Seek(key); k != nil; k, _ = c.Prev() {
				if skip_lim >= target_count {
					break
				}
				skip_lim++
			}
		} else {
			//no skip needed. Get first item
			k, v := c.Seek(key)
			if k != nil {
				objs = append(objs, [][]byte{k, v})
			} else {
				return err
			}
		}
		var lim int = 2
		for k, v := c.Prev(); k != nil; k, v = c.Prev() {
			objs = append(objs, [][]byte{k, v})
			if lim == count {
				break
			}
			lim++
		}
		return err
	})
	return
}

func (s BoltStore) _Filter(prefix []byte, count int, skip int, resource string) (objs [][][]byte, err error) {
	s.CreateBucket(resource)
	b_prefix := []byte(prefix)
	err = s.Db.View(func(tx *bolt.Tx) error {
		var lim int = 1
		c := tx.Bucket([]byte(resource)).Cursor()
		if skip > 0 {
			var skip_lim int = 1
			var target_count int = skip - 1
			for k, _ := c.Seek(b_prefix); k != nil; k, _ = c.Next() {
				if skip_lim >= target_count {
					break
				}
				skip_lim++
			}
		} else {
			//no skip needed. Get first item
			k, v := c.Seek(b_prefix)
			if k != nil {
				objs = append(objs, [][]byte{k, v})
			} else {
				return err
			}
		}

		for k, v := c.Next(); bytes.HasPrefix(k, b_prefix); k, v = c.Next() {
			objs = append(objs, [][]byte{k, v})
			if lim == count {
				break
			}
			lim++
		}
		return nil
	})
	return
}

func (s BoltStore) FilterSuffix(suffix []byte, count int, resource string) (objs [][]byte, err error) {
	s.CreateBucket(resource)
	b_prefix := []byte(suffix)
	err = s.Db.View(func(tx *bolt.Tx) error {
		var lim int = 1
		c := tx.Bucket([]byte(resource)).Cursor()
		for k, v := c.Seek(b_prefix); bytes.HasPrefix(k, b_prefix); k, v = c.Next() {
			objs = append(objs, v)
			if lim == count {
				break
			}
			lim++
		}
		return nil
	})
	return
}

func (s BoltStore) StreamFilter(key []byte, count int, resource string) chan []byte {

	s.CreateBucket(resource)
	//Uses channels to stream filtered keys
	ch := make(chan []byte)
	go func() {
		b_prefix := []byte(key)
		s.Db.View(func(tx *bolt.Tx) error {
			var lim int = 1
			c := tx.Bucket([]byte(resource)).Cursor()
			for k, v := c.Seek(b_prefix); bytes.HasPrefix(k, b_prefix); k, v = c.Next() {
				ch <- v
				if lim == count {
					break
				}
				lim++
			}
			return nil
		})
		close(ch)
	}()
	return ch
}

func (s BoltStore) StreamAll(count int, resource string) chan [][]byte {

	s.CreateBucket(resource)
	//Uses channels to stream filtered keys
	ch := make(chan [][]byte)
	go func() {
		s.Db.View(func(tx *bolt.Tx) error {
			var lim int = 1
			c := tx.Bucket([]byte(resource)).Cursor()
			for k, v := c.Last(); k != nil; k, v = c.Prev() {
				ch <- [][]byte{k, v}
				if lim == count {
					break
				}
				lim++
			}
			close(ch)
			return nil
		})
	}()
	return ch
}

func (s BoltStore) Stats(bucket string) (data map[string]interface{}, err error) {
	err = s.Db.View(func(tx *bolt.Tx) error {
		v := tx.Bucket([]byte(bucket)).Stats()
		data = structs.Map(v)
		return nil
	})
	return
}

func (s BoltStore) GetStoreObject() interface{}{
	return s.Db
}

//New Api
type BoltRows struct{
	rows [][][]byte
	i int
	len int
}
func (s BoltRows) Next(dst interface{}) (bool, error) {
	if s.i >= s.len{
		return false, nil
	}
	if err := json.Unmarshal(s.rows[s.i][1], dst); err != nil{
		return false, err
	}
	s.i++
	return true, nil
}

func (s BoltRows) Close() {
	s.rows = nil
}

func (s BoltStore) All(count int, skip int, store string) (ObjectRows, error){
	_rows, err := s._GetAll(count, skip, store)
	if err != nil{
		return nil, err
	}
	return BoltRows{_rows, 0, len(_rows)}, nil
}
func (s BoltStore) AllCursor(store string) (ObjectRows, error){return nil, nil}

func (s BoltStore) Since(id string, count int, skip int, store string) (ObjectRows, error) {return nil, nil} //Get all recent items from a key
func (s BoltStore) Before(id string, count int, skip int, store string) (ObjectRows, error){return nil, nil} //Get all existing items before a key

func (s BoltStore) FilterSince(id string, filter map[string]interface{}, count int, skip int, store string, opts ObjectStoreOptions) (ObjectRows, error){return nil, nil}  //Get all recent items from a key
func (s BoltStore) FilterBefore(id string, filter map[string]interface{}, count int, skip int, store string, opts ObjectStoreOptions) (ObjectRows, error){return nil, nil} //Get all existing items before a key
func (s BoltStore) FilterBeforeCount(id string, filter map[string]interface{}, count int, skip int, store string, opts ObjectStoreOptions) (int64, error){return 0, nil} //Get all existing items before a key

func (s BoltStore) Get(key string, store string, dst interface{}) error{return nil}
func (s BoltStore) Save(store string, src interface{}) (string, error){return "", nil}
func (s BoltStore) Update(key string, store string, src interface{}) error{return nil}
func (s BoltStore) Replace(key string, store string, src interface{}) error{return nil}
func (s BoltStore) Delete(key string, store string) error{return nil}

//Filter
func (s BoltStore) FilterUpdate(filter map[string]interface{}, src interface{}, store string, opts ObjectStoreOptions) error {return nil}
func (s BoltStore) FilterReplace(filter map[string]interface{}, src interface{}, store string,  opts ObjectStoreOptions) error{return nil}
func (s BoltStore) FilterGet(filter map[string]interface{}, store string, dst interface{}, opts ObjectStoreOptions) error {return nil}
func (s BoltStore) FilterGetAll(filter map[string]interface{}, count int, skip int, store string, opts ObjectStoreOptions) (ObjectRows, error){return nil, nil}
func (s BoltStore) FilterDelete(filter map[string]interface{}, store string, opts ObjectStoreOptions) error{return nil}
func (s BoltStore) FilterCount(filter map[string]interface{}, store string, opts ObjectStoreOptions) (int64, error){return 0, nil}

//Misc gets
func (s BoltStore) GetByField(name, val, store string, dst interface{}) error{return nil}
func (s BoltStore) GetByFieldsByField(name, val, store string, fields []string, dst interface{}) (err error){return nil}
func (s BoltStore) Close(){}
func NewBoltObjectStore(db *bolt.DB, database string) BoltObjectStore {
	e := BoltObjectStore{db}
	//	e.CreateBucket(bucket)
	return e
}

type BoltObjectStore struct{
	Db     *bolt.DB
}<|endoftext|>


<commit_before>package speedctl

import (
	"fmt"
	"time"
)

// Byte is abstract for convert. By decimal multiplication(1000) not power of 2 (2^10 or 1024).
type Byte int64

// Convert into byte
func (f Byte) Byte() int64 {
	return int64(f)
}

// Convert into Kilobyte (Unite: kB)
func (f Byte) Kilobyte() int64 {
	return int64(f / Kilobyte)
}

// Convert into Megabyte (Unite: MB)
func (f Byte) Megabyte() int64 {
	return int64(f / Megabyte)
}

// Convert into Gigabyte (Unite: GB)
func (f Byte) Gigabyte() int64 {
	return int64(f / Gigabyte)
}

// Convert into Terabyte (Unite: TB)
func (f Byte) Terabyte() int64 {
	return int64(f / Terabyte)
}

// Convert into Petabyte (Unite: PB)
func (f Byte) Petabyte() int64 {
	return int64(f / Petabyte)
}

func (b Byte) String() string {
	var unit string
	var valu int64

	switch {
	case b == Byteunite && b < Kilobyte:
		unit = "Byte"
		valu = b.Byte()
	case b > Byteunite && b < Kilobyte:
		unit = "Bytes"
		valu = b.Byte()
	case b >= Kilobyte && b < Megabyte:
		unit = "kB"
		valu = b.Kilobyte()
	case b >= Megabyte && b < Gigabyte:
		unit = "MB"
		valu = b.Megabyte()
	case b >= Gigabyte && b < Terabyte:
		unit = "GB"
		valu = b.Gigabyte()
	case b >= Terabyte && b < Petabyte:
		unit = "TB"
		valu = b.Terabyte()
	case b >= Petabyte:
		unit = "PB"
		valu = b.Petabyte()
	}

	return fmt.Sprintf("%d %s", valu, unit)
}

func (b *Byte) ParseByte(parse string) error {
	speed := 0
	unit := ""

	fmt.Sscanf(parse, "%d%s", &speed, &unit)

	if v, ok := convMap[unit]; ok {
		*b = Byte(speed) * v
		return nil
	}

	return UnknowUnit
}

// Convert Byte/Duration into Byte/second
func BytePerSeconds(bytes Byte, dur time.Duration) Byte {
	f := float64(bytes.Byte()) / dur.Seconds()

	return Byte(f)
}
<commit_msg>add unmarshal/marshal json<commit_after>package speedctl

import (
	"fmt"
	"time"
)

// Byte is abstract for convert. By decimal multiplication(1000) not power of 2 (2^10 or 1024).
type Byte int64

// Convert into byte
func (f Byte) Byte() int64 {
	return int64(f)
}

// Convert into Kilobyte (Unite: kB)
func (f Byte) Kilobyte() int64 {
	return int64(f / Kilobyte)
}

// Convert into Megabyte (Unite: MB)
func (f Byte) Megabyte() int64 {
	return int64(f / Megabyte)
}

// Convert into Gigabyte (Unite: GB)
func (f Byte) Gigabyte() int64 {
	return int64(f / Gigabyte)
}

// Convert into Terabyte (Unite: TB)
func (f Byte) Terabyte() int64 {
	return int64(f / Terabyte)
}

// Convert into Petabyte (Unite: PB)
func (f Byte) Petabyte() int64 {
	return int64(f / Petabyte)
}

func (b Byte) String() string {
	var unit string
	var valu int64

	switch {
	case b == Byteunite && b < Kilobyte:
		unit = "Byte"
		valu = b.Byte()
	case b > Byteunite && b < Kilobyte:
		unit = "Bytes"
		valu = b.Byte()
	case b >= Kilobyte && b < Megabyte:
		unit = "kB"
		valu = b.Kilobyte()
	case b >= Megabyte && b < Gigabyte:
		unit = "MB"
		valu = b.Megabyte()
	case b >= Gigabyte && b < Terabyte:
		unit = "GB"
		valu = b.Gigabyte()
	case b >= Terabyte && b < Petabyte:
		unit = "TB"
		valu = b.Terabyte()
	case b >= Petabyte:
		unit = "PB"
		valu = b.Petabyte()
	}

	return fmt.Sprintf("%d %s", valu, unit)
}

func (b *Byte) ParseByte(parse string) error {
	speed := 0
	unit := ""

	fmt.Sscanf(parse, "%d%s", &speed, &unit)

	if v, ok := convMap[unit]; ok {
		*b = Byte(speed) * v
		return nil
	}

	return UnknowUnit
}

func (b *Byte) UnmarshalJSON(js []byte) error {
	p := string(js[1 : len(js)-1])
	return b.ParseByte(p)
}

func (b *Byte) MarshalJSON() ([]byte, error) {
	return []byte("\"" + b.String() + "\""), nil
}

// Convert Byte/Duration into Byte/second
func BytePerSeconds(bytes Byte, dur time.Duration) Byte {
	f := float64(bytes.Byte()) / dur.Seconds()

	return Byte(f)
}
<|endoftext|>


<commit_before>package main

import "encoding/pem"
import "crypto/x509"
import "crypto/x509/pkix"
import "crypto/rsa"
import mathRand "math/rand"
import "crypto/rand"
import "math/big"
import "time"

func loadPublicKey(input []byte) *rsa.PublicKey {
  block, _ := pem.Decode(input)
  result, _ := x509.ParsePKIXPublicKey(block.Bytes)
  return result.(*rsa.PublicKey)
}

func Certify(ca *CA, public *rsa.PublicKey, subject pkix.Name, days time.Duration) []byte {
  certificate := x509.Certificate {
    Version: 3,
    PublicKeyAlgorithm: x509.RSA,
    SignatureAlgorithm: x509.SHA256WithRSA,
    PublicKey: public,
    SerialNumber: big.NewInt(mathRand.Int63()),
    Issuer: ca.GetIssuer(),
    Subject: subject,
    NotBefore: time.Now(),
    BasicConstraintsValid: true,
    IsCA: false,
    KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
    ExtKeyUsage: []x509.ExtKeyUsage {x509.ExtKeyUsageServerAuth},
  }
  certificate.NotAfter = certificate.NotBefore.Add(time.Hour * 24 * days)

  result, _ := x509.CreateCertificate(rand.Reader, &certificate, &ca.Certificate, ca.Key, ca.Key.Public())
  return result
}
<commit_msg>Certification outpouts PEM-encoded data<commit_after>package main

import "encoding/pem"
import "crypto/x509"
import "crypto/x509/pkix"
import mathRand "math/rand"
import "crypto/rand"
import "crypto"
import "math/big"
import "time"

func LoadPublicKey(input []byte) *crypto.PublicKey {
  block, _ := pem.Decode(input)
  result, _ := x509.ParsePKIXPublicKey(block.Bytes)
  return result.(*crypto.PublicKey)
}

func Certify(ca *CA, public *crypto.PublicKey, subject pkix.Name, days time.Duration) []byte {
  certificate := x509.Certificate {
    Version: 3,
    PublicKeyAlgorithm: x509.RSA,
    SignatureAlgorithm: x509.SHA256WithRSA,
    PublicKey: public,
    SerialNumber: big.NewInt(mathRand.Int63()),
    Issuer: ca.GetIssuer(),
    Subject: subject,
    NotBefore: time.Now(),
    BasicConstraintsValid: true,
    IsCA: false,
    KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
    ExtKeyUsage: []x509.ExtKeyUsage {x509.ExtKeyUsageServerAuth},
  }
  certificate.NotAfter = certificate.NotBefore.Add(time.Hour * 24 * days)

  der, _ := x509.CreateCertificate(rand.Reader, &certificate, &ca.Certificate, ca.Key.Public(), ca.Key)
  result := pem.EncodeToMemory(&pem.Block {Type: "CERTIFICATE", Bytes: der})
  return result
}
<|endoftext|>