<commit_before>package cec

/*
#cgo pkg-config: libcec
#include <stdio.h>
#include <libcec/cecc.h>

ICECCallbacks g_callbacks;
// callbacks.go exports
int logMessageCallback(void *, const cec_log_message);

void setupCallbacks(libcec_configuration *conf)
{
	g_callbacks.CBCecLogMessage = &logMessageCallback;
	(*conf).callbacks = &g_callbacks;
}

void setName(libcec_configuration *conf, char *name)
{
	snprintf((*conf).strDeviceName, 13, "%s", name);
}

static void clearLogicalAddresses(cec_logical_addresses* addresses)
{
	int i;

	addresses->primary = CECDEVICE_UNREGISTERED;
	for (i = 0; i < 16; i++)
		addresses->addresses[i] = 0;
}

void setLogicalAddress(cec_logical_addresses* addresses, cec_logical_address address)
{
	if (addresses->primary == CECDEVICE_UNREGISTERED)
		addresses->primary = address;

	addresses->addresses[(int) address] = 1;
}

*/
import "C"

import (
	"errors"
	"encoding/hex"
	"strings"
	"log"
	"fmt"
)

type CECConfiguration struct {
	DeviceName string
}

type CECAdapter struct {
	Path string
	Comm string
}

func cecInit(config CECConfiguration) error {
	var conf C.libcec_configuration

	conf.clientVersion = C.uint32_t(C.CEC_CLIENT_VERSION_CURRENT)
	conf.serverVersion = C.uint32_t(C.CEC_SERVER_VERSION_CURRENT)

	for i:=0; i<5; i++ {
		conf.deviceTypes.types[i] = C.CEC_DEVICE_TYPE_RESERVED
        }
	conf.deviceTypes.types[0] = C.CEC_DEVICE_TYPE_RECORDING_DEVICE

	C.setName(&conf, C.CString(config.DeviceName))
	C.setupCallbacks(&conf)

	result := C.cec_initialise(&conf)
	if result < 1 {
		return errors.New("Failed to init CEC")
	}
	return nil
}

func getAdapter(name string) (CECAdapter, error) {
	var adapter CECAdapter

	var deviceList [10]C.cec_adapter
	devicesFound := int(C.cec_find_adapters(&deviceList[0], 10, nil))

	for i:=0; i < devicesFound; i++ {
		device := deviceList[i]
		adapter.Path = C.GoStringN(&device.path[0], 1024)
		adapter.Comm = C.GoStringN(&device.comm[0], 1024)

		if strings.Contains(adapter.Path, name) || strings.Contains(adapter.Comm, name) {
			return adapter, nil
		}
	}

	return adapter, errors.New("No Device Found")
}

func openAdapter(adapter CECAdapter) error {
        C.cec_init_video_standalone()

	result := C.cec_open(C.CString(adapter.Comm), C.CEC_DEFAULT_CONNECT_TIMEOUT)
	if result < 1 {
		return errors.New("Failed to open adapter")
	}

	return nil
}

func Transmit(command string) {
        var cec_command C.cec_command

        cmd, err := hex.DecodeString(removeSeparators(command))
        if err != nil {
                log.Fatal(err)
        }
        cmd_len := len(cmd)

        if (cmd_len > 0) {
                cec_command.initiator = C.cec_logical_address(cmd[0] >> 4)
                cec_command.destination = C.cec_logical_address(cmd[0] & 7)
                if (cmd_len > 1) {
                        cec_command.opcode_set = 1
                        cec_command.opcode = C.cec_opcode(cmd[1])
                } else {
                        cec_command.opcode_set = 0
                }
                if (cmd_len > 2) {
                        cec_command.parameters.size = C.uint8_t(cmd_len-2)
                        for i := 0; i < cmd_len-2; i++ {
                                cec_command.parameters.data[i] = C.uint8_t(cmd[i+2])
                        }
                } else {
                        cec_command.parameters.size = 0
                }
        }

        C.cec_transmit((*C.cec_command)(&cec_command))
}

func Destroy() {
	C.cec_destroy()
}

func PowerOn(address int) error {
	if C.cec_power_on_devices(C.cec_logical_address(address)) != 0 {
		return errors.New("Error in cec_power_on_devices")
	}
	return nil
}

func Standby(address int) error {
	if C.cec_standby_devices(C.cec_logical_address(address)) != 0 {
		return errors.New("Error in cec_standby_devices")
	}
	return nil
}

func VolumeUp() error {
	if C.cec_volume_up(C.int(1)) != 0 {
		return errors.New("Error in cec_volume_up")
	}
	return nil
}

func VolumeDown() error {
	if C.cec_volume_down(C.int(1)) != 0 {
		return errors.New("Error in cec_volume_down")
	}
	return nil
}

func Mute() error {
	if C.cec_mute_audio(C.int(1)) != 0 {
		return errors.New("Error in cec_mute_audio")
	}
	return nil
}

func KeyPress(address int, key int) error {
	if C.cec_send_keypress(C.cec_logical_address(address), C.cec_user_control_code(key), 1) != 0 {
		return errors.New("Error in cec_send_keypress")
	}
	return nil
}

func KeyRelease(address int) error {
	if C.cec_send_key_release(C.cec_logical_address(address), 1) != 0{
		return errors.New("Error in cec_send_key_release")
	}
	return nil
}

func GetActiveDevices() [16]bool {
	var devices [16]bool
	result := C.cec_get_active_devices()

	for i:=0; i < 16; i++ {
		if int(result.addresses[i]) > 0 {
			devices[i] = true
		}
	}

	return devices
}

func GetDeviceOSDName(address int) string {
	result := C.cec_get_device_osd_name(C.cec_logical_address(address))

	return C.GoString(&result.name[0])
}

func IsActiveSource(address int) bool {
	result := C.cec_is_active_source(C.cec_logical_address(address))

	if int(result) != 0 {
		return true
	} else {
		return false
	}
}

func GetDeviceVendorId(address int) uint64 {
	result := C.cec_get_device_vendor_id(C.cec_logical_address(address))

	return uint64(result)
}

func GetDevicePhysicalAddress(address int) string {
	result := C.cec_get_device_physical_address(C.cec_logical_address(address))

	return fmt.Sprintf("%x.%x.%x.%x", (uint(result) >> 12) & 0xf, (uint(result) >> 8) & 0xf, (uint(result) >> 4) & 0xf, uint(result) & 0xf)
}

func GetDevicePowerStatus(address int) string {
	result := C.cec_get_device_power_status(C.cec_logical_address(address))

	// C.CEC_POWER_STATUS_UNKNOWN == error

	if int(result) == C.CEC_POWER_STATUS_ON {
		return "on"
	} else if int(result) == C.CEC_POWER_STATUS_STANDBY {
		return "standby"
	} else if int(result) == C.CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON {
		return "starting"
	} else if int(result) == C.CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY {
		return "shutting down"
	} else {
		return ""
	}
}
<commit_msg>fixes for libcec<commit_after>package cec

/*
#cgo pkg-config: libcec
#include <stdio.h>
#include <libcec/cecc.h>

ICECCallbacks g_callbacks;
// callbacks.go exports
int logMessageCallback(void *, const cec_log_message);

void setupCallbacks(libcec_configuration *conf)
{
	g_callbacks.CBCecLogMessage = &logMessageCallback;
	(*conf).callbacks = &g_callbacks;
}

void setName(libcec_configuration *conf, char *name)
{
	snprintf((*conf).strDeviceName, 13, "%s", name);
}

static void clearLogicalAddresses(cec_logical_addresses* addresses)
{
	int i;

	addresses->primary = CECDEVICE_UNREGISTERED;
	for (i = 0; i < 16; i++)
		addresses->addresses[i] = 0;
}

void setLogicalAddress(cec_logical_addresses* addresses, cec_logical_address address)
{
	if (addresses->primary == CECDEVICE_UNREGISTERED)
		addresses->primary = address;

	addresses->addresses[(int) address] = 1;
}

*/
import "C"

import (
	"errors"
	"encoding/hex"
	"strings"
	"log"
	"fmt"
)

type CECConfiguration struct {
	DeviceName string
}

type CECAdapter struct {
	Path string
	Comm string
}

func cecInit(config CECConfiguration) error {
	var conf C.libcec_configuration

	conf.clientVersion = C.uint32_t(C.CEC_CLIENT_VERSION_CURRENT)
	conf.serverVersion = C.uint32_t(C.CEC_SERVER_VERSION_CURRENT)

	for i:=0; i<5; i++ {
		conf.deviceTypes.types[i] = C.CEC_DEVICE_TYPE_RESERVED
        }
	conf.deviceTypes.types[0] = C.CEC_DEVICE_TYPE_RECORDING_DEVICE

	C.setName(&conf, C.CString(config.DeviceName))
	C.setupCallbacks(&conf)

	result := C.cec_initialise(&conf)
	if result < 1 {
		return errors.New("Failed to init CEC")
	}
	return nil
}

func getAdapter(name string) (CECAdapter, error) {
	var adapter CECAdapter

	var deviceList [10]C.cec_adapter
	devicesFound := int(C.cec_find_adapters(&deviceList[0], 10, nil))

	for i:=0; i < devicesFound; i++ {
		device := deviceList[i]
		adapter.Path = C.GoStringN(&device.path[0], 1024)
		adapter.Comm = C.GoStringN(&device.comm[0], 1024)

		if strings.Contains(adapter.Path, name) || strings.Contains(adapter.Comm, name) {
			return adapter, nil
		}
	}

	return adapter, errors.New("No Device Found")
}

func openAdapter(adapter CECAdapter) error {
        C.cec_init_video_standalone()

	result := C.cec_open(C.CString(adapter.Comm), C.CEC_DEFAULT_CONNECT_TIMEOUT)
	if result < 1 {
		return errors.New("Failed to open adapter")
	}

	return nil
}

func Transmit(command string) {
        var cec_command C.cec_command

        cmd, err := hex.DecodeString(removeSeparators(command))
        if err != nil {
                log.Fatal(err)
        }
        cmd_len := len(cmd)

        if (cmd_len > 0) {
                cec_command.initiator = C.cec_logical_address((cmd[0] >> 4) & 0xF)
                cec_command.destination = C.cec_logical_address(cmd[0] & 0xF)
                if (cmd_len > 1) {
                        cec_command.opcode_set = 1
                        cec_command.opcode = C.cec_opcode(cmd[1])
                } else {
                        cec_command.opcode_set = 0
                }
                if (cmd_len > 2) {
                        cec_command.parameters.size = C.uint8_t(cmd_len-2)
                        for i := 0; i < cmd_len-2; i++ {
                                cec_command.parameters.data[i] = C.uint8_t(cmd[i+2])
                        }
                } else {
                        cec_command.parameters.size = 0
                }
        }

        C.cec_transmit((*C.cec_command)(&cec_command))
}

func Destroy() {
	C.cec_destroy()
}

func PowerOn(address int) error {
	if C.cec_power_on_devices(C.cec_logical_address(address)) != 0 {
		return errors.New("Error in cec_power_on_devices")
	}
	return nil
}

func Standby(address int) error {
	if C.cec_standby_devices(C.cec_logical_address(address)) != 0 {
		return errors.New("Error in cec_standby_devices")
	}
	return nil
}

func VolumeUp() error {
	if C.cec_volume_up(1) != 0 {
		return errors.New("Error in cec_volume_up")
	}
	return nil
}

func VolumeDown() error {
	if C.cec_volume_down(1) != 0 {
		return errors.New("Error in cec_volume_down")
	}
	return nil
}

func Mute() error {
	if C.cec_mute_audio(1) != 0 {
		return errors.New("Error in cec_mute_audio")
	}
	return nil
}

func KeyPress(address int, key int) error {
	if C.cec_send_keypress(C.cec_logical_address(address), C.cec_user_control_code(key), 1) != 0 {
		return errors.New("Error in cec_send_keypress")
	}
	return nil
}

func KeyRelease(address int) error {
	if C.cec_send_key_release(C.cec_logical_address(address), 1) != 0{
		return errors.New("Error in cec_send_key_release")
	}
	return nil
}

func GetActiveDevices() [16]bool {
	var devices [16]bool
	result := C.cec_get_active_devices()

	for i:=0; i < 16; i++ {
		if int(result.addresses[i]) > 0 {
			devices[i] = true
		}
	}

	return devices
}

func GetDeviceOSDName(address int) string {
	result := C.cec_get_device_osd_name(C.cec_logical_address(address))

	return C.GoString(&result.name[0])
}

func IsActiveSource(address int) bool {
	result := C.cec_is_active_source(C.cec_logical_address(address))

	if int(result) != 0 {
		return true
	} else {
		return false
	}
}

func GetDeviceVendorId(address int) uint64 {
	result := C.cec_get_device_vendor_id(C.cec_logical_address(address))

	return uint64(result)
}

func GetDevicePhysicalAddress(address int) string {
	result := C.cec_get_device_physical_address(C.cec_logical_address(address))

	return fmt.Sprintf("%x.%x.%x.%x", (uint(result) >> 12) & 0xf, (uint(result) >> 8) & 0xf, (uint(result) >> 4) & 0xf, uint(result) & 0xf)
}

func GetDevicePowerStatus(address int) string {
	result := C.cec_get_device_power_status(C.cec_logical_address(address))

	// C.CEC_POWER_STATUS_UNKNOWN == error

	if int(result) == C.CEC_POWER_STATUS_ON {
		return "on"
	} else if int(result) == C.CEC_POWER_STATUS_STANDBY {
		return "standby"
	} else if int(result) == C.CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON {
		return "starting"
	} else if int(result) == C.CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY {
		return "shutting down"
	} else {
		return ""
	}
}
<|endoftext|>


