<commit_before>package youtubedl

import (
	"bufio"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
)

// Error youtubedl specific error
type Error string

func (e Error) Error() string {
	return string(e)
}

// Info youtubedl json, thumbnail bytes and raw JSON
type Info struct {
	Artist   string `json:"artist"`
	Uploader string `json:"uploader"`
	Creator  string `json:"creator"`

	Title       string    `json:"title"`
	Description string    `json:"description"`
	Duration    float64   `json:"duration"`
	Thumbnail   string    `json:"thumbnail"`
	Formats     []*Format `json:"formats"`

	// not unmarshalled, populated from image thumbnail file
	ThumbnailBytes []byte `json:"-"`

	// private, save raw json to be used later when downloading
	rawJSON []byte
}

// Format youtubedl downloadable format
type Format struct {
	FormatID string  `json:"format_id"`
	Protocol string  `json:"protocol"`
	Ext      string  `json:"ext"`
	ACodec   string  `json:"acodec"`
	VCodec   string  `json:"vcodec"`
	TBR      float64 `json:"tbr"`
	ABR      float64 `json:"abr"`
	VBR      float64 `json:"vbr"`

	NormBR     float64
	NormACodec string
	NormVCodec string
}

func (f *Format) String() string {
	return fmt.Sprintf("%s:%s:%s:%s:%s:%f",
		f.FormatID,
		f.Protocol,
		f.Ext,
		f.NormACodec,
		f.NormVCodec,
		f.NormBR,
	)
}

// guess codec from fuzzy codec name
func normalizeCodecName(c string) string {
	codecNameNormalizeMap := map[string]string{
		"none": "",
		"avc1": "h264",
		"mp4a": "aac",
		"mp4v": "h264",
		"h265": "hevc",
	}

	// "  NAME.something  " -> "name"
	c = strings.Trim(c, " ")
	c = strings.ToLower(c)
	p := strings.SplitN(c, ".", 2)
	c = p[0]

	if n, ok := codecNameNormalizeMap[c]; ok {
		return n
	}

	return c
}

// guess codecs based on ext
func codecFromExt(ext string) (acodec string, vcodec string) {
	switch strings.ToLower(ext) {
	case "mp3":
		return "mp3", ""
	case "mp4":
		return "aac", "h264"
	case "flv":
		return "aac", "h264"
	default:
		return "", ""
	}
}

func parseInfo(r io.Reader) (i *Info, err error) {
	i = &Info{}

	i.rawJSON, err = ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}

	if err := json.Unmarshal(i.rawJSON, i); err != nil {
		return nil, err
	}

	for _, f := range i.Formats {
		f.NormACodec = normalizeCodecName(f.ACodec)
		f.NormVCodec = normalizeCodecName(f.VCodec)

		extACodec, extVCodec := codecFromExt(f.Ext)
		if f.ACodec == "" {
			f.NormACodec = extACodec
		}
		if f.VCodec == "" {
			f.NormVCodec = extVCodec
		}

		if f.TBR != 0 {
			f.NormBR = f.TBR
		} else {
			f.NormBR = f.ABR + f.VBR
		}
	}

	return i, nil
}

// NewFromURL new Info downloaded from URL using context
func NewFromURL(ctx context.Context, url string, stdout io.Writer) (i *Info, err error) {
	tempPath, _ := ioutil.TempDir("", "ydls-youtubedl")
	defer os.RemoveAll(tempPath)

	cmd := exec.CommandContext(
		ctx,
		"youtube-dl",
		"--no-call-home",
		"--no-cache-dir",
		"--skip-download",
		"--write-info-json",
		"--write-thumbnail",
		// don't base output filename on source info
		"--output", "source",
		// provide URL via stdin for security, youtube-dl has some run command args
		"--batch-file", "-",
	)
	cmd.Dir = tempPath
	cmd.Stdout = stdout
	cmdStderr, cmdStderrErr := cmd.StderrPipe()
	if cmdStderrErr != nil {
		return nil, cmdStderrErr
	}
	cmdStdin, cmdStdinErr := cmd.StdinPipe()
	if cmdStdinErr != nil {
		return nil, cmdStdinErr
	}

	if err := cmd.Start(); err != nil {
		return nil, err
	}
	defer cmd.Wait()

	fmt.Fprintln(cmdStdin, url)
	cmdStdin.Close()

	stderrLineScanner := bufio.NewScanner(cmdStderr)
	for stderrLineScanner.Scan() {
		const errorPrefix = "ERROR: "
		line := stderrLineScanner.Text()
		if strings.HasPrefix(line, errorPrefix) {
			return nil, Error(line[len(errorPrefix):])
		}
	}

	return NewFromPath(tempPath)
}

// NewFromPath new Info from path with JSON and optional image
func NewFromPath(infoPath string) (i *Info, err error) {
	files, err := ioutil.ReadDir(infoPath)
	if err != nil {
		return nil, err
	}

	infoJSONPath := ""
	thumbnailPath := ""
	for _, f := range files {
		ext := path.Ext(f.Name())
		if ext == ".json" {
			infoJSONPath = path.Join(infoPath, f.Name())
		} else if ext == ".png" || ext == ".jpg" || ext == ".jpeg" {
			thumbnailPath = path.Join(infoPath, f.Name())
		}
	}

	if infoPath == "" {
		return nil, fmt.Errorf("no info json found")
	}

	file, err := os.Open(infoJSONPath)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	i, err = parseInfo(file)
	if err != nil {
		return nil, err
	}

	if thumbnailPath != "" {
		i.ThumbnailBytes, err = ioutil.ReadFile(thumbnailPath)
		if err != nil {
			return nil, fmt.Errorf("failed to read thumbnail")
		}
	}

	return i, nil
}

// DownloadResult download result
type DownloadResult struct {
	Reader io.ReadCloser
	waitCh chan struct{}
}

// Wait for resource cleanup
func (dr *DownloadResult) Wait() {
	<-dr.waitCh
}

// Download format matched by filter
func (i *Info) Download(ctx context.Context, filter string, stderr io.Writer) (*DownloadResult, error) {
	tempPath, tempErr := ioutil.TempDir("", "ydls-youtubedl")
	if tempErr != nil {
		return nil, tempErr
	}
	jsonTempPath := path.Join(tempPath, "info.json")
	if err := ioutil.WriteFile(jsonTempPath, i.rawJSON, 0644); err != nil {
		os.RemoveAll(tempPath)
		return nil, err
	}

	dr := &DownloadResult{
		waitCh: make(chan struct{}, 1),
	}

	cmd := exec.CommandContext(
		ctx,
		"youtube-dl",
		"--no-call-home",
		"--no-cache-dir",
		"--load-info", jsonTempPath,
		"-f", filter,
		"-o", "-",
	)
	cmd.Dir = tempPath
	var w io.WriteCloser
	dr.Reader, w = io.Pipe()
	cmd.Stdout = w
	cmd.Stderr = stderr

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	go func() {
		cmd.Wait()
		w.Close()
		os.RemoveAll(tempPath)
		close(dr.waitCh)
	}()

	return dr, nil
}
<commit_msg>youtubedl.Info does not need to be ref type<commit_after>package youtubedl

import (
	"bufio"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
)

// Error youtubedl specific error
type Error string

func (e Error) Error() string {
	return string(e)
}

// Info youtubedl json, thumbnail bytes and raw JSON
type Info struct {
	Artist   string `json:"artist"`
	Uploader string `json:"uploader"`
	Creator  string `json:"creator"`

	Title       string   `json:"title"`
	Description string   `json:"description"`
	Duration    float64  `json:"duration"`
	Thumbnail   string   `json:"thumbnail"`
	Formats     []Format `json:"formats"`

	// not unmarshalled, populated from image thumbnail file
	ThumbnailBytes []byte `json:"-"`

	// private, save raw json to be used later when downloading
	rawJSON []byte
}

// Format youtubedl downloadable format
type Format struct {
	FormatID string  `json:"format_id"`
	Protocol string  `json:"protocol"`
	Ext      string  `json:"ext"`
	ACodec   string  `json:"acodec"`
	VCodec   string  `json:"vcodec"`
	TBR      float64 `json:"tbr"`
	ABR      float64 `json:"abr"`
	VBR      float64 `json:"vbr"`

	NormBR     float64
	NormACodec string
	NormVCodec string
}

func (f Format) String() string {
	return fmt.Sprintf("%s:%s:%s:%s:%s:%f",
		f.FormatID,
		f.Protocol,
		f.Ext,
		f.NormACodec,
		f.NormVCodec,
		f.NormBR,
	)
}

// guess codec from fuzzy codec name
func normalizeCodecName(c string) string {
	codecNameNormalizeMap := map[string]string{
		"none": "",
		"avc1": "h264",
		"mp4a": "aac",
		"mp4v": "h264",
		"h265": "hevc",
	}

	// "  NAME.something  " -> "name"
	c = strings.Trim(c, " ")
	c = strings.ToLower(c)
	p := strings.SplitN(c, ".", 2)
	c = p[0]

	if n, ok := codecNameNormalizeMap[c]; ok {
		return n
	}

	return c
}

// guess codecs based on ext
func codecFromExt(ext string) (acodec string, vcodec string) {
	switch strings.ToLower(ext) {
	case "mp3":
		return "mp3", ""
	case "mp4":
		return "aac", "h264"
	case "flv":
		return "aac", "h264"
	default:
		return "", ""
	}
}

func parseInfo(r io.Reader) (info Info, err error) {
	info = Info{}

	info.rawJSON, err = ioutil.ReadAll(r)
	if err != nil {
		return Info{}, err
	}

	if err := json.Unmarshal(info.rawJSON, &info); err != nil {
		return Info{}, err
	}

	for i, _ := range info.Formats {
		f := &info.Formats[i]

		f.NormACodec = normalizeCodecName(f.ACodec)
		f.NormVCodec = normalizeCodecName(f.VCodec)

		extACodec, extVCodec := codecFromExt(f.Ext)
		if f.ACodec == "" {
			f.NormACodec = extACodec
		}
		if f.VCodec == "" {
			f.NormVCodec = extVCodec
		}

		if f.TBR != 0 {
			f.NormBR = f.TBR
		} else {
			f.NormBR = f.ABR + f.VBR
		}
	}

	return info, nil
}

// NewFromURL new Info downloaded from URL using context
func NewFromURL(ctx context.Context, url string, stdout io.Writer) (info Info, err error) {
	tempPath, _ := ioutil.TempDir("", "ydls-youtubedl")
	defer os.RemoveAll(tempPath)

	cmd := exec.CommandContext(
		ctx,
		"youtube-dl",
		"--no-call-home",
		"--no-cache-dir",
		"--skip-download",
		"--write-info-json",
		"--write-thumbnail",
		"--restrict-filenames",
		// don't base output filename on source info
		"--output", "source",
		// provide URL via stdin for security, youtube-dl has some run command args
		"--batch-file", "-",
	)
	cmd.Dir = tempPath
	cmd.Stdout = stdout
	cmdStderr, cmdStderrErr := cmd.StderrPipe()
	if cmdStderrErr != nil {
		return Info{}, cmdStderrErr
	}
	cmdStdin, cmdStdinErr := cmd.StdinPipe()
	if cmdStdinErr != nil {
		return Info{}, cmdStdinErr
	}

	if err := cmd.Start(); err != nil {
		return Info{}, err
	}
	defer cmd.Wait()

	fmt.Fprintln(cmdStdin, url)
	cmdStdin.Close()

	stderrLineScanner := bufio.NewScanner(cmdStderr)
	for stderrLineScanner.Scan() {
		const errorPrefix = "ERROR: "
		line := stderrLineScanner.Text()
		if strings.HasPrefix(line, errorPrefix) {
			return Info{}, Error(line[len(errorPrefix):])
		}
	}

	return NewFromPath(tempPath)
}

