<commit_before>package ethui

import (
	"bitbucket.org/kardianos/osext"
	"fmt"
	"github.com/ethereum/eth-go"
	"github.com/ethereum/eth-go/ethchain"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/ethereum/go-ethereum/utils"
	"github.com/go-qml/qml"
	"os"
	"path"
	"path/filepath"
	"runtime"
)

type memAddr struct {
	Num   string
	Value string
}

// UI Library that has some basic functionality exposed
type UiLib struct {
	engine    *qml.Engine
	eth       *eth.Ethereum
	connected bool
	assetPath string
	// The main application window
	win *qml.Window
	Db  *Debugger
}

func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
	if assetPath == "" {
		assetPath = DefaultAssetPath()
	}
	return &UiLib{engine: engine, eth: eth, assetPath: assetPath}
}

// Opens a QML file (external application)
func (ui *UiLib) Open(path string) {
	component, err := ui.engine.LoadFile(path[7:])
	if err != nil {
		ethutil.Config.Log.Debugln(err)
	}
	win := component.CreateWindow(nil)

	go func() {
		win.Show()
		win.Wait()
	}()
}

func (ui *UiLib) OpenHtml(path string) {
	component, err := ui.engine.LoadFile(ui.AssetPath("qml/webapp.qml"))
	if err != nil {
		ethutil.Config.Log.Debugln(err)

		return
	}
	win := component.CreateWindow(nil)
	if filepath.Ext(path) == "eth" {
		fmt.Println("Ethereum package not yet supported")

		return

		// TODO
		ethutil.OpenPackage(path)
	}
	win.Set("url", path)

	go func() {
		win.Show()
		win.Wait()
	}()
}

func (ui *UiLib) Connect(button qml.Object) {
	if !ui.connected {
		ui.eth.Start()
		ui.connected = true
		button.Set("enabled", false)
	}
}

func (ui *UiLib) ConnectToPeer(addr string) {
	ui.eth.ConnectToPeer(addr)
}

func (ui *UiLib) AssetPath(p string) string {
	return path.Join(ui.assetPath, p)
}

func DefaultAssetPath() string {
	var base string
	// If the current working directory is the go-ethereum dir
	// assume a debug build and use the source directory as
	// asset directory.
	pwd, _ := os.Getwd()
	if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "ethereal") {
		base = path.Join(pwd, "assets")
	} else {
		switch runtime.GOOS {
		case "darwin":
			// Get Binary Directory
			exedir, _ := osext.ExecutableFolder()
			base = filepath.Join(exedir, "../Resources")
		case "linux":
			base = "/usr/share/ethereal"
		case "window":
			fallthrough
		default:
			base = "."
		}
	}

	return base
}

func (ui *UiLib) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string) {
	state := ui.eth.BlockChain().CurrentBlock.State()

	mainInput, _ := ethutil.PreProcess(data)
	callerScript, err := utils.Compile(mainInput)
	if err != nil {
		ethutil.Config.Log.Debugln(err)

		return
	}

	dis := ethchain.Disassemble(callerScript)
	ui.win.Root().Call("clearAsm")

	for _, str := range dis {
		ui.win.Root().Call("setAsm", str)
	}
	callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), ethutil.Big(gasStr), ethutil.Big(gasPriceStr), callerScript, nil)

	// Contract addr as test address
	keyPair := ethutil.Config.Db.GetKeys()[0]
	account := ui.eth.StateManager().GetAddrState(keyPair.Address()).Object
	c := ethchain.MakeContract(callerTx, state)
	callerClosure := ethchain.NewClosure(account, c, c.Script(), state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr), ethutil.Big(valueStr))

	block := ui.eth.BlockChain().CurrentBlock
	vm := ethchain.NewVm(state, ethchain.RuntimeVars{
		Origin:      account.Address(),
		BlockNumber: block.BlockInfo().Number,
		PrevHash:    block.PrevHash,
		Coinbase:    block.Coinbase,
		Time:        block.Time,
		Diff:        block.Difficulty,
		TxData:      nil,
	})

	go func() {
		callerClosure.Call(vm, nil, ui.Db.halting)

		state.Reset()
	}()
}

func (ui *UiLib) Next() {
	ui.Db.Next()
}

type Debugger struct {
	win *qml.Window
	N   chan bool
}

func (d *Debugger) halting(pc int, op ethchain.OpCode, mem *ethchain.Memory, stack *ethchain.Stack) {
	d.win.Root().Call("setInstruction", pc)
	d.win.Root().Call("clearMem")
	d.win.Root().Call("clearStack")

	addr := 0
	for i := 0; i+32 <= mem.Len(); i += 32 {
		d.win.Root().Call("setMem", memAddr{fmt.Sprintf("%03d", addr), fmt.Sprintf("% x", mem.Data()[i:i+32])})
		addr++
	}

	for _, val := range stack.Data() {
		d.win.Root().Call("setStack", val.String())
	}

out:
	for {
		select {
		case <-d.N:
			break out
		default:
		}
	}
}

func (d *Debugger) Next() {
	d.N <- true
}
<commit_msg>Added new block sub for webapp<commit_after>package ethui

import (
	"bitbucket.org/kardianos/osext"
	"fmt"
	"github.com/ethereum/eth-go"
	"github.com/ethereum/eth-go/ethchain"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/ethereum/go-ethereum/utils"
	"github.com/go-qml/qml"
	"os"
	"path"
	"path/filepath"
	"runtime"
)

type memAddr struct {
	Num   string
	Value string
}

// UI Library that has some basic functionality exposed
type UiLib struct {
	engine    *qml.Engine
	eth       *eth.Ethereum
	connected bool
	assetPath string
	// The main application window
	win *qml.Window
	Db  *Debugger
}

func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
	if assetPath == "" {
		assetPath = DefaultAssetPath()
	}
	return &UiLib{engine: engine, eth: eth, assetPath: assetPath}
}

// Opens a QML file (external application)
func (ui *UiLib) Open(path string) {
	component, err := ui.engine.LoadFile(path[7:])
	if err != nil {
		ethutil.Config.Log.Debugln(err)
	}
	win := component.CreateWindow(nil)

	go func() {
		win.Show()
		win.Wait()
	}()
}

func (ui *UiLib) OpenHtml(path string) {
	component, err := ui.engine.LoadFile(ui.AssetPath("qml/webapp.qml"))
	if err != nil {
		ethutil.Config.Log.Debugln(err)

		return
	}
	win := component.CreateWindow(nil)
	if filepath.Ext(path) == "eth" {
		fmt.Println("Ethereum package not yet supported")

		return

		// TODO
		ethutil.OpenPackage(path)
	}
	win.Set("url", path)

	go func() {
		blockChan := make(chan ethutil.React, 1)
		quitChan := make(chan bool)

		go func() {
		out:
			for {
				select {
				case <-quitChan:
					ui.eth.Reactor().Unsubscribe("newBlock", blockChan)
					break out
				case block := <-blockChan:
					if block, ok := block.Resource.(*ethchain.Block); ok {
						b := &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
						win.ObjectByName("webView").Call("onNewBlockCb", b)
					}
				}
			}

			// Clean up
			close(blockChan)
			close(quitChan)
		}()
		ui.eth.Reactor().Subscribe("newBlock", blockChan)

		win.Show()
		win.Wait()

		quitChan <- true
	}()
}

func (ui *UiLib) Connect(button qml.Object) {
	if !ui.connected {
		ui.eth.Start()
		ui.connected = true
		button.Set("enabled", false)
	}
}

func (ui *UiLib) ConnectToPeer(addr string) {
	ui.eth.ConnectToPeer(addr)
}

func (ui *UiLib) AssetPath(p string) string {
	return path.Join(ui.assetPath, p)
}

func DefaultAssetPath() string {
	var base string
	// If the current working directory is the go-ethereum dir
	// assume a debug build and use the source directory as
	// asset directory.
	pwd, _ := os.Getwd()
	if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "ethereal") {
		base = path.Join(pwd, "assets")
	} else {
		switch runtime.GOOS {
		case "darwin":
			// Get Binary Directory
			exedir, _ := osext.ExecutableFolder()
			base = filepath.Join(exedir, "../Resources")
		case "linux":
			base = "/usr/share/ethereal"
		case "window":
			fallthrough
		default:
			base = "."
		}
	}

	return base
}

func (ui *UiLib) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string) {
	state := ui.eth.BlockChain().CurrentBlock.State()

	mainInput, _ := ethutil.PreProcess(data)
	callerScript, err := utils.Compile(mainInput)
	if err != nil {
		ethutil.Config.Log.Debugln(err)

		return
	}

	dis := ethchain.Disassemble(callerScript)
	ui.win.Root().Call("clearAsm")

	for _, str := range dis {
		ui.win.Root().Call("setAsm", str)
	}
	callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), ethutil.Big(gasStr), ethutil.Big(gasPriceStr), callerScript, nil)

	// Contract addr as test address
	keyPair := ethutil.Config.Db.GetKeys()[0]
	account := ui.eth.StateManager().GetAddrState(keyPair.Address()).Object
	c := ethchain.MakeContract(callerTx, state)
	callerClosure := ethchain.NewClosure(account, c, c.Script(), state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr), ethutil.Big(valueStr))

	block := ui.eth.BlockChain().CurrentBlock
	vm := ethchain.NewVm(state, ethchain.RuntimeVars{
		Origin:      account.Address(),
		BlockNumber: block.BlockInfo().Number,
		PrevHash:    block.PrevHash,
		Coinbase:    block.Coinbase,
		Time:        block.Time,
		Diff:        block.Difficulty,
		TxData:      nil,
	})

	go func() {
		callerClosure.Call(vm, nil, ui.Db.halting)

		state.Reset()
	}()
}

func (ui *UiLib) Next() {
	ui.Db.Next()
}

type Debugger struct {
	win *qml.Window
	N   chan bool
}

func (d *Debugger) halting(pc int, op ethchain.OpCode, mem *ethchain.Memory, stack *ethchain.Stack) {
	d.win.Root().Call("setInstruction", pc)
	d.win.Root().Call("clearMem")
	d.win.Root().Call("clearStack")

	addr := 0
	for i := 0; i+32 <= mem.Len(); i += 32 {
		d.win.Root().Call("setMem", memAddr{fmt.Sprintf("%03d", addr), fmt.Sprintf("% x", mem.Data()[i:i+32])})
		addr++
	}

	for _, val := range stack.Data() {
		d.win.Root().Call("setStack", val.String())
	}

out:
	for {
		select {
		case <-d.N:
			break out
		default:
		}
	}
}

func (d *Debugger) Next() {
	d.N <- true
}
<|endoftext|>


<commit_before>package main

var UsageConnect = `'alias' or 'transport://[addr][/path]/targetcall[?params...]'

transport:
  winmor:     WINMOR TNC
  ardop:      ARDOP TNC
  ax25:       AX.25 (Linux only)
  telnet:     TCP/IP
  serial-tnc: Serial AX.25 TNC

addr:
  Used to address the transport device, _not_ to be confused with the connection
   PATH. Format: [user[:pass]@]host[:port]

  telnet:       [user:pass]@host:port
  ax25:         (optional) host=axport

path:
  The last element of the path is the target station's callsign. If the path has
   multiple hops (e.g. AX.25), they are separated by '/'.

params:
  ?freq=        Sets QSY frequency (winmor and ardop only)
`
var ExampleConnect = `
  connect telnet                     (alias) Connect to one of the Winlink Common Message Servers via tcp.
  connect ax25:///LA1B-10            Connect to the RMS Gateway LA1B-10 using Linux AX.25 on the default axport.
  connect ax25://tmd710/LA1B-10      Connect to the RMS Gateway LA1B-10 using Linux AX.25 on axport 'tmd710'.
  connect ax25:///LA1B/LA5NTA        Peer-to-peer connection with LA5NTA via LA1B digipeater.
  connect winmor:///LA3F             Connect to the RMS HF Gateway LA3F using WINMOR TNC on default tcp address and port.
  connect winmor:///LA3F?freq=5350   Same as above, but set dial frequency of the radio using rigcontrol.
  connect ardop:///LA3F              Connect to the RMS HF Gateway LA3F using ARDOP on the default tcp address and port.
  connect ardop:///LA3F?freq=5350    Same as above, but set dial frequency of the radio using rigcontrol.
  connect serial-tnc:///LA1B-10      Connect to the RMS Gateway LA1B-10 over a AX.25 serial TNC on the default serial port.
`
<commit_msg>cmd/wl2k: Update usage<commit_after>package main