<commit_before>/****************************************************************************
 * This file is part of Builder.
 *
 * Copyright (C) 2015 Pier Luigi Fiorini
 *
 * Author(s):
 *    Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
 *
 * $BEGIN_LICENSE:AGPL3+$
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $END_LICENSE$
 ***************************************************************************/

package database

import (
	"bytes"
	"encoding/json"
	"github.com/boltdb/bolt"
)

type VcsInfo struct {
	Url    string `json:"url"`
	Branch string `json:"branch"`
}

type Package struct {
	Name          string   `json:"name"`
	Architectures []string `json:"architectures"`
	Ci            bool     `json:"ci"`
	Vcs           VcsInfo  `json:"vcs"`
	UpstreamVcs   VcsInfo  `json:"upstream_vcs"`
}

// Return whether the package was stored into the db.
func (db *Database) HasPackage(name string) bool {
	var found bool = false
	db.db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte("package")).Cursor()
		for k, _ := c.Seek([]byte(name)); bytes.Equal(k, []byte(name)); k, _ = c.Next() {
			found = true
			return nil
		}
		return nil
	})
	return found
}

// Return a list of package names.
func (db *Database) GetPackageNames() []string {
	var list = []string{}
	db.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("package"))
		bucket.ForEach(func(k, v []byte) error {
			list = append(list, string(k))
			return nil
		})
		return nil
	})
	return list
}

// Return a list of all packages.
func (db *Database) ListAllPackages() []*Package {
	var list []*Package
	db.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("package"))
		bucket.ForEach(func(k, v []byte) error {
			pkg := &Package{}
			json.Unmarshal(v, &pkg)
			list = append(list, pkg)
			return nil
		})
		return nil
	})
	return list
}

// Add a package to the database.
func (db *Database) AddPackage(pkg *Package) error {
	encoded, err := json.Marshal(pkg)
	if err != nil {
		return nil
	}
	return db.db.Update(func(tx *bolt.Tx) error {
		bucket, err := tx.CreateBucketIfNotExists([]byte("package"))
		if err != nil {
			return err
		}

		err = bucket.Put([]byte(pkg.Name), encoded)
		if err != nil {
			return err
		}

		return nil
	})
}

// Remove a package from the database.
func (db *Database) RemovePackage(name string) error {
	return db.db.Update(func(tx *bolt.Tx) error {
		return tx.DeleteBucket([]byte(name))
	})
}
<commit_msg>Fix removing packages<commit_after>/****************************************************************************
 * This file is part of Builder.
 *
 * Copyright (C) 2015 Pier Luigi Fiorini
 *
 * Author(s):
 *    Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
 *
 * $BEGIN_LICENSE:AGPL3+$
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $END_LICENSE$
 ***************************************************************************/

package database

import (
	"bytes"
	"encoding/json"
	"github.com/boltdb/bolt"
)

type VcsInfo struct {
	Url    string `json:"url"`
	Branch string `json:"branch"`
}

type Package struct {
	Name          string   `json:"name"`
	Architectures []string `json:"architectures"`
	Ci            bool     `json:"ci"`
	Vcs           VcsInfo  `json:"vcs"`
	UpstreamVcs   VcsInfo  `json:"upstream_vcs"`
}

// Return whether the package was stored into the db.
func (db *Database) HasPackage(name string) bool {
	var found bool = false
	db.db.View(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte("package")).Cursor()
		for k, _ := c.Seek([]byte(name)); bytes.Equal(k, []byte(name)); k, _ = c.Next() {
			found = true
			return nil
		}
		return nil
	})
	return found
}

// Return a list of package names.
func (db *Database) GetPackageNames() []string {
	var list = []string{}
	db.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("package"))
		bucket.ForEach(func(k, v []byte) error {
			list = append(list, string(k))
			return nil
		})
		return nil
	})
	return list
}

// Return a list of all packages.
func (db *Database) ListAllPackages() []*Package {
	var list []*Package
	db.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("package"))
		bucket.ForEach(func(k, v []byte) error {
			pkg := &Package{}
			json.Unmarshal(v, &pkg)
			list = append(list, pkg)
			return nil
		})
		return nil
	})
	return list
}

// Add a package to the database.
func (db *Database) AddPackage(pkg *Package) error {
	encoded, err := json.Marshal(pkg)
	if err != nil {
		return nil
	}
	return db.db.Update(func(tx *bolt.Tx) error {
		bucket, err := tx.CreateBucketIfNotExists([]byte("package"))
		if err != nil {
			return err
		}

		err = bucket.Put([]byte(pkg.Name), encoded)
		if err != nil {
			return err
		}

		return nil
	})
}

// Remove a package from the database.
func (db *Database) RemovePackage(name string) error {
	return db.db.Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("package"))
		err := bucket.Delete([]byte(name))
		if err != nil {
			return err
		}

		return nil
	})
}
<|endoftext|>


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

package build

const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows "
const goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le "
<commit_msg>go/build: reserve GOARCH values for all common architectures<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package build

const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows "
const goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc s390 s390x sparc sparc64 "
<|endoftext|>


<commit_before>package http

import (
	"github.com/geodan/gost/src/configuration"
	"github.com/geodan/gost/src/database/postgis"
	"github.com/geodan/gost/src/mqtt"
	"github.com/geodan/gost/src/sensorthings/api"
	"github.com/stretchr/testify/assert"
	"testing"
)

// Test the router functionality
func TestCreateRouter(t *testing.T) {
	// arrange
	cfg := configuration.Config{}
	mqttServer := mqtt.CreateMQTTClient(configuration.MQTTConfig{})
	database := postgis.NewDatabase("", 123, "", "", "", "", false, 50, 100, 200)
	a := api.NewAPI(database, cfg, mqttServer)

	// act
	router := CreateRouter(&a)

	// assert
	assert.NotNil(t, router, "Router should be created")
}

func TestDashboardRedirects(t *testing.T) {
	// arrange
	cfg := configuration.Config{}
	mqttServer := mqtt.CreateMQTTClient(configuration.MQTTConfig{})
	database := postgis.NewDatabase("", 123, "", "", "", "", false, 50, 100, 200)
	a := api.NewAPI(database, cfg, mqttServer)
	router := CreateRouter(&a)

	// act
	setDashboardRedirects(router)

	// assert
	assert.NotNil(t, router.Methods, "router should have methods for dasthboard redirects")
}
<commit_msg>trying to use image dashboard instead of local dashboard<commit_after>package http

import (
	"github.com/geodan/gost/src/configuration"
	"github.com/geodan/gost/src/database/postgis"
	"github.com/geodan/gost/src/mqtt"
	"github.com/geodan/gost/src/sensorthings/api"
	"github.com/stretchr/testify/assert"
	"testing"
)

// Test the router functionality
func TestCreateRouter(t *testing.T) {
	// arrange
	cfg := configuration.Config{}
	mqttServer := mqtt.CreateMQTTClient(configuration.MQTTConfig{})
	database := postgis.NewDatabase("", 123, "", "", "", "", false, 50, 100, 200)
	a := api.NewAPI(database, cfg, mqttServer)

	// act
	router := CreateRouter(&a)

	// assert
	assert.NotNil(t, router, "Router should be created")
}

/**
func TestDashboardRedirects(t *testing.T) {
	// arrange
	cfg := configuration.Config{}
	mqttServer := mqtt.CreateMQTTClient(configuration.MQTTConfig{})
	database := postgis.NewDatabase("", 123, "", "", "", "", false, 50, 100, 200)
	a := api.NewAPI(database, cfg, mqttServer)
	router := CreateRouter(&a)

	// act
	setDashboardRedirects(router)

	// assert
	assert.NotNil(t, router.Methods, "router should have methods for dasthboard redirects")
}*/
<|endoftext|>


<commit_before>package terraform

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"io"
	"io/ioutil"
	"regexp"
	"strings"
	"testing"
)

// debugInfo should be safe when nil
func TestDebugInfo_nil(t *testing.T) {
	var d *debugInfo

	d.SetPhase("none")
	d.WriteFile("none", nil)
	d.Close()
}

func TestDebugInfo_basicFile(t *testing.T) {
	var w bytes.Buffer
	debug, err := newDebugInfo("test-debug-info", &w)
	if err != nil {
		t.Fatal(err)
	}
	debug.SetPhase("test")

	fileData := map[string][]byte{
		"file1": []byte("file 1 data"),
		"file2": []byte("file 2 data"),
		"file3": []byte("file 3 data"),
	}

	for f, d := range fileData {
		err = debug.WriteFile(f, d)
		if err != nil {
			t.Fatal(err)
		}
	}

	err = debug.Close()
	if err != nil {
		t.Fatal(err)
	}

	gz, err := gzip.NewReader(&w)
	if err != nil {
		t.Fatal(err)
	}
	tr := tar.NewReader(gz)

	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			break
		}
		if err != nil {
			t.Fatal(err)
		}

		// get the filename part of the archived file
		name := regexp.MustCompile(`\w+$`).FindString(hdr.Name)
		data := fileData[name]

		delete(fileData, name)

		tarData, err := ioutil.ReadAll(tr)
		if err != nil {
			t.Fatal(err)
		}
		if !bytes.Equal(data, tarData) {
			t.Fatalf("got '%s' for file '%s'", tarData, name)
		}
	}

	for k := range fileData {
		t.Fatalf("didn't find file %s", k)
	}
}

// Test that we get logs and graphs from a walk. We're not looking for anything
// specific, since the output is going to change in the near future.
func TestDebug_plan(t *testing.T) {
	var out bytes.Buffer
	d, err := newDebugInfo("test-debug-info", &out)
	if err != nil {
		t.Fatal(err)
	}
	// set the global debug value
	dbug = d

	// run a basic plan
	m := testModule(t, "plan-good")
	p := testProvider("aws")
	p.DiffFn = testDiffFn
	ctx := testContext2(t, &ContextOpts{
		Config: m,
		ProviderResolver: ResourceProviderResolverFixed(
			map[string]ResourceProviderFactory{
				"aws": testProviderFuncFixed(p),
			},
		),
	})

	_, diags := ctx.Plan()
	if diags.HasErrors() {
		t.Fatalf("err: %s", diags.Err())
	}

	err = CloseDebugInfo()
	if err != nil {
		t.Fatal(err)
	}

	gz, err := gzip.NewReader(&out)
	if err != nil {
		t.Fatal(err)
	}
	tr := tar.NewReader(gz)

	graphLogs := 0
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			break
		}
		if err != nil {
			t.Fatal(err)
		}

		// record any file that contains data
		if hdr.Size > 0 {
			if strings.HasSuffix(hdr.Name, "graph.json") {
				graphLogs++
			}
		}
	}

	if graphLogs == 0 {
		t.Fatal("no json graphs")
	}
}

// verify that no hooks panic on nil input
func TestDebugHook_nilArgs(t *testing.T) {
	// make sure debug isn't nil, so the hooks try to execute
	var w bytes.Buffer
	var err error
	dbug, err = newDebugInfo("test-debug-info", &w)
	if err != nil {
		t.Fatal(err)
	}

	var h DebugHook
	h.PostApply(nil, nil, nil)
	h.PostDiff(nil, nil)
	h.PostImportState(nil, nil)
	h.PostProvision(nil, "", nil)
	h.PostProvisionResource(nil, nil)
	h.PostRefresh(nil, nil)
	h.PostStateUpdate(nil)
	h.PreApply(nil, nil, nil)
	h.PreDiff(nil, nil)
	h.PreImportState(nil, "")
	h.PreProvision(nil, "")
	h.PreProvisionResource(nil, nil)
	h.PreRefresh(nil, nil)
	h.ProvisionOutput(nil, "", "")
}
<commit_msg>core: fix tests for debug.go<commit_after>package terraform

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"io"
	"io/ioutil"
	"regexp"
	"strings"
	"testing"

	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/config/configschema"
)

// debugInfo should be safe when nil
func TestDebugInfo_nil(t *testing.T) {
	var d *debugInfo

	d.SetPhase("none")
	d.WriteFile("none", nil)
	d.Close()
}

func TestDebugInfo_basicFile(t *testing.T) {
	var w bytes.Buffer
	debug, err := newDebugInfo("test-debug-info", &w)
	if err != nil {
		t.Fatal(err)
	}
	debug.SetPhase("test")

	fileData := map[string][]byte{
		"file1": []byte("file 1 data"),
		"file2": []byte("file 2 data"),
		"file3": []byte("file 3 data"),
	}

	for f, d := range fileData {
		err = debug.WriteFile(f, d)
		if err != nil {
			t.Fatal(err)
		}
	}

	err = debug.Close()
	if err != nil {
		t.Fatal(err)
	}

	gz, err := gzip.NewReader(&w)
	if err != nil {
		t.Fatal(err)
	}
	tr := tar.NewReader(gz)

	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			break
		}
		if err != nil {
			t.Fatal(err)
		}

		// get the filename part of the archived file
		name := regexp.MustCompile(`\w+$`).FindString(hdr.Name)
		data := fileData[name]

		delete(fileData, name)

		tarData, err := ioutil.ReadAll(tr)
		if err != nil {
			t.Fatal(err)
		}
		if !bytes.Equal(data, tarData) {
			t.Fatalf("got '%s' for file '%s'", tarData, name)
		}
	}

	for k := range fileData {
		t.Fatalf("didn't find file %s", k)
	}
}