// NewFromPath new Info from path with JSON and optional image
func NewFromPath(infoPath string) (info Info, err error) {
	files, err := ioutil.ReadDir(infoPath)
	if err != nil {
		return Info{}, err
	}

	infoJSONPath := ""
	thumbnailPath := ""
	for _, f := range files {
		ext := path.Ext(f.Name())
		if ext == ".json" {
			infoJSONPath = path.Join(infoPath, f.Name())
		} else if ext == ".png" || ext == ".jpg" || ext == ".jpeg" {
			thumbnailPath = path.Join(infoPath, f.Name())
		}
	}

	if infoPath == "" {
		return Info{}, fmt.Errorf("no info json found")
	}

	file, err := os.Open(infoJSONPath)
	if err != nil {
		return Info{}, err
	}
	defer file.Close()
	info, err = parseInfo(file)
	if err != nil {
		return Info{}, err
	}

	if thumbnailPath != "" {
		info.ThumbnailBytes, err = ioutil.ReadFile(thumbnailPath)
		if err != nil {
			return Info{}, fmt.Errorf("failed to read thumbnail")
		}
	}

	return info, nil
}

// DownloadResult download result
type DownloadResult struct {
	Reader io.ReadCloser
	waitCh chan struct{}
}

// Download format matched by filter
func (info Info) Download(ctx context.Context, filter string, stderr io.Writer) (*DownloadResult, error) {
	tempPath, tempErr := ioutil.TempDir("", "ydls-youtubedl")
	if tempErr != nil {
		return nil, tempErr
	}
	jsonTempPath := path.Join(tempPath, "info.json")
	if err := ioutil.WriteFile(jsonTempPath, info.rawJSON, 0644); err != nil {
		os.RemoveAll(tempPath)
		return nil, err
	}

	dr := &DownloadResult{
		waitCh: make(chan struct{}, 1),
	}

	cmd := exec.CommandContext(
		ctx,
		"youtube-dl",
		"--no-call-home",
		"--no-cache-dir",
		"--restrict-filenames",
		"--load-info", jsonTempPath,
		"-f", filter,
		"-o", "-",
	)
	cmd.Dir = tempPath
	var w io.WriteCloser
	dr.Reader, w = io.Pipe()
	cmd.Stdout = w
	cmd.Stderr = stderr

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	go func() {
		cmd.Wait()
		w.Close()
		os.RemoveAll(tempPath)
		close(dr.waitCh)
	}()

	return dr, nil
}

// Wait for resource cleanup
func (dr *DownloadResult) Wait() {
	<-dr.waitCh
}
<|endoftext|>


<commit_before>package zerologger

import (
	"fmt"
	"path"
	"path/filepath"
	"strings"

	"goa.design/goa/v3/codegen"
	"goa.design/goa/v3/eval"
	"goa.design/goa/v3/expr"
)

type fileToModify struct {
	file        *codegen.File
	path        string
	serviceName string
	isMain      bool
}

// Register the plugin Generator functions.
func init() {
	codegen.RegisterPluginFirst("zerologger", "gen", nil, Generate)
	codegen.RegisterPluginLast("zerologger-updater", "example", nil, UpdateExample)
}

// Generate generates zerolog logger specific files.
func Generate(genpkg string, roots []eval.Root, files []*codegen.File) ([]*codegen.File, error) {
	for _, root := range roots {
		if r, ok := root.(*expr.RootExpr); ok {
			files = append(files, GenerateFiles(genpkg, r)...)
		}
	}
	return files, nil
}

// UpdateExample modifies the example generated files by replacing
// the log import reference when needed
// It also modify the initially generated main and service files
func UpdateExample(genpkg string, roots []eval.Root, files []*codegen.File) ([]*codegen.File, error) {

	filesToModify := []*fileToModify{}

	for _, root := range roots {
		if r, ok := root.(*expr.RootExpr); ok {

			// Add the generated main files
			for _, svr := range r.API.Servers {
				pkg := codegen.SnakeCase(codegen.Goify(svr.Name, true))
				filesToModify = append(filesToModify,
					&fileToModify{path: filepath.Join("cmd", pkg, "main.go"), serviceName: svr.Name, isMain: true})
				filesToModify = append(filesToModify,
					&fileToModify{path: filepath.Join("cmd", pkg, "http.go"), serviceName: svr.Name, isMain: true})
				filesToModify = append(filesToModify,
					&fileToModify{path: filepath.Join("cmd", pkg, "grpc.go"), serviceName: svr.Name, isMain: true})
			}

			// Add the generated service files
			for _, svc := range r.API.HTTP.Services {
				servicePath := codegen.SnakeCase(svc.Name()) + ".go"
				filesToModify = append(filesToModify, &fileToModify{path: servicePath, serviceName: svc.Name(), isMain: false})
			}

			// Update the added files
			for _, fileToModify := range filesToModify {
				for _, file := range files {
					if file.Path == fileToModify.path {
						fileToModify.file = file
						updateExampleFile(genpkg, r, fileToModify)
						break
					}
				}
			}
		}
	}

	return files, nil
}

// GenerateFiles create log specific files
func GenerateFiles(genpkg string, root *expr.RootExpr) []*codegen.File {
	fw := make([]*codegen.File, 1)
	fw[0] = GenerateLoggerFile(genpkg)
	return fw
}

// GenerateLoggerFile returns the generated zerolog logger file.
func GenerateLoggerFile(genpkg string) *codegen.File {
	path := filepath.Join(codegen.Gendir, "log", "logger.go")
	title := fmt.Sprint("Zerolog logger implementation")
	sections := []*codegen.SectionTemplate{
		codegen.Header(title, "log", []*codegen.ImportSpec{
			{Path: "github.com/rs/zerolog"},
			{Path: "goa.design/goa/v3/http/middleware"},
			{Path: "os"},
			{Path: "fmt"},
		}),
	}

	sections = append(sections, &codegen.SectionTemplate{
		Name:   "zerologger",
		Source: loggerT,
	})

	return &codegen.File{Path: path, SectionTemplates: sections}
}

func updateExampleFile(genpkg string, root *expr.RootExpr, f *fileToModify) {

	header := f.file.SectionTemplates[0]
	logPath := path.Join(genpkg, "log")

	data := header.Data.(map[string]interface{})
	specs := data["Imports"].([]*codegen.ImportSpec)

	for _, spec := range specs {
		if spec.Path == "log" {
			spec.Name = "log"
			spec.Path = logPath
		}
	}

	if f.isMain {

		codegen.AddImport(header, &codegen.ImportSpec{Path: "github.com/rs/zerolog"})

		for _, s := range f.file.SectionTemplates {
			s.Source = strings.Replace(s.Source, `logger = log.New(os.Stderr, "[{{ .APIPkg }}] ", log.Ltime)`,
				`logger = log.New("{{ .APIPkg }}", false)`, 1)
			s.Source = strings.Replace(s.Source, "adapter = middleware.NewLogger(logger)", "adapter = logger", 1)
			s.Source = strings.Replace(s.Source, "handler = middleware.RequestID()(handler)",
				`handler = middleware.PopulateRequestContext()(handler)
				handler = middleware.RequestID(middleware.UseXRequestIDHeaderOption(true))(handler)`, 1)
			s.Source = strings.Replace(s.Source, `logger.Printf("[%s] ERROR: %s", id, err.Error())`,
				`logger.Error().Str("id",id).Err(err.Error())`, 1)
			s.Source = strings.Replace(s.Source, "logger.Print(", "logger.Info().Msg(", -1)
			s.Source = strings.Replace(s.Source, "logger.Printf(", "logger.Info().Msg(", -1)
			s.Source = strings.Replace(s.Source, "logger.Println(", "logger.Info().Msg(", -1)
		}
	} else {
		for _, s := range f.file.SectionTemplates {
			s.Source = strings.Replace(s.Source, "logger.Print(", "logger.Info().Msg(", -1)
			s.Source = strings.Replace(s.Source, "logger.Printf(", "logger.Info().Msg(", -1)
			s.Source = strings.Replace(s.Source, "logger.Println(", "logger.Info().Msg(", -1)
		}
	}
}

const loggerT =`
// Logger is an adapted zerologger
type Logger struct {
	*zerolog.Logger
}

// New creates a new zerologger
func New(serviceName string, isDebug bool) *Logger {
	logLevel := zerolog.InfoLevel
	if isDebug {
		logLevel = zerolog.DebugLevel
	}
	zerolog.SetGlobalLevel(logLevel)
    logger := zerolog.New(os.Stderr).With().Str("service", serviceName).Logger()
	return &Logger{&logger}
}

// Log is called by the log middleware to log HTTP requests key values
func (logger *Logger) Log(keyvals ...interface{}) error {
	fields := FormatFields(keyvals)
	logger.Info().Fields(fields).Msgf("HTTP Request")
	return nil
}

// formatFields formats input keyvals
// ref: https://github.com/goadesign/goa/blob/v1/logging/logrus/adapter.go#L64
func FormatFields(keyvals []interface{}) map[string]interface{} {
	n := (len(keyvals) + 1) / 2
	res := make(map[string]interface{}, n)
	for i := 0; i < len(keyvals); i += 2 {
		k := keyvals[i]
		var v interface{}
		if i+1 < len(keyvals) {
			v = keyvals[i+1]
		}
		res[fmt.Sprintf("%v", k)] = v
	}
	return res
}
`
<commit_msg>fix use msgf<commit_after>package zerologger

import (
	"fmt"
	"path"
	"path/filepath"
	"strings"

	"goa.design/goa/v3/codegen"
	"goa.design/goa/v3/eval"
	"goa.design/goa/v3/expr"
)

type fileToModify struct {
	file        *codegen.File
	path        string
	serviceName string
	isMain      bool
}

// Register the plugin Generator functions.
func init() {
	codegen.RegisterPluginFirst("zerologger", "gen", nil, Generate)
	codegen.RegisterPluginLast("zerologger-updater", "example", nil, UpdateExample)
}

// Generate generates zerolog logger specific files.
func Generate(genpkg string, roots []eval.Root, files []*codegen.File) ([]*codegen.File, error) {
	for _, root := range roots {
		if r, ok := root.(*expr.RootExpr); ok {
			files = append(files, GenerateFiles(genpkg, r)...)
		}
	}
	return files, nil
}

// UpdateExample modifies the example generated files by replacing
// the log import reference when needed
// It also modify the initially generated main and service files
func UpdateExample(genpkg string, roots []eval.Root, files []*codegen.File) ([]*codegen.File, error) {

	filesToModify := []*fileToModify{}

	for _, root := range roots {
		if r, ok := root.(*expr.RootExpr); ok {

			// Add the generated main files
			for _, svr := range r.API.Servers {
				pkg := codegen.SnakeCase(codegen.Goify(svr.Name, true))
				filesToModify = append(filesToModify,
					&fileToModify{path: filepath.Join("cmd", pkg, "main.go"), serviceName: svr.Name, isMain: true})
				filesToModify = append(filesToModify,
					&fileToModify{path: filepath.Join("cmd", pkg, "http.go"), serviceName: svr.Name, isMain: true})
				filesToModify = append(filesToModify,
					&fileToModify{path: filepath.Join("cmd", pkg, "grpc.go"), serviceName: svr.Name, isMain: true})
			}

			// Add the generated service files
			for _, svc := range r.API.HTTP.Services {
				servicePath := codegen.SnakeCase(svc.Name()) + ".go"
				filesToModify = append(filesToModify, &fileToModify{path: servicePath, serviceName: svc.Name(), isMain: false})
			}

			// Update the added files
			for _, fileToModify := range filesToModify {
				for _, file := range files {
					if file.Path == fileToModify.path {
						fileToModify.file = file
						updateExampleFile(genpkg, r, fileToModify)
						break
					}
				}
			}
		}
	}

	return files, nil
}

// GenerateFiles create log specific files
func GenerateFiles(genpkg string, root *expr.RootExpr) []*codegen.File {
	fw := make([]*codegen.File, 1)
	fw[0] = GenerateLoggerFile(genpkg)
	return fw
}

// GenerateLoggerFile returns the generated zerolog logger file.
func GenerateLoggerFile(genpkg string) *codegen.File {
	path := filepath.Join(codegen.Gendir, "log", "logger.go")
	title := fmt.Sprint("Zerolog logger implementation")
	sections := []*codegen.SectionTemplate{
		codegen.Header(title, "log", []*codegen.ImportSpec{
			{Path: "github.com/rs/zerolog"},
			{Path: "goa.design/goa/v3/http/middleware"},
			{Path: "os"},
			{Path: "fmt"},
		}),
	}

	sections = append(sections, &codegen.SectionTemplate{
		Name:   "zerologger",
		Source: loggerT,
	})

	return &codegen.File{Path: path, SectionTemplates: sections}
}