var UsageConnect = `'alias' or 'transport://[addr][/path]/targetcall[?params...]'

transport:
  winmor:     WINMOR TNC
  ardop:      ARDOP TNC
  ax25:       AX.25 (Linux only)
  telnet:     TCP/IP
  serial-tnc: Serial AX.25 TNC

addr:
  Used to address the transport device, _not_ to be confused with the connection
   PATH. Format: [user[:pass]@]host[:port]

  telnet:       [user:pass]@host:port
  ax25:         (optional) host=axport

path:
  The last element of the path is the target station's callsign. If the path has
   multiple hops (e.g. AX.25), they are separated by '/'.

params:
  ?freq=        Sets QSY frequency (winmor, ardop and ax25 only)
`
var ExampleConnect = `
  connect telnet                     (alias) Connect to one of the Winlink Common Message Servers via tcp.
  connect ax25:///LA1B-10            Connect to the RMS Gateway LA1B-10 using Linux AX.25 on the default axport.
  connect ax25://tmd710/LA1B-10      Connect to the RMS Gateway LA1B-10 using Linux AX.25 on axport 'tmd710'.
  connect ax25:///LA1B/LA5NTA        Peer-to-peer connection with LA5NTA via LA1B digipeater.
  connect winmor:///LA3F             Connect to the RMS HF Gateway LA3F using WINMOR TNC on default tcp address and port.
  connect winmor:///LA3F?freq=5350   Same as above, but set dial frequency of the radio using rigcontrol.
  connect ardop:///LA3F              Connect to the RMS HF Gateway LA3F using ARDOP on the default tcp address and port.
  connect ardop:///LA3F?freq=5350    Same as above, but set dial frequency of the radio using rigcontrol.
  connect serial-tnc:///LA1B-10      Connect to the RMS Gateway LA1B-10 over a AX.25 serial TNC on the default serial port.
`
<|endoftext|>


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

// Package wav provides WAV (RIFF) decoder.
package wav

import (
	"bytes"
	"fmt"
	"io"

	"github.com/hajimehoshi/ebiten/v2/audio"
	"github.com/hajimehoshi/ebiten/v2/audio/internal/convert"
)

// Stream is a decoded audio stream.
type Stream struct {
	inner io.ReadSeeker
	size  int64
}

// Read is implementation of io.Reader's Read.
func (s *Stream) Read(p []byte) (int, error) {
	return s.inner.Read(p)
}

// Seek is implementation of io.Seeker's Seek.
//
// Note that Seek can take long since decoding is a relatively heavy task.
func (s *Stream) Seek(offset int64, whence int) (int64, error) {
	return s.inner.Seek(offset, whence)
}

// Length returns the size of decoded stream in bytes.
func (s *Stream) Length() int64 {
	return s.size
}

type stream struct {
	src        io.ReadSeeker
	headerSize int64
	dataSize   int64
	remaining  int64
}

// Read is implementation of io.Reader's Read.
func (s *stream) Read(p []byte) (int, error) {
	if s.remaining <= 0 {
		return 0, io.EOF
	}
	if s.remaining < int64(len(p)) {
		p = p[0:s.remaining]
	}
	n, err := s.src.Read(p)
	s.remaining -= int64(n)
	return n, err
}

// Seek is implementation of io.Seeker's Seek.
func (s *stream) Seek(offset int64, whence int) (int64, error) {
	switch whence {
	case io.SeekStart:
		offset = offset + s.headerSize
	case io.SeekCurrent:
	case io.SeekEnd:
		offset = s.headerSize + s.dataSize + offset
		whence = io.SeekStart
	}
	n, err := s.src.Seek(offset, whence)
	if err != nil {
		return 0, err
	}
	if n-s.headerSize < 0 {
		return 0, fmt.Errorf("wav: invalid offset")
	}
	s.remaining = s.dataSize - (n - s.headerSize)
	// There could be a tail in wav file.
	if s.remaining < 0 {
		s.remaining = 0
		return s.dataSize, nil
	}
	return n - s.headerSize, nil
}

// DecodeWithSampleRate decodes WAV (RIFF) data to playable stream.
//
// The format must be 1 or 2 channels, 8bit or 16bit little endian PCM.
// The format is converted into 2 channels and 16bit.
//
// DecodeWithSampleRate returns error when decoding fails or IO error happens.
//
// DecodeWithSampleRate automatically resamples the stream to fit with sampleRate if necessary.
//
// A Stream doesn't close src even if src implements io.Closer.
// Closing the source is src owner's responsibility.
func DecodeWithSampleRate(sampleRate int, src io.ReadSeeker) (*Stream, error) {
	buf := make([]byte, 12)
	n, err := io.ReadFull(src, buf)
	if n != len(buf) {
		return nil, fmt.Errorf("wav: invalid header")
	}
	if err != nil {
		return nil, err
	}
	if !bytes.Equal(buf[0:4], []byte("RIFF")) {
		return nil, fmt.Errorf("wav: invalid header: 'RIFF' not found")
	}
	if !bytes.Equal(buf[8:12], []byte("WAVE")) {
		return nil, fmt.Errorf("wav: invalid header: 'WAVE' not found")
	}

	// Read chunks
	dataSize := int64(0)
	headerSize := int64(len(buf))
	sampleRateFrom := 0
	sampleRateTo := 0
	mono := false
	bitsPerSample := 0
chunks:
	for {
		buf := make([]byte, 8)
		n, err := io.ReadFull(src, buf)
		if n != len(buf) {
			return nil, fmt.Errorf("wav: invalid header")
		}
		if err != nil {
			return nil, err
		}
		headerSize += 8
		size := int64(buf[4]) | int64(buf[5])<<8 | int64(buf[6])<<16 | int64(buf[7])<<24
		switch {
		case bytes.Equal(buf[0:4], []byte("fmt ")):
			// Size of 'fmt' header is usually 16, but can be more than 16.
			if size < 16 {
				return nil, fmt.Errorf("wav: invalid header: maybe non-PCM file?")
			}
			buf := make([]byte, size)
			n, err := io.ReadFull(src, buf)
			if n != len(buf) {
				return nil, fmt.Errorf("wav: invalid header")
			}
			if err != nil {
				return nil, err
			}
			format := int(buf[0]) | int(buf[1])<<8
			if format != 1 {
				return nil, fmt.Errorf("wav: format must be linear PCM")
			}
			channelNum := int(buf[2]) | int(buf[3])<<8
			switch channelNum {
			case 1:
				mono = true
			case 2:
				mono = false
			default:
				return nil, fmt.Errorf("wav: channel num must be 1 or 2 but was %d", channelNum)
			}
			bitsPerSample = int(buf[14]) | int(buf[15])<<8
			if bitsPerSample != 8 && bitsPerSample != 16 {
				return nil, fmt.Errorf("wav: bits per sample must be 8 or 16 but was %d", bitsPerSample)
			}
			origSampleRate := int64(buf[4]) | int64(buf[5])<<8 | int64(buf[6])<<16 | int64(buf[7])<<24
			if int64(sampleRate) != origSampleRate {
				sampleRateFrom = int(origSampleRate)
				sampleRateTo = sampleRate
			}
			headerSize += size
		case bytes.Equal(buf[0:4], []byte("data")):
			dataSize = size
			break chunks
		default:
			buf := make([]byte, size)
			n, err := io.ReadFull(src, buf)
			if n != len(buf) {
				return nil, fmt.Errorf("wav: invalid header")
			}
			if err != nil {
				return nil, err
			}
			headerSize += size
		}
	}
	var s io.ReadSeeker = &stream{
		src:        src,
		headerSize: headerSize,
		dataSize:   dataSize,
		remaining:  dataSize,
	}

	if mono || bitsPerSample != 16 {
		s = convert.NewStereo16(s, mono, bitsPerSample != 16)
		if mono {
			dataSize *= 2
		}
		if bitsPerSample != 16 {
			dataSize *= 2
		}
	}
	if sampleRateFrom != sampleRateTo {
		r := convert.NewResampling(s, dataSize, sampleRateFrom, sampleRateTo)
		s = r
		dataSize = r.Length()
	}
	ss := &Stream{inner: s, size: dataSize}
	return ss, nil
}

// Decode decodes WAV (RIFF) data to playable stream.
//
// The format must be 1 or 2 channels, 8bit or 16bit little endian PCM.
// The format is converted into 2 channels and 16bit.
//
// Decode returns error when decoding fails or IO error happens.
//
// Decode automatically resamples the stream to fit with the audio context if necessary.
//
// A Stream doesn't close src even if src implements io.Closer.
// Closing the source is src owner's responsibility.
//
// Deprecated: as of v2.1. Use DecodeWithSampleRate instead.
func Decode(context *audio.Context, src io.ReadSeeker) (*Stream, error) {
	return DecodeWithSampleRate(context.SampleRate(), src)
}
<commit_msg>audio/wav: Accept io.Reader instead of io.ReadSeeker<commit_after>// Copyright 2016 Hajime Hoshi
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package wav provides WAV (RIFF) decoder.
package wav

import (
	"bytes"
	"fmt"
	"io"

	"github.com/hajimehoshi/ebiten/v2/audio"
	"github.com/hajimehoshi/ebiten/v2/audio/internal/convert"
)

// Stream is a decoded audio stream.
type Stream struct {
	inner io.ReadSeeker
	size  int64
}

// Read is implementation of io.Reader's Read.
func (s *Stream) Read(p []byte) (int, error) {
	return s.inner.Read(p)
}

// Seek is implementation of io.Seeker's Seek.
//
// Note that Seek can take long since decoding is a relatively heavy task.
//
// If the underlying source is not an io.Seeker, Seek panics.
func (s *Stream) Seek(offset int64, whence int) (int64, error) {
	return s.inner.Seek(offset, whence)
}

// Length returns the size of decoded stream in bytes.
func (s *Stream) Length() int64 {
	return s.size
}

type stream struct {
	src        io.Reader
	headerSize int64
	dataSize   int64
	remaining  int64
}

// Read is implementation of io.Reader's Read.
func (s *stream) Read(p []byte) (int, error) {
	if s.remaining <= 0 {
		return 0, io.EOF
	}
	if s.remaining < int64(len(p)) {
		p = p[0:s.remaining]
	}
	n, err := s.src.Read(p)
	s.remaining -= int64(n)
	return n, err
}

// Seek is implementation of io.Seeker's Seek.
//
// If the underlying source is not an io.Seeker, Seek panics.
func (s *stream) Seek(offset int64, whence int) (int64, error) {
	seeker, ok := s.src.(io.Seeker)
	if !ok {
		panic("wav: s.src must be io.Seeker but not")
	}

	switch whence {
	case io.SeekStart:
		offset = offset + s.headerSize
	case io.SeekCurrent:
	case io.SeekEnd:
		offset = s.headerSize + s.dataSize + offset
		whence = io.SeekStart
	}
	n, err := seeker.Seek(offset, whence)
	if err != nil {
		return 0, err
	}
	if n-s.headerSize < 0 {
		return 0, fmt.Errorf("wav: invalid offset")
	}
	s.remaining = s.dataSize - (n - s.headerSize)
	// There could be a tail in wav file.
	if s.remaining < 0 {
		s.remaining = 0
		return s.dataSize, nil
	}
	return n - s.headerSize, nil
}