// Test that we get logs and graphs from a walk. We're not looking for anything
// specific, since the output is going to change in the near future.
func TestDebug_plan(t *testing.T) {
	var out bytes.Buffer
	d, err := newDebugInfo("test-debug-info", &out)
	if err != nil {
		t.Fatal(err)
	}
	// set the global debug value
	dbug = d

	// run a basic plan
	m := testModule(t, "plan-good")
	p := mockProviderWithResourceTypeSchema("aws_instance", &configschema.Block{
		Attributes: map[string]*configschema.Attribute{
			"num": {
				Type:     cty.Number,
				Optional: true,
			},
			"foo": {
				Type:     cty.Number,
				Optional: true,
			},
		},
	})
	p.DiffFn = testDiffFn
	ctx := testContext2(t, &ContextOpts{
		Config: m,
		ProviderResolver: ResourceProviderResolverFixed(
			map[string]ResourceProviderFactory{
				"aws": testProviderFuncFixed(p),
			},
		),
	})

	_, diags := ctx.Plan()
	if diags.HasErrors() {
		t.Fatalf("err: %s", diags.Err())
	}

	err = CloseDebugInfo()
	if err != nil {
		t.Fatal(err)
	}

	gz, err := gzip.NewReader(&out)
	if err != nil {
		t.Fatal(err)
	}
	tr := tar.NewReader(gz)

	graphLogs := 0
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			break
		}
		if err != nil {
			t.Fatal(err)
		}

		// record any file that contains data
		if hdr.Size > 0 {
			if strings.HasSuffix(hdr.Name, "graph.json") {
				graphLogs++
			}
		}
	}

	if graphLogs == 0 {
		t.Fatal("no json graphs")
	}
}

// verify that no hooks panic on nil input
func TestDebugHook_nilArgs(t *testing.T) {
	// make sure debug isn't nil, so the hooks try to execute
	var w bytes.Buffer
	var err error
	dbug, err = newDebugInfo("test-debug-info", &w)
	if err != nil {
		t.Fatal(err)
	}

	var h DebugHook
	h.PostApply(nil, nil, nil)
	h.PostDiff(nil, nil)
	h.PostImportState(nil, nil)
	h.PostProvision(nil, "", nil)
	h.PostProvisionResource(nil, nil)
	h.PostRefresh(nil, nil)
	h.PostStateUpdate(nil)
	h.PreApply(nil, nil, nil)
	h.PreDiff(nil, nil)
	h.PreImportState(nil, "")
	h.PreProvision(nil, "")
	h.PreProvisionResource(nil, nil)
	h.PreRefresh(nil, nil)
	h.ProvisionOutput(nil, "", "")
}
<|endoftext|>


<commit_before>// Copyright 2016 Albert Nigmatzianov. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package menu

import (
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"time"

	"github.com/bogem/nehm/api"
	"github.com/bogem/nehm/track"
	jww "github.com/spf13/jWalterWeatherman"
)

// TracksMenu gets tracks from GetTracks function, show these tracks in menu
// and returns selected.
//
// TracksMenu finishes when user pushes 'd' button.
type TracksMenu struct {
	GetTracks func(offset uint) ([]track.Track, error)
	Limit     uint
	Offset    uint

	// isSelected holds the ids of selected tracks. With map we can
	// detect really fast if track is selected.
	isSelected map[float64]bool
	// selectedTracks holds selected tracks in initial sequence.
	selectedTracks []track.Track

	selectionFinished bool
}

// Show gets tracks from GetTracks function, show these tracks,
// adds id of selected track to tm.isSelected to detect, what track is selected,
// adds selected to tm.selectedTracks and returns them.
func (tm *TracksMenu) Show() []track.Track {
	jww.FEEDBACK.Println("Getting information about tracks")
	tracks, err := tm.GetTracks(tm.Offset)
	if err != nil {
		jww.FATAL.Fatalln(err)
	}
	if len(tracks) == 0 {
		jww.FEEDBACK.Println("There are no tracks to show")
		os.Exit(0)
	}

	oldOffset := tm.Offset

	tm.isSelected = make(map[float64]bool)
	for !tm.selectionFinished {
		if oldOffset != tm.Offset { // If it's new page.
			oldOffset = tm.Offset
			tracks, err = tm.GetTracks(tm.Offset)
			if err != nil {
				jww.ERROR.Println(err)

				// If it's first page or it's unknown error, we should exit.
				if tm.Offset < tm.Limit || !(err == api.ErrForbidden || err == api.ErrNotFound) {
					os.Exit(1)
				}

				jww.FEEDBACK.Println("Downloading previous page")
				time.Sleep(1 * time.Second) // Sleep so user can read the errors.

				tm.Offset -= tm.Limit
				continue
			}
		}

		trackItems := tm.formTrackItems(tracks)
		clearScreen()
		tm.showMenu(trackItems)
	}

	return tm.selectedTracks
}

var trackItems []MenuItem

func (tm *TracksMenu) formTrackItems(tracks []track.Track) []MenuItem {
	if trackItems == nil {
		trackItems = make([]MenuItem, 0, tm.Limit)
	}
	trackItems = trackItems[:0]

	for i, t := range tracks {
		desc := t.Fullname() + " (" + t.Duration() + ")"

		var trackItem MenuItem
		if _, contains := tm.isSelected[t.ID()]; contains {
			trackItem = MenuItem{
				Index: "A",
				Desc:  desc,
			}
		} else {
			t := t // https://golang.org/doc/faq#closures_and_goroutines
			trackItem = MenuItem{
				Index: strconv.Itoa(i + 1),
				Desc:  desc,
				Run: func() {
					tm.isSelected[t.ID()] = true
					tm.selectedTracks = append(tm.selectedTracks, t)
				},
			}
		}
		trackItems = append(trackItems, trackItem)
	}
	return trackItems
}

// clearPath is used for holding the path to 'clear'/'cls' binary,
// so exec.Command() don't have to always look the path to command.
var clearPath string

func clearScreen() {
	if clearPath == "error" {
		return
	}

	if clearPath == "" {
		var err error
		if runtime.GOOS == "windows" {
			clearPath, err = exec.LookPath("cls")
		} else {
			clearPath, err = exec.LookPath("clear")
		}
		if err != nil { // if there is no clear command, just do not clear the screen ...
			clearPath = "error" // ... and don't check it later
			return
		}
	}

	cmd := exec.Command(clearPath)
	cmd.Stdout = os.Stdout
	cmd.Run()
}

var (
	controlItems []MenuItem
	menu         Menu
)

func (tm *TracksMenu) showMenu(trackItems []MenuItem) {
	if controlItems == nil {
		controlItems = tm.controlItems()
	}
	menu.Reset()
	menu.AddItems(trackItems...)
	menu.AddNewline()
	menu.AddItems(controlItems...)
	menu.Show()
}

func (tm *TracksMenu) controlItems() []MenuItem {
	return []MenuItem{
		MenuItem{
			Index: "d",
			Desc:  "Download tracks",
			Run:   func() { tm.selectionFinished = true },
		},

		MenuItem{
			Index: "n",
			Desc:  "Next page",
			Run:   func() { tm.Offset += tm.Limit },
		},

		MenuItem{
			Index: "p",
			Desc:  "Prev page",
			Run: func() {
				if tm.Offset >= tm.Limit {
					tm.Offset -= tm.Limit
				} else {
					tm.Offset = 0
				}
			},
		},
	}
}
<commit_msg>menu: Fix typo<commit_after>// Copyright 2016 Albert Nigmatzianov. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package menu

import (
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"time"

	"github.com/bogem/nehm/api"
	"github.com/bogem/nehm/track"
	jww "github.com/spf13/jWalterWeatherman"
)

// TracksMenu gets tracks from GetTracks function, shows them in menu
// and returns selected tracks.
//
// TracksMenu finishes when user pushes 'd' button.
type TracksMenu struct {
	GetTracks func(offset uint) ([]track.Track, error)
	Limit     uint
	Offset    uint

	// isSelected holds the ids of selected tracks. With map we can
	// detect really fast if track is selected.
	isSelected map[float64]bool
	// selectedTracks holds selected tracks in initial sequence.
	selectedTracks []track.Track

	selectionFinished bool
}

// Show gets tracks from GetTracks function, show these tracks,
// adds id of selected track to tm.isSelected to detect, what track is selected,
// adds selected to tm.selectedTracks and returns them.
func (tm *TracksMenu) Show() []track.Track {
	jww.FEEDBACK.Println("Getting information about tracks")
	tracks, err := tm.GetTracks(tm.Offset)
	if err != nil {
		jww.FATAL.Fatalln(err)
	}
	if len(tracks) == 0 {
		jww.FEEDBACK.Println("There are no tracks to show")
		os.Exit(0)
	}

	oldOffset := tm.Offset

	tm.isSelected = make(map[float64]bool)
	for !tm.selectionFinished {
		if oldOffset != tm.Offset { // If it's new page.
			oldOffset = tm.Offset
			tracks, err = tm.GetTracks(tm.Offset)
			if err != nil {
				jww.ERROR.Println(err)

				// If it's first page or it's unknown error, we should exit.
				if tm.Offset < tm.Limit || !(err == api.ErrForbidden || err == api.ErrNotFound) {
					os.Exit(1)
				}

				jww.FEEDBACK.Println("Downloading previous page")
				time.Sleep(1 * time.Second) // Sleep so user can read the errors.

				tm.Offset -= tm.Limit
				continue
			}
		}

		trackItems := tm.formTrackItems(tracks)
		clearScreen()
		tm.showMenu(trackItems)
	}

	return tm.selectedTracks
}

var trackItems []MenuItem

func (tm *TracksMenu) formTrackItems(tracks []track.Track) []MenuItem {
	if trackItems == nil {
		trackItems = make([]MenuItem, 0, tm.Limit)
	}
	trackItems = trackItems[:0]

	for i, t := range tracks {
		desc := t.Fullname() + " (" + t.Duration() + ")"

		var trackItem MenuItem
		if _, contains := tm.isSelected[t.ID()]; contains {
			trackItem = MenuItem{
				Index: "A",
				Desc:  desc,
			}
		} else {
			t := t // https://golang.org/doc/faq#closures_and_goroutines
			trackItem = MenuItem{
				Index: strconv.Itoa(i + 1),
				Desc:  desc,
				Run: func() {
					tm.isSelected[t.ID()] = true
					tm.selectedTracks = append(tm.selectedTracks, t)
				},
			}
		}
		trackItems = append(trackItems, trackItem)
	}
	return trackItems
}

// clearPath is used for holding the path to 'clear'/'cls' binary,
// so exec.Command() don't have to always look the path to command.
var clearPath string

func clearScreen() {
	if clearPath == "error" {
		return
	}

	if clearPath == "" {
		var err error
		if runtime.GOOS == "windows" {
			clearPath, err = exec.LookPath("cls")
		} else {
			clearPath, err = exec.LookPath("clear")
		}
		if err != nil { // if there is no clear command, just do not clear the screen ...
			clearPath = "error" // ... and don't check it later
			return
		}
	}

	cmd := exec.Command(clearPath)
	cmd.Stdout = os.Stdout
	cmd.Run()
}

var (
	controlItems []MenuItem
	menu         Menu
)

func (tm *TracksMenu) showMenu(trackItems []MenuItem) {
	if controlItems == nil {
		controlItems = tm.controlItems()
	}
	menu.Reset()
	menu.AddItems(trackItems...)
	menu.AddNewline()
	menu.AddItems(controlItems...)
	menu.Show()
}

func (tm *TracksMenu) controlItems() []MenuItem {
	return []MenuItem{
		MenuItem{
			Index: "d",
			Desc:  "Download tracks",
			Run:   func() { tm.selectionFinished = true },
		},

		MenuItem{
			Index: "n",
			Desc:  "Next page",
			Run:   func() { tm.Offset += tm.Limit },
		},

		MenuItem{
			Index: "p",
			Desc:  "Prev page",
			Run: func() {
				if tm.Offset >= tm.Limit {
					tm.Offset -= tm.Limit
				} else {
					tm.Offset = 0
				}
			},
		},
	}
}
<|endoftext|>


<commit_before>package bagman_test

import (
	"testing"
	"github.com/APTrust/bagman"
	"github.com/APTrust/bagins"
	"errors"
	"os"
	"fmt"
	"io/ioutil"
	"path/filepath"
)

var gopath string = os.Getenv("GOPATH")
var testDataPath = filepath.Join(gopath, "src/github.com/APTrust/bagman/testdata")
var sampleBadChecksums string = filepath.Join(testDataPath, "sample_bad_checksums.tar")
var sampleGood string = filepath.Join(testDataPath, "sample_good.tar")
var sampleMissingDataFile string = filepath.Join(testDataPath, "sample_missing_data_file.tar")
var sampleNoBagInfo string = filepath.Join(testDataPath, "sample_no_bag_info.tar")
var sampleNoBagit string = filepath.Join(testDataPath, "sample_no_bagit.tar")
var badFiles []string = []string{
	sampleBadChecksums,
	sampleMissingDataFile,
	sampleNoBagInfo,
	sampleNoBagit,
}
var goodFiles []string = []string{
	sampleGood,
}
var allFiles []string = append(badFiles, goodFiles ...)

func setup() {

}