func updateExampleFile(genpkg string, root *expr.RootExpr, f *fileToModify) {

	header := f.file.SectionTemplates[0]
	logPath := path.Join(genpkg, "log")

	data := header.Data.(map[string]interface{})
	specs := data["Imports"].([]*codegen.ImportSpec)

	for _, spec := range specs {
		if spec.Path == "log" {
			spec.Name = "log"
			spec.Path = logPath
		}
	}

	if f.isMain {

		codegen.AddImport(header, &codegen.ImportSpec{Path: "github.com/rs/zerolog"})

		for _, s := range f.file.SectionTemplates {
			s.Source = strings.Replace(s.Source, `logger = log.New(os.Stderr, "[{{ .APIPkg }}] ", log.Ltime)`,
				`logger = log.New("{{ .APIPkg }}", false)`, 1)
			s.Source = strings.Replace(s.Source, "adapter = middleware.NewLogger(logger)", "adapter = logger", 1)
			s.Source = strings.Replace(s.Source, "handler = middleware.RequestID()(handler)",
				`handler = middleware.PopulateRequestContext()(handler)
				handler = middleware.RequestID(middleware.UseXRequestIDHeaderOption(true))(handler)`, 1)
			s.Source = strings.Replace(s.Source, `logger.Printf("[%s] ERROR: %s", id, err.Error())`,
				`logger.Error().Str("id", id).Err(err).Send()`, 1)
			s.Source = strings.Replace(s.Source, "logger.Print(", "logger.Info().Msg(", -1)
			s.Source = strings.Replace(s.Source, "logger.Printf(", "logger.Info().Msgf(", -1)
			s.Source = strings.Replace(s.Source, "logger.Println(", "logger.Info().Msg(", -1)
		}
	} else {
		for _, s := range f.file.SectionTemplates {
			s.Source = strings.Replace(s.Source, "logger.Print(", "logger.Info().Msg(", -1)
			s.Source = strings.Replace(s.Source, "logger.Printf(", "logger.Info().Msgf(", -1)
			s.Source = strings.Replace(s.Source, "logger.Println(", "logger.Info().Msg(", -1)
		}
	}
}

const loggerT =`
// Logger is an adapted zerologger
type Logger struct {
	*zerolog.Logger
}

// New creates a new zerologger
func New(serviceName string, isDebug bool) *Logger {
	logLevel := zerolog.InfoLevel
	if isDebug {
		logLevel = zerolog.DebugLevel
	}
	zerolog.SetGlobalLevel(logLevel)
    logger := zerolog.New(os.Stderr).With().Str("service", serviceName).Logger()
	return &Logger{&logger}
}

// Log is called by the log middleware to log HTTP requests key values
func (logger *Logger) Log(keyvals ...interface{}) error {
	fields := FormatFields(keyvals)
	logger.Info().Fields(fields).Msgf("HTTP Request")
	return nil
}

// formatFields formats input keyvals
// ref: https://github.com/goadesign/goa/blob/v1/logging/logrus/adapter.go#L64
func FormatFields(keyvals []interface{}) map[string]interface{} {
	n := (len(keyvals) + 1) / 2
	res := make(map[string]interface{}, n)
	for i := 0; i < len(keyvals); i += 2 {
		k := keyvals[i]
		var v interface{}
		if i+1 < len(keyvals) {
			v = keyvals[i+1]
		}
		res[fmt.Sprintf("%v", k)] = v
	}
	return res
}
`
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"io"
	"log"
	"os"
	"path/filepath"

	"github.com/jessevdk/go-flags"
	"github.com/mit-dci/lit/lnutil"
)

// createDefaultConfigFile creates a config file  -- only call this if the
// config file isn't already there
func createDefaultConfigFile(destinationPath string) error {

	dest, err := os.OpenFile(filepath.Join(destinationPath, defaultConfigFilename),
		os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return err
	}
	defer dest.Close()

	writer := bufio.NewWriter(dest)
	defaultArgs := []byte("tn3=1")
	_, err = writer.Write(defaultArgs)
	if err != nil {
		return err
	}
	writer.Flush()
	return nil
}