// DecodeWithSampleRate decodes WAV (RIFF) data to playable stream.
//
// The format must be 1 or 2 channels, 8bit or 16bit little endian PCM.
// The format is converted into 2 channels and 16bit.
//
// DecodeWithSampleRate returns error when decoding fails or IO error happens.
//
// DecodeWithSampleRate automatically resamples the stream to fit with sampleRate if necessary.
//
// The returned Stream's Seek is available only when src is an io.Seeker.
//
// A Stream doesn't close src even if src implements io.Closer.
// Closing the source is src owner's responsibility.
func DecodeWithSampleRate(sampleRate int, src io.Reader) (*Stream, error) {
	buf := make([]byte, 12)
	n, err := io.ReadFull(src, buf)
	if n != len(buf) {
		return nil, fmt.Errorf("wav: invalid header")
	}
	if err != nil {
		return nil, err
	}
	if !bytes.Equal(buf[0:4], []byte("RIFF")) {
		return nil, fmt.Errorf("wav: invalid header: 'RIFF' not found")
	}
	if !bytes.Equal(buf[8:12], []byte("WAVE")) {
		return nil, fmt.Errorf("wav: invalid header: 'WAVE' not found")
	}

	// Read chunks
	dataSize := int64(0)
	headerSize := int64(len(buf))
	sampleRateFrom := 0
	sampleRateTo := 0
	mono := false
	bitsPerSample := 0
chunks:
	for {
		buf := make([]byte, 8)
		n, err := io.ReadFull(src, buf)
		if n != len(buf) {
			return nil, fmt.Errorf("wav: invalid header")
		}
		if err != nil {
			return nil, err
		}
		headerSize += 8
		size := int64(buf[4]) | int64(buf[5])<<8 | int64(buf[6])<<16 | int64(buf[7])<<24
		switch {
		case bytes.Equal(buf[0:4], []byte("fmt ")):
			// Size of 'fmt' header is usually 16, but can be more than 16.
			if size < 16 {
				return nil, fmt.Errorf("wav: invalid header: maybe non-PCM file?")
			}
			buf := make([]byte, size)
			n, err := io.ReadFull(src, buf)
			if n != len(buf) {
				return nil, fmt.Errorf("wav: invalid header")
			}
			if err != nil {
				return nil, err
			}
			format := int(buf[0]) | int(buf[1])<<8
			if format != 1 {
				return nil, fmt.Errorf("wav: format must be linear PCM")
			}
			channelNum := int(buf[2]) | int(buf[3])<<8
			switch channelNum {
			case 1:
				mono = true
			case 2:
				mono = false
			default:
				return nil, fmt.Errorf("wav: channel num must be 1 or 2 but was %d", channelNum)
			}
			bitsPerSample = int(buf[14]) | int(buf[15])<<8
			if bitsPerSample != 8 && bitsPerSample != 16 {
				return nil, fmt.Errorf("wav: bits per sample must be 8 or 16 but was %d", bitsPerSample)
			}
			origSampleRate := int64(buf[4]) | int64(buf[5])<<8 | int64(buf[6])<<16 | int64(buf[7])<<24
			if int64(sampleRate) != origSampleRate {
				sampleRateFrom = int(origSampleRate)
				sampleRateTo = sampleRate
			}
			headerSize += size
		case bytes.Equal(buf[0:4], []byte("data")):
			dataSize = size
			break chunks
		default:
			buf := make([]byte, size)
			n, err := io.ReadFull(src, buf)
			if n != len(buf) {
				return nil, fmt.Errorf("wav: invalid header")
			}
			if err != nil {
				return nil, err
			}
			headerSize += size
		}
	}
	var s io.ReadSeeker = &stream{
		src:        src,
		headerSize: headerSize,
		dataSize:   dataSize,
		remaining:  dataSize,
	}

	if mono || bitsPerSample != 16 {
		s = convert.NewStereo16(s, mono, bitsPerSample != 16)
		if mono {
			dataSize *= 2
		}
		if bitsPerSample != 16 {
			dataSize *= 2
		}
	}
	if sampleRateFrom != sampleRateTo {
		r := convert.NewResampling(s, dataSize, sampleRateFrom, sampleRateTo)
		s = r
		dataSize = r.Length()
	}
	ss := &Stream{inner: s, size: dataSize}
	return ss, nil
}

// Decode decodes WAV (RIFF) data to playable stream.
//
// The format must be 1 or 2 channels, 8bit or 16bit little endian PCM.
// The format is converted into 2 channels and 16bit.
//
// Decode returns error when decoding fails or IO error happens.
//
// Decode automatically resamples the stream to fit with the audio context if necessary.
//
// The returned Stream's Seek is available only when src is an io.Seeker.
//
// A Stream doesn't close src even if src implements io.Closer.
// Closing the source is src owner's responsibility.
//
// Deprecated: as of v2.1. Use DecodeWithSampleRate instead.
func Decode(context *audio.Context, src io.Reader) (*Stream, error) {
	return DecodeWithSampleRate(context.SampleRate(), src)
}
<|endoftext|>


<commit_before>package restfulspec

import (
	"net/http"
	"reflect"
	"strings"

	restful "github.com/emicklei/go-restful"
	"github.com/go-openapi/spec"
)

// KeyOpenAPITags is a Metadata key for a restful Route
const KeyOpenAPITags = "openapi.tags"

func buildPaths(ws *restful.WebService, cfg Config) spec.Paths {
	p := spec.Paths{Paths: map[string]spec.PathItem{}}
	for _, each := range ws.Routes() {
		existingPathItem, ok := p.Paths[each.Path]
		if !ok {
			existingPathItem = spec.PathItem{}
		}
		p.Paths[each.Path] = buildPathItem(ws, each, existingPathItem, cfg)
	}
	return p
}

func buildPathItem(ws *restful.WebService, r restful.Route, existingPathItem spec.PathItem, cfg Config) spec.PathItem {
	op := buildOperation(ws, r, cfg)
	switch r.Method {
	case "GET":
		existingPathItem.Get = op
	case "POST":
		existingPathItem.Post = op
	case "PUT":
		existingPathItem.Put = op
	case "DELETE":
		existingPathItem.Delete = op
	case "PATCH":
		existingPathItem.Patch = op
	case "OPTIONS":
		existingPathItem.Options = op
	case "HEAD":
		existingPathItem.Head = op
	}
	return existingPathItem
}

func buildOperation(ws *restful.WebService, r restful.Route, cfg Config) *spec.Operation {
	o := spec.NewOperation(r.Operation)
	o.Description = r.Doc
	// take the first line to be the summary
	if lines := strings.Split(r.Doc, "\n"); len(lines) > 0 {
		o.Summary = lines[0]
	}
	o.Consumes = r.Consumes
	o.Produces = r.Produces
	if r.Metadata != nil {
		if tags, ok := r.Metadata[KeyOpenAPITags]; ok {
			if tagList, ok := tags.([]string); ok {
				o.Tags = tagList
			}
		}
	}
	// collect any path parameters
	for _, param := range ws.PathParameters() {
		o.Parameters = append(o.Parameters, buildParameter(r, param, cfg))
	}
	// route specific params
	for _, each := range r.ParameterDocs {
		o.Parameters = append(o.Parameters, buildParameter(r, each, cfg))
	}
	o.Responses = new(spec.Responses)
	props := &o.Responses.ResponsesProps
	props.StatusCodeResponses = map[int]spec.Response{}
	for k, v := range r.ResponseErrors {
		r := buildResponse(v, cfg)
		props.StatusCodeResponses[k] = r
		if 200 == k { // any 2xx code?
			o.Responses.Default = &r
		}
	}
	if len(o.Responses.StatusCodeResponses) == 0 {
		o.Responses.StatusCodeResponses[200] = spec.Response{ResponseProps: spec.ResponseProps{Description: http.StatusText(http.StatusOK)}}
	}
	return o
}

func buildParameter(r restful.Route, restfulParam *restful.Parameter, cfg Config) spec.Parameter {
	p := spec.Parameter{}
	param := restfulParam.Data()
	p.In = asParamType(param.Kind)
	p.Type = param.DataType
	p.Description = param.Description
	p.Name = param.Name
	p.Required = param.Required
	p.Default = param.DefaultValue
	p.Format = param.DataFormat
	if p.In == "body" && r.ReadSample != nil && p.Type == reflect.TypeOf(r.ReadSample).String() {
		p.Schema = new(spec.Schema)
		p.Schema.Ref = spec.MustCreateRef("#/definitions/" + p.Type)
	}
	return p
}

func buildResponse(e restful.ResponseError, cfg Config) (r spec.Response) {
	r.Description = e.Message
	if e.Model != nil {
		st := reflect.TypeOf(e.Model)
		if st.Kind() == reflect.Ptr {
			// For pointer type, use element type as the key; otherwise we'll
			// endup with '#/definitions/*Type' which violates openapi spec.
			st = st.Elem()
		}
		r.Schema = new(spec.Schema)
		if st.Kind() == reflect.Array || st.Kind() == reflect.Slice {
			modelName := definitionBuilder{}.keyFrom(st.Elem())
			r.Schema.Type = []string{"array"}
			r.Schema.Items = &spec.SchemaOrArray{
				Schema: &spec.Schema{},
			}
			r.Schema.Items.Schema.Ref = spec.MustCreateRef("#/definitions/" + modelName)
		} else {
			modelName := definitionBuilder{}.keyFrom(st)
			r.Schema.Ref = spec.MustCreateRef("#/definitions/" + modelName)
		}
	}
	return r
}
<commit_msg>use correct types in query parameters<commit_after>package restfulspec

import (
	"net/http"
	"reflect"
	"strconv"
	"strings"

	restful "github.com/emicklei/go-restful"
	"github.com/go-openapi/spec"
)

// KeyOpenAPITags is a Metadata key for a restful Route
const KeyOpenAPITags = "openapi.tags"

func buildPaths(ws *restful.WebService, cfg Config) spec.Paths {
	p := spec.Paths{Paths: map[string]spec.PathItem{}}
	for _, each := range ws.Routes() {
		existingPathItem, ok := p.Paths[each.Path]
		if !ok {
			existingPathItem = spec.PathItem{}
		}
		p.Paths[each.Path] = buildPathItem(ws, each, existingPathItem, cfg)
	}
	return p
}

func buildPathItem(ws *restful.WebService, r restful.Route, existingPathItem spec.PathItem, cfg Config) spec.PathItem {
	op := buildOperation(ws, r, cfg)
	switch r.Method {
	case "GET":
		existingPathItem.Get = op
	case "POST":
		existingPathItem.Post = op
	case "PUT":
		existingPathItem.Put = op
	case "DELETE":
		existingPathItem.Delete = op
	case "PATCH":
		existingPathItem.Patch = op
	case "OPTIONS":
		existingPathItem.Options = op
	case "HEAD":
		existingPathItem.Head = op
	}
	return existingPathItem
}

func buildOperation(ws *restful.WebService, r restful.Route, cfg Config) *spec.Operation {
	o := spec.NewOperation(r.Operation)
	o.Description = r.Doc
	// take the first line to be the summary
	if lines := strings.Split(r.Doc, "\n"); len(lines) > 0 {
		o.Summary = lines[0]
	}
	o.Consumes = r.Consumes
	o.Produces = r.Produces
	if r.Metadata != nil {
		if tags, ok := r.Metadata[KeyOpenAPITags]; ok {
			if tagList, ok := tags.([]string); ok {
				o.Tags = tagList
			}
		}
	}
	// collect any path parameters
	for _, param := range ws.PathParameters() {
		o.Parameters = append(o.Parameters, buildParameter(r, param, cfg))
	}
	// route specific params
	for _, each := range r.ParameterDocs {
		o.Parameters = append(o.Parameters, buildParameter(r, each, cfg))
	}
	o.Responses = new(spec.Responses)
	props := &o.Responses.ResponsesProps
	props.StatusCodeResponses = map[int]spec.Response{}
	for k, v := range r.ResponseErrors {
		r := buildResponse(v, cfg)
		props.StatusCodeResponses[k] = r
		if 200 == k { // any 2xx code?
			o.Responses.Default = &r
		}
	}
	if len(o.Responses.StatusCodeResponses) == 0 {
		o.Responses.StatusCodeResponses[200] = spec.Response{ResponseProps: spec.ResponseProps{Description: http.StatusText(http.StatusOK)}}
	}
	return o
}