func teardown() {
	files, err := ioutil.ReadDir(testDataPath)
	if err != nil {
		fmt.Errorf("Can't cleanup %s: %s", testDataPath, err.Error())
		return
	}
	for _, fileInfo := range files {
		if fileInfo.IsDir() {
			subDir := filepath.Join(testDataPath, fileInfo.Name())
			err := os.RemoveAll(subDir)
			if err != nil {
				fmt.Errorf("Test cleanup was unable delete %s", subDir)
			}
		}
	}
}

func assertTagMatch(tag bagins.TagField, expectedLabel string, expectedValue string) (err error) {
	if tag.Label() != expectedLabel || tag.Value() != expectedValue {
		return errors.New(fmt.Sprintf("Expected tag '%s: %s', got '%s: %s'",
			expectedLabel, expectedValue, tag.Label(), tag.Value()))
	}
	return nil
}

// Make sure we can parse a bag that is known to be good, and that we
// get the right data in the results. This is not a strict unit test,
// since it depends on bagman.Untar succeeding.
func TestGoodBagParsesCorrectly(t *testing.T) {
	setup()
	defer teardown()
	tarResult := bagman.Untar(sampleGood)
	result := bagman.ReadBag(tarResult.OutputDir)
	if result.Path != tarResult.OutputDir {
		t.Errorf("Result path %s is incorrect, expected %s", result.Path, tarResult.OutputDir)
	}
	if len(result.Files) != 8 {
		t.Errorf("Unpacked %d files, expected %d", len(result.Files), 8)
	}
	if result.Error != nil {
		t.Errorf("Unexpected error in read result: %v", result.Error)
	}
	// Note that we're testing to see not only that the tags are present,
	// but that they are in the correct order.
	//
	// TODO: Bagins is returning one extra empty tag as the first element in every tag list
	// from every bag file. We need to fix that.
	if len(result.Tags) != 6 {
		t.Errorf("Expected 6 tags, got %d", len(result.Tags))
	}
	// TODO: This empty tag should not be here.
	if err := assertTagMatch(result.Tags[0], "", ""); err != nil { t.Error(err) }

	err := assertTagMatch(result.Tags[1], "Source-Organization:", "virginia.edu")
	if err != nil { t.Error(err) }

	err = assertTagMatch(result.Tags[2], "Bagging-Date:", "2014-04-14T11:55:26.17-0400")
	if err != nil { t.Error(err) }

	err = assertTagMatch(result.Tags[3], "Bag-Count:", "1 of 1")
	if err != nil { t.Error(err) }

	err = assertTagMatch(result.Tags[4], "Bag-Group-Identifier:", "")
	if err != nil { t.Error(err) }

	err = assertTagMatch(result.Tags[5], "Internal-Sender-Description:", "")
	if err != nil { t.Error(err) }

	if len(result.ChecksumErrors) != 0 {
		t.Errorf("Bag read result contained %d checksum errors; it should have none",
			len(result.ChecksumErrors))
	}
}

func TestBadBagReturnsError(t *testing.T) {
	setup()
	defer teardown()
	for _, tarFile := range badFiles {
		tarResult := bagman.Untar(tarFile)
		result := bagman.ReadBag(tarResult.OutputDir)
		if result.Error == nil {
			t.Errorf("Bag unpacked from %s should have produced an error, but did not",
				tarResult.OutputDir)
		}
	}
}
<commit_msg>Removed colons from expected tag labels<commit_after>package bagman_test

import (
	"testing"
	"github.com/APTrust/bagman"
	"github.com/APTrust/bagins"
	"errors"
	"os"
	"fmt"
	"io/ioutil"
	"path/filepath"
)

var gopath string = os.Getenv("GOPATH")
var testDataPath = filepath.Join(gopath, "src/github.com/APTrust/bagman/testdata")
var sampleBadChecksums string = filepath.Join(testDataPath, "sample_bad_checksums.tar")
var sampleGood string = filepath.Join(testDataPath, "sample_good.tar")
var sampleMissingDataFile string = filepath.Join(testDataPath, "sample_missing_data_file.tar")
var sampleNoBagInfo string = filepath.Join(testDataPath, "sample_no_bag_info.tar")
var sampleNoBagit string = filepath.Join(testDataPath, "sample_no_bagit.tar")
var badFiles []string = []string{
	sampleBadChecksums,
	sampleMissingDataFile,
	sampleNoBagInfo,
	sampleNoBagit,
}
var goodFiles []string = []string{
	sampleGood,
}
var allFiles []string = append(badFiles, goodFiles ...)

func setup() {

}

func teardown() {
	files, err := ioutil.ReadDir(testDataPath)
	if err != nil {
		fmt.Errorf("Can't cleanup %s: %s", testDataPath, err.Error())
		return
	}
	for _, fileInfo := range files {
		if fileInfo.IsDir() {
			subDir := filepath.Join(testDataPath, fileInfo.Name())
			err := os.RemoveAll(subDir)
			if err != nil {
				fmt.Errorf("Test cleanup was unable delete %s", subDir)
			}
		}
	}
}

func assertTagMatch(tag bagins.TagField, expectedLabel string, expectedValue string) (err error) {
	if tag.Label() != expectedLabel || tag.Value() != expectedValue {
		return errors.New(fmt.Sprintf("Expected tag '%s: %s', got '%s: %s'",
			expectedLabel, expectedValue, tag.Label(), tag.Value()))
	}
	return nil
}

// Make sure we can parse a bag that is known to be good, and that we
// get the right data in the results. This is not a strict unit test,
// since it depends on bagman.Untar succeeding.
func TestGoodBagParsesCorrectly(t *testing.T) {
	setup()
	defer teardown()
	tarResult := bagman.Untar(sampleGood)
	result := bagman.ReadBag(tarResult.OutputDir)
	if result.Path != tarResult.OutputDir {
		t.Errorf("Result path %s is incorrect, expected %s", result.Path, tarResult.OutputDir)
	}
	if len(result.Files) != 8 {
		t.Errorf("Unpacked %d files, expected %d", len(result.Files), 8)
	}
	if result.Error != nil {
		t.Errorf("Unexpected error in read result: %v", result.Error)
	}
	// Note that we're testing to see not only that the tags are present,
	// but that they are in the correct order.
	//
	// TODO: Bagins is returning one extra empty tag as the first element in every tag list
	// from every bag file. We need to fix that.
	if len(result.Tags) != 6 {
		t.Errorf("Expected 6 tags, got %d", len(result.Tags))
	}
	// TODO: This empty tag should not be here.
	if err := assertTagMatch(result.Tags[0], "", ""); err != nil { t.Error(err) }

	err := assertTagMatch(result.Tags[1], "Source-Organization", "virginia.edu")
	if err != nil { t.Error(err) }

	err = assertTagMatch(result.Tags[2], "Bagging-Date", "2014-04-14T11:55:26.17-0400")
	if err != nil { t.Error(err) }

	err = assertTagMatch(result.Tags[3], "Bag-Count", "1 of 1")
	if err != nil { t.Error(err) }

	err = assertTagMatch(result.Tags[4], "Bag-Group-Identifier", "")
	if err != nil { t.Error(err) }

	err = assertTagMatch(result.Tags[5], "Internal-Sender-Description", "")
	if err != nil { t.Error(err) }

	if len(result.ChecksumErrors) != 0 {
		t.Errorf("Bag read result contained %d checksum errors; it should have none",
			len(result.ChecksumErrors))
	}
}

func TestBadBagReturnsError(t *testing.T) {
	setup()
	defer teardown()
	for _, tarFile := range badFiles {
		tarResult := bagman.Untar(tarFile)
		result := bagman.ReadBag(tarResult.OutputDir)
		if result.Error == nil {
			t.Errorf("Bag unpacked from %s should have produced an error, but did not",
				tarResult.OutputDir)
		}
	}
}
<|endoftext|>


<commit_before>package ecs

import (
	"github.com/denverdino/aliyungo/common"
	"os"
)

// Interval for checking status in WaitForXXX method
const DefaultWaitForInterval = 5

// Default timeout value for WaitForXXX method
const DefaultTimeout = 60

type Client struct {
	common.Client
}

const (
	// ECSDefaultEndpoint is the default API endpoint of ECS services
	ECSDefaultEndpoint = "https://ecs.aliyuncs.com"
	ECSAPIVersion      = "2014-05-26"
)

// NewClient creates a new instance of ECS client
func NewClient(accessKeyId, accessKeySecret string) *Client {
	endpoint := os.Getenv("ECS_ENDPOINT")
	if endpoint == "" {
		endpoint = ECSDefaultEndpoint
	}
	return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
}

func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client {
	client := &Client{}
	client.Init(endpoint, ECSAPIVersion, accessKeyId, accessKeySecret)
	return client
}
<commit_msg>update ecsendpoint<commit_after>package ecs

import (
	"github.com/denverdino/aliyungo/common"
	"os"
)

// Interval for checking status in WaitForXXX method
const DefaultWaitForInterval = 5

// Default timeout value for WaitForXXX method
const DefaultTimeout = 60

type Client struct {
	common.Client
}

const (
	// ECSDefaultEndpoint is the default API endpoint of ECS services
	ECSDefaultEndpoint = "https://ecs-cn-hangzhou.aliyuncs.com"
	ECSAPIVersion      = "2014-05-26"
)

// NewClient creates a new instance of ECS client
func NewClient(accessKeyId, accessKeySecret string) *Client {
	endpoint := os.Getenv("ECS_ENDPOINT")
	if endpoint == "" {
		endpoint = ECSDefaultEndpoint
	}
	return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
}

func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client {
	client := &Client{}
	client.Init(endpoint, ECSAPIVersion, accessKeyId, accessKeySecret)
	return client
}
<|endoftext|>


<commit_before>package rootfs_spec

import (
	"net/url"

	"code.cloudfoundry.org/garden"
)

type Spec struct {
	RootFS     *url.URL
	Username   string
	Password   string
	Namespaced bool
	QuotaSize  int64
	QuotaScope garden.DiskLimitScope
}
<commit_msg>Don't print docker passwords to logs<commit_after>package rootfs_spec

import (
	"net/url"

	"code.cloudfoundry.org/garden"
)

type Spec struct {
	RootFS     *url.URL
	Username   string `json:"-"`
	Password   string `json:"-"`
	Namespaced bool
	QuotaSize  int64
	QuotaScope garden.DiskLimitScope
}
<|endoftext|>


<commit_before>package rdbtools

import (
	"os"
	"testing"
)

// This file contains tests for all the dumps in the dumps/ directory
// Those dumps are taken from https://github.com/sripathikrishnan/redis-rdb-tools

func mustOpen(t *testing.T, path string) *os.File {
	f, err := os.Open(path)
	if err != nil {
		t.Fatalf("Error while opening file '%s'; err=%s", path, err)
	}

	return f
}

func doParse(t *testing.T, p *Parser, path string) {
	err := p.Parse(mustOpen(t, path))
	if err != nil {
		p.ctx.closeChannels()
		t.Fatalf("Error while parsing '%s'; err=%s", path, err)
	}
}

func TestDumpDictionary(t *testing.T) {
	p := NewParser(ParserContext{
		HashMetadataCh: make(chan HashMetadata),
		HashDataCh:     make(chan HashEntry),
	})

	go doParse(t, p, "dumps/dictionary.rdb")

	var i, j int
	stop := false
	for !stop {
		select {
		case _, ok := <-p.ctx.HashMetadataCh:
			if !ok {
				p.ctx.HashMetadataCh = nil
				break
			}
			i++
		case _, ok := <-p.ctx.HashDataCh:
			if !ok {
				p.ctx.HashDataCh = nil
				break
			}
			j++
		}

		if p.ctx.Invalid() {
			break
		}
	}

	equals(t, 1, i)
	equals(t, 1000, j)
}

func TestDumpKeysWithExpiry(t *testing.T) {
	p := NewParser(ParserContext{
		StringObjectCh: make(chan StringObject),
	})

	go doParse(t, p, "dumps/keys_with_expiry.rdb")

	stop := false
	for !stop {
		select {
		case v, ok := <-p.ctx.StringObjectCh:
			if !ok {
				p.ctx.StringObjectCh = nil
				break
			}
			equals(t, "expires_ms_precision", DataToString(v.Key.Key))
			equals(t, "2022-12-25 10:11:12 +0000 UTC", v.Key.ExpiryTime.UTC().String())
			equals(t, "2022-12-25 10:11:12.573 UTC", DataToString(v.Value))
		}

		if p.ctx.Invalid() {
			break
		}
	}
}

func TestDumpWithChecksum(t *testing.T) {
	p := NewParser(ParserContext{
		StringObjectCh: make(chan StringObject),
	})

	go doParse(t, p, "dumps/rdb_version_5_with_checksum.rdb")

	stop := false
	for !stop {
		select {
		case v, ok := <-p.ctx.StringObjectCh:
			if !ok {
				p.ctx.StringObjectCh = nil
				break
			}
		}

		if p.ctx.Invalid() {
			break
		}
	}
}
<commit_msg>Complete the test TestDumpWithChecksum<commit_after>package rdbtools

import (
	"os"
	"testing"
)

// This file contains tests for all the dumps in the dumps/ directory
// Those dumps are taken from https://github.com/sripathikrishnan/redis-rdb-tools

func mustOpen(t *testing.T, path string) *os.File {
	f, err := os.Open(path)
	if err != nil {
		t.Fatalf("Error while opening file '%s'; err=%s", path, err)
	}

	return f
}

func doParse(t *testing.T, p *Parser, path string) {
	err := p.Parse(mustOpen(t, path))
	if err != nil {
		p.ctx.closeChannels()
		t.Fatalf("Error while parsing '%s'; err=%s", path, err)
	}
}