// litSetup performs most of the setup when lit is run, such as setting
// configuration variables, reading in key data, reading and creating files if
// they're not yet there.  It takes in a config, and returns a key.
// (maybe add the key to the config?
func litSetup(conf *config) *[32]byte {
	// Pre-parse the command line options to see if an alternative config
	// file or the version flag was specified.  Any errors aside from the
	// help message error can be ignored here since they will be caught by
	// the final parse below.

	//	usageMessage := fmt.Sprintf("Use %s -h to show usage", "./lit")

	preconf := *conf
	preParser := newConfigParser(&preconf, flags.HelpFlag)
	_, err := preParser.ParseArgs(os.Args)
	if err != nil {
		if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp {
			log.Fatal(err)
		}
	}

	// Load config from file
	parser := newConfigParser(conf, flags.Default) //parse

	_, err = os.Stat(preconf.LitHomeDir) // create directory
	if err != nil {
		log.Println("Error while creating a directory")
	}
	if os.IsNotExist(err) {
		// first time the guy is running lit, lets set tn3 to true
		os.Mkdir(preconf.LitHomeDir, 0700)
		log.Println("Creating a new config file")
		err := createDefaultConfigFile(preconf.LitHomeDir) // Source of error
		if err != nil {
			log.Println("Error creating a default config file: %v\n")
			log.Fatal(err)
		}
	}

	if _, err := os.Stat(filepath.Join(filepath.Join(preconf.LitHomeDir), "lit.conf")); os.IsNotExist(err) {
		// if there is no config file found over at the directory, create one
		if err != nil {
			log.Println(err)
		}
		log.Println("Creating a new config file")
		err := createDefaultConfigFile(filepath.Join(preconf.LitHomeDir)) // Source of error
		if err != nil {
			log.Fatal(err)
		}
	}

	preconf.ConfigFile = filepath.Join(filepath.Join(preconf.LitHomeDir), "lit.conf")
	// lets parse the config file provided, if any
	err = flags.NewIniParser(parser).ParseFile(preconf.ConfigFile)
	if err != nil {
		_, ok := err.(*os.PathError)
		if !ok {
			log.Fatal(err)
		}
	}
	// Parse command line options again to ensure they take precedence.
	_, err = parser.ParseArgs(os.Args) // returns invalid flags
	if err != nil {
		log.Fatal(err)
	}

	logFilePath := filepath.Join(conf.LitHomeDir, "lit.log")

	logfile, err := os.OpenFile(logFilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	// TODO ... what's this do?
	defer logfile.Close()

	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)

	if conf.Verbose {
		logOutput := io.MultiWriter(os.Stdout, logfile)
		log.SetOutput(logOutput)
	} else {
		log.SetOutput(logfile)
	}

	// Allow node with no linked wallets, for testing.
	// TODO Should update tests and disallow nodes without wallets later.
	//	if conf.Tn3host == "" && conf.Lt4host == "" && conf.Reghost == "" {
	//		log.Fatal("error: no network specified; use -tn3, -reg, -lt4")
	//	}

	// Keys: the litNode, and wallits, all get 32 byte keys.
	// Right now though, they all get the *same* key.  For lit as a single binary
	// now, all using the same key makes sense; could split up later.

	keyFilePath := filepath.Join(conf.LitHomeDir, defaultKeyFileName)

	// read key file (generate if not found)
	key, err := lnutil.ReadKeyFile(keyFilePath)
	if err != nil {
		log.Fatal(err)
	}

	return key
}
<commit_msg>Resolve bug where unknown flag message is displayed twice (#147)<commit_after>package main

import (
	"bufio"
	"io"
	"log"
	"os"
	"path/filepath"

	"github.com/jessevdk/go-flags"
	"github.com/mit-dci/lit/lnutil"
)

// createDefaultConfigFile creates a config file  -- only call this if the
// config file isn't already there
func createDefaultConfigFile(destinationPath string) error {

	dest, err := os.OpenFile(filepath.Join(destinationPath, defaultConfigFilename),
		os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return err
	}
	defer dest.Close()

	writer := bufio.NewWriter(dest)
	defaultArgs := []byte("tn3=1")
	_, err = writer.Write(defaultArgs)
	if err != nil {
		return err
	}
	writer.Flush()
	return nil
}

// litSetup performs most of the setup when lit is run, such as setting
// configuration variables, reading in key data, reading and creating files if
// they're not yet there.  It takes in a config, and returns a key.
// (maybe add the key to the config?
func litSetup(conf *config) *[32]byte {
	// Pre-parse the command line options to see if an alternative config
	// file or the version flag was specified.  Any errors aside from the
	// help message error can be ignored here since they will be caught by
	// the final parse below.

	//	usageMessage := fmt.Sprintf("Use %s -h to show usage", "./lit")

	preconf := *conf
	preParser := newConfigParser(&preconf, flags.HelpFlag)
	_, err := preParser.ParseArgs(os.Args)
	if err != nil {
		log.Fatal(err)
	}

	// Load config from file and parse
	parser := newConfigParser(conf, flags.Default)

 	// create home directory
	_, err = os.Stat(preconf.LitHomeDir)
	if err != nil {
		log.Println("Error while creating a directory")
	}
	if os.IsNotExist(err) {
		// first time the guy is running lit, lets set tn3 to true
		os.Mkdir(preconf.LitHomeDir, 0700)
		log.Println("Creating a new config file")
		err := createDefaultConfigFile(preconf.LitHomeDir) // Source of error
		if err != nil {
			log.Println("Error creating a default config file: %v\n")
			log.Fatal(err)
		}
	}

	if _, err := os.Stat(filepath.Join(filepath.Join(preconf.LitHomeDir), "lit.conf")); os.IsNotExist(err) {
		// if there is no config file found over at the directory, create one
		if err != nil {
			log.Println(err)
		}
		log.Println("Creating a new config file")
		err := createDefaultConfigFile(filepath.Join(preconf.LitHomeDir)) // Source of error
		if err != nil {
			log.Fatal(err)
		}
	}

	preconf.ConfigFile = filepath.Join(filepath.Join(preconf.LitHomeDir), "lit.conf")
	// lets parse the config file provided, if any
	err = flags.NewIniParser(parser).ParseFile(preconf.ConfigFile)
	if err != nil {
		_, ok := err.(*os.PathError)
		if !ok {
			log.Fatal(err)
		}
	}
	// Parse command line options again to ensure they take precedence.
	_, err = parser.ParseArgs(os.Args) // returns invalid flags
	if err != nil {
		log.Fatal(err)
	}

	logFilePath := filepath.Join(conf.LitHomeDir, "lit.log")

	logfile, err := os.OpenFile(logFilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	// TODO ... what's this do?
	defer logfile.Close()

	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)

	if conf.Verbose {
		logOutput := io.MultiWriter(os.Stdout, logfile)
		log.SetOutput(logOutput)
	} else {
		log.SetOutput(logfile)
	}

	// Allow node with no linked wallets, for testing.
	// TODO Should update tests and disallow nodes without wallets later.
	//	if conf.Tn3host == "" && conf.Lt4host == "" && conf.Reghost == "" {
	//		log.Fatal("error: no network specified; use -tn3, -reg, -lt4")
	//	}

	// Keys: the litNode, and wallits, all get 32 byte keys.
	// Right now though, they all get the *same* key.  For lit as a single binary
	// now, all using the same key makes sense; could split up later.

	keyFilePath := filepath.Join(conf.LitHomeDir, defaultKeyFileName)

	// read key file (generate if not found)
	key, err := lnutil.ReadKeyFile(keyFilePath)
	if err != nil {
		log.Fatal(err)
	}

	return key
}
<|endoftext|>


<commit_before>package goopenzwave

// #include "gzw_notification.h"
// #include <stdlib.h>
import "C"
import (
	"fmt"
)

// NotificationType defines a type for the notification type enum.
type NotificationType int

const (
	NotificationTypeValueAdded NotificationType = iota
	NotificationTypeValueRemoved
	NotificationTypeValueChanged
	NotificationTypeValueRefreshed
	NotificationTypeGroup
	NotificationTypeNodeNew
	NotificationTypeNodeAdded
	NotificationTypeNodeRemoved
	NotificationTypeNodeProtocolInfo
	NotificationTypeNodeNaming
	NotificationTypeNodeEvent
	NotificationTypePollingDisabled
	NotificationTypePollingEnabled
	NotificationTypeSceneEvent
	NotificationTypeCreateButton
	NotificationTypeDeleteButton
	NotificationTypeButtonOn
	NotificationTypeButtonOff
	NotificationTypeDriverReady
	NotificationTypeDriverFailed
	NotificationTypeDriverReset
	NotificationTypeEssentialNodeQueriesComplete
	NotificationTypeNodeQueriesComplete
	NotificationTypeAwakeNodesQueried
	NotificationTypeAllNodesQueriedSomeDead
	NotificationTypeAllNodesQueried
	NotificationTypeNotification
	NotificationTypeDriverRemoved
	NotificationTypeControllerCommand
	NotificationTypeNodeReset
)

func (nt NotificationType) String() string {
	switch nt {
	case NotificationTypeValueAdded:
		return "ValueAdded"
	case NotificationTypeValueRemoved:
		return "ValueRemoved"
	case NotificationTypeValueChanged:
		return "ValueChanged"
	case NotificationTypeValueRefreshed:
		return "ValueRefreshed"
	case NotificationTypeGroup:
		return "Group"
	case NotificationTypeNodeNew:
		return "NodeNew"
	case NotificationTypeNodeAdded:
		return "NodeAdded"
	case NotificationTypeNodeRemoved:
		return "NodeRemoved"
	case NotificationTypeNodeProtocolInfo:
		return "NodeProtocolInfo"
	case NotificationTypeNodeNaming:
		return "NodeNaming"
	case NotificationTypeNodeEvent:
		return "NodeEvent"
	case NotificationTypePollingDisabled:
		return "PollingDisabled"
	case NotificationTypePollingEnabled:
		return "PollingEnabled"
	case NotificationTypeSceneEvent:
		return "SceneEvent"
	case NotificationTypeCreateButton:
		return "CreateButton"
	case NotificationTypeDeleteButton:
		return "DeleteButton"
	case NotificationTypeButtonOn:
		return "ButtonOn"
	case NotificationTypeButtonOff:
		return "ButtonOff"
	case NotificationTypeDriverReady:
		return "DriverReady"
	case NotificationTypeDriverFailed:
		return "DriverFailed"
	case NotificationTypeDriverReset:
		return "DriverReset"
	case NotificationTypeEssentialNodeQueriesComplete:
		return "EssentialNodeQueriesComplete"
	case NotificationTypeNodeQueriesComplete:
		return "NodeQueriesComplete"
	case NotificationTypeAwakeNodesQueried:
		return "AwakeNodesQueried"
	case NotificationTypeAllNodesQueriedSomeDead:
		return "AllNodesQueriedSomeDead"
	case NotificationTypeAllNodesQueried:
		return "AllNodesQueried"
	case NotificationTypeNotification:
		return "Notification"
	case NotificationTypeDriverRemoved:
		return "DriverRemoved"
	case NotificationTypeControllerCommand:
		return "ControllerCommand"
	case NotificationTypeNodeReset:
		return "NodeReset"
	}
	return "UNKNOWN"
}

// NotificationCode defines a type for the notification code enum.
type NotificationCode int

const (
	NotificationCodeMsgComplete NotificationCode = iota // C.notification_code_msgComplete
	NotificationCodeTimeout                             // C.notification_code_timeout
	NotificationCodeNoOperation                         // C.notification_code_noOperation
	NotificationCodeAwake                               // C.notification_code_awake
	NotificationCodeSleep                               // C.notification_code_sleep
	NotificationCodeDead                                // C.notification_code_dead
	NotificationCodeAlive                               // C.notification_code_alive
)

func (nc NotificationCode) String() string {
	switch nc {
	case NotificationCodeMsgComplete:
		return "MsgComplete"
	case NotificationCodeTimeout:
		return "Timeout"
	case NotificationCodeNoOperation:
		return "NoOperation"
	case NotificationCodeAwake:
		return "Awake"
	case NotificationCodeSleep:
		return "Sleep"
	case NotificationCodeDead:
		return "Dead"
	case NotificationCodeAlive:
		return "Alive"
	}
	return "UNKNOWN"
}

// Notification is a container for the C++ OpenZWave library Notification class.
type Notification struct {
	Type         NotificationType
	HomeID       uint32
	NodeID       uint8
	ValueID      *ValueID
	GroupIDX     *uint8
	Event        *uint8
	ButtonID     *uint8
	SceneID      *uint8
	Notification *NotificationCode
}

// buildNotification builds a new Notification filled with the relevant
// information from the OpenZWave::Notification as received from the OpenZWave
// library.
func buildNotification(n C.notification_t) *Notification {
	notification := &Notification{
		HomeID:  uint32(C.notification_getHomeId(n)),
		NodeID:  uint8(C.notification_getNodeId(n)),
		ValueID: buildValueID(C.notification_getValueId(n)),
	}

	switch C.notification_getType(n) {
	case C.notification_type_valueAdded:
		notification.Type = NotificationTypeValueAdded
	case C.notification_type_valueRemoved:
		notification.Type = NotificationTypeValueRemoved
	case C.notification_type_valueChanged:
		notification.Type = NotificationTypeValueChanged
	case C.notification_type_valueRefreshed:
		notification.Type = NotificationTypeValueRefreshed
	case C.notification_type_group:
		notification.Type = NotificationTypeGroup
	case C.notification_type_nodeNew:
		notification.Type = NotificationTypeNodeNew
	case C.notification_type_nodeAdded:
		notification.Type = NotificationTypeNodeAdded
	case C.notification_type_nodeRemoved:
		notification.Type = NotificationTypeNodeRemoved
	case C.notification_type_nodeProtocolInfo:
		notification.Type = NotificationTypeNodeProtocolInfo
	case C.notification_type_nodeNaming:
		notification.Type = NotificationTypeNodeNaming
	case C.notification_type_nodeEvent:
		notification.Type = NotificationTypeNodeEvent
	case C.notification_type_pollingDisabled:
		notification.Type = NotificationTypePollingDisabled
	case C.notification_type_pollingEnabled:
		notification.Type = NotificationTypePollingEnabled
	case C.notification_type_sceneEvent:
		notification.Type = NotificationTypeSceneEvent
	case C.notification_type_createButton:
		notification.Type = NotificationTypeCreateButton
	case C.notification_type_deleteButton:
		notification.Type = NotificationTypeDeleteButton
	case C.notification_type_buttonOn:
		notification.Type = NotificationTypeButtonOn
	case C.notification_type_buttonOff:
		notification.Type = NotificationTypeButtonOff
	case C.notification_type_driverReady:
		notification.Type = NotificationTypeDriverReady
	case C.notification_type_driverFailed:
		notification.Type = NotificationTypeDriverFailed
	case C.notification_type_driverReset:
		notification.Type = NotificationTypeDriverReset
	case C.notification_type_essentialNodeQueriesComplete:
		notification.Type = NotificationTypeEssentialNodeQueriesComplete
	case C.notification_type_nodeQueriesComplete:
		notification.Type = NotificationTypeNodeQueriesComplete
	case C.notification_type_awakeNodesQueried:
		notification.Type = NotificationTypeAwakeNodesQueried
	case C.notification_type_allNodesQueriedSomeDead:
		notification.Type = NotificationTypeAllNodesQueriedSomeDead
	case C.notification_type_allNodesQueried:
		notification.Type = NotificationTypeAllNodesQueried
	case C.notification_type_notification:
		notification.Type = NotificationTypeNotification
	case C.notification_type_driverRemoved:
		notification.Type = NotificationTypeDriverRemoved
	case C.notification_type_controllerCommand:
		notification.Type = NotificationTypeControllerCommand
	case C.notification_type_nodeReset:
		notification.Type = NotificationTypeNodeReset
	}

	switch notification.Type {
	case NotificationTypeCreateButton, NotificationTypeDeleteButton, NotificationTypeButtonOn, NotificationTypeButtonOff:
		if notification.ButtonID == nil {
			notification.ButtonID = new(uint8)
		}
		*(notification.ButtonID) = uint8(C.notification_getButtonId(n))

	case NotificationTypeNodeEvent:
		if notification.Event == nil {
			notification.Event = new(uint8)
		}
		*(notification.Event) = uint8(C.notification_getEvent(n))

	case NotificationTypeGroup:
		if notification.GroupIDX == nil {
			notification.GroupIDX = new(uint8)
		}
		*(notification.GroupIDX) = uint8(C.notification_getGroupIdx(n))

	case NotificationTypeNotification:
		if notification.Notification == nil {
			notification.Notification = new(NotificationCode)
		}
		switch C.notification_getNotification(n) {
		case C.notification_code_msgComplete:
			*notification.Notification = NotificationCodeMsgComplete
		case C.notification_code_timeout:
			*notification.Notification = NotificationCodeTimeout
		case C.notification_code_noOperation:
			*notification.Notification = NotificationCodeNoOperation
		case C.notification_code_awake:
			*notification.Notification = NotificationCodeAwake
		case C.notification_code_sleep:
			*notification.Notification = NotificationCodeSleep
		case C.notification_code_dead:
			*notification.Notification = NotificationCodeDead
		case C.notification_code_alive:
			*notification.Notification = NotificationCodeAlive
		}

	case NotificationTypeControllerCommand:
		if notification.Event == nil {
			notification.Event = new(uint8)
		}
		*(notification.Event) = uint8(C.notification_getEvent(n))
		if notification.Notification == nil {
			notification.Notification = new(NotificationCode)
		}
		*(notification.Notification) = NotificationCode(C.notification_getNotification(n))

	case NotificationTypeSceneEvent:
		if notification.SceneID == nil {
			notification.SceneID = new(uint8)
		}
		*(notification.SceneID) = uint8(C.notification_getSceneId(n))
	}

	return notification
}

func (n *Notification) String() string {
	var pointed []string
	if n.GroupIDX != nil {
		pointed = append(pointed, fmt.Sprintf("GroupIDX: %d", *(n.GroupIDX)))
	}
	if n.Event != nil {
		pointed = append(pointed, fmt.Sprintf("Event: %d", *(n.Event)))
	}
	if n.ButtonID != nil {
		pointed = append(pointed, fmt.Sprintf("ButtonID: %d", *(n.ButtonID)))
	}
	if n.SceneID != nil {
		pointed = append(pointed, fmt.Sprintf("SceneID: %d", *(n.SceneID)))
	}
	if n.Notification != nil {
		pointed = append(pointed, fmt.Sprintf("Notification: %d", *(n.Notification)))
	}
	output := fmt.Sprintf("{Type: %s, HomeID: %d, NodeID: %d, ValueID: %s", n.Type, n.HomeID, n.NodeID, n.ValueID)
	for i := range pointed {
		output = fmt.Sprintf("%s, %s", output, pointed[i])
	}
	output = fmt.Sprintf("%s}", output)
	return output
}
<commit_msg>notification: only get valueid when necessary<commit_after>package goopenzwave

// #include "gzw_notification.h"
// #include <stdlib.h>
import "C"
import (
	"fmt"
)

// NotificationType defines a type for the notification type enum.
type NotificationType int

const (
	NotificationTypeValueAdded NotificationType = iota
	NotificationTypeValueRemoved
	NotificationTypeValueChanged
	NotificationTypeValueRefreshed
	NotificationTypeGroup
	NotificationTypeNodeNew
	NotificationTypeNodeAdded
	NotificationTypeNodeRemoved
	NotificationTypeNodeProtocolInfo
	NotificationTypeNodeNaming
	NotificationTypeNodeEvent
	NotificationTypePollingDisabled
	NotificationTypePollingEnabled
	NotificationTypeSceneEvent
	NotificationTypeCreateButton
	NotificationTypeDeleteButton
	NotificationTypeButtonOn
	NotificationTypeButtonOff
	NotificationTypeDriverReady
	NotificationTypeDriverFailed
	NotificationTypeDriverReset
	NotificationTypeEssentialNodeQueriesComplete
	NotificationTypeNodeQueriesComplete
	NotificationTypeAwakeNodesQueried
	NotificationTypeAllNodesQueriedSomeDead
	NotificationTypeAllNodesQueried
	NotificationTypeNotification
	NotificationTypeDriverRemoved
	NotificationTypeControllerCommand
	NotificationTypeNodeReset
)

func (nt NotificationType) String() string {
	switch nt {
	case NotificationTypeValueAdded:
		return "ValueAdded"
	case NotificationTypeValueRemoved:
		return "ValueRemoved"
	case NotificationTypeValueChanged:
		return "ValueChanged"
	case NotificationTypeValueRefreshed:
		return "ValueRefreshed"
	case NotificationTypeGroup:
		return "Group"
	case NotificationTypeNodeNew:
		return "NodeNew"
	case NotificationTypeNodeAdded:
		return "NodeAdded"
	case NotificationTypeNodeRemoved:
		return "NodeRemoved"
	case NotificationTypeNodeProtocolInfo:
		return "NodeProtocolInfo"
	case NotificationTypeNodeNaming:
		return "NodeNaming"
	case NotificationTypeNodeEvent:
		return "NodeEvent"
	case NotificationTypePollingDisabled:
		return "PollingDisabled"
	case NotificationTypePollingEnabled:
		return "PollingEnabled"
	case NotificationTypeSceneEvent:
		return "SceneEvent"
	case NotificationTypeCreateButton:
		return "CreateButton"
	case NotificationTypeDeleteButton:
		return "DeleteButton"
	case NotificationTypeButtonOn:
		return "ButtonOn"
	case NotificationTypeButtonOff:
		return "ButtonOff"
	case NotificationTypeDriverReady:
		return "DriverReady"
	case NotificationTypeDriverFailed:
		return "DriverFailed"
	case NotificationTypeDriverReset:
		return "DriverReset"
	case NotificationTypeEssentialNodeQueriesComplete:
		return "EssentialNodeQueriesComplete"
	case NotificationTypeNodeQueriesComplete:
		return "NodeQueriesComplete"
	case NotificationTypeAwakeNodesQueried:
		return "AwakeNodesQueried"
	case NotificationTypeAllNodesQueriedSomeDead:
		return "AllNodesQueriedSomeDead"
	case NotificationTypeAllNodesQueried:
		return "AllNodesQueried"
	case NotificationTypeNotification:
		return "Notification"
	case NotificationTypeDriverRemoved:
		return "DriverRemoved"
	case NotificationTypeControllerCommand:
		return "ControllerCommand"
	case NotificationTypeNodeReset:
		return "NodeReset"
	}
	return "UNKNOWN"
}

// NotificationCode defines a type for the notification code enum.
type NotificationCode int

const (
	NotificationCodeMsgComplete NotificationCode = iota // C.notification_code_msgComplete
	NotificationCodeTimeout                             // C.notification_code_timeout
	NotificationCodeNoOperation                         // C.notification_code_noOperation
	NotificationCodeAwake                               // C.notification_code_awake
	NotificationCodeSleep                               // C.notification_code_sleep
	NotificationCodeDead                                // C.notification_code_dead
	NotificationCodeAlive                               // C.notification_code_alive
)

func (nc NotificationCode) String() string {
	switch nc {
	case NotificationCodeMsgComplete:
		return "MsgComplete"
	case NotificationCodeTimeout:
		return "Timeout"
	case NotificationCodeNoOperation:
		return "NoOperation"
	case NotificationCodeAwake:
		return "Awake"
	case NotificationCodeSleep:
		return "Sleep"
	case NotificationCodeDead:
		return "Dead"
	case NotificationCodeAlive:
		return "Alive"
	}
	return "UNKNOWN"
}

// Notification is a container for the C++ OpenZWave library Notification class.
type Notification struct {
	Type         NotificationType
	HomeID       uint32
	NodeID       uint8
	ValueID      *ValueID
	GroupIDX     *uint8
	Event        *uint8
	ButtonID     *uint8
	SceneID      *uint8
	Notification *NotificationCode
}

// buildNotification builds a new Notification filled with the relevant
// information from the OpenZWave::Notification as received from the OpenZWave
// library.
func buildNotification(n C.notification_t) *Notification {
	notification := &Notification{
		HomeID: uint32(C.notification_getHomeId(n)),
		NodeID: uint8(C.notification_getNodeId(n)),
	}

	switch C.notification_getType(n) {
	case C.notification_type_valueAdded:
		notification.Type = NotificationTypeValueAdded
	case C.notification_type_valueRemoved:
		notification.Type = NotificationTypeValueRemoved
	case C.notification_type_valueChanged:
		notification.Type = NotificationTypeValueChanged
	case C.notification_type_valueRefreshed:
		notification.Type = NotificationTypeValueRefreshed
	case C.notification_type_group:
		notification.Type = NotificationTypeGroup
	case C.notification_type_nodeNew:
		notification.Type = NotificationTypeNodeNew
	case C.notification_type_nodeAdded:
		notification.Type = NotificationTypeNodeAdded
	case C.notification_type_nodeRemoved:
		notification.Type = NotificationTypeNodeRemoved
	case C.notification_type_nodeProtocolInfo:
		notification.Type = NotificationTypeNodeProtocolInfo
	case C.notification_type_nodeNaming:
		notification.Type = NotificationTypeNodeNaming
	case C.notification_type_nodeEvent:
		notification.Type = NotificationTypeNodeEvent
	case C.notification_type_pollingDisabled:
		notification.Type = NotificationTypePollingDisabled
	case C.notification_type_pollingEnabled:
		notification.Type = NotificationTypePollingEnabled
	case C.notification_type_sceneEvent:
		notification.Type = NotificationTypeSceneEvent
	case C.notification_type_createButton:
		notification.Type = NotificationTypeCreateButton
	case C.notification_type_deleteButton:
		notification.Type = NotificationTypeDeleteButton
	case C.notification_type_buttonOn:
		notification.Type = NotificationTypeButtonOn
	case C.notification_type_buttonOff:
		notification.Type = NotificationTypeButtonOff
	case C.notification_type_driverReady:
		notification.Type = NotificationTypeDriverReady
	case C.notification_type_driverFailed:
		notification.Type = NotificationTypeDriverFailed
	case C.notification_type_driverReset:
		notification.Type = NotificationTypeDriverReset
	case C.notification_type_essentialNodeQueriesComplete:
		notification.Type = NotificationTypeEssentialNodeQueriesComplete
	case C.notification_type_nodeQueriesComplete:
		notification.Type = NotificationTypeNodeQueriesComplete
	case C.notification_type_awakeNodesQueried:
		notification.Type = NotificationTypeAwakeNodesQueried
	case C.notification_type_allNodesQueriedSomeDead:
		notification.Type = NotificationTypeAllNodesQueriedSomeDead
	case C.notification_type_allNodesQueried:
		notification.Type = NotificationTypeAllNodesQueried
	case C.notification_type_notification:
		notification.Type = NotificationTypeNotification
	case C.notification_type_driverRemoved:
		notification.Type = NotificationTypeDriverRemoved
	case C.notification_type_controllerCommand:
		notification.Type = NotificationTypeControllerCommand
	case C.notification_type_nodeReset:
		notification.Type = NotificationTypeNodeReset
	}

	switch notification.Type {
	case NotificationTypeCreateButton, NotificationTypeDeleteButton, NotificationTypeButtonOn, NotificationTypeButtonOff:
		if notification.ButtonID == nil {
			notification.ButtonID = new(uint8)
		}
		*(notification.ButtonID) = uint8(C.notification_getButtonId(n))

	case NotificationTypeNodeEvent:
		if notification.Event == nil {
			notification.Event = new(uint8)
		}
		*(notification.Event) = uint8(C.notification_getEvent(n))

	case NotificationTypeGroup:
		if notification.GroupIDX == nil {
			notification.GroupIDX = new(uint8)
		}
		*(notification.GroupIDX) = uint8(C.notification_getGroupIdx(n))

	case NotificationTypeNotification:
		if notification.Notification == nil {
			notification.Notification = new(NotificationCode)
		}
		switch C.notification_getNotification(n) {
		case C.notification_code_msgComplete:
			*notification.Notification = NotificationCodeMsgComplete
		case C.notification_code_timeout:
			*notification.Notification = NotificationCodeTimeout
		case C.notification_code_noOperation:
			*notification.Notification = NotificationCodeNoOperation
		case C.notification_code_awake:
			*notification.Notification = NotificationCodeAwake
		case C.notification_code_sleep:
			*notification.Notification = NotificationCodeSleep
		case C.notification_code_dead:
			*notification.Notification = NotificationCodeDead
		case C.notification_code_alive:
			*notification.Notification = NotificationCodeAlive
		}

	case NotificationTypeControllerCommand:
		if notification.Event == nil {
			notification.Event = new(uint8)
		}
		*(notification.Event) = uint8(C.notification_getEvent(n))
		if notification.Notification == nil {
			notification.Notification = new(NotificationCode)
		}
		*(notification.Notification) = NotificationCode(C.notification_getNotification(n))

	case NotificationTypeSceneEvent:
		if notification.SceneID == nil {
			notification.SceneID = new(uint8)
		}
		*(notification.SceneID) = uint8(C.notification_getSceneId(n))
	}

	return notification
}

func (n *Notification) String() string {
	var pointed []string
	if n.ValueID != nil {
		pointed = append(pointed, fmt.Sprintf("ValueID: %s", n.ValueID))
	}
	if n.GroupIDX != nil {
		pointed = append(pointed, fmt.Sprintf("GroupIDX: %d", *(n.GroupIDX)))
	}
	if n.Event != nil {
		pointed = append(pointed, fmt.Sprintf("Event: %d", *(n.Event)))
	}
	if n.ButtonID != nil {
		pointed = append(pointed, fmt.Sprintf("ButtonID: %d", *(n.ButtonID)))
	}
	if n.SceneID != nil {
		pointed = append(pointed, fmt.Sprintf("SceneID: %d", *(n.SceneID)))
	}
	if n.Notification != nil {
		pointed = append(pointed, fmt.Sprintf("Notification: %d", *(n.Notification)))
	}
	output := fmt.Sprintf("<%s, HomeID: %x, NodeID: %d", n.Type, n.HomeID, n.NodeID)
	for i := range pointed {
		output = fmt.Sprintf("%s, %s", output, pointed[i])
	}
	output = fmt.Sprintf("%s>", output)
	return output
}
<|endoftext|>


<commit_before>package log

import (
	"fmt"
	"strings"

	"github.com/mralves/tracer"

	"github.com/mundipagg/boleto-api/config"
)

type LogEntry = map[string]interface{}

var logger tracer.Logger

//Operation a operacao usada na API
var Operation string

//Recipient o nome do banco
var Recipient string

//Log struct com os elemtos do log
type Log struct {
	Operation   string
	Recipient   string
	RequestKey  string
	BankName    string
	IPAddress   string
	ServiceUser string
	NossoNumero uint
	logger      tracer.Logger
}

//Install instala o "servico" de log do SEQ
func Install() {
	configureTracer()
	logger = tracer.GetLogger("boleto")
}

func formatter(message string) string {
	return "[{Application}: {Operation}] - {MessageType} " + message
}

//CreateLog cria uma nova instancia do Log
func CreateLog() *Log {
	return &Log{
		logger: logger,
	}
}

//Request loga o request para algum banco
func (l *Log) Request(content interface{}, url string, headers map[string]string) {
	if config.Get().DisableLog {
		return
	}

	go (func() {
		props := l.defaultProperties("Request", content)
		props["Headers"] = headers
		props["URL"] = url

		action := strings.Split(url, "/")
		msg := formatter(fmt.Sprintf("to {BankName} (%s) | {Recipient}", action[len(action)-1]))

		l.logger.Info(msg, props)
	})()
}

//Response loga o response para algum banco
func (l *Log) Response(content interface{}, url string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {

		action := strings.Split(url, "/")
		msg := formatter(fmt.Sprintf("from {BankName} (%s) | {Recipient}", action[len(action)-1]))

		props := l.defaultProperties("Response", content)
		props["URL"] = url

		l.logger.Info(msg, props)
	})()
}