func buildParameter(r restful.Route, restfulParam *restful.Parameter, cfg Config) spec.Parameter {
	p := spec.Parameter{}
	param := restfulParam.Data()
	p.In = asParamType(param.Kind)
	p.Type = param.DataType
	p.Description = param.Description
	p.Name = param.Name
	p.Required = param.Required
	if param.DefaultValue != "" {
		if parsedInt, err := strconv.ParseInt(param.DefaultValue, 10, 64); err == nil {
			p.Default = parsedInt
		} else if parsedBool, err := strconv.ParseBool(param.DefaultValue); err == nil {
			p.Default = parsedBool
		} else {
			p.Default = param.DefaultValue
		}
	}
	p.Format = param.DataFormat
	if p.In == "body" && r.ReadSample != nil && p.Type == reflect.TypeOf(r.ReadSample).String() {
		p.Schema = new(spec.Schema)
		p.Schema.Ref = spec.MustCreateRef("#/definitions/" + p.Type)
	}
	return p
}

func buildResponse(e restful.ResponseError, cfg Config) (r spec.Response) {
	r.Description = e.Message
	if e.Model != nil {
		st := reflect.TypeOf(e.Model)
		if st.Kind() == reflect.Ptr {
			// For pointer type, use element type as the key; otherwise we'll
			// endup with '#/definitions/*Type' which violates openapi spec.
			st = st.Elem()
		}
		r.Schema = new(spec.Schema)
		if st.Kind() == reflect.Array || st.Kind() == reflect.Slice {
			modelName := definitionBuilder{}.keyFrom(st.Elem())
			r.Schema.Type = []string{"array"}
			r.Schema.Items = &spec.SchemaOrArray{
				Schema: &spec.Schema{},
			}
			r.Schema.Items.Schema.Ref = spec.MustCreateRef("#/definitions/" + modelName)
		} else {
			modelName := definitionBuilder{}.keyFrom(st)
			r.Schema.Ref = spec.MustCreateRef("#/definitions/" + modelName)
		}
	}
	return r
}
<|endoftext|>


<commit_before>package input

import (
	"time"

	"github.com/funkygao/dbus/engine"
	"github.com/funkygao/dbus/plugins/input/myslave"
	//"github.com/funkygao/dbus/plugins/model"
	conf "github.com/funkygao/jsconf"
	log "github.com/funkygao/log4go"
)

type MysqlbinlogInput struct {
	stopChan chan struct{}

	slave *myslave.MySlave
}

func (this *MysqlbinlogInput) Init(config *conf.Conf) {
	this.stopChan = make(chan struct{})
	this.slave = myslave.New().LoadConfig(config)
}

func (this *MysqlbinlogInput) Run(r engine.InputRunner, h engine.PluginHelper) error {
	defer this.slave.Close()

	for {
	RESTART_REPLICATION:

		log.Info("starting replication")

		ready := make(chan struct{})
		go this.slave.StartReplication(ready)
		<-ready

		rows := this.slave.EventStream()
		errors := this.slave.Errors()
		for {
			select {
			case <-this.stopChan:
				log.Trace("yes sir! I quit")
				return nil

			case err := <-errors:
				log.Error("slave: %v", err)
				this.slave.StopReplication()
				time.Sleep(time.Second * 5)
				goto RESTART_REPLICATION

			case pack, ok := <-r.InChan():
				if !ok {
					return nil
				}

				select {
				case row, ok := <-rows:
					if !ok {
						log.Info("event stream closed")
						return nil
					}

					pack.Payload = row
					r.Inject(pack)

				case <-this.stopChan:
					log.Trace("yes sir! I quit")
					return nil
				}
			}
		}
	}

	return nil
}

func (this *MysqlbinlogInput) Stop() {
	close(this.stopChan)
}

func init() {
	engine.RegisterPlugin("MysqlbinlogInput", func() engine.Plugin {
		return new(MysqlbinlogInput)
	})
}
<commit_msg>BUG FIX: got stuck<commit_after>package input

import (
	"time"

	"github.com/funkygao/dbus/engine"
	"github.com/funkygao/dbus/plugins/input/myslave"
	//"github.com/funkygao/dbus/plugins/model"
	conf "github.com/funkygao/jsconf"
	log "github.com/funkygao/log4go"
)

type MysqlbinlogInput struct {
	stopChan chan struct{}

	slave *myslave.MySlave
}

func (this *MysqlbinlogInput) Init(config *conf.Conf) {
	this.stopChan = make(chan struct{})
	this.slave = myslave.New().LoadConfig(config)
}

func (this *MysqlbinlogInput) Run(r engine.InputRunner, h engine.PluginHelper) error {
	defer this.slave.Close()

	backoff := time.Second * 5
	for {
	RESTART_REPLICATION:

		log.Info("starting replication")

		ready := make(chan struct{})
		go this.slave.StartReplication(ready)
		<-ready

		rows := this.slave.EventStream()
		errors := this.slave.Errors()
		for {
			select {
			case <-this.stopChan:
				log.Trace("yes sir! I quit")
				return nil

			case err := <-errors:
				log.Error("backoff %s: %v", backoff, err)
				this.slave.StopReplication()
				time.Sleep(backoff)
				goto RESTART_REPLICATION

			case pack, ok := <-r.InChan():
				if !ok {
					return nil
				}

				select {
				case err := <-errors:
					log.Error("backoff %s: %v", backoff, err)
					this.slave.StopReplication()
					time.Sleep(time.Second * 5)
					goto RESTART_REPLICATION

				case row, ok := <-rows:
					if !ok {
						log.Info("event stream closed")
						return nil
					}

					pack.Payload = row
					r.Inject(pack)

				case <-this.stopChan:
					log.Trace("yes sir! I quit")
					return nil
				}
			}
		}
	}

	return nil
}

func (this *MysqlbinlogInput) Stop() {
	close(this.stopChan)
}

func init() {
	engine.RegisterPlugin("MysqlbinlogInput", func() engine.Plugin {
		return new(MysqlbinlogInput)
	})
}
<|endoftext|>


<commit_before>// Package urltitle implements a plugin to watch web URLs, fetch and display title.
package urltitle

import (
	"fmt"
	"log"
	"regexp"
	"strings"

	"github.com/StalkR/goircbot/bot"
	"github.com/StalkR/goircbot/lib/url"
	"github.com/fluffle/goirc/client"
)

var (
	linkRE    = regexp.MustCompile(`(?:^|\s)(https?://[^#\s]+)`)
	silenceRE = regexp.MustCompile(`(^|\s)tg(\s|$)`) // Line ignored if matched.
)

func watchLine(b *bot.Bot, line *client.Line, ignoremap map[string]bool) {
	target := line.Args[0]
	if !strings.HasPrefix(target, "#") {
		return
	}
	if _, ignore := ignoremap[line.Nick]; ignore {
		return
	}
	text := line.Args[1]
	if silenceRE.MatchString(text) {
		return
	}
	link := linkRE.FindStringSubmatch(text)
	if link == nil || len(link[1]) > 200 {
		return
	}
	title, err := url.Title(link[1])
	if err != nil {
		log.Println("urltitle:", err)
		return
	}
	if len(title) > 200 {
		title = title[:200]
	}
	b.Conn.Privmsg(target, fmt.Sprintf("%s :: %s", link[1], title))
}

// Register registers the plugin with a bot.
func Register(b *bot.Bot, ignore []string) {
	ignoremap := make(map[string]bool)
	for _, nick := range ignore {
		ignoremap[nick] = true
	}

	b.Conn.HandleFunc("privmsg",
		func(conn *client.Conn, line *client.Line) {
			watchLine(b, line, ignoremap)
		})
}
<commit_msg>urltitle: allow silence word + )<commit_after>// Package urltitle implements a plugin to watch web URLs, fetch and display title.
package urltitle

import (
	"fmt"
	"log"
	"regexp"
	"strings"

	"github.com/StalkR/goircbot/bot"
	"github.com/StalkR/goircbot/lib/url"
	"github.com/fluffle/goirc/client"
)

var (
	linkRE    = regexp.MustCompile(`(?:^|\s)(https?://[^#\s]+)`)
	silenceRE = regexp.MustCompile(`(^|\s)tg(\)|\s|$)`) // Line ignored if matched.
)

func watchLine(b *bot.Bot, line *client.Line, ignoremap map[string]bool) {
	target := line.Args[0]
	if !strings.HasPrefix(target, "#") {
		return
	}
	if _, ignore := ignoremap[line.Nick]; ignore {
		return
	}
	text := line.Args[1]
	if silenceRE.MatchString(text) {
		return
	}
	link := linkRE.FindStringSubmatch(text)
	if link == nil || len(link[1]) > 200 {
		return
	}
	title, err := url.Title(link[1])
	if err != nil {
		log.Println("urltitle:", err)
		return
	}
	if len(title) > 200 {
		title = title[:200]
	}
	b.Conn.Privmsg(target, fmt.Sprintf("%s :: %s", link[1], title))
}

// Register registers the plugin with a bot.
func Register(b *bot.Bot, ignore []string) {
	ignoremap := make(map[string]bool)
	for _, nick := range ignore {
		ignoremap[nick] = true
	}

	b.Conn.HandleFunc("privmsg",
		func(conn *client.Conn, line *client.Line) {
			watchLine(b, line, ignoremap)
		})
}
<|endoftext|>


<commit_before>package client

import (
	"context"
	"io/ioutil"
	"sort"
	"testing"

	log "github.com/Sirupsen/logrus"
	"github.com/sahib/brig/server"
	colorlog "github.com/sahib/brig/util/log"
	"github.com/stretchr/testify/require"
)

func init() {
	log.SetLevel(log.DebugLevel)
	log.SetFormatter(&colorlog.ColorfulLogFormatter{})
}

func withDaemon(t *testing.T, fn func(ctl *Client)) {
	base, err := ioutil.TempDir("", "brig-ctl-test-")
	require.Nil(t, err)

	srv, err := server.BootServer(base, "klaus", "", 6667)
	require.Nil(t, err)

	waitForDeath := make(chan bool)
	go func() {
		defer func() {
			waitForDeath <- true
		}()
		require.Nil(t, srv.Serve())
	}()

	ctl, err := Dial(context.Background(), 6667)
	require.Nil(t, err)

	require.Nil(t, ctl.Init(base, "alice", "klaus", "mock"))
	fn(ctl)

	require.Nil(t, ctl.Quit())

	<-waitForDeath
}

func TestStageAndCat(t *testing.T) {
	withDaemon(t, func(ctl *Client) {
		fd, err := ioutil.TempFile("", "brig-dummy-data")
		path := fd.Name()

		require.Nil(t, err)
		_, err = fd.Write([]byte("hello"))
		require.Nil(t, err)
		require.Nil(t, fd.Close())

		require.Nil(t, ctl.Stage(path, "/hello"))
		rw, err := ctl.Cat("hello")
		require.Nil(t, err)

		data, err := ioutil.ReadAll(rw)
		require.Nil(t, err)

		require.Equal(t, []byte("hello"), data)
		require.Nil(t, rw.Close())
	})
}

func TestMkdir(t *testing.T) {
	withDaemon(t, func(ctl *Client) {
		// Create something nested with -p...
		require.Nil(t, ctl.Mkdir("/a/b/c", true))

		// Create it twice...
		require.Nil(t, ctl.Mkdir("/a/b/c", true))

		// Create something nested without -p
		err := ctl.Mkdir("/x/y/z", false)
		require.Contains(t, err.Error(), "No such file")

		require.Nil(t, ctl.Mkdir("/x", false))
		require.Nil(t, ctl.Mkdir("/x/y", false))
		require.Nil(t, ctl.Mkdir("/x/y/z", false))

		lst, err := ctl.List("/", -1)
		require.Nil(t, err)

		paths := []string{}
		for _, info := range lst {
			paths = append(paths, info.Path)
		}

		sort.Strings(paths)
		require.Equal(t, paths, []string{
			"/",
			"/a",
			"/a/b",
			"/a/b/c",
			"/x",
			"/x/y",
			"/x/y/z",
		})
	})
}
<commit_msg>test: fix local client test compilation<commit_after>package client