func TestDumpDictionary(t *testing.T) {
	p := NewParser(ParserContext{
		HashMetadataCh: make(chan HashMetadata),
		HashDataCh:     make(chan HashEntry),
	})

	go doParse(t, p, "dumps/dictionary.rdb")

	var i, j int
	stop := false
	for !stop {
		select {
		case _, ok := <-p.ctx.HashMetadataCh:
			if !ok {
				p.ctx.HashMetadataCh = nil
				break
			}
			i++
		case _, ok := <-p.ctx.HashDataCh:
			if !ok {
				p.ctx.HashDataCh = nil
				break
			}
			j++
		}

		if p.ctx.Invalid() {
			break
		}
	}

	equals(t, 1, i)
	equals(t, 1000, j)
}

func TestDumpKeysWithExpiry(t *testing.T) {
	p := NewParser(ParserContext{
		StringObjectCh: make(chan StringObject),
	})

	go doParse(t, p, "dumps/keys_with_expiry.rdb")

	stop := false
	for !stop {
		select {
		case v, ok := <-p.ctx.StringObjectCh:
			if !ok {
				p.ctx.StringObjectCh = nil
				break
			}
			equals(t, "expires_ms_precision", DataToString(v.Key.Key))
			equals(t, "2022-12-25 10:11:12 +0000 UTC", v.Key.ExpiryTime.UTC().String())
			equals(t, "2022-12-25 10:11:12.573 UTC", DataToString(v.Value))
		}

		if p.ctx.Invalid() {
			break
		}
	}
}

func TestDumpWithChecksum(t *testing.T) {
	p := NewParser(ParserContext{
		StringObjectCh: make(chan StringObject),
	})

	go doParse(t, p, "dumps/rdb_version_5_with_checksum.rdb")

	stop := false
	res := make([]StringObject, 0)
	for !stop {
		select {
		case v, ok := <-p.ctx.StringObjectCh:
			if !ok {
				p.ctx.StringObjectCh = nil
				break
			}

			res = append(res, v)
		}

		if p.ctx.Invalid() {
			break
		}
	}

	equals(t, "abcd", DataToString(res[0].Key.Key))
	equals(t, true, res[0].Key.ExpiryTime.IsZero())
	equals(t, "efgh", DataToString(res[0].Value))

	equals(t, "foo", DataToString(res[1].Key.Key))
	equals(t, true, res[1].Key.ExpiryTime.IsZero())
	equals(t, "bar", DataToString(res[1].Value))

	equals(t, "bar", DataToString(res[2].Key.Key))
	equals(t, true, res[2].Key.ExpiryTime.IsZero())
	equals(t, "baz", DataToString(res[2].Value))

	equals(t, "abcdef", DataToString(res[3].Key.Key))
	equals(t, true, res[3].Key.ExpiryTime.IsZero())
	equals(t, "abcdef", DataToString(res[3].Value))

	equals(t, "longerstring", DataToString(res[4].Key.Key))
	equals(t, true, res[4].Key.ExpiryTime.IsZero())
	equals(t, "thisisalongerstring.idontknowwhatitmeans", DataToString(res[4].Value))

	equals(t, "abc", DataToString(res[5].Key.Key))
	equals(t, true, res[5].Key.ExpiryTime.IsZero())
	equals(t, "def", DataToString(res[5].Value))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/justone/pmb/api"
)

type NotifyCommand struct {
	Message string  `short:"m" long:"message" description:"Message to send."`
	Pid     int     `short:"p" long:"pid" description:"Notify after PID exits."`
	Level   float64 `short:"l" long:"level" description:"Notification level (1-5), higher numbers indictate higher importance" default:"3"`
}

var notifyCommand NotifyCommand

func (x *NotifyCommand) Execute(args []string) error {
	bus := pmb.GetPMB(globalOptions.Primary)

	if len(args) == 0 && len(notifyCommand.Message) == 0 && notifyCommand.Pid == 0 {
		return fmt.Errorf("A message is required")
	}

	// fail fast if pid isn't found
	if notifyCommand.Pid > 0 {
		found, _ := findProcess(notifyCommand.Pid)

		if !found {
			return fmt.Errorf("Process %d not found.", notifyCommand.Pid)
		}
	}

	id := pmb.GenerateRandomID("notify")

	conn, err := bus.ConnectClient(id, !globalOptions.TrustKey)
	if err != nil {
		return err
	}

	return runNotify(conn, id, args)
}

func init() {
	parser.AddCommand("notify",
		"Send a notification.",
		"",
		&notifyCommand)
}

func runNotify(conn *pmb.Connection, id string, args []string) error {

	message := notifyCommand.Message

	if len(args) > 0 {
		cmd := exec.Command(args[0], args[1:]...)

		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout

		command := strings.Join(args, " ")
		logrus.Infof("Waiting for command '%s' to finish...\n", command)

		err := cmd.Run()

		result := "successfully"
		if err != nil {
			result = fmt.Sprintf("with error '%s'", err.Error())
		}
		logrus.Infof("Process complete.")

		if len(message) == 0 {
			message = fmt.Sprintf("Command [%s] completed %s.", command, result)
		} else {
			message = fmt.Sprintf("%s. Command completed %s.", message, result)
		}
	} else if notifyCommand.Pid != 0 {

		notifyExecutable := ""
		logrus.Infof("Waiting for pid %d to finish...\n", notifyCommand.Pid)
		for {
			found, exec := findProcess(notifyCommand.Pid)

			// capture the name of the executable for the notification
			if len(notifyExecutable) == 0 {
				notifyExecutable = exec
			}

			if !found {
				logrus.Infof("Process complete.")
				break
			} else {
				time.Sleep(1 * time.Second)
			}
		}

		if len(message) == 0 {
			message = fmt.Sprintf("Command [%s] completed.", notifyExecutable)
		}
	}

	note := pmb.Notification{Message: message, Level: notifyCommand.Level}
	return pmb.SendNotification(conn, note)
}

// TODO: use a go-based library for this, maybe gopsutil
func findProcess(pid int) (bool, string) {

	procCmd := exec.Command("/bin/ps", "-o", "pid=", "-p", strconv.Itoa(pid))

	err := procCmd.Run()

	if _, ok := err.(*exec.ExitError); ok {
		return false, ""
	} else if err != nil {
		return false, ""
	} else {
		return true, fmt.Sprintf("pid %d", pid)
	}

	return false, ""
}
<commit_msg>pipe through stderr as well<commit_after>package main

import (
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/justone/pmb/api"
)

type NotifyCommand struct {
	Message string  `short:"m" long:"message" description:"Message to send."`
	Pid     int     `short:"p" long:"pid" description:"Notify after PID exits."`
	Level   float64 `short:"l" long:"level" description:"Notification level (1-5), higher numbers indictate higher importance" default:"3"`
}

var notifyCommand NotifyCommand

func (x *NotifyCommand) Execute(args []string) error {
	bus := pmb.GetPMB(globalOptions.Primary)

	if len(args) == 0 && len(notifyCommand.Message) == 0 && notifyCommand.Pid == 0 {
		return fmt.Errorf("A message is required")
	}

	// fail fast if pid isn't found
	if notifyCommand.Pid > 0 {
		found, _ := findProcess(notifyCommand.Pid)

		if !found {
			return fmt.Errorf("Process %d not found.", notifyCommand.Pid)
		}
	}

	id := pmb.GenerateRandomID("notify")

	conn, err := bus.ConnectClient(id, !globalOptions.TrustKey)
	if err != nil {
		return err
	}

	return runNotify(conn, id, args)
}

func init() {
	parser.AddCommand("notify",
		"Send a notification.",
		"",
		&notifyCommand)
}

func runNotify(conn *pmb.Connection, id string, args []string) error {

	message := notifyCommand.Message

	if len(args) > 0 {
		cmd := exec.Command(args[0], args[1:]...)

		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr

		command := strings.Join(args, " ")
		logrus.Infof("Waiting for command '%s' to finish...\n", command)

		err := cmd.Run()

		result := "successfully"
		if err != nil {
			result = fmt.Sprintf("with error '%s'", err.Error())
		}
		logrus.Infof("Process complete.")

		if len(message) == 0 {
			message = fmt.Sprintf("Command [%s] completed %s.", command, result)
		} else {
			message = fmt.Sprintf("%s. Command completed %s.", message, result)
		}
	} else if notifyCommand.Pid != 0 {

		notifyExecutable := ""
		logrus.Infof("Waiting for pid %d to finish...\n", notifyCommand.Pid)
		for {
			found, exec := findProcess(notifyCommand.Pid)

			// capture the name of the executable for the notification
			if len(notifyExecutable) == 0 {
				notifyExecutable = exec
			}

			if !found {
				logrus.Infof("Process complete.")
				break
			} else {
				time.Sleep(1 * time.Second)
			}
		}

		if len(message) == 0 {
			message = fmt.Sprintf("Command [%s] completed.", notifyExecutable)
		}
	}

	note := pmb.Notification{Message: message, Level: notifyCommand.Level}
	return pmb.SendNotification(conn, note)
}

// TODO: use a go-based library for this, maybe gopsutil
func findProcess(pid int) (bool, string) {

	procCmd := exec.Command("/bin/ps", "-o", "pid=", "-p", strconv.Itoa(pid))

	err := procCmd.Run()

	if _, ok := err.(*exec.ExitError); ok {
		return false, ""
	} else if err != nil {
		return false, ""
	} else {
		return true, fmt.Sprintf("pid %d", pid)
	}

	return false, ""
}
<|endoftext|>


<commit_before>package web

//import "gopkg.in/webnice/debug.v1"
//import "gopkg.in/webnice/log.v2"
import (
	"crypto/tls"
	"net"
	"os"
)

// Wait while web server is running
func (wsv *web) Wait() Interface { wsv.doCloseDone.Wait(); return wsv }

// ListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections
func (wsv *web) ListenAndServe(addr string) Interface {
	var conf *Configuration

	if conf, wsv.err = parseAddress(addr); wsv.err != nil {
		return wsv
	}

	return wsv.ListenAndServeWithConfig(conf)
}

// ListenAndServeTLS listens on the TCP network address address with TLS and then calls Serve with handler
// to handle requests on incoming connections
func (wsv *web) ListenAndServeTLS(addr string, certFile string, keyFile string, tlsConfig *tls.Config) Interface {
	var conf *Configuration

	if conf, wsv.err = parseAddress(addr); wsv.err != nil {
		return wsv
	}
	conf.TLSPublicKeyPEM, conf.TLSPrivateKeyPEM = certFile, keyFile

	return wsv.ListenAndServeTLSWithConfig(conf, tlsConfig)
}

// ListenAndServeWithConfig Fully configurable web server listens and then calls Serve on incoming connections
func (wsv *web) ListenAndServeWithConfig(conf *Configuration) Interface {
	if conf == nil {
		wsv.err = ErrNoConfiguration()
		return wsv
	}
	wsv.conf = conf

	return wsv.Listen(nil)
}

// ListenAndServeTLSWithConfig Fully configurable web server listens and then calls Serve on incoming connections
func (wsv *web) ListenAndServeTLSWithConfig(conf *Configuration, tlsConfig *tls.Config) Interface {
	if conf == nil {
		wsv.err = ErrNoConfiguration()
		return wsv
	}
	wsv.conf = conf
	if tlsConfig == nil {
		if tlsConfig, wsv.err = wsv.tlsConfigDefault(conf.TLSPublicKeyPEM, conf.TLSPrivateKeyPEM); wsv.err != nil {
			return wsv
		}
	}

	return wsv.Listen(tlsConfig)
}

// NewListener Make new listener from web server configuration
func (wsv *web) NewListener(conf *Configuration) (ret net.Listener, err error) {
	var (
		lstWithNames map[string][]net.Listener
		listeners    []net.Listener
		ok           bool
	)

	defaultConfiguration(conf)
	switch conf.Mode {
	case netSystemd:
		if conf.Socket != "" {
			// Имена сокетов указаны
			if lstWithNames, err = wsv.ListenersSystemdWithNames(false); err != nil {
				return
			}
			// Выбор сокета по имени
			if listeners, ok = lstWithNames[conf.Socket]; ok {
				err = ErrListenSystemdNotFound()
				return
			}
		} else {
			// Имена сокетов не указаны
			if listeners, err = wsv.ListenersSystemdWithoutNames(false); err != nil {
				return
			}
		}
		if len(listeners) == 0 {
			err = ErrListenSystemdUnexpectedNumber()
			return
		}
		ret = listeners[0]
	case netUnix, netUnixPacket:
		_ = os.Remove(conf.Socket)
		ret, err = net.Listen(conf.Mode, conf.Socket)
		_ = os.Chmod(conf.Socket, os.FileMode(0666))
	default:
		ret, err = net.Listen(conf.Mode, conf.HostPort)
	}

	return
}

// NewListenerTLS Make new listener with TLS from web server configuration
func (wsv *web) NewListenerTLS(conf *Configuration, tlsConfig *tls.Config) (ret net.Listener, err error) {
	var l net.Listener

	if l, err = wsv.NewListener(conf); err != nil {
		return
	}
	if tlsConfig == nil {
		if tlsConfig, err = wsv.tlsConfigDefault(conf.TLSPublicKeyPEM, conf.TLSPrivateKeyPEM); err != nil {
			return
		}
	}
	ret = tls.NewListener(l, tlsConfig)

	return
}