//RequestApplication loga o request que chega na boleto api
func (l *Log) RequestApplication(content interface{}, url string, headers map[string]string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {

		props := l.defaultProperties("Request", content)
		props["Headers"] = headers
		props["URL"] = url

		msg := formatter("from {IPAddress} | {Recipient}")

		l.logger.Info(msg, props)
	})()
}

//ResponseApplication loga o response que sai da boleto api
func (l *Log) ResponseApplication(content interface{}, url string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.defaultProperties("Response", content)
		props["URL"] = url

		msg := formatter("{Operation} | {Recipient}")

		l.logger.Info(msg, props)
	})()
}

//Info loga mensagem do level INFO
func (l *Log) Info(msg string) {
	if config.Get().DisableLog {
		return
	}
	go l.logger.Info(msg, nil)
}

//Info loga mensagem do level INFO
func Info(msg string) {
	if config.Get().DisableLog {
		return
	}
	go logger.Info(msg, nil)
}

//Warn loga mensagem do leve Warning
func (l *Log) Warn(content interface{}, msg string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.defaultProperties("Warning", content)
		m := formatter(msg)

		l.logger.Warn(m, props)
	})()
}

func (l *Log) Error(content interface{}, msg string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.defaultProperties("Error", content)
		m := formatter(msg)

		l.logger.Error(m, props)
	})()
}