import (
	"context"
	"io/ioutil"
	"sort"
	"testing"

	log "github.com/Sirupsen/logrus"
	"github.com/sahib/brig/server"
	colorlog "github.com/sahib/brig/util/log"
	"github.com/stretchr/testify/require"
)

func init() {
	log.SetLevel(log.DebugLevel)
	log.SetFormatter(&colorlog.ColorfulLogFormatter{})
}

func withDaemon(t *testing.T, fn func(ctl *Client)) {
	base, err := ioutil.TempDir("", "brig-ctl-test-")
	require.Nil(t, err)

	srv, err := server.BootServer(base, "klaus", "", "localhost", 6667)
	require.Nil(t, err)

	waitForDeath := make(chan bool)
	go func() {
		defer func() {
			waitForDeath <- true
		}()
		require.Nil(t, srv.Serve())
	}()

	ctl, err := Dial(context.Background(), 6667)
	require.Nil(t, err)

	require.Nil(t, ctl.Init(base, "alice", "klaus", "mock"))
	fn(ctl)

	require.Nil(t, ctl.Quit())

	<-waitForDeath
}

func TestStageAndCat(t *testing.T) {
	withDaemon(t, func(ctl *Client) {
		fd, err := ioutil.TempFile("", "brig-dummy-data")
		path := fd.Name()

		require.Nil(t, err)
		_, err = fd.Write([]byte("hello"))
		require.Nil(t, err)
		require.Nil(t, fd.Close())

		require.Nil(t, ctl.Stage(path, "/hello"))
		rw, err := ctl.Cat("hello")
		require.Nil(t, err)

		data, err := ioutil.ReadAll(rw)
		require.Nil(t, err)

		require.Equal(t, []byte("hello"), data)
		require.Nil(t, rw.Close())
	})
}

func TestMkdir(t *testing.T) {
	withDaemon(t, func(ctl *Client) {
		// Create something nested with -p...
		require.Nil(t, ctl.Mkdir("/a/b/c", true))

		// Create it twice...
		require.Nil(t, ctl.Mkdir("/a/b/c", true))

		// Create something nested without -p
		err := ctl.Mkdir("/x/y/z", false)
		require.Contains(t, err.Error(), "No such file")

		require.Nil(t, ctl.Mkdir("/x", false))
		require.Nil(t, ctl.Mkdir("/x/y", false))
		require.Nil(t, ctl.Mkdir("/x/y/z", false))

		lst, err := ctl.List("/", -1)
		require.Nil(t, err)

		paths := []string{}
		for _, info := range lst {
			paths = append(paths, info.Path)
		}

		sort.Strings(paths)
		require.Equal(t, paths, []string{
			"/",
			"/a",
			"/a/b",
			"/a/b/c",
			"/x",
			"/x/y",
			"/x/y/z",
		})
	})
}
<|endoftext|>


<commit_before>package client

import "time"

// Message is a chat message.
type Message struct {
	From    string    `json:"from,omitempty"`
	To      string    `json:"to,omitempty"`
	Time    time.Time `json:"time"`
	Message string    `json:"message"`
}
<commit_msg>message.to field cannot be nil<commit_after>package client

import "time"

// Message is a chat message.
type Message struct {
	From    string    `json:"from,omitempty"`
	To      string    `json:"to"`
	Time    time.Time `json:"time"`
	Message string    `json:"message"`
}
<|endoftext|>


<commit_before>package couchbase

import (
	"bytes"
	"fmt"
)

type User struct {
	Name  string
	Id    string
	Domain  string
	Roles []Role
}

type Role struct {
	Role       string
	BucketName string `json:"bucket_name"`
}

// Sample:
// {"role":"admin","name":"Admin","desc":"Can manage ALL cluster features including security.","ce":true}
// {"role":"query_select","bucket_name":"*","name":"Query Select","desc":"Can execute SELECT statement on bucket to retrieve data"}
type RoleDescription struct {
	Role       string
	Name       string
	Desc       string
	Ce         bool
	BucketName string `json:"bucket_name"`
}