// Конфигурация TLS по умолчанию
func (wsv *web) tlsConfigDefault(tlsPublicFile string, tlsPrivateFile string) (ret *tls.Config, err error) {
	ret = &tls.Config{
		MinVersion:               tls.VersionTLS12,
		CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
		PreferServerCipherSuites: true,
		CipherSuites: []uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		Certificates: make([]tls.Certificate, 1),
	}
	if ret.Certificates[0], err = tls.LoadX509KeyPair(tlsPublicFile, tlsPrivateFile); err != nil {
		return
	}

	return
}

// Listen Begin listen port and web server serve
func (wsv *web) Listen(tlsConfig *tls.Config) Interface {
	var ltn net.Listener

	if wsv.isRun.Load().(bool) {
		wsv.err = ErrAlreadyRunning()
		return wsv
	}
	switch tlsConfig == nil {
	case true:
		ltn, wsv.err = wsv.NewListener(wsv.conf)
	case false:
		ltn, wsv.err = wsv.NewListenerTLS(wsv.conf, tlsConfig)
	}
	if wsv.err != nil {
		return wsv
	}

	return wsv.ServeTLS(ltn, tlsConfig)
}

// Serve accepts incoming connections on the listener, creating a new web server goroutine
func (wsv *web) Serve(ltn net.Listener) Interface { return wsv.ServeTLS(ltn, nil) }

// ServeTLS accepts incoming connections on the listener with TLS configuration, creating a new web server goroutine
func (wsv *web) ServeTLS(ltn net.Listener, tlsConfig *tls.Config) Interface {
	var conf *Configuration

	// TODO: Реализовать поддержку PROXY Protocol через "gopkg.in/webnice/web.v1/proxyp", conf.ProxyProtocol

	if wsv.conf == nil {
		conf, _ = parseAddress(ltn.Addr().String())
		defaultConfiguration(conf)
		wsv.conf = conf
	}
	wsv.listener = ltn
	wsv.isRun.Store(true)
	wsv.doCloseDone.Add(1)
	go wsv.run(tlsConfig)

	return wsv
}

// Goroutine of the web server
func (wsv *web) run(tlsConfig *tls.Config) {
	defer wsv.doCloseDone.Done()
	defer wsv.isRun.Store(false)
	defer func() {
		if wsv.conf.Socket == "" {
			return
		}
		switch wsv.conf.Mode {
		case netSystemd:
			return
		case netUnix, netUnixPacket:
			_ = os.Remove(wsv.conf.Socket)
		}
	}()

	// Configure net/http web server
	if wsv.server = wsv.loadConfiguration(tlsConfig); wsv.err != nil {
		return
	}
	// Configure keepalive of web server
	if wsv.conf.KeepAliveDisable {
		wsv.server.SetKeepAlivesEnabled(false)
	}
	// Begin serve
	if wsv.conf.TLSPrivateKeyPEM == "" || wsv.conf.TLSPublicKeyPEM == "" {
		wsv.err = wsv.server.Serve(wsv.listener)
		return
	}
	wsv.err = wsv.server.ServeTLS(wsv.listener, wsv.conf.TLSPublicKeyPEM, wsv.conf.TLSPrivateKeyPEM)
}
<commit_msg>Debug added temporarily<commit_after>package web

import "gopkg.in/webnice/debug.v1"
import "gopkg.in/webnice/log.v2"
import (
	"crypto/tls"
	"net"
	"os"
)

// Wait while web server is running
func (wsv *web) Wait() Interface { wsv.doCloseDone.Wait(); return wsv }

// ListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections
func (wsv *web) ListenAndServe(addr string) Interface {
	var conf *Configuration

	if conf, wsv.err = parseAddress(addr); wsv.err != nil {
		return wsv
	}

	return wsv.ListenAndServeWithConfig(conf)
}

// ListenAndServeTLS listens on the TCP network address address with TLS and then calls Serve with handler
// to handle requests on incoming connections
func (wsv *web) ListenAndServeTLS(addr string, certFile string, keyFile string, tlsConfig *tls.Config) Interface {
	var conf *Configuration

	if conf, wsv.err = parseAddress(addr); wsv.err != nil {
		return wsv
	}
	conf.TLSPublicKeyPEM, conf.TLSPrivateKeyPEM = certFile, keyFile

	return wsv.ListenAndServeTLSWithConfig(conf, tlsConfig)
}

// ListenAndServeWithConfig Fully configurable web server listens and then calls Serve on incoming connections
func (wsv *web) ListenAndServeWithConfig(conf *Configuration) Interface {
	if conf == nil {
		wsv.err = ErrNoConfiguration()
		return wsv
	}
	wsv.conf = conf

	return wsv.Listen(nil)
}

// ListenAndServeTLSWithConfig Fully configurable web server listens and then calls Serve on incoming connections
func (wsv *web) ListenAndServeTLSWithConfig(conf *Configuration, tlsConfig *tls.Config) Interface {
	if conf == nil {
		wsv.err = ErrNoConfiguration()
		return wsv
	}
	wsv.conf = conf
	if tlsConfig == nil {
		if tlsConfig, wsv.err = wsv.tlsConfigDefault(conf.TLSPublicKeyPEM, conf.TLSPrivateKeyPEM); wsv.err != nil {
			return wsv
		}
	}

	return wsv.Listen(tlsConfig)
}

// NewListener Make new listener from web server configuration
func (wsv *web) NewListener(conf *Configuration) (ret net.Listener, err error) {
	var (
		lstWithNames map[string][]net.Listener
		listeners    []net.Listener
		ok           bool
	)

	defaultConfiguration(conf)
	switch conf.Mode {
	case netSystemd:
		if conf.Socket != "" {
			// Имена сокетов указаны
			if lstWithNames, err = wsv.ListenersSystemdWithNames(false); err != nil {
				return
			}
			// Выбор сокета по имени
			if listeners, ok = lstWithNames[conf.Socket]; ok {
				err = ErrListenSystemdNotFound()
				return
			}
		} else {
			// Имена сокетов не указаны
			if listeners, err = wsv.ListenersSystemdWithoutNames(false); err != nil {
				return
			}
		}
		if len(listeners) == 0 {
			log.Debug(debug.DumperString(lstWithNames, listeners, os.Environ()))
			err = ErrListenSystemdUnexpectedNumber()
			return
		}
		ret = listeners[0]
	case netUnix, netUnixPacket:
		_ = os.Remove(conf.Socket)
		ret, err = net.Listen(conf.Mode, conf.Socket)
		_ = os.Chmod(conf.Socket, os.FileMode(0666))
	default:
		ret, err = net.Listen(conf.Mode, conf.HostPort)
	}

	return
}

// NewListenerTLS Make new listener with TLS from web server configuration
func (wsv *web) NewListenerTLS(conf *Configuration, tlsConfig *tls.Config) (ret net.Listener, err error) {
	var l net.Listener

	if l, err = wsv.NewListener(conf); err != nil {
		return
	}
	if tlsConfig == nil {
		if tlsConfig, err = wsv.tlsConfigDefault(conf.TLSPublicKeyPEM, conf.TLSPrivateKeyPEM); err != nil {
			return
		}
	}
	ret = tls.NewListener(l, tlsConfig)

	return
}

// Конфигурация TLS по умолчанию
func (wsv *web) tlsConfigDefault(tlsPublicFile string, tlsPrivateFile string) (ret *tls.Config, err error) {
	ret = &tls.Config{
		MinVersion:               tls.VersionTLS12,
		CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
		PreferServerCipherSuites: true,
		CipherSuites: []uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		Certificates: make([]tls.Certificate, 1),
	}
	if ret.Certificates[0], err = tls.LoadX509KeyPair(tlsPublicFile, tlsPrivateFile); err != nil {
		return
	}

	return
}

// Listen Begin listen port and web server serve
func (wsv *web) Listen(tlsConfig *tls.Config) Interface {
	var ltn net.Listener

	if wsv.isRun.Load().(bool) {
		wsv.err = ErrAlreadyRunning()
		return wsv
	}
	switch tlsConfig == nil {
	case true:
		ltn, wsv.err = wsv.NewListener(wsv.conf)
	case false:
		ltn, wsv.err = wsv.NewListenerTLS(wsv.conf, tlsConfig)
	}
	if wsv.err != nil {
		return wsv
	}

	return wsv.ServeTLS(ltn, tlsConfig)
}

// Serve accepts incoming connections on the listener, creating a new web server goroutine
func (wsv *web) Serve(ltn net.Listener) Interface { return wsv.ServeTLS(ltn, nil) }

// ServeTLS accepts incoming connections on the listener with TLS configuration, creating a new web server goroutine
func (wsv *web) ServeTLS(ltn net.Listener, tlsConfig *tls.Config) Interface {
	var conf *Configuration

	// TODO: Реализовать поддержку PROXY Protocol через "gopkg.in/webnice/web.v1/proxyp", conf.ProxyProtocol

	if wsv.conf == nil {
		conf, _ = parseAddress(ltn.Addr().String())
		defaultConfiguration(conf)
		wsv.conf = conf
	}
	wsv.listener = ltn
	wsv.isRun.Store(true)
	wsv.doCloseDone.Add(1)
	go wsv.run(tlsConfig)

	return wsv
}

// Goroutine of the web server
func (wsv *web) run(tlsConfig *tls.Config) {
	defer wsv.doCloseDone.Done()
	defer wsv.isRun.Store(false)
	defer func() {
		if wsv.conf.Socket == "" {
			return
		}
		switch wsv.conf.Mode {
		case netSystemd:
			return
		case netUnix, netUnixPacket:
			_ = os.Remove(wsv.conf.Socket)
		}
	}()

	// Configure net/http web server
	if wsv.server = wsv.loadConfiguration(tlsConfig); wsv.err != nil {
		return
	}
	// Configure keepalive of web server
	if wsv.conf.KeepAliveDisable {
		wsv.server.SetKeepAlivesEnabled(false)
	}
	// Begin serve
	if wsv.conf.TLSPrivateKeyPEM == "" || wsv.conf.TLSPublicKeyPEM == "" {
		wsv.err = wsv.server.Serve(wsv.listener)
		return
	}
	wsv.err = wsv.server.ServeTLS(wsv.listener, wsv.conf.TLSPublicKeyPEM, wsv.conf.TLSPrivateKeyPEM)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
)

const (
	salsaGroupID = 2638
	salsaApiUrl  = "https://salsa.debian.org/api/v4"
)

type gitlabProject struct {
	ID            int    `json:"id"`
	Name          string `json:"name"`
	HttpUrlToRepo string `json:"http_url_to_repo"`
}

func execCreateSalsaProject(args []string) {
	projectName := mustGetProjectName(args)
	token := mustGetSalsaToken()

	gitlabProject, err := createSalsaProject(projectName, token)
	if err != nil {
		log.Fatalf("Could not create %s on salsa: %s\n", projectName, err)
	}

	fmt.Printf("Project %s was created on salsa.debian.org: %s\n",
		gitlabProject.Name,
		gitlabProject.HttpUrlToRepo)

	if err := createSalsaWebhook(gitlabProject.ID,
		"https://webhook.salsa.debian.org/tagpending/"+gitlabProject.Name,
		token); err != nil {
		log.Fatalf("Could not create webhook on salsa project: %s\n", err)
	}

	for _, branch := range []string{"master", "debian/*", "upstream", "upstream/*", "pristine-tar"} {
		if err := protectSalsaProjectBranch(gitlabProject.ID, branch, token); err != nil {
			log.Printf("Could not protect branch %s: %s\n", branch, err)
		}
	}

}

func postFormToSalsaApi(path string, data url.Values, token string) (*http.Response, error) {
	postUrl := salsaApiUrl + path
	data.Add("private_token", token)
	return http.PostForm(postUrl, data)
}

func protectSalsaProjectBranch(projectId int, branch, token string) error {
	postPath := "/projects/" + strconv.Itoa(projectId) + "/protected_branches"

	response, err := postFormToSalsaApi(postPath,
		url.Values{
			"name": {branch},
		},
		token)
	if err != nil {
		return err
	}

	if response.StatusCode != http.StatusCreated {
		responseData, _ := ioutil.ReadAll(response.Body)

		return fmt.Errorf("http status %d: %s",
			response.StatusCode,
			responseData)
	}

	return nil
}

func createSalsaWebhook(projectId int, webhookUrl, token string) error {
	postPath := "/projects/" + strconv.Itoa(projectId) + "/hooks"

	response, err := postFormToSalsaApi(postPath,
		url.Values{
			"url":         {webhookUrl},
			"push_events": {"true"},
		},
		token)
	if err != nil {
		return err
	}

	if response.StatusCode != http.StatusCreated {
		responseData, _ := ioutil.ReadAll(response.Body)

		return fmt.Errorf("http status %d: %s",
			response.StatusCode,
			responseData)
	}

	return nil
}

func mustGetProjectName(args []string) string {
	fs := flag.NewFlagSet("search", flag.ExitOnError)

	if err := fs.Parse(args); err != nil {
		log.Fatal(err)
	}

	if fs.NArg() != 1 {
		log.Printf("Usage: %s create-salsa-project <project-name>\n", os.Args[0])
		log.Fatalf("Example: %s create-salsa-project golang-github-mattn-go-sqlite3\n", os.Args[0])
	}

	projectName := fs.Arg(0)

	return projectName
}

func mustGetSalsaToken() string {
	token := os.Getenv("SALSA_TOKEN")
	if token == "" {
		log.Printf("Please set the SALSA_TOKEN environment variable.\n")
		log.Fatalf("Obtain it from the following page: https://salsa.debian.org/profile/personal_access_tokens\n")
	}
	return token
}