// Fatal loga erros da aplicação
func (l *Log) Fatal(content interface{}, msg string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.defaultProperties("Fatal", content)
		m := formatter(msg)

		l.logger.Fatal(m, props)
	})()
}

//InitRobot loga o inicio da execução do robô de recovery
func (l *Log) InitRobot(totalRecords int) {
	msg := formatter("- Starting execution")
	go func() {
		props := defaultRobotProperties("Execute", l.Operation, "")
		props["TotalRecords"] = totalRecords
		logger.Info(msg, props)
	}()
}

//ResumeRobot loga um resumo de Recovery do robô de recovery
func (l *Log) ResumeRobot(key string) {
	msg := formatter(key)
	go func() {
		props := defaultRobotProperties("RecoveryBoleto", l.Operation, key)
		props["RequestKey"] = l.RequestKey
		logger.Info(msg, props)
	}()
}

//EndRobot loga o fim da execução do robô de recovery
func (l *Log) EndRobot() {
	msg := formatter("- Finishing execution")
	go logger.Info(msg, defaultRobotProperties("Finish", l.Operation, ""))
}

func (l *Log) defaultProperties(messageType string, content interface{}) LogEntry {
	props := LogEntry{
		"Content":     content,
		"Recipient":   l.Recipient,
		"NossoNumero": l.NossoNumero,
		"RequestKey":  l.RequestKey,
		"BankName":    l.BankName,
		"ServiceUser": l.ServiceUser,
	}

	for k, v := range l.basicProperties(messageType) {
		props[k] = v
	}

	return props
}

//Warn loga mensagem do leve Warning
func (l *Log) GetBoleto(msg string, id string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.basicProperties("Information")
		props["Id"] = id
		m := formatter(msg)

		l.logger.Info(m, props)
	})()
}

func (l *Log) basicProperties(messageType string) LogEntry {
	props := LogEntry{
		"MessageType": messageType,
		"Operation":   l.Operation,
		"IPAddress":   l.IPAddress,
	}
	return props
}

func defaultRobotProperties(msgType, op, key string) LogEntry {
	props := LogEntry{
		"MessageType": msgType,
		"Operation":   op,
	}

	if key != "" {
		props["BoletoKey"] = key
	}
	return props
}
<commit_msg>:art: Corrige descrição do método<commit_after>package log

import (
	"fmt"
	"strings"

	"github.com/mralves/tracer"

	"github.com/mundipagg/boleto-api/config"
)

type LogEntry = map[string]interface{}

var logger tracer.Logger

//Operation a operacao usada na API
var Operation string

//Recipient o nome do banco
var Recipient string

//Log struct com os elemtos do log
type Log struct {
	Operation   string
	Recipient   string
	RequestKey  string
	BankName    string
	IPAddress   string
	ServiceUser string
	NossoNumero uint
	logger      tracer.Logger
}

//Install instala o "servico" de log do SEQ
func Install() {
	configureTracer()
	logger = tracer.GetLogger("boleto")
}

func formatter(message string) string {
	return "[{Application}: {Operation}] - {MessageType} " + message
}

//CreateLog cria uma nova instancia do Log
func CreateLog() *Log {
	return &Log{
		logger: logger,
	}
}

//Request loga o request para algum banco
func (l *Log) Request(content interface{}, url string, headers map[string]string) {
	if config.Get().DisableLog {
		return
	}

	go (func() {
		props := l.defaultProperties("Request", content)
		props["Headers"] = headers
		props["URL"] = url

		action := strings.Split(url, "/")
		msg := formatter(fmt.Sprintf("to {BankName} (%s) | {Recipient}", action[len(action)-1]))

		l.logger.Info(msg, props)
	})()
}

//Response loga o response para algum banco
func (l *Log) Response(content interface{}, url string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {

		action := strings.Split(url, "/")
		msg := formatter(fmt.Sprintf("from {BankName} (%s) | {Recipient}", action[len(action)-1]))

		props := l.defaultProperties("Response", content)
		props["URL"] = url

		l.logger.Info(msg, props)
	})()
}

//RequestApplication loga o request que chega na boleto api
func (l *Log) RequestApplication(content interface{}, url string, headers map[string]string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {

		props := l.defaultProperties("Request", content)
		props["Headers"] = headers
		props["URL"] = url

		msg := formatter("from {IPAddress} | {Recipient}")

		l.logger.Info(msg, props)
	})()
}

//ResponseApplication loga o response que sai da boleto api
func (l *Log) ResponseApplication(content interface{}, url string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.defaultProperties("Response", content)
		props["URL"] = url

		msg := formatter("{Operation} | {Recipient}")

		l.logger.Info(msg, props)
	})()
}

//Info loga mensagem do level INFO
func (l *Log) Info(msg string) {
	if config.Get().DisableLog {
		return
	}
	go l.logger.Info(msg, nil)
}

//Info loga mensagem do level INFO
func Info(msg string) {
	if config.Get().DisableLog {
		return
	}
	go logger.Info(msg, nil)
}

//Warn loga mensagem do leve Warning
func (l *Log) Warn(content interface{}, msg string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.defaultProperties("Warning", content)
		m := formatter(msg)

		l.logger.Warn(m, props)
	})()
}

func (l *Log) Error(content interface{}, msg string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.defaultProperties("Error", content)
		m := formatter(msg)

		l.logger.Error(m, props)
	})()
}

// Fatal loga erros da aplicação
func (l *Log) Fatal(content interface{}, msg string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.defaultProperties("Fatal", content)
		m := formatter(msg)

		l.logger.Fatal(m, props)
	})()
}

//InitRobot loga o inicio da execução do robô de recovery
func (l *Log) InitRobot(totalRecords int) {
	msg := formatter("- Starting execution")
	go func() {
		props := defaultRobotProperties("Execute", l.Operation, "")
		props["TotalRecords"] = totalRecords
		logger.Info(msg, props)
	}()
}

//ResumeRobot loga um resumo de Recovery do robô de recovery
func (l *Log) ResumeRobot(key string) {
	msg := formatter(key)
	go func() {
		props := defaultRobotProperties("RecoveryBoleto", l.Operation, key)
		props["RequestKey"] = l.RequestKey
		logger.Info(msg, props)
	}()
}

//EndRobot loga o fim da execução do robô de recovery
func (l *Log) EndRobot() {
	msg := formatter("- Finishing execution")
	go logger.Info(msg, defaultRobotProperties("Finish", l.Operation, ""))
}

func (l *Log) defaultProperties(messageType string, content interface{}) LogEntry {
	props := LogEntry{
		"Content":     content,
		"Recipient":   l.Recipient,
		"NossoNumero": l.NossoNumero,
		"RequestKey":  l.RequestKey,
		"BankName":    l.BankName,
		"ServiceUser": l.ServiceUser,
	}

	for k, v := range l.basicProperties(messageType) {
		props[k] = v
	}

	return props
}

//GetBoleto Loga mensagem de recuperação de boleto
func (l *Log) GetBoleto(msg string, id string) {
	if config.Get().DisableLog {
		return
	}
	go (func() {
		props := l.basicProperties("Information")
		props["Id"] = id
		m := formatter(msg)

		l.logger.Info(m, props)
	})()
}

func (l *Log) basicProperties(messageType string) LogEntry {
	props := LogEntry{
		"MessageType": messageType,
		"Operation":   l.Operation,
		"IPAddress":   l.IPAddress,
	}
	return props
}

func defaultRobotProperties(msgType, op, key string) LogEntry {
	props := LogEntry{
		"MessageType": msgType,
		"Operation":   op,
	}

	if key != "" {
		props["BoletoKey"] = key
	}
	return props
}
<|endoftext|>


<commit_before>package log

import (
	"time"
)

type Level uint

const (
	_                = 0
	ErrorLevel Level = 1 << (iota - 1)
	WarnLevel
	InfoLevel
	DebugLevel
	TraceLevel
)

type Logger struct {
	recorder Recorder
	ctx      []Item
}

type Record struct {
	l      Logger
	Meta   Metadata
	Format string
	Args   []interface{}
}

func (r *Record) Context() []Item {
	return r.l.ctx
}

type Item struct {
	Name  string
	Value interface{}
}

type Metadata struct {
	Level Level
	Time  time.Time
	File  string
	Line  uint
}

func newRecord(l Logger, m Metadata, format string, args []interface{}) Record {
	return Record{l: l, Meta: m, Format: format, Args: args}
}

func newMetadata(lvl Level, withTime bool) Metadata {
	if withTime {
		return Metadata{Level: lvl, Time: time.Now()}
	}
	return Metadata{Level: lvl}
}

func (l Logger) IsEnabled(lvl Level) bool {
	m := newMetadata(lvl, false)
	return l.recorder.IsEnabled(&m)
}

func (l Logger) Logf(lvl Level, format string, args ...interface{}) {
	if !l.IsEnabled(lvl) {
		return
	}
	r := newRecord(l, newMetadata(lvl, true), format, args)
	l.recorder.Log(&r)
}

func (l Logger) Log(lvl Level, message string) {
	l.Logf(lvl, message)
}

func (l Logger) LogV(lvl Level, args ...interface{}) {
	l.Logf(lvl, "", args...)
}

func (l Logger) Info(message string) {
	l.Log(InfoLevel, message)
}

func (l Logger) Warn(message string) {
	l.Log(WarnLevel, message)
}

func (l Logger) Error(message string) {
	l.Log(ErrorLevel, message)
}

func (l Logger) Debug(message string) {
	l.Log(DebugLevel, message)
}

func (l Logger) Trace(message string) {
	l.Log(TraceLevel, message)
}

func (l Logger) InfoV(args ...interface{}) {
	l.LogV(InfoLevel, args...)
}

func (l Logger) WarnV(args ...interface{}) {
	l.LogV(WarnLevel, args...)
}

func (l Logger) ErrorV(args ...interface{}) {
	l.LogV(ErrorLevel, args...)
}

func (l Logger) DebugV(args ...interface{}) {
	l.LogV(DebugLevel, args...)
}

func (l Logger) TraceV(args ...interface{}) {
	l.LogV(TraceLevel, args...)
}

func (l Logger) Infof(format string, args ...interface{}) {
	l.Logf(InfoLevel, format, args...)
}

func (l Logger) Warnf(format string, args ...interface{}) {
	l.Logf(WarnLevel, format, args...)
}

func (l Logger) Errorf(format string, args ...interface{}) {
	l.Logf(ErrorLevel, format, args...)
}

func (l Logger) Debugf(format string, args ...interface{}) {
	l.Logf(DebugLevel, format, args...)
}

func (l Logger) Tracef(format string, args ...interface{}) {
	l.Logf(TraceLevel, format, args...)
}

func (l Logger) Flush() {
	l.recorder.Flush()
}

func (l Logger) WithContext(name string, value interface{}) Logger {
	cx := append(l.ctx, Item{name, value})
	return Logger{g.recorder, cx}
}

func (l Logger) WithContextItems(items []Item) Logger {
	cx := append(g.ctx, items...)
	return Logger{g.recorder, cx}
}

func IsEnabled(lvl Level) bool {
	return g.IsEnabled(lvl)
}

func Logf(lvl Level, format string, args ...interface{}) {
	g.Logf(lvl, format, args...)
}