// Return user-role data, as parsed JSON.
// Sample:
//   [{"id":"ivanivanov","name":"Ivan Ivanov","roles":[{"role":"cluster_admin"},{"bucket_name":"default","role":"bucket_admin"}]},
//    {"id":"petrpetrov","name":"Petr Petrov","roles":[{"role":"replication_admin"}]}]
func (c *Client) GetUserRoles() ([]interface{}, error) {
	ret := make([]interface{}, 0, 1)
	err := c.parseURLResponse("/settings/rbac/users", &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (c *Client) GetUserInfoAll() ([]User, error) {
	ret := make([]User, 0, 16)
	err := c.parseURLResponse("/settings/rbac/users", &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func rolesToParamFormat(roles []Role) string {
	var buffer bytes.Buffer
	for i, role := range roles {
		if i > 0 {
			buffer.WriteString(",")
		}
		buffer.WriteString(role.Role)
		if role.BucketName != "" {
			buffer.WriteString("[")
			buffer.WriteString(role.BucketName)
			buffer.WriteString("]")
		}
	}
	return buffer.String()
}

func (c *Client) PutUserInfo(u *User) error {
	params := map[string]interface{}{
		"name":  u.Name,
		"roles": rolesToParamFormat(u.Roles),
	}
	var target string
	switch u.Domain {
	case "external":
		target = "/settings/rbac/users/" + u.Id
	case "local":
		target = "/settings/rbac/users/local/" + u.Id
	default:
		return fmt.Errorf("Unknown user type: %s", u.Domain)
	}
	var ret string // PUT returns an empty string. We ignore it.
	err := c.parsePutURLResponse(target, params, &ret)
	return err
}

func (c *Client) GetRolesAll() ([]RoleDescription, error) {
	ret := make([]RoleDescription, 0, 32)
	err := c.parseURLResponse("/settings/rbac/roles", &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}
<commit_msg>MB-23858 add configured administrator to user_info and my_user_info tables<commit_after>package couchbase

import (
	"bytes"
	"fmt"
)

type User struct {
	Name   string
	Id     string
	Domain string
	Roles  []Role
}

type Role struct {
	Role       string
	BucketName string `json:"bucket_name"`
}

// Sample:
// {"role":"admin","name":"Admin","desc":"Can manage ALL cluster features including security.","ce":true}
// {"role":"query_select","bucket_name":"*","name":"Query Select","desc":"Can execute SELECT statement on bucket to retrieve data"}
type RoleDescription struct {
	Role       string
	Name       string
	Desc       string
	Ce         bool
	BucketName string `json:"bucket_name"`
}

// Return user-role data, as parsed JSON.
// Sample:
//   [{"id":"ivanivanov","name":"Ivan Ivanov","roles":[{"role":"cluster_admin"},{"bucket_name":"default","role":"bucket_admin"}]},
//    {"id":"petrpetrov","name":"Petr Petrov","roles":[{"role":"replication_admin"}]}]
func (c *Client) GetUserRoles() ([]interface{}, error) {
	ret := make([]interface{}, 0, 1)
	err := c.parseURLResponse("/settings/rbac/users", &ret)
	if err != nil {
		return nil, err
	}

	// Get the configured administrator.
	// Expected result: {"port":8091,"username":"Administrator"}
	adminInfo := make(map[string]interface{}, 2)
	err = c.parseURLResponse("/settings/web", &adminInfo)
	if err != nil {
		return nil, err
	}

	// Create a special entry for the configured administrator.
	adminResult := map[string]interface{}{
		"name": adminInfo["username"],
		"id":   adminInfo["username"],
		"roles": []interface{}{
			map[string]interface{}{
				"role": "admin",
			},
		},
	}

	// Add the configured administrator to the list of results.
	ret = append(ret, adminResult)

	return ret, nil
}

func (c *Client) GetUserInfoAll() ([]User, error) {
	ret := make([]User, 0, 16)
	err := c.parseURLResponse("/settings/rbac/users", &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func rolesToParamFormat(roles []Role) string {
	var buffer bytes.Buffer
	for i, role := range roles {
		if i > 0 {
			buffer.WriteString(",")
		}
		buffer.WriteString(role.Role)
		if role.BucketName != "" {
			buffer.WriteString("[")
			buffer.WriteString(role.BucketName)
			buffer.WriteString("]")
		}
	}
	return buffer.String()
}

func (c *Client) PutUserInfo(u *User) error {
	params := map[string]interface{}{
		"name":  u.Name,
		"roles": rolesToParamFormat(u.Roles),
	}
	var target string
	switch u.Domain {
	case "external":
		target = "/settings/rbac/users/" + u.Id
	case "local":
		target = "/settings/rbac/users/local/" + u.Id
	default:
		return fmt.Errorf("Unknown user type: %s", u.Domain)
	}
	var ret string // PUT returns an empty string. We ignore it.
	err := c.parsePutURLResponse(target, params, &ret)
	return err
}

func (c *Client) GetRolesAll() ([]RoleDescription, error) {
	ret := make([]RoleDescription, 0, 32)
	err := c.parseURLResponse("/settings/rbac/roles", &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}
<|endoftext|>


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

package client

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"mime"
	"net/http"
	"net/http/httputil"
	"strings"
	"sync"
	"time"

	"golang.org/x/net/context"
	"golang.org/x/net/context/ctxhttp"

	"github.com/go-openapi/runtime"
	"github.com/go-openapi/runtime/logger"
	"github.com/go-openapi/runtime/middleware"
	"github.com/go-openapi/strfmt"
)

// TLSClientOptions to configure client authentication with mutual TLS
type TLSClientOptions struct {
	Certificate        string
	Key                string
	CA                 string
	ServerName         string
	InsecureSkipVerify bool
	_                  struct{}
}

// TLSClientAuth creates a tls.Config for mutual auth
func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
	// create client tls config
	cfg := &tls.Config{}

	// load client cert if specified
	if opts.Certificate != "" {
		cert, err := tls.LoadX509KeyPair(opts.Certificate, opts.Key)
		if err != nil {
			return nil, fmt.Errorf("tls client cert: %v", err)
		}
		cfg.Certificates = []tls.Certificate{cert}
	}

	cfg.InsecureSkipVerify = opts.InsecureSkipVerify

	// When no CA certificate is provided, default to the system cert pool
	// that way when a request is made to a server known by the system trust store,
	// the name is still verified
	if opts.CA != "" {
		// load ca cert
		caCert, err := ioutil.ReadFile(opts.CA)
		if err != nil {
			return nil, fmt.Errorf("tls client ca: %v", err)
		}
		caCertPool := x509.NewCertPool()
		caCertPool.AppendCertsFromPEM(caCert)
		cfg.RootCAs = caCertPool
	}

	// apply servername overrride
	if opts.ServerName != "" {
		cfg.InsecureSkipVerify = false
		cfg.ServerName = opts.ServerName
	}

	cfg.BuildNameToCertificate()

	return cfg, nil
}

// TLSTransport creates a http client transport suitable for mutual tls auth
func TLSTransport(opts TLSClientOptions) (http.RoundTripper, error) {
	cfg, err := TLSClientAuth(opts)
	if err != nil {
		return nil, err
	}

	return &http.Transport{TLSClientConfig: cfg}, nil
}

// TLSClient creates a http.Client for mutual auth
func TLSClient(opts TLSClientOptions) (*http.Client, error) {
	transport, err := TLSTransport(opts)
	if err != nil {
		return nil, err
	}
	return &http.Client{Transport: transport}, nil
}

// DefaultTimeout the default request timeout
var DefaultTimeout = 30 * time.Second

// Runtime represents an API client that uses the transport
// to make http requests based on a swagger specification.
type Runtime struct {
	DefaultMediaType      string
	DefaultAuthentication runtime.ClientAuthInfoWriter
	Consumers             map[string]runtime.Consumer
	Producers             map[string]runtime.Producer

	Transport http.RoundTripper
	Jar       http.CookieJar
	//Spec      *spec.Document
	Host     string
	BasePath string
	Formats  strfmt.Registry
	Context  context.Context

	Debug  bool
	logger logger.Logger

	clientOnce *sync.Once
	client     *http.Client
	schemes    []string
	do         func(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error)
}

// New creates a new default runtime for a swagger api runtime.Client
func New(host, basePath string, schemes []string) *Runtime {
	var rt Runtime
	rt.DefaultMediaType = runtime.JSONMime

	// TODO: actually infer this stuff from the spec
	rt.Consumers = map[string]runtime.Consumer{
		runtime.JSONMime:    runtime.JSONConsumer(),
		runtime.XMLMime:     runtime.XMLConsumer(),
		runtime.TextMime:    runtime.TextConsumer(),
		runtime.DefaultMime: runtime.ByteStreamConsumer(),
	}
	rt.Producers = map[string]runtime.Producer{
		runtime.JSONMime:    runtime.JSONProducer(),
		runtime.XMLMime:     runtime.XMLProducer(),
		runtime.TextMime:    runtime.TextProducer(),
		runtime.DefaultMime: runtime.ByteStreamProducer(),
	}
	rt.Transport = http.DefaultTransport
	rt.Jar = nil
	rt.Host = host
	rt.BasePath = basePath
	rt.Context = context.Background()
	rt.clientOnce = new(sync.Once)
	if !strings.HasPrefix(rt.BasePath, "/") {
		rt.BasePath = "/" + rt.BasePath
	}

	rt.Debug = logger.DebugEnabled()
	rt.logger = logger.StandardLogger{}

	if len(schemes) > 0 {
		rt.schemes = schemes
	}
	rt.do = ctxhttp.Do
	return &rt
}

// NewWithClient allows you to create a new transport with a configured http.Client
func NewWithClient(host, basePath string, schemes []string, client *http.Client) *Runtime {
	rt := New(host, basePath, schemes)
	if client != nil {
		rt.clientOnce.Do(func() {
			rt.client = client
		})
	}
	return rt
}

func (r *Runtime) pickScheme(schemes []string) string {
	if v := r.selectScheme(r.schemes); v != "" {
		return v
	}
	if v := r.selectScheme(schemes); v != "" {
		return v
	}
	return "http"
}

func (r *Runtime) selectScheme(schemes []string) string {
	schLen := len(schemes)
	if schLen == 0 {
		return ""
	}

	scheme := schemes[0]
	// prefer https, but skip when not possible
	if scheme != "https" && schLen > 1 {
		for _, sch := range schemes {
			if sch == "https" {
				scheme = sch
				break
			}
		}
	}
	return scheme
}

// Submit a request and when there is a body on success it will turn that into the result
// all other things are turned into an api error for swagger which retains the status code
func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
	params, readResponse, auth := operation.Params, operation.Reader, operation.AuthInfo

	request, err := newRequest(operation.Method, operation.PathPattern, params)
	if err != nil {
		return nil, err
	}

	var accept []string
	accept = append(accept, operation.ProducesMediaTypes...)
	if err = request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
		return nil, err
	}

	if auth == nil && r.DefaultAuthentication != nil {
		auth = r.DefaultAuthentication
	}
	//if auth != nil {
	//	if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
	//		return nil, err
	//	}
	//}

	// TODO: pick appropriate media type
	cmt := r.DefaultMediaType
	for _, mediaType := range operation.ConsumesMediaTypes {
		// Pick first non-empty media type
		if mediaType != "" {
			cmt = mediaType
			break
		}
	}

	req, err := request.buildHTTP(cmt, r.BasePath, r.Producers, r.Formats, auth)
	if err != nil {
		return nil, err
	}
	req.URL.Scheme = r.pickScheme(operation.Schemes)
	req.URL.Host = r.Host

	r.clientOnce.Do(func() {
		r.client = &http.Client{
			Transport: r.Transport,
			Jar:       r.Jar,
		}
	})

	if r.Debug {
		b, err2 := httputil.DumpRequestOut(req, true)
		if err2 != nil {
			return nil, err2
		}
		r.logger.Debugf("%s\n", string(b)) + "\n")
	}

	var hasTimeout bool
	pctx := operation.Context
	if pctx == nil {
		pctx = r.Context
	} else {
		hasTimeout = true
	}
	if pctx == nil {
		pctx = context.Background()
	}
	var ctx context.Context
	var cancel context.CancelFunc
	if hasTimeout {
		ctx, cancel = context.WithCancel(pctx)
	} else {
		ctx, cancel = context.WithTimeout(pctx, request.timeout)
	}
	defer cancel()

	client := operation.Client
	if client == nil {
		client = r.client
	}
	if r.do == nil {
		r.do = ctxhttp.Do
	}
	res, err := r.do(ctx, client, req) // make requests, by default follows 10 redirects before failing
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	if r.Debug {
		b, err2 := httputil.DumpResponse(res, true)
		if err2 != nil {
			return nil, err2
		}
		r.logger.Debugf("%s\n", string(b)) + "\n")
	}

	ct := res.Header.Get(runtime.HeaderContentType)
	if ct == "" { // this should really really never occur
		ct = r.DefaultMediaType
	}

	mt, _, err := mime.ParseMediaType(ct)
	if err != nil {
		return nil, fmt.Errorf("parse content type: %s", err)
	}

	cons, ok := r.Consumers[mt]
	if !ok {
		// scream about not knowing what to do
		return nil, fmt.Errorf("no consumer: %q", ct)
	}
	return readResponse.ReadResponse(response{res}, cons)
}

// SetDebug changes the debug flag.
// It ensures that client and middlewares have the set debug level.
func (r *Runtime) SetDebug(debug bool) {
	r.Debug = debug
	middleware.Debug = debug
}

// SetLogger changes the logger stream.
// It ensures that client and middlewares use the same logger.
func (r *Runtime) SetLogger(logger logger.Logger) {
	r.logger = logger
	middleware.Logger = logger
}
<commit_msg>fix debug logging for real<commit_after>// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"mime"
	"net/http"
	"net/http/httputil"
	"strings"
	"sync"
	"time"

	"golang.org/x/net/context"
	"golang.org/x/net/context/ctxhttp"

	"github.com/go-openapi/runtime"
	"github.com/go-openapi/runtime/logger"
	"github.com/go-openapi/runtime/middleware"
	"github.com/go-openapi/strfmt"
)

// TLSClientOptions to configure client authentication with mutual TLS
type TLSClientOptions struct {
	Certificate        string
	Key                string
	CA                 string
	ServerName         string
	InsecureSkipVerify bool
	_                  struct{}
}

// TLSClientAuth creates a tls.Config for mutual auth
func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
	// create client tls config
	cfg := &tls.Config{}

	// load client cert if specified
	if opts.Certificate != "" {
		cert, err := tls.LoadX509KeyPair(opts.Certificate, opts.Key)
		if err != nil {
			return nil, fmt.Errorf("tls client cert: %v", err)
		}
		cfg.Certificates = []tls.Certificate{cert}
	}

	cfg.InsecureSkipVerify = opts.InsecureSkipVerify

	// When no CA certificate is provided, default to the system cert pool
	// that way when a request is made to a server known by the system trust store,
	// the name is still verified
	if opts.CA != "" {
		// load ca cert
		caCert, err := ioutil.ReadFile(opts.CA)
		if err != nil {
			return nil, fmt.Errorf("tls client ca: %v", err)
		}
		caCertPool := x509.NewCertPool()
		caCertPool.AppendCertsFromPEM(caCert)
		cfg.RootCAs = caCertPool
	}

	// apply servername overrride
	if opts.ServerName != "" {
		cfg.InsecureSkipVerify = false
		cfg.ServerName = opts.ServerName
	}

	cfg.BuildNameToCertificate()

	return cfg, nil
}

// TLSTransport creates a http client transport suitable for mutual tls auth
func TLSTransport(opts TLSClientOptions) (http.RoundTripper, error) {
	cfg, err := TLSClientAuth(opts)
	if err != nil {
		return nil, err
	}

	return &http.Transport{TLSClientConfig: cfg}, nil
}

// TLSClient creates a http.Client for mutual auth
func TLSClient(opts TLSClientOptions) (*http.Client, error) {
	transport, err := TLSTransport(opts)
	if err != nil {
		return nil, err
	}
	return &http.Client{Transport: transport}, nil
}

// DefaultTimeout the default request timeout
var DefaultTimeout = 30 * time.Second

// Runtime represents an API client that uses the transport
// to make http requests based on a swagger specification.
type Runtime struct {
	DefaultMediaType      string
	DefaultAuthentication runtime.ClientAuthInfoWriter
	Consumers             map[string]runtime.Consumer
	Producers             map[string]runtime.Producer

	Transport http.RoundTripper
	Jar       http.CookieJar
	//Spec      *spec.Document
	Host     string
	BasePath string
	Formats  strfmt.Registry
	Context  context.Context

	Debug  bool
	logger logger.Logger

	clientOnce *sync.Once
	client     *http.Client
	schemes    []string
	do         func(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error)
}

// New creates a new default runtime for a swagger api runtime.Client
func New(host, basePath string, schemes []string) *Runtime {
	var rt Runtime
	rt.DefaultMediaType = runtime.JSONMime

	// TODO: actually infer this stuff from the spec
	rt.Consumers = map[string]runtime.Consumer{
		runtime.JSONMime:    runtime.JSONConsumer(),
		runtime.XMLMime:     runtime.XMLConsumer(),
		runtime.TextMime:    runtime.TextConsumer(),
		runtime.DefaultMime: runtime.ByteStreamConsumer(),
	}
	rt.Producers = map[string]runtime.Producer{
		runtime.JSONMime:    runtime.JSONProducer(),
		runtime.XMLMime:     runtime.XMLProducer(),
		runtime.TextMime:    runtime.TextProducer(),
		runtime.DefaultMime: runtime.ByteStreamProducer(),
	}
	rt.Transport = http.DefaultTransport
	rt.Jar = nil
	rt.Host = host
	rt.BasePath = basePath
	rt.Context = context.Background()
	rt.clientOnce = new(sync.Once)
	if !strings.HasPrefix(rt.BasePath, "/") {
		rt.BasePath = "/" + rt.BasePath
	}

	rt.Debug = logger.DebugEnabled()
	rt.logger = logger.StandardLogger{}

	if len(schemes) > 0 {
		rt.schemes = schemes
	}
	rt.do = ctxhttp.Do
	return &rt
}

// NewWithClient allows you to create a new transport with a configured http.Client
func NewWithClient(host, basePath string, schemes []string, client *http.Client) *Runtime {
	rt := New(host, basePath, schemes)
	if client != nil {
		rt.clientOnce.Do(func() {
			rt.client = client
		})
	}
	return rt
}

func (r *Runtime) pickScheme(schemes []string) string {
	if v := r.selectScheme(r.schemes); v != "" {
		return v
	}
	if v := r.selectScheme(schemes); v != "" {
		return v
	}
	return "http"
}

func (r *Runtime) selectScheme(schemes []string) string {
	schLen := len(schemes)
	if schLen == 0 {
		return ""
	}

	scheme := schemes[0]
	// prefer https, but skip when not possible
	if scheme != "https" && schLen > 1 {
		for _, sch := range schemes {
			if sch == "https" {
				scheme = sch
				break
			}
		}
	}
	return scheme
}