func createSalsaProject(projectName, token string) (*gitlabProject, error) {
	response, err := postFormToSalsaApi("/projects",
		url.Values{
			"private_token": {token},
			"path":          {projectName},
			"namespace_id":  {strconv.Itoa(salsaGroupID)},
			"description":   {fmt.Sprintf("Debian packaging for %s", projectName)},
			"visibility":    {"public"},
		},
		token)
	if err != nil {
		return nil, err
	}

	if response.StatusCode != http.StatusCreated {
		responseData, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return nil, err
		}

		return nil, errors.New(fmt.Sprintf("http status %d: %s", response.StatusCode, responseData))
	}

	var project gitlabProject

	if err := json.NewDecoder(response.Body).Decode(&project); err != nil {
		return nil, err
	}

	return &project, err
}
<commit_msg>create salsa projects via a request to pgt-api-server<commit_after>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
)

func execCreateSalsaProject(args []string) {
	fs := flag.NewFlagSet("search", flag.ExitOnError)

	if err := fs.Parse(args); err != nil {
		log.Fatal(err)
	}

	if fs.NArg() != 1 {
		log.Printf("Usage: %s create-salsa-project <project-name>\n", os.Args[0])
		log.Fatalf("Example: %s create-salsa-project golang-github-mattn-go-sqlite3\n", os.Args[0])
	}

	projectName := fs.Arg(0)

	// The source code of the corresponding server can be found at:
	// https://github.com/Debian/pkg-go-tools/tree/master/cmd/pgt-api-server
	u, _ := url.Parse("https://pgt-api-server.debian.net/v1/createrepo")
	q := u.Query()
	q.Set("repo", projectName)
	u.RawQuery = q.Encode()

	resp, err := http.Post(u.String(), "", nil)
	if err != nil {
		log.Fatal(err)
	}
	if got, want := resp.StatusCode, http.StatusOK; got != want {
		b, _ := ioutil.ReadAll(resp.Body)
		log.Fatalf("unexpected HTTP status code: got %d, want %d (response: %s)", got, want, string(b))
	}
}
<|endoftext|>


<commit_before>package nuance

/*
#cgo CPPFLAGS: -I /usr/local/include/nuance-omnipage-csdk-19.2
#cgo LDFLAGS: -L /usr/local/lib/nuance-omnipage-csdk-lib64-19.2 -lrecapiplus -lkernelapi -lrecpdf -Wl,-rpath-link,/usr/local/lib/nuance-omnipage-csdk-lib64-19.2,-rpath,/usr/local/lib/nuance-omnipage-csdk-lib64-19.2

#include <KernelApi.h>

#include "nuancec.h"
*/
import "C"

import (
	"errors"
	"fmt"
	"io/ioutil"
	"math/rand"
	"os"
	"path"
	"time"
	"unsafe"
)

type nuance struct {
	nuancePtr C.nuancePtr
}

var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func init() {
	rand.Seed(time.Now().UnixNano())
}

func New() (n nuance) {
	n.nuancePtr = C.nuanceNew()
	return
}

func (n *nuance) Free() {
	C.nuanceFree(unsafe.Pointer(n.nuancePtr))
}