func Log(lvl Level, message string) {
	g.Log(lvl, message)
}

func LogV(lvl Level, args ...interface{}) {
	g.LogV(lvl, args...)
}

func Info(message string) {
	g.Info(message)
}

func Warn(message string) {
	g.Warn(message)
}

func Error(message string) {
	g.Error(message)
}

func Debug(message string) {
	g.Debug(message)
}

func Trace(message string) {
	g.Trace(message)
}

func InfoV(args ...interface{}) {
	g.InfoV(args...)
}

func WarnV(args ...interface{}) {
	g.WarnV(args...)
}

func ErrorV(args ...interface{}) {
	g.ErrorV(args...)
}

func DebugV(args ...interface{}) {
	g.DebugV(args...)
}

func TraceV(args ...interface{}) {
	g.TraceV(args...)
}

func Infof(format string, args ...interface{}) {
	g.Infof(format, args...)
}

func Warnf(format string, args ...interface{}) {
	g.Warnf(format, args...)
}

func Errorf(format string, args ...interface{}) {
	g.Errorf(format, args...)
}

func Debugf(format string, args ...interface{}) {
	g.Debugf(format, args...)
}

func Tracef(format string, args ...interface{}) {
	g.Tracef(format, args...)
}

func Flush() {
	g.Flush()
}

func WithContext(name string, val interface{}) Logger {
	return g.WithContext(name, val)
}

func WithContextItems(items []Item) Logger {
	return g.WithContextItems(items)
}

var (
	g Logger
)

func init() {
	g = Logger{recorder: NopRecorder{}}
}

func SetGlobal(recorder Recorder) {
	g.recorder = recorder
}

func New(recorder Recorder) *Logger {
	return &Logger{recorder, nil}
}
<commit_msg>change: use pointers for globals<commit_after>package log

import (
	"time"
)

type Level uint

const (
	_                = 0
	ErrorLevel Level = 1 << (iota - 1)
	WarnLevel
	InfoLevel
	DebugLevel
	TraceLevel
)

type Logger struct {
	recorder Recorder
	ctx      []Item
}

type Record struct {
	l      Logger
	Meta   Metadata
	Format string
	Args   []interface{}
}

func (r *Record) Context() []Item {
	return r.l.ctx
}

type Item struct {
	Name  string
	Value interface{}
}

type Metadata struct {
	Level Level
	Time  time.Time
	File  string
	Line  uint
}

func newRecord(l Logger, m Metadata, format string, args []interface{}) Record {
	return Record{l: l, Meta: m, Format: format, Args: args}
}

func newMetadata(lvl Level, withTime bool) Metadata {
	if withTime {
		return Metadata{Level: lvl, Time: time.Now()}
	}
	return Metadata{Level: lvl}
}

func (l Logger) IsEnabled(lvl Level) bool {
	m := newMetadata(lvl, false)
	return l.recorder.IsEnabled(&m)
}

func (l Logger) Logf(lvl Level, format string, args ...interface{}) {
	if !l.IsEnabled(lvl) {
		return
	}
	r := newRecord(l, newMetadata(lvl, true), format, args)
	l.recorder.Log(&r)
}

func (l Logger) Log(lvl Level, message string) {
	l.Logf(lvl, message)
}

func (l Logger) LogV(lvl Level, args ...interface{}) {
	l.Logf(lvl, "", args...)
}

func (l Logger) Info(message string) {
	l.Log(InfoLevel, message)
}

func (l Logger) Warn(message string) {
	l.Log(WarnLevel, message)
}

func (l Logger) Error(message string) {
	l.Log(ErrorLevel, message)
}

func (l Logger) Debug(message string) {
	l.Log(DebugLevel, message)
}

func (l Logger) Trace(message string) {
	l.Log(TraceLevel, message)
}

func (l Logger) InfoV(args ...interface{}) {
	l.LogV(InfoLevel, args...)
}

func (l Logger) WarnV(args ...interface{}) {
	l.LogV(WarnLevel, args...)
}

func (l Logger) ErrorV(args ...interface{}) {
	l.LogV(ErrorLevel, args...)
}

func (l Logger) DebugV(args ...interface{}) {
	l.LogV(DebugLevel, args...)
}

func (l Logger) TraceV(args ...interface{}) {
	l.LogV(TraceLevel, args...)
}

func (l Logger) Infof(format string, args ...interface{}) {
	l.Logf(InfoLevel, format, args...)
}

func (l Logger) Warnf(format string, args ...interface{}) {
	l.Logf(WarnLevel, format, args...)
}

func (l Logger) Errorf(format string, args ...interface{}) {
	l.Logf(ErrorLevel, format, args...)
}

func (l Logger) Debugf(format string, args ...interface{}) {
	l.Logf(DebugLevel, format, args...)
}

func (l Logger) Tracef(format string, args ...interface{}) {
	l.Logf(TraceLevel, format, args...)
}

func (l Logger) Flush() {
	l.recorder.Flush()
}

func (l Logger) WithContext(name string, value interface{}) Logger {
	cx := append(l.ctx, Item{name, value})
	return Logger{g.recorder, cx}
}

func (l Logger) WithContextItems(items []Item) Logger {
	cx := append(g.ctx, items...)
	return Logger{g.recorder, cx}
}

func IsEnabled(lvl Level) bool {
	return g.IsEnabled(lvl)
}

func Logf(lvl Level, format string, args ...interface{}) {
	g.Logf(lvl, format, args...)
}

func Log(lvl Level, message string) {
	g.Log(lvl, message)
}

func LogV(lvl Level, args ...interface{}) {
	g.LogV(lvl, args...)
}

func Info(message string) {
	g.Info(message)
}

func Warn(message string) {
	g.Warn(message)
}

func Error(message string) {
	g.Error(message)
}

func Debug(message string) {
	g.Debug(message)
}

func Trace(message string) {
	g.Trace(message)
}

func InfoV(args ...interface{}) {
	g.InfoV(args...)
}

func WarnV(args ...interface{}) {
	g.WarnV(args...)
}

func ErrorV(args ...interface{}) {
	g.ErrorV(args...)
}

func DebugV(args ...interface{}) {
	g.DebugV(args...)
}

func TraceV(args ...interface{}) {
	g.TraceV(args...)
}

func Infof(format string, args ...interface{}) {
	g.Infof(format, args...)
}

func Warnf(format string, args ...interface{}) {
	g.Warnf(format, args...)
}

func Errorf(format string, args ...interface{}) {
	g.Errorf(format, args...)
}

func Debugf(format string, args ...interface{}) {
	g.Debugf(format, args...)
}

func Tracef(format string, args ...interface{}) {
	g.Tracef(format, args...)
}

func Flush() {
	g.Flush()
}

func WithContext(name string, val interface{}) Logger {
	return g.WithContext(name, val)
}

func WithContextItems(items []Item) Logger {
	return g.WithContextItems(items)
}

var (
	g *Logger
)

func init() {
	g = &Logger{recorder: NopRecorder{}}
}

func SetGlobal(l *Logger) {
	g = l
}

func GetGlobal() *Logger {
	return g
}

func New(recorder Recorder) *Logger {
	return &Logger{recorder, nil}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/deevatech/manager/runner"
	. "github.com/deevatech/manager/types"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"os"
)

func init() {
	log.Println("Deeva Manager!")
}

func main() {
	router := gin.Default()
	router.POST("/run", handleRunRequest)

	port := os.Getenv("DEEVA_MANAGER_PORT")
	if len(port) == 0 {
		port = "8080"
	}

	log.Printf("Starting in %s mode on port %s\n", gin.Mode(), port)
	host := fmt.Sprintf(":%s", port)
	router.Run(host)
}

func handleRunRequest(c *gin.Context) {
	var run RunParams
	if errParams := c.BindJSON(&run); errParams == nil {
		if result, errRun := runner.Run(run); errRun == nil {
			c.JSON(http.StatusOK, result)
		} else {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": errRun,
			})
		}
	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": errParams,
		})
	}
}
<commit_msg>Add endpoint to fetch a test by id<commit_after>package main

import (
	"fmt"
	"github.com/deevatech/manager/models/tests"
	"github.com/deevatech/manager/runner"
	. "github.com/deevatech/manager/types"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"os"
	"strconv"
)

func init() {
	log.Println("Deeva Manager!")
}

func main() {
	router := gin.Default()
	router.POST("/run", handleRunRequest)
	router.GET("/tests/:id", handleTestLookupRequest)

	port := os.Getenv("DEEVA_MANAGER_PORT")
	if len(port) == 0 {
		port = "8080"
	}

	log.Printf("Starting in %s mode on port %s\n", gin.Mode(), port)
	host := fmt.Sprintf(":%s", port)
	router.Run(host)
}

func handleRunRequest(c *gin.Context) {
	var run RunParams
	if errParams := c.BindJSON(&run); errParams == nil {
		if result, errRun := runner.Run(run); errRun == nil {
			c.JSON(http.StatusOK, result)
		} else {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": errRun,
			})
		}
	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": errParams,
		})
	}
}

func handleTestLookupRequest(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": err,
		})
		return
	}

	test := tests.FindById(id)
	c.JSON(http.StatusOK, test)
}
<|endoftext|>


<commit_before>package smitego

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
)

// MatchPlayer is a struct that represents a player that participated in a Smite
// match.
type MatchPlayer struct {
	AccountLevel       int    `json:"Account_Level"`
	Activeid1          int    `json:"ActiveId1"`
	Activeid2          int    `json:"ActiveId2"`
	Assists            int    `json:"Assists"`
	Ban1               string `json:"Ban1"`
	Ban1id             int    `json:"Ban1Id"`
	Ban2               string `json:"Ban2"`
	Ban2id             int    `json:"Ban2Id"`
	Ban3               string `json:"Ban3"`
	Ban3id             int    `json:"Ban3Id"`
	Ban4               string `json:"Ban4"`
	Ban4id             int    `json:"Ban4Id"`
	DamageBot          int    `json:"Damage_Bot"`
	DamageDoneMagical  int    `json:"Damage_Done_Magical"`
	DamageDonePhysical int    `json:"Damage_Done_Physical"`
	DamagePlayer       int    `json:"Damage_Player"`
	DamageTaken        int    `json:"Damage_Taken"`
	Deaths             int    `json:"Deaths"`
	EntryDatetime      string `json:"Entry_Datetime"`
	FinalMatchLevel    int    `json:"Final_Match_Level"`
	Godid              int    `json:"GodId"`
	GoldEarned         int    `json:"Gold_Earned"`
	GoldPerMinute      int    `json:"Gold_Per_Minute"`
	Healing            int    `json:"Healing"`
	Itemid1            int    `json:"ItemId1"`
	Itemid2            int    `json:"ItemId2"`
	Itemid3            int    `json:"ItemId3"`
	Itemid4            int    `json:"ItemId4"`
	Itemid5            int    `json:"ItemId5"`
	Itemid6            int    `json:"ItemId6"`
	ItemActive1        string `json:"Item_Active_1"`
	ItemActive2        string `json:"Item_Active_2"`
	ItemActive3        string `json:"Item_Active_3"`
	ItemPurch1         string `json:"Item_Purch_1"`
	ItemPurch2         string `json:"Item_Purch_2"`
	ItemPurch3         string `json:"Item_Purch_3"`
	ItemPurch4         string `json:"Item_Purch_4"`
	ItemPurch5         string `json:"Item_Purch_5"`
	ItemPurch6         string `json:"Item_Purch_6"`
	KillingSpree       int    `json:"Killing_Spree"`
	KillsBot           int    `json:"Kills_Bot"`
	KillsPlayer        int    `json:"Kills_Player"`
	MasteryLevel       int    `json:"Mastery_Level"`
	Match              int    `json:"Match"`
	Minutes            int    `json:"Minutes"`
	MultiKillMax       int    `json:"Multi_kill_Max"`
	Partyid            int    `json:"PartyId"`
	ReferenceName      string `json:"Reference_Name"`
	Skin               string `json:"Skin"`
	Skinid             int    `json:"SkinId"`
	StructureDamage    int    `json:"Structure_Damage"`
	Surrendered        string `json:"Surrendered"`
	Team1score         int    `json:"Team1Score"`
	Team2score         int    `json:"Team2Score"`
	Teamid             int    `json:"TeamId"`
	TeamName           string `json:"Team_Name"`
	WinStatus          string `json:"Win_Status"`
	Name               string `json:"name"`
	Playername         string `json:"playerName"`
	RetMsg             string `json:"ret_msg"`
}