// Submit a request and when there is a body on success it will turn that into the result
// all other things are turned into an api error for swagger which retains the status code
func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
	params, readResponse, auth := operation.Params, operation.Reader, operation.AuthInfo

	request, err := newRequest(operation.Method, operation.PathPattern, params)
	if err != nil {
		return nil, err
	}

	var accept []string
	accept = append(accept, operation.ProducesMediaTypes...)
	if err = request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
		return nil, err
	}

	if auth == nil && r.DefaultAuthentication != nil {
		auth = r.DefaultAuthentication
	}
	//if auth != nil {
	//	if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
	//		return nil, err
	//	}
	//}

	// TODO: pick appropriate media type
	cmt := r.DefaultMediaType
	for _, mediaType := range operation.ConsumesMediaTypes {
		// Pick first non-empty media type
		if mediaType != "" {
			cmt = mediaType
			break
		}
	}

	req, err := request.buildHTTP(cmt, r.BasePath, r.Producers, r.Formats, auth)
	if err != nil {
		return nil, err
	}
	req.URL.Scheme = r.pickScheme(operation.Schemes)
	req.URL.Host = r.Host

	r.clientOnce.Do(func() {
		r.client = &http.Client{
			Transport: r.Transport,
			Jar:       r.Jar,
		}
	})

	if r.Debug {
		b, err2 := httputil.DumpRequestOut(req, true)
		if err2 != nil {
			return nil, err2
		}
		r.logger.Debugf("%s\n", string(b))
	}

	var hasTimeout bool
	pctx := operation.Context
	if pctx == nil {
		pctx = r.Context
	} else {
		hasTimeout = true
	}
	if pctx == nil {
		pctx = context.Background()
	}
	var ctx context.Context
	var cancel context.CancelFunc
	if hasTimeout {
		ctx, cancel = context.WithCancel(pctx)
	} else {
		ctx, cancel = context.WithTimeout(pctx, request.timeout)
	}
	defer cancel()

	client := operation.Client
	if client == nil {
		client = r.client
	}
	if r.do == nil {
		r.do = ctxhttp.Do
	}
	res, err := r.do(ctx, client, req) // make requests, by default follows 10 redirects before failing
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	if r.Debug {
		b, err2 := httputil.DumpResponse(res, true)
		if err2 != nil {
			return nil, err2
		}
		r.logger.Debugf("%s\n", string(b))
	}

	ct := res.Header.Get(runtime.HeaderContentType)
	if ct == "" { // this should really really never occur
		ct = r.DefaultMediaType
	}

	mt, _, err := mime.ParseMediaType(ct)
	if err != nil {
		return nil, fmt.Errorf("parse content type: %s", err)
	}

	cons, ok := r.Consumers[mt]
	if !ok {
		// scream about not knowing what to do
		return nil, fmt.Errorf("no consumer: %q", ct)
	}
	return readResponse.ReadResponse(response{res}, cons)
}

// SetDebug changes the debug flag.
// It ensures that client and middlewares have the set debug level.
func (r *Runtime) SetDebug(debug bool) {
	r.Debug = debug
	middleware.Debug = debug
}

// SetLogger changes the logger stream.
// It ensures that client and middlewares use the same logger.
func (r *Runtime) SetLogger(logger logger.Logger) {
	r.logger = logger
	middleware.Logger = logger
}
<|endoftext|>


<commit_before>package goNessus

type Nessus struct {
	Ip        string
	Port      string
	AccessKey string
	SecretKey string
	Token     string
}
<commit_msg>Add godocs for the client struct<commit_after>// Package goNessus provides a Golang based interface to Nessus 6
package goNessus

// Nessus struct is used to contain information about a Nessus scanner. This
// will be used to connect to the scanner and make API requests.
type Nessus struct {
	Ip        string
	Port      string
	AccessKey string
	SecretKey string
	Token     string
}
<|endoftext|>


<commit_before>package gomigrate

import (
	"path/filepath"
	"regexp"
	"strconv"
)

var (
	upMigrationFile   = regexp.MustCompile(`(\d+)_(\w+)_up\.sql`)
	downMigrationFile = regexp.MustCompile(`(\d+)_(\w+)_down\.sql`)
	subMigrationSplit = regexp.MustCompile(`;\s*$`)
	allWhitespace     = regexp.MustCompile(`^\s*$`)
)

// Returns the migration number, type and base name, so 1, "up", "migration" from "01_migration_up.sql"
func parseMigrationPath(path string) (uint64, migrationType, string, error) {
	filebase := filepath.Base(path)

	matches := upMigrationFile.FindAllSubmatch([]byte(filebase), -1)
	if matches != nil {
		return parseMatches(matches, upMigration)
	}
	matches = downMigrationFile.FindAllSubmatch([]byte(filebase), -1)
	if matches != nil {
		return parseMatches(matches, downMigration)
	}

	return 0, "", "", InvalidMigrationFile
}

// Parses matches given by a migration file regex.
func parseMatches(matches [][][]byte, mType migrationType) (uint64, migrationType, string, error) {
	num := matches[0][1]
	name := matches[0][2]
	parsedNum, err := strconv.ParseUint(string(num), 10, 64)
	if err != nil {
		return 0, "", "", err
	}
	return parsedNum, mType, string(name), nil
}

// Splits migration sql into different strings separated by a semi-colon.
func splitMigrationString(sql string) []string {
	return subMigrationSplit.Split(sql, -1)
}

// This type is used to sort migration ids.
type uint64slice []uint64

func (u uint64slice) Len() int {
	return len(u)
}

func (u uint64slice) Less(a, b int) bool {
	return u[a] < u[b]
}

func (u uint64slice) Swap(a, b int) {
	tempA := u[a]
	u[a] = u[b]
	u[b] = tempA
}
<commit_msg>Cover to end of line<commit_after>package gomigrate

import (
	"path/filepath"
	"regexp"
	"strconv"
)

var (
	upMigrationFile   = regexp.MustCompile(`(\d+)_(\w+)_up\.sql`)
	downMigrationFile = regexp.MustCompile(`(\d+)_(\w+)_down\.sql`)
	subMigrationSplit = regexp.MustCompile(`;\s*\\n`)
	allWhitespace     = regexp.MustCompile(`^\s*$`)
)

// Returns the migration number, type and base name, so 1, "up", "migration" from "01_migration_up.sql"
func parseMigrationPath(path string) (uint64, migrationType, string, error) {
	filebase := filepath.Base(path)

	matches := upMigrationFile.FindAllSubmatch([]byte(filebase), -1)
	if matches != nil {
		return parseMatches(matches, upMigration)
	}
	matches = downMigrationFile.FindAllSubmatch([]byte(filebase), -1)
	if matches != nil {
		return parseMatches(matches, downMigration)
	}

	return 0, "", "", InvalidMigrationFile
}

// Parses matches given by a migration file regex.
func parseMatches(matches [][][]byte, mType migrationType) (uint64, migrationType, string, error) {
	num := matches[0][1]
	name := matches[0][2]
	parsedNum, err := strconv.ParseUint(string(num), 10, 64)
	if err != nil {
		return 0, "", "", err
	}
	return parsedNum, mType, string(name), nil
}

// Splits migration sql into different strings separated by a semi-colon.
func splitMigrationString(sql string) []string {
	return subMigrationSplit.Split(sql, -1)
}

// This type is used to sort migration ids.
type uint64slice []uint64

func (u uint64slice) Len() int {
	return len(u)
}

func (u uint64slice) Less(a, b int) bool {
	return u[a] < u[b]
}

func (u uint64slice) Swap(a, b int) {
	tempA := u[a]
	u[a] = u[b]
	u[b] = tempA
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os/user"
	"strconv"
	"strings"

	"github.com/fatih/color"
	"github.com/mikkeloscar/sshconfig"
	"github.com/urfave/cli"
)

const (
	version = "0.0.1"
	useage  = "management ssh config easier"
)

var (
	whiteBoldColor  = color.New(color.FgWhite, color.Bold)
	yellowBoldColor = color.New(color.FgYellow, color.Bold)
	successColor    = color.New(color.BgGreen, color.FgWhite)
	errorColor      = color.New(color.BgRed, color.FgWhite)
)

func saveHosts(hosts []*sshconfig.SSHHost) error {
	var buffer bytes.Buffer
	for _, host := range hosts {
		buffer.WriteString(fmt.Sprintf("Host %s\n", strings.Join(host.Host, " ")))
		buffer.WriteString(fmt.Sprintf("    User %s\n", host.User))
		buffer.WriteString(fmt.Sprintf("    HostName %s\n", host.HostName))
		buffer.WriteString(fmt.Sprintf("    Port %d\n", host.Port))
		if host.IdentityFile != "" {
			buffer.WriteString(fmt.Sprintf("    IdentityFile %s\n", host.IdentityFile))
		}
		if host.ProxyCommand != "" {
			buffer.WriteString(fmt.Sprintf("    ProxyCommand %s\n", host.ProxyCommand))
		}
	}
	if err := ioutil.WriteFile(path, buffer.Bytes(), 0644); err != nil {
		printErrorFlag()
		return cli.NewExitError(err, 1)
	}
	return nil
}

func parseHost(alias, hostStr string, originHost *sshconfig.SSHHost) *sshconfig.SSHHost {
	var host *sshconfig.SSHHost
	if originHost != nil {
		host = originHost
	} else {
		host = &sshconfig.SSHHost{
			Host: []string{alias},
		}
	}
	host.Port = 22
	u, _ := user.Current()
	host.User = u.Name

	hs := strings.Split(hostStr, "@")
	connectUrl := hs[0]
	if len(hs) > 1 {
		if hs[0] != "" {
			host.User = hs[0]
		}
		connectUrl = hs[1]
	}
	hss := strings.Split(connectUrl, ":")
	host.HostName = hss[0]
	if len(hss) > 1 {
		if port, err := strconv.Atoi(hss[1]); err == nil {
			host.Port = port
		}
	}
	return host
}

func getHostsMap(hosts []*sshconfig.SSHHost) map[string]*sshconfig.SSHHost {
	hostMap := map[string]*sshconfig.SSHHost{}
	for _, host := range hosts {
		for _, alias := range host.Host {
			hostMap[alias] = host
		}
	}
	return hostMap
}

func formatHost(host *sshconfig.SSHHost) string {
	return fmt.Sprintf("%s@%s:%d", host.User, host.HostName, host.Port)
}

func printSuccessFlag() {
	successColor.Printf("%-10s", " success")
}

func printErrorFlag() {
	errorColor.Printf("%-8s", " error")
}

func printHost(host *sshconfig.SSHHost) {
	yellowBoldColor.Printf("    %s", strings.Join(host.Host, " "))
	fmt.Printf(" -> %s\n\n", formatHost(host))
}

func argumentsCheck(c *cli.Context, min, max int) error {
	argCount := c.NArg()
	var err error
	if min > 0 && argCount < min {
		err = errors.New("too few arguments.")
	}
	if max > 0 && argCount > max {
		err = errors.New("too many arguments.")
	}
	if err != nil {
		cli.ShowSubcommandHelp(c)
		fmt.Println()
		printErrorFlag()
		return cli.NewExitError(err, 1)
	}
	return nil
}

func query(values, keys []string) bool {
	for _, key := range keys {
		if !contains(values, key) {
			return false
		}
	}
	return true
}

func contains(values []string, key string) bool {
	for _, value := range values {
		if strings.Contains(value, key) {
			return true
		}
	}
	return false
}
<commit_msg>show custom options for list command<commit_after>package main

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os/user"
	"strconv"
	"strings"

	"github.com/fatih/color"
	"github.com/mikkeloscar/sshconfig"
	"github.com/urfave/cli"
)

const (
	version = "0.0.1"
	useage  = "management ssh config easier"
)

var (
	whiteBoldColor  = color.New(color.FgWhite, color.Bold)
	yellowBoldColor = color.New(color.FgYellow, color.Bold)
	successColor    = color.New(color.BgGreen, color.FgWhite)
	errorColor      = color.New(color.BgRed, color.FgWhite)
)