func (n *nuance) Init(company string, product string) (err error) {
	errBuff := make([]byte, 1024)
	if C.nuanceInit(
		unsafe.Pointer(n.nuancePtr),
		C.CString(company),
		C.CString(product),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func (n *nuance) SetLicense(licenseFile string, oemCode string) (err error) {
	errBuff := make([]byte, 1024)

	if C.nuanceSetLicense(
		unsafe.Pointer(n.nuancePtr),
		C.CString(licenseFile),
		C.CString(oemCode),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func (n *nuance) Quit() {
	C.nuanceQuit(unsafe.Pointer(n.nuancePtr))
}

func (n *nuance) LoadFormTemplateLibrary(templateFile string) (err error) {
	errBuff := make([]byte, 1024)
	if C.nuanceLoadFormTemplateLibrary(
		unsafe.Pointer(n.nuancePtr),
		C.CString(templateFile),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func (n *nuance) OCRImgWithTemplate(imgFile string) (ret map[string]string, err error) {
	errBuff := make([]byte, 1024)
	ret = make(map[string]string)

	if C.nuancePreprocessImgWithTemplate(
		unsafe.Pointer(n.nuancePtr),
		C.CString(imgFile),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	zoneCount := int(C.nuanceGetZoneCount(unsafe.Pointer(n.nuancePtr)))

	fmt.Println("zoneCount:", zoneCount)

	for i := 0; i < zoneCount; i++ {
		zoneName := make([]byte, 256)
		zoneText := make([]byte, 256)

		C.nuanceGetZoneData(
			unsafe.Pointer(n.nuancePtr),
			C.int(i),
			(*C.char)(unsafe.Pointer(&zoneName[0])),
			C.int(256),
			(*C.char)(unsafe.Pointer(&zoneText[0])),
			C.int(256))

		ret[string(zoneName)] = string(zoneText)
		//fmt.Printf("%s: [%s]\n", string(zoneName), string(zoneText))
	}

	C.nuanceFreeImgWithTemplate(unsafe.Pointer(n.nuancePtr))
	err = nil
	return
}

func (n *nuance) OCRImgToFile(imgFile string,
	outputFile string,
	nPage int,
	auxDocumentFile string) (err error) {
	errBuff := make([]byte, 1024)

	if C.nuanceOCRImgToFile(
		unsafe.Pointer(n.nuancePtr),
		C.CString(imgFile),
		C.CString(outputFile),
		C.int(nPage),
		C.CString(auxDocumentFile),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func randString(n int) string {
	b := make([]rune, n)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

func (n *nuance) OCRImgPageToText(imgFile string,
	nPage int,
) (txt string, err error) {
	randomAux := randString(6)
	tempDir := path.Join(os.TempDir(), randomAux)
	tempFile := fmt.Sprintf("%s.txt", tempDir)
	defer func() {
		os.Remove(tempFile)
		os.RemoveAll(tempDir)
	}()
	err = n.OCRImgToFile(imgFile, tempFile, nPage, tempDir)
	if err != nil {
		fmt.Println(err)
		return "", err
	}
	rawTxt, err := ioutil.ReadFile(tempFile)
	if err != nil {
		fmt.Println(err)
		return "", err
	}
	txt = string(rawTxt)
	return
}

func (n *nuance) OCRImgToText(imgFile string) (txt string, err error) {
	var pages int
	pages, err = n.CountPages(imgFile)
	if err != nil {
		return
	}
	var aux string
	for i := 0; i < pages; i++ {
		aux, err = n.OCRImgPageToText(imgFile, i)
		if err != nil {
			return
		}
		if len(txt) > 0 {
			txt += "\f"
		}
		txt += aux
	}
	return
}

func (n *nuance) SetLanguagePtBr() (err error) {
	errBuff := make([]byte, 1024)

	if C.nuanceSetLanguagePtBr(
		unsafe.Pointer(n.nuancePtr),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func (n *nuance) CountPages(imgFile string) (nPage int, err error) {
	errBuff := make([]byte, 1024)
	nPage = 0

	if C.nuanceCountPages(
		unsafe.Pointer(n.nuancePtr),
		C.CString(imgFile),
		(*C.int)(unsafe.Pointer(&nPage)),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}
<commit_msg>Concat text using line break character<commit_after>package nuance

/*
#cgo CPPFLAGS: -I /usr/local/include/nuance-omnipage-csdk-19.2
#cgo LDFLAGS: -L /usr/local/lib/nuance-omnipage-csdk-lib64-19.2 -lrecapiplus -lkernelapi -lrecpdf -Wl,-rpath-link,/usr/local/lib/nuance-omnipage-csdk-lib64-19.2,-rpath,/usr/local/lib/nuance-omnipage-csdk-lib64-19.2

#include <KernelApi.h>

#include "nuancec.h"
*/
import "C"

import (
	"errors"
	"fmt"
	"io/ioutil"
	"math/rand"
	"os"
	"path"
	"time"
	"unsafe"
)

type nuance struct {
	nuancePtr C.nuancePtr
}

var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func init() {
	rand.Seed(time.Now().UnixNano())
}

func New() (n nuance) {
	n.nuancePtr = C.nuanceNew()
	return
}

func (n *nuance) Free() {
	C.nuanceFree(unsafe.Pointer(n.nuancePtr))
}

func (n *nuance) Init(company string, product string) (err error) {
	errBuff := make([]byte, 1024)
	if C.nuanceInit(
		unsafe.Pointer(n.nuancePtr),
		C.CString(company),
		C.CString(product),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func (n *nuance) SetLicense(licenseFile string, oemCode string) (err error) {
	errBuff := make([]byte, 1024)

	if C.nuanceSetLicense(
		unsafe.Pointer(n.nuancePtr),
		C.CString(licenseFile),
		C.CString(oemCode),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func (n *nuance) Quit() {
	C.nuanceQuit(unsafe.Pointer(n.nuancePtr))
}

func (n *nuance) LoadFormTemplateLibrary(templateFile string) (err error) {
	errBuff := make([]byte, 1024)
	if C.nuanceLoadFormTemplateLibrary(
		unsafe.Pointer(n.nuancePtr),
		C.CString(templateFile),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func (n *nuance) OCRImgWithTemplate(imgFile string) (ret map[string]string, err error) {
	errBuff := make([]byte, 1024)
	ret = make(map[string]string)

	if C.nuancePreprocessImgWithTemplate(
		unsafe.Pointer(n.nuancePtr),
		C.CString(imgFile),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	zoneCount := int(C.nuanceGetZoneCount(unsafe.Pointer(n.nuancePtr)))

	fmt.Println("zoneCount:", zoneCount)

	for i := 0; i < zoneCount; i++ {
		zoneName := make([]byte, 256)
		zoneText := make([]byte, 256)

		C.nuanceGetZoneData(
			unsafe.Pointer(n.nuancePtr),
			C.int(i),
			(*C.char)(unsafe.Pointer(&zoneName[0])),
			C.int(256),
			(*C.char)(unsafe.Pointer(&zoneText[0])),
			C.int(256))

		ret[string(zoneName)] = string(zoneText)
		//fmt.Printf("%s: [%s]\n", string(zoneName), string(zoneText))
	}

	C.nuanceFreeImgWithTemplate(unsafe.Pointer(n.nuancePtr))
	err = nil
	return
}

func (n *nuance) OCRImgToFile(imgFile string,
	outputFile string,
	nPage int,
	auxDocumentFile string) (err error) {
	errBuff := make([]byte, 1024)

	if C.nuanceOCRImgToFile(
		unsafe.Pointer(n.nuancePtr),
		C.CString(imgFile),
		C.CString(outputFile),
		C.int(nPage),
		C.CString(auxDocumentFile),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func randString(n int) string {
	b := make([]rune, n)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

func (n *nuance) OCRImgPageToText(imgFile string,
	nPage int,
) (txt string, err error) {
	randomAux := randString(6)
	tempDir := path.Join(os.TempDir(), randomAux)
	tempFile := fmt.Sprintf("%s.txt", tempDir)
	defer func() {
		os.Remove(tempFile)
		os.RemoveAll(tempDir)
	}()
	err = n.OCRImgToFile(imgFile, tempFile, nPage, tempDir)
	if err != nil {
		fmt.Println(err)
		return "", err
	}
	rawTxt, err := ioutil.ReadFile(tempFile)
	if err != nil {
		fmt.Println(err)
		return "", err
	}
	txt = string(rawTxt)
	return
}

func (n *nuance) OCRImgToText(imgFile string) (txt string, err error) {
	var pages int
	pages, err = n.CountPages(imgFile)
	if err != nil {
		return
	}
	var aux string
	for i := 0; i < pages; i++ {
		aux, err = n.OCRImgPageToText(imgFile, i)
		if err != nil {
			return
		}
		if len(txt) > 0 {
			txt += "\n"
		}
		txt += aux
	}
	return
}

func (n *nuance) SetLanguagePtBr() (err error) {
	errBuff := make([]byte, 1024)

	if C.nuanceSetLanguagePtBr(
		unsafe.Pointer(n.nuancePtr),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}

func (n *nuance) CountPages(imgFile string) (nPage int, err error) {
	errBuff := make([]byte, 1024)
	nPage = 0

	if C.nuanceCountPages(
		unsafe.Pointer(n.nuancePtr),
		C.CString(imgFile),
		(*C.int)(unsafe.Pointer(&nPage)),
		(*C.char)(unsafe.Pointer(&errBuff[0])),
		C.int(len(errBuff))) != 0 {

		err = errors.New(string(errBuff))
		return
	}

	err = nil
	return
}
<|endoftext|>


<commit_before>package skynology

import (
	"fmt"
	"time"
)

// get field value
func (obj *Object) Get(field string) interface{} {
	return obj.data[field]
}

func (obj *Object) GetInt(field string) int {
	v := obj.Get(field)
	return GetInt(v)
}

func (obj *Object) GetInt64(field string) int64 {
	v := obj.Get(field)
	return GetInt64(v)
}

func (obj *Object) GetFloat64(field string) float64 {
	v := obj.Get(field)
	return GetFloat64(v)
}
func (obj *Object) GetString(field string) string {
	v := obj.Get(field)
	return GetString(v)
}
func (obj *Object) GetBool(field string) bool {
	v := obj.Get(field)
	return GetBool(v)
}

func (obj *Object) GetMap(field string) (result map[string]interface{}) {
	if m, ok := obj.Get(field).(map[string]interface{}); ok {
		return m
	}

	return
}

// set field value
func (obj *Object) Set(field string, value interface{}) *Object {
	obj.changedData[field] = value
	return obj
}

// 设置多个
func (obj *Object) SetMulti(data map[string]interface{}) *Object {
	for k, v := range data {
		obj.Set(k, v)
	}

	return obj
}

// 返回查到的数据
// 不包括修改的内容
func (obj *Object) Map() map[string]interface{} {
	return obj.data
}

// increment the give amount
func (obj *Object) Increment(field string) *Object {
	return obj.IncrementWithAmount(field, 1)
}

// increment the give amount
func (obj *Object) IncrementWithAmount(field string, amount int) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "Increment", "amount": amount}
	return obj
}

// add a value to the end of the array field
func (obj *Object) AddValueToArray(field string, value interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "Add", "objects": []interface{}{value}}
	return obj
}

// add a value to the array field, only if it is not already present in the array
func (obj *Object) AddUniqueValueToArray(field string, value interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "AddToUnique", "objects": []interface{}{value}}
	return obj
}

// remove value from array field
func (obj *Object) RemoveValueFromArray(field string, value interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "Remove", "objects": []interface{}{value}}
	return obj
}

// add a values from given list to the field
func (obj *Object) AddValueToArrayFromList(field string, value []interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "Add", "objects": value}
	return obj
}

// add a values from given list to the field, only if it is not already present in the array
func (obj *Object) AddUniqueValueToArrayFromList(field string, value []interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "AddToUnique", "objects": value}
	return obj
}

// remove value from array field
func (obj *Object) RemoveValueFromArrayFromList(field string, value []interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "AddToUnique", "objects": value}
	return obj
}

// update element in array
func (obj *Object) UpdateObjectInArray(query map[string]interface{}, data map[string]interface{}) *Object {
	// just allow update element,
	// so clear all another updates
	obj.changedData = map[string]interface{}{}
	obj.changedData["query"] = query
	obj.changedData["data"] = data
	obj.addtionalURL = "/array"
	return obj
}

// 设置指定用户的读写权限
// 若以往已经有此用户的ACL信息, 将会被覆盖
func (obj *Object) SetReadWriteAccessByUserId(userId string, read bool, write bool) *Object {
	obj.setAccessControl(userId, AccessControlTypeRead, read)
	obj.setAccessControl(userId, AccessControlTypeWrite, write)
	return obj
}

func (obj *Object) SetReadAccessByUserId(userId string, access bool) *Object {
	obj.setAccessControl(userId, AccessControlTypeRead, access)
	return obj
}
func (obj *Object) SetWriteAccessByUserId(userId string, access bool) *Object {
	obj.setAccessControl(userId, AccessControlTypeWrite, access)
	return obj
}

// 用指定角色名来设置读写权限
// 若以往已经有此数据的ACL信息, 将会被覆盖
func (obj *Object) SetReadWriteAccessRoleName(roleName string, read bool, write bool) *Object {
	roleName = "role:" + roleName
	obj.setAccessControl(roleName, AccessControlTypeRead, read)
	obj.setAccessControl(roleName, AccessControlTypeWrite, write)
	return obj
}
func (obj *Object) SetReadAccessByRoleName(roleName string, access bool) *Object {
	roleName = "role:" + roleName
	obj.setAccessControl(roleName, AccessControlTypeRead, access)
	return obj
}
func (obj *Object) SetWriteAccessByRoleName(roleName string, access bool) *Object {
	roleName = "role:" + roleName
	obj.setAccessControl(roleName, AccessControlTypeWrite, access)
	return obj
}
func (obj *Object) setAccessControl(key string, typ AccessControlType, value bool) {
	var acl ACL
	var item ACLItem
	acl, ok := obj.changedData["ACL"].(ACL)
	if !ok {
		acl = ACL{}
	}
	item, ok = acl[key]
	if !ok {
		item = ACLItem{}
	}
	if typ == AccessControlTypeRead {
		item.Read = value
	} else if typ == AccessControlTypeWrite {
		item.Write = value
	}
	acl[key] = item
	obj.changedData["ACL"] = acl
}
func (obj *Object) Save() (bool, *APIError) {
	var m map[string]interface{}
	var err *APIError

	url := fmt.Sprintf("%s/resources/%s", obj.app.baseURL, obj.ResourceName)
	if obj.ObjectId != "" {
		url += "/" + obj.ObjectId
	}
	if obj.addtionalURL != "" {
		url += obj.addtionalURL
	}

	if obj.ObjectId != "" {
		m, err = obj.app.sendPutRequest(url, obj.changedData)
	} else {
		m, err = obj.app.sendPostRequest(url, obj.changedData)
	}

	fmt.Println("save object:", m)

	if err != nil {
		return false, err
	}

	obj.initData(m)

	return true, nil
}

func (obj *Object) Delete() (bool, *APIError) {
	url := fmt.Sprintf("%s/resources/%s/%s", obj.app.baseURL, obj.ResourceName, obj.ObjectId)
	_, err := obj.app.sendDeleteRequest(url, nil)
	if err != nil {
		return false, err
	}

	obj.clear()

	return true, nil

}

func (obj *Object) initData(data map[string]interface{}) {
	obj.changedData = make(map[string]interface{})
	obj.data = data

	if id, ok := data["objectId"]; ok {
		obj.ObjectId = id.(string)
	}

	if acl, ok := data["ACL"].(map[string]interface{}); ok {
		nacl, err := NewACL(acl)
		if err != nil {
			obj.ACL = nacl
		}
	}

	if cd, ok := data["createdAt"]; ok {
		if t, err := time.Parse(time.RFC3339Nano, cd.(string)); err == nil {
			obj.CreatedAt = t
		}
	}

	if ud, ok := data["createdAt"]; ok {
		if t, err := time.Parse(time.RFC3339Nano, ud.(string)); err == nil {
			obj.UpdatedAt = t
		}
	}
}

func (obj *Object) clear() {
	obj.changedData = make(map[string]interface{})
	obj.data = make(map[string]interface{})
	obj.ObjectId = ""
	obj.CreatedAt = time.Time{}
	obj.UpdatedAt = time.Time{}
	obj.ACL = nil
}
<commit_msg>add RemoveObjectFromArray<commit_after>package skynology

import (
	"fmt"
	"time"
)

// get field value
func (obj *Object) Get(field string) interface{} {
	return obj.data[field]
}

func (obj *Object) GetInt(field string) int {
	v := obj.Get(field)
	return GetInt(v)
}

func (obj *Object) GetInt64(field string) int64 {
	v := obj.Get(field)
	return GetInt64(v)
}

func (obj *Object) GetFloat64(field string) float64 {
	v := obj.Get(field)
	return GetFloat64(v)
}
func (obj *Object) GetString(field string) string {
	v := obj.Get(field)
	return GetString(v)
}
func (obj *Object) GetBool(field string) bool {
	v := obj.Get(field)
	return GetBool(v)
}

func (obj *Object) GetMap(field string) (result map[string]interface{}) {
	if m, ok := obj.Get(field).(map[string]interface{}); ok {
		return m
	}

	return
}

// set field value
func (obj *Object) Set(field string, value interface{}) *Object {
	obj.changedData[field] = value
	return obj
}

// 设置多个
func (obj *Object) SetMulti(data map[string]interface{}) *Object {
	for k, v := range data {
		obj.Set(k, v)
	}

	return obj
}

// 返回查到的数据
// 不包括修改的内容
func (obj *Object) Map() map[string]interface{} {
	return obj.data
}

// increment the give amount
func (obj *Object) Increment(field string) *Object {
	return obj.IncrementWithAmount(field, 1)
}

// increment the give amount
func (obj *Object) IncrementWithAmount(field string, amount int) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "Increment", "amount": amount}
	return obj
}

// add a value to the end of the array field
func (obj *Object) AddValueToArray(field string, value interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "Add", "objects": []interface{}{value}}
	return obj
}

// add a value to the array field, only if it is not already present in the array
func (obj *Object) AddUniqueValueToArray(field string, value interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "AddToUnique", "objects": []interface{}{value}}
	return obj
}

// remove value from array field
func (obj *Object) RemoveValueFromArray(field string, value interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "Remove", "objects": []interface{}{value}}
	return obj
}

// add a values from given list to the field
func (obj *Object) AddValueToArrayFromList(field string, value []interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "Add", "objects": value}
	return obj
}

// add a values from given list to the field, only if it is not already present in the array
func (obj *Object) AddUniqueValueToArrayFromList(field string, value []interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "AddToUnique", "objects": value}
	return obj
}

// remove value from array field
func (obj *Object) RemoveValueFromArrayFromList(field string, value []interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "AddToUnique", "objects": value}
	return obj
}

// remove object from array
func (obj *Object) RemoveObjectFromArray(field string, query interface{}) *Object {
	obj.changedData[field] = map[string]interface{}{"__op": "RemoveObject", "query": query}
	return obj
}

// update element in array
func (obj *Object) UpdateObjectInArray(query map[string]interface{}, data map[string]interface{}) *Object {
	// just allow update element,
	// so clear all another updates
	obj.changedData = map[string]interface{}{}
	obj.changedData["query"] = query
	obj.changedData["data"] = data
	obj.addtionalURL = "/array"
	return obj
}

// 设置指定用户的读写权限
// 若以往已经有此用户的ACL信息, 将会被覆盖
func (obj *Object) SetReadWriteAccessByUserId(userId string, read bool, write bool) *Object {
	obj.setAccessControl(userId, AccessControlTypeRead, read)
	obj.setAccessControl(userId, AccessControlTypeWrite, write)
	return obj
}

func (obj *Object) SetReadAccessByUserId(userId string, access bool) *Object {
	obj.setAccessControl(userId, AccessControlTypeRead, access)
	return obj
}
func (obj *Object) SetWriteAccessByUserId(userId string, access bool) *Object {
	obj.setAccessControl(userId, AccessControlTypeWrite, access)
	return obj
}

// 用指定角色名来设置读写权限
// 若以往已经有此数据的ACL信息, 将会被覆盖
func (obj *Object) SetReadWriteAccessRoleName(roleName string, read bool, write bool) *Object {
	roleName = "role:" + roleName
	obj.setAccessControl(roleName, AccessControlTypeRead, read)
	obj.setAccessControl(roleName, AccessControlTypeWrite, write)
	return obj
}
func (obj *Object) SetReadAccessByRoleName(roleName string, access bool) *Object {
	roleName = "role:" + roleName
	obj.setAccessControl(roleName, AccessControlTypeRead, access)
	return obj
}
func (obj *Object) SetWriteAccessByRoleName(roleName string, access bool) *Object {
	roleName = "role:" + roleName
	obj.setAccessControl(roleName, AccessControlTypeWrite, access)
	return obj
}
func (obj *Object) setAccessControl(key string, typ AccessControlType, value bool) {
	var acl ACL
	var item ACLItem
	acl, ok := obj.changedData["ACL"].(ACL)
	if !ok {
		acl = ACL{}
	}
	item, ok = acl[key]
	if !ok {
		item = ACLItem{}
	}
	if typ == AccessControlTypeRead {
		item.Read = value
	} else if typ == AccessControlTypeWrite {
		item.Write = value
	}
	acl[key] = item
	obj.changedData["ACL"] = acl
}
func (obj *Object) Save() (bool, *APIError) {
	var m map[string]interface{}
	var err *APIError

	url := fmt.Sprintf("%s/resources/%s", obj.app.baseURL, obj.ResourceName)
	if obj.ObjectId != "" {
		url += "/" + obj.ObjectId
	}
	if obj.addtionalURL != "" {
		url += obj.addtionalURL
	}

	if obj.ObjectId != "" {
		m, err = obj.app.sendPutRequest(url, obj.changedData)
	} else {
		m, err = obj.app.sendPostRequest(url, obj.changedData)
	}

	fmt.Println("save object:", m)

	if err != nil {
		return false, err
	}

	obj.initData(m)

	return true, nil
}

func (obj *Object) Delete() (bool, *APIError) {
	url := fmt.Sprintf("%s/resources/%s/%s", obj.app.baseURL, obj.ResourceName, obj.ObjectId)
	_, err := obj.app.sendDeleteRequest(url, nil)
	if err != nil {
		return false, err
	}

	obj.clear()

	return true, nil

}

func (obj *Object) initData(data map[string]interface{}) {
	obj.changedData = make(map[string]interface{})
	obj.data = data

	if id, ok := data["objectId"]; ok {
		obj.ObjectId = id.(string)
	}

	if acl, ok := data["ACL"].(map[string]interface{}); ok {
		nacl, err := NewACL(acl)
		if err != nil {
			obj.ACL = nacl
		}
	}

	if cd, ok := data["createdAt"]; ok {
		if t, err := time.Parse(time.RFC3339Nano, cd.(string)); err == nil {
			obj.CreatedAt = t
		}
	}

	if ud, ok := data["createdAt"]; ok {
		if t, err := time.Parse(time.RFC3339Nano, ud.(string)); err == nil {
			obj.UpdatedAt = t
		}
	}
}

func (obj *Object) clear() {
	obj.changedData = make(map[string]interface{})
	obj.data = make(map[string]interface{})
	obj.ObjectId = ""
	obj.CreatedAt = time.Time{}
	obj.UpdatedAt = time.Time{}
	obj.ACL = nil
}
<|endoftext|>