// ModeDetail is a struct that represents the mode information of a given match.
type ModeDetail struct {
	Ban1               string `json:"Ban1"`
	Ban2               string `json:"Ban2"`
	EntryDatetime      string `json:"Entry_Datetime"`
	Match              int    `json:"Match"`
	MatchTime          int    `json:"Match_Time"`
	OfflineSpectators  int    `json:"Offline_Spectators"`
	RealtimeSpectators int    `json:"Realtime_Spectators"`
	RecordingEnded     string `json:"Recording_Ended"`
	RecordingStarted   string `json:"Recording_Started"`
	Team1Avglevel      int    `json:"Team1_AvgLevel"`
	Team1Gold          int    `json:"Team1_Gold"`
	Team1Kills         int    `json:"Team1_Kills"`
	Team1Score         int    `json:"Team1_Score"`
	Team2Avglevel      int    `json:"Team2_AvgLevel"`
	Team2Gold          int    `json:"Team2_Gold"`
	Team2Kills         int    `json:"Team2_Kills"`
	Team2Score         int    `json:"Team2_Score"`
	WinningTeam        int    `json:"Winning_Team"`
	ReturnMessage      string `json:"ret_msg"`
}

// GetModeDetails returns a ModeDetail instance loaded with mode information
// for a specific match ID.
func GetModeDetails(matchID string) ModeDetail {
	hash := getMD5Hash(DevID + "getmodetails" + AuthKey + getTimestamp())
	url := "http://api.smitegame.com/smiteapi.svc/getmodetailsJson/" + DevID + "/" + hash + "/" + SessionID + "/" + getTimestamp() + matchID

	response, err := http.Get(url)
	if err != nil {
		perror(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			perror(err)
		} else {
			var modeDetail []ModeDetail
			json.Unmarshal(contents, &modeDetail)
			return modeDetail[0]
		}
	}
	modeDetail := ModeDetail{ReturnMessage: "Not found"}
	return modeDetail

	// TODO: This API endpoint is broken, find out why.

	// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	//
	//
	//     <title>Service</title>
	//
	//
	//
	//

	//
Service

	//
Endpoint not found.

	//

	//
	//
}
<commit_msg>Fix bug with getmodedetails api endpoint.<commit_after>package smitego

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
)

// MatchPlayer is a struct that represents a player that participated in a Smite
// match.
type MatchPlayer struct {
	AccountLevel       int    `json:"Account_Level"`
	Activeid1          int    `json:"ActiveId1"`
	Activeid2          int    `json:"ActiveId2"`
	Assists            int    `json:"Assists"`
	Ban1               string `json:"Ban1"`
	Ban1id             int    `json:"Ban1Id"`
	Ban2               string `json:"Ban2"`
	Ban2id             int    `json:"Ban2Id"`
	Ban3               string `json:"Ban3"`
	Ban3id             int    `json:"Ban3Id"`
	Ban4               string `json:"Ban4"`
	Ban4id             int    `json:"Ban4Id"`
	DamageBot          int    `json:"Damage_Bot"`
	DamageDoneMagical  int    `json:"Damage_Done_Magical"`
	DamageDonePhysical int    `json:"Damage_Done_Physical"`
	DamagePlayer       int    `json:"Damage_Player"`
	DamageTaken        int    `json:"Damage_Taken"`
	Deaths             int    `json:"Deaths"`
	EntryDatetime      string `json:"Entry_Datetime"`
	FinalMatchLevel    int    `json:"Final_Match_Level"`
	Godid              int    `json:"GodId"`
	GoldEarned         int    `json:"Gold_Earned"`
	GoldPerMinute      int    `json:"Gold_Per_Minute"`
	Healing            int    `json:"Healing"`
	Itemid1            int    `json:"ItemId1"`
	Itemid2            int    `json:"ItemId2"`
	Itemid3            int    `json:"ItemId3"`
	Itemid4            int    `json:"ItemId4"`
	Itemid5            int    `json:"ItemId5"`
	Itemid6            int    `json:"ItemId6"`
	ItemActive1        string `json:"Item_Active_1"`
	ItemActive2        string `json:"Item_Active_2"`
	ItemActive3        string `json:"Item_Active_3"`
	ItemPurch1         string `json:"Item_Purch_1"`
	ItemPurch2         string `json:"Item_Purch_2"`
	ItemPurch3         string `json:"Item_Purch_3"`
	ItemPurch4         string `json:"Item_Purch_4"`
	ItemPurch5         string `json:"Item_Purch_5"`
	ItemPurch6         string `json:"Item_Purch_6"`
	KillingSpree       int    `json:"Killing_Spree"`
	KillsBot           int    `json:"Kills_Bot"`
	KillsPlayer        int    `json:"Kills_Player"`
	MasteryLevel       int    `json:"Mastery_Level"`
	Match              int    `json:"Match"`
	Minutes            int    `json:"Minutes"`
	MultiKillMax       int    `json:"Multi_kill_Max"`
	Partyid            int    `json:"PartyId"`
	ReferenceName      string `json:"Reference_Name"`
	Skin               string `json:"Skin"`
	Skinid             int    `json:"SkinId"`
	StructureDamage    int    `json:"Structure_Damage"`
	Surrendered        string `json:"Surrendered"`
	Team1score         int    `json:"Team1Score"`
	Team2score         int    `json:"Team2Score"`
	Teamid             int    `json:"TeamId"`
	TeamName           string `json:"Team_Name"`
	WinStatus          string `json:"Win_Status"`
	Name               string `json:"name"`
	Playername         string `json:"playerName"`
	RetMsg             string `json:"ret_msg"`
}

// ModeDetail is a struct that represents the mode information of a given match.
type ModeDetail struct {
	Ban1               string `json:"Ban1"`
	Ban2               string `json:"Ban2"`
	EntryDatetime      string `json:"Entry_Datetime"`
	Match              int    `json:"Match"`
	MatchTime          int    `json:"Match_Time"`
	OfflineSpectators  int    `json:"Offline_Spectators"`
	RealtimeSpectators int    `json:"Realtime_Spectators"`
	RecordingEnded     string `json:"Recording_Ended"`
	RecordingStarted   string `json:"Recording_Started"`
	Team1Avglevel      int    `json:"Team1_AvgLevel"`
	Team1Gold          int    `json:"Team1_Gold"`
	Team1Kills         int    `json:"Team1_Kills"`
	Team1Score         int    `json:"Team1_Score"`
	Team2Avglevel      int    `json:"Team2_AvgLevel"`
	Team2Gold          int    `json:"Team2_Gold"`
	Team2Kills         int    `json:"Team2_Kills"`
	Team2Score         int    `json:"Team2_Score"`
	WinningTeam        int    `json:"Winning_Team"`
	ReturnMessage      string `json:"ret_msg"`
}

// GetModeDetails returns a ModeDetail instance loaded with mode information
// for a specific match ID.
func GetModeDetails(matchID string) ModeDetail {
	hash := getMD5Hash(DevID + "getdemodetails" + AuthKey + getTimestamp())
	url := "http://api.smitegame.com/smiteapi.svc/getdemodetailsJson/" + DevID + "/" + hash + "/" + SessionID + "/" + getTimestamp() + "/" + matchID

	response, err := http.Get(url)
	if err != nil {
		perror(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			perror(err)
		} else {
			var modeDetail []ModeDetail
			json.Unmarshal(contents, &modeDetail)
			return modeDetail[0]
		}
	}
	modeDetail := ModeDetail{ReturnMessage: "Not found"}
	return modeDetail

	// TODO: This API endpoint is broken, find out why.

	// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	//
	//
	//     <title>Service</title>
	//
	//
	//
	//

	//
Service

	//
Endpoint not found.

	//

	//
	//
}
<|endoftext|>


<commit_before>package openrtb_test

import (
	"encoding/json"
	"io/ioutil"
	"path/filepath"
	"testing"

	"github.com/mxmCherry/openrtb"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
)

func TestOpenRTB(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "OpenRTB")
}

// ----------------------------------------------------------------------------

var _ = DescribeTable(
	"Marshalling",
	func(filename string, subject interface{}) {

		expected, err := ioutil.ReadFile(filepath.Join("testdata", filename))
		Expect(err).NotTo(HaveOccurred())

		Expect(json.Unmarshal(expected, subject)).To(Succeed())

		actual, err := json.Marshal(subject)
		Expect(err).NotTo(HaveOccurred())

		Expect(actual).To(MatchJSON(expected))
	},
	Entry(
		"Bid Request - Simple Banner",
		"bid-request-simple-banner.json",
		new(openrtb.BidRequest)),
	Entry(
		"Bid Request - Expandable Creative",
		"bid-request-expandable-creative.json",
		new(openrtb.BidRequest)),
	Entry(
		"Bid Request - Mobile",
		"bid-request-mobile.json",
		new(openrtb.BidRequest)),
	Entry(
		"Bid Request - Video",
		"bid-request-video.json",
		new(openrtb.BidRequest)),
	Entry(
		"Bid Request - PMP with Direct Deal",
		"bid-request-pmp-with-direct-deal.json",
		new(openrtb.BidRequest)),
	Entry(
		"Bid Request - Native Ad",
		"bid-request-native-ad.json",
		new(openrtb.BidRequest)),

	Entry(
		"Bid Response - Ad Served on Win Notice",
		"bid-response-ad-served-on-win-notice.json",
		new(openrtb.BidResponse)),
	Entry(
		"Bid Response - VAST XML Document Returned Inline",
		"bid-response-vast-xml-document-returned-inline.json",
		new(openrtb.BidResponse)),
	Entry(
		"Bid Response - Direct Deal Ad Served on Win Notice",
		"bid-response-direct-deal-ad-served-on-win-notice.json",
		new(openrtb.BidResponse)),
	Entry(
		"Bid Response - Native Markup Returned Inline",
		"bid-response-native-markup-returned-inline.json",
		new(openrtb.BidResponse)),
)
<commit_msg>Test OCD cosmetics<commit_after>package openrtb_test

import (
	"encoding/json"
	"io/ioutil"
	"path/filepath"
	"testing"

	. "github.com/mxmCherry/openrtb"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
)

func TestOpenRTB(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "OpenRTB")
}

// ----------------------------------------------------------------------------

var _ = DescribeTable(
	"Marshalling",
	func(filename string, subject interface{}) {

		expected, err := ioutil.ReadFile(filepath.Join("testdata", filename))
		Expect(err).NotTo(HaveOccurred())

		Expect(json.Unmarshal(expected, subject)).To(Succeed())

		actual, err := json.Marshal(subject)
		Expect(err).NotTo(HaveOccurred())

		Expect(actual).To(MatchJSON(expected))
	},
	Entry(
		"Bid Request - Simple Banner",
		"bid-request-simple-banner.json",
		new(BidRequest)),
	Entry(
		"Bid Request - Expandable Creative",
		"bid-request-expandable-creative.json",
		new(BidRequest)),
	Entry(
		"Bid Request - Mobile",
		"bid-request-mobile.json",
		new(BidRequest)),
	Entry(
		"Bid Request - Video",
		"bid-request-video.json",
		new(BidRequest)),
	Entry(
		"Bid Request - PMP with Direct Deal",
		"bid-request-pmp-with-direct-deal.json",
		new(BidRequest)),
	Entry(
		"Bid Request - Native Ad",
		"bid-request-native-ad.json",
		new(BidRequest)),

	Entry(
		"Bid Response - Ad Served on Win Notice",
		"bid-response-ad-served-on-win-notice.json",
		new(BidResponse)),
	Entry(
		"Bid Response - VAST XML Document Returned Inline",
		"bid-response-vast-xml-document-returned-inline.json",
		new(BidResponse)),
	Entry(
		"Bid Response - Direct Deal Ad Served on Win Notice",
		"bid-response-direct-deal-ad-served-on-win-notice.json",
		new(BidResponse)),
	Entry(
		"Bid Response - Native Markup Returned Inline",
		"bid-response-native-markup-returned-inline.json",
		new(BidResponse)),
)
<|endoftext|>