func saveHosts(hosts []*sshconfig.SSHHost) error {
	var buffer bytes.Buffer
	for _, host := range hosts {
		buffer.WriteString(fmt.Sprintf("Host %s\n", strings.Join(host.Host, " ")))
		buffer.WriteString(fmt.Sprintf("    User %s\n", host.User))
		buffer.WriteString(fmt.Sprintf("    HostName %s\n", host.HostName))
		buffer.WriteString(fmt.Sprintf("    Port %d\n", host.Port))
		if host.IdentityFile != "" {
			buffer.WriteString(fmt.Sprintf("    IdentityFile %s\n", host.IdentityFile))
		}
		if host.ProxyCommand != "" {
			buffer.WriteString(fmt.Sprintf("    ProxyCommand %s\n", host.ProxyCommand))
		}
	}
	if err := ioutil.WriteFile(path, buffer.Bytes(), 0644); err != nil {
		printErrorFlag()
		return cli.NewExitError(err, 1)
	}
	return nil
}

func parseHost(alias, hostStr string, originHost *sshconfig.SSHHost) *sshconfig.SSHHost {
	var host *sshconfig.SSHHost
	if originHost != nil {
		host = originHost
	} else {
		host = &sshconfig.SSHHost{
			Host: []string{alias},
		}
	}
	host.Port = 22
	u, _ := user.Current()
	host.User = u.Name

	hs := strings.Split(hostStr, "@")
	connectUrl := hs[0]
	if len(hs) > 1 {
		if hs[0] != "" {
			host.User = hs[0]
		}
		connectUrl = hs[1]
	}
	hss := strings.Split(connectUrl, ":")
	host.HostName = hss[0]
	if len(hss) > 1 {
		if port, err := strconv.Atoi(hss[1]); err == nil {
			host.Port = port
		}
	}
	return host
}

func getHostsMap(hosts []*sshconfig.SSHHost) map[string]*sshconfig.SSHHost {
	hostMap := map[string]*sshconfig.SSHHost{}
	for _, host := range hosts {
		for _, alias := range host.Host {
			hostMap[alias] = host
		}
	}
	return hostMap
}

func formatHost(host *sshconfig.SSHHost) string {
	return fmt.Sprintf("%s@%s:%d", host.User, host.HostName, host.Port)
}

func printSuccessFlag() {
	successColor.Printf("%-9s", " success")
}

func printErrorFlag() {
	errorColor.Printf("%-6s", " error")
}

func printHost(host *sshconfig.SSHHost) {
	yellowBoldColor.Printf("\t%s", strings.Join(host.Host, " "))
	fmt.Printf(" -> %s\n", formatHost(host))
	if host.IdentityFile != "" {
		fmt.Printf("\t\tIdentityFile = %s\n", host.IdentityFile)
	}
	if host.ProxyCommand != "" {
		fmt.Printf("\t\tProxyCommand = %s\n", host.ProxyCommand)
	}
	fmt.Println()
}

func argumentsCheck(c *cli.Context, min, max int) error {
	argCount := c.NArg()
	var err error
	if min > 0 && argCount < min {
		err = errors.New("too few arguments.")
	}
	if max > 0 && argCount > max {
		err = errors.New("too many arguments.")
	}
	if err != nil {
		cli.ShowSubcommandHelp(c)
		fmt.Println()
		printErrorFlag()
		return cli.NewExitError(err, 1)
	}
	return nil
}

func query(values, keys []string) bool {
	for _, key := range keys {
		if !contains(values, key) {
			return false
		}
	}
	return true
}

func contains(values []string, key string) bool {
	for _, value := range values {
		if strings.Contains(value, key) {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package utils

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/http/pprof"

	"github.com/gorilla/mux"
)

// JSON response convenience function
func jsonResponse(w http.ResponseWriter, status int, data interface{}, err error) {
	w.Header().Add("Content-Type", "application/json")

	// Error Response - Return early
	if err != nil {
		jErr, _ := json.Marshal(map[string]interface{}{
			"Error": err.Error(),
		})
		w.WriteHeader(500)
		w.Write(jErr)
	}

	// Try to handle data
	jRes, mErr := json.Marshal(data)
	if mErr != nil {
		jErr, _ := json.Marshal(map[string]interface{}{
			"Data Error": err.Error(),
		})
		w.WriteHeader(500)
		w.Write(jErr)
	}
	w.WriteHeader(status)
	w.Write(jRes)
}

// Nests map (for adding envelope)
func envelope(d interface{}, envelope string) map[string]interface{} {
	return map[string]interface{}{
		envelope: d,
	}
}

// Unpacks map (opposite process of envelope)
func unvelope(d []byte, envelope string) ([]byte, error) {
	var raw map[string]interface{}

	// Need to use a custom JSON decoder in order to handle large ID
	dec := json.NewDecoder(bytes.NewReader(d))
	dec.UseNumber()
	err := dec.Decode(&raw)
	if err != nil {
		return nil, err
	}

	return json.Marshal(raw[envelope])
}

func enableProfiling(r *mux.Router) {
	r.HandleFunc("/debug/pprof", pprof.Index)
	r.HandleFunc("/debug/pprof/profile", pprof.Profile)
	r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
	r.Handle("/debug/block", pprof.Handler("block"))
	r.Handle("/debug/goroutine", pprof.Handler("goroutine"))
	r.Handle("/debug/heap", pprof.Handler("heap"))
	r.Handle("/debug/threadcreate", pprof.Handler("threadcreate"))
}
<commit_msg>export functions<commit_after>package utils

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/http/pprof"

	"github.com/gorilla/mux"
)

// JSON response convenience function
func JSONResponse(w http.ResponseWriter, status int, data interface{}, err error) {
	w.Header().Add("Content-Type", "application/json")

	// Error Response - Return early
	if err != nil {
		jErr, _ := json.Marshal(map[string]interface{}{
			"Error": err.Error(),
		})
		w.WriteHeader(500)
		w.Write(jErr)
	}

	// Try to handle data
	jRes, mErr := json.Marshal(data)
	if mErr != nil {
		jErr, _ := json.Marshal(map[string]interface{}{
			"Data Error": err.Error(),
		})
		w.WriteHeader(500)
		w.Write(jErr)
	}
	w.WriteHeader(status)
	w.Write(jRes)
}

// Nests map (for adding envelope)
func Envelope(d interface{}, envelope string) map[string]interface{} {
	return map[string]interface{}{
		envelope: d,
	}
}

// Unpacks map (opposite process of envelope)
func Unvelope(d []byte, envelope string) ([]byte, error) {
	var raw map[string]interface{}

	// Need to use a custom JSON decoder in order to handle large ID
	dec := json.NewDecoder(bytes.NewReader(d))
	dec.UseNumber()
	err := dec.Decode(&raw)
	if err != nil {
		return nil, err
	}

	return json.Marshal(raw[envelope])
}

func EnableProfiling(r *mux.Router) {
	r.HandleFunc("/debug/pprof", pprof.Index)
	r.HandleFunc("/debug/pprof/profile", pprof.Profile)
	r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
	r.Handle("/debug/block", pprof.Handler("block"))
	r.Handle("/debug/goroutine", pprof.Handler("goroutine"))
	r.Handle("/debug/heap", pprof.Handler("heap"))
	r.Handle("/debug/threadcreate", pprof.Handler("threadcreate"))
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"log"
	"gopkg.in/yaml.v2"
)

type Config struct {
	Url string `yaml:"url"`
	User string `yaml:"user"`
	Passwd string `yaml:"passwd"`
	PrivateKey string `yaml:"privateKey"`
	PublicKey string `yaml:"publicKey"`
}

func (c *Config) GetConf(env string) *Config {
	yamlFile, err := ioutil.ReadFile("conf-"+ env + ".yaml")
	if err != nil {
		log.Printf("yamlFile.Get err   #%v ", err)
	}
	err = yaml.Unmarshal(yamlFile, c)
	if err != nil {
		log.Fatalf("Unmarshal: %v", err)
	}
	return c
}

func fatal(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>fix wrong path<commit_after>package main

import (
	"io/ioutil"
	"log"
	"gopkg.in/yaml.v2"
)

type Config struct {
	Url string `yaml:"url"`
	User string `yaml:"user"`
	Passwd string `yaml:"passwd"`
	PrivateKey string `yaml:"privateKey"`
	PublicKey string `yaml:"publicKey"`
}

func (c *Config) GetConf(env string) *Config {
	yamlFile, err := ioutil.ReadFile("conf/conf-"+ env + ".yaml")
	if err != nil {
		log.Printf("yamlFile.Get err   #%v ", err)
	}
	err = yaml.Unmarshal(yamlFile, c)
	if err != nil {
		log.Fatalf("Unmarshal: %v", err)
	}
	return c
}

func fatal(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	_ "crypto/sha512"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"unicode"

	"github.com/mikkyang/id3-go"
)

func downloadFile(filepath string, url string) (err error) {

	// Create the file
	out, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer out.Close()

	// Get the data
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	// Writer the body to file
	_, err = io.Copy(out, resp.Body)
	if err != nil {
		return err
	}

	return nil
}

func setID3TagsForFile(filepath string, artist string, title string) {
	mp3File, _ := id3.Open(filepath)
	defer mp3File.Close()

	mp3File.SetArtist(artist)
	mp3File.SetTitle(title)
}

func htmlForURL(url string) string {
	client := &http.Client{}

	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0")

	resp, _ := client.Do(req)
	bytes, _ := ioutil.ReadAll(resp.Body)

	defer resp.Body.Close()
	return string(bytes)
}

func FileExists(name string) bool {
	if _, err := os.Stat(name); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

func TranscodeToMP3(originalFile string, destinationFile string) {
	args := []string{"-y", "-i", originalFile, "-q:a", "2", destinationFile}

	cmd := exec.Command("ffmpeg", args...)
	var out bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
		return
	}
}

func AddFileToUploadList(filename string) {
	uploadFile := "toUpload.m3u"

	f, err := os.OpenFile(uploadFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0600)
	if err != nil {
		fmt.Println(err)
	}
	n, err := io.WriteString(f, filename+"\n")
	if err != nil {
		fmt.Println(n, err)
	}
	f.Close()
}

func GenerateSlug(str string) (slug string) {
	return strings.Map(func(r rune) rune {
		switch {
		case r == ' ', r == '-':
			return '-'
		case r == '_', unicode.IsLetter(r), unicode.IsDigit(r):
			return r
		default:
			return -1
		}
		return -1
	}, strings.ToLower(strings.TrimSpace(str)))
}
<commit_msg>Use a different id3 library<commit_after>package main

import (
	"bytes"
	_ "crypto/sha512"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"unicode"

	"github.com/bogem/id3v2"
)

func downloadFile(filepath string, url string) (err error) {

	// Create the file
	out, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer out.Close()

	// Get the data
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	// Writer the body to file
	_, err = io.Copy(out, resp.Body)
	if err != nil {
		return err
	}

	return nil
}

func setID3TagsForFile(filepath string, artist string, title string) {
	mp3File, err := id3v2.Open(filepath)
	if err != nil {
		log.Fatal(err)
	}
	defer mp3File.Close()

	mp3File.SetArtist(artist)
	mp3File.SetTitle(title)

	mp3File.Save()
}

func htmlForURL(url string) string {
	client := &http.Client{}

	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0")

	resp, _ := client.Do(req)
	bytes, _ := ioutil.ReadAll(resp.Body)

	defer resp.Body.Close()
	return string(bytes)
}

func FileExists(name string) bool {
	if _, err := os.Stat(name); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

func TranscodeToMP3(originalFile string, destinationFile string) {
	args := []string{"-y", "-i", originalFile, "-q:a", "2", destinationFile}

	cmd := exec.Command("ffmpeg", args...)
	var out bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
		return
	}
}

func AddFileToUploadList(filename string) {
	uploadFile := "toUpload.m3u"

	f, err := os.OpenFile(uploadFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0600)
	if err != nil {
		fmt.Println(err)
	}
	n, err := io.WriteString(f, filename+"\n")
	if err != nil {
		fmt.Println(n, err)
	}
	f.Close()
}

func GenerateSlug(str string) (slug string) {
	return strings.Map(func(r rune) rune {
		switch {
		case r == ' ', r == '-':
			return '-'
		case r == '_', unicode.IsLetter(r), unicode.IsDigit(r):
			return r
		default:
			return -1
		}
		return -1
	}, strings.ToLower(strings.TrimSpace(str)))
}
<|endoftext